-
-
Save abeppu/1074045 to your computer and use it in GitHub Desktop.
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.25.0"></script> | |
| <script type="text/javascript" src="http://mbostock.github.com/d3/d3.time.js?1.25.0"></script> | |
| <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> | |
| </head> | |
| <body> | |
| <div id="chart"></div> | |
| <script type="text/javascript"> | |
| var width = 900; | |
| var height = 500; | |
| String.prototype.format = function() { | |
| var formatted = this; | |
| for (var i = 0; i < arguments.length; i++) { | |
| var regexp = new RegExp('\\{'+i+'\\}', 'gi'); | |
| formatted = formatted.replace(regexp, arguments[i]); | |
| } | |
| return formatted; | |
| }; | |
| var dateFormat = d3.time.format("%Y-%m-%d"); | |
| var end = new Date(); | |
| var start = new Date(end.getTime() - 1000 * 60 * 60 * 24 * 60); | |
| var data = []; | |
| function min(a, b){ return a < b ? a : b ; } | |
| function max(a, b){ return a > b ? a : b; } | |
| function buildChart(data){ | |
| var margin = 50; | |
| var chart = d3.select("#chart") | |
| .append("svg:svg") | |
| .attr("class", "chart") | |
| .attr("width", width) | |
| .attr("height", height); | |
| var y = d3.scale.linear() | |
| .domain([d3.min(data.map(function(x) {return x["Low"];})), d3.max(data.map(function(x){return x["High"];}))]) | |
| .range([height-margin, margin]); | |
| var x = d3.scale.linear() | |
| .domain([d3.min(data.map(function(d){return dateFormat.parse(d.Date).getTime();})), | |
| d3.max(data.map(function(d){return dateFormat.parse(d.Date).getTime();}))]) | |
| .range([margin,width-margin]); | |
| chart.selectAll("line.x") | |
| .data(x.ticks(10)) | |
| .enter().append("svg:line") | |
| .attr("class", "x") | |
| .attr("x1", x) | |
| .attr("x2", x) | |
| .attr("y1", margin) | |
| .attr("y2", height - margin) | |
| .attr("stroke", "#ccc"); | |
| chart.selectAll("line.y") | |
| .data(y.ticks(10)) | |
| .enter().append("svg:line") | |
| .attr("class", "y") | |
| .attr("x1", margin) | |
| .attr("x2", width - margin) | |
| .attr("y1", y) | |
| .attr("y2", y) | |
| .attr("stroke", "#ccc"); | |
| chart.selectAll("text.xrule") | |
| .data(x.ticks(10)) | |
| .enter().append("svg:text") | |
| .attr("class", "xrule") | |
| .attr("x", x) | |
| .attr("y", height - margin) | |
| .attr("dy", 20) | |
| .attr("text-anchor", "middle") | |
| .text(function(d){ var date = new Date(d * 1000); return (date.getMonth() + 1)+"/"+date.getDate(); }); | |
| chart.selectAll("text.yrule") | |
| .data(y.ticks(10)) | |
| .enter().append("svg:text") | |
| .attr("class", "yrule") | |
| .attr("x", width - margin) | |
| .attr("y", y) | |
| .attr("dy", 0) | |
| .attr("dx", 20) | |
| .attr("text-anchor", "middle") | |
| .text(String); | |
| chart.selectAll("rect") | |
| .data(data) | |
| .enter().append("svg:rect") | |
| .attr("x", function(d) { return x(dateFormat.parse(d.Date).getTime()); }) | |
| .attr("y", function(d) {return y(max(d.Open, d.Close));}) | |
| .attr("height", function(d) { return y(min(d.Open, d.Close))-y(max(d.Open, d.Close));}) | |
| .attr("width", function(d) { return 0.5 * (width - 2*margin)/data.length; }) | |
| .attr("fill",function(d) { return d.Open > d.Close ? "red" : "green" ;}); | |
| chart.selectAll("line.stem") | |
| .data(data) | |
| .enter().append("svg:line") | |
| .attr("class", "stem") | |
| .attr("x1", function(d) { return x(dateFormat.parse(d.Date).getTime()) + 0.25 * (width - 2 * margin)/ data.length;}) | |
| .attr("x2", function(d) { return x(dateFormat.parse(d.Date).getTime()) + 0.25 * (width - 2 * margin)/ data.length;}) | |
| .attr("y1", function(d) { return y(d.High);}) | |
| .attr("y2", function(d) { return y(d.Low); }) | |
| .attr("stroke", function(d){ return d.Open > d.Close ? "red" : "green"; }) | |
| } | |
| function appendToData(x){ | |
| if(data.length > 0){ | |
| return; | |
| } | |
| data = x.query.results.quote; | |
| for(var i=0;i<data.length;i++){ | |
| data[i].timestamp = (new Date(data[i].date).getTime() / 1000); | |
| } | |
| data = data.sort(function(x, y){ return dateFormat.parse(x.Date).getTime() - dateFormat.parse(y.Date).getTime(); }); | |
| buildChart(data); | |
| } | |
| function buildQuery(){ | |
| var symbol = window.location.hash; | |
| if(symbol === ""){ | |
| symbol = "AMZN"; | |
| } | |
| symbol = symbol.replace("#", ""); | |
| var base = "select * from yahoo.finance.historicaldata where symbol = \"{0}\" and startDate = \"{1}\" and endDate = \"{2}\""; | |
| var getDateString = d3.time.format("%Y-%m-%d"); | |
| var query = base.format(symbol, getDateString(start), getDateString(end)); | |
| query = encodeURIComponent(query); | |
| var url = "http://query.yahooapis.com/v1/public/yql?q={0}&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=appendToData".format(query); | |
| return url; | |
| } | |
| function fetchData(){ | |
| url = buildQuery(); | |
| scriptElement = document.createElement("SCRIPT"); | |
| scriptElement.type = "text/javascript"; | |
| // i add to the url the call back function | |
| scriptElement.src = url; | |
| document.getElementsByTagName("HEAD")[0].appendChild(scriptElement); | |
| } | |
| $(document).ready(fetchData); | |
| </script> | |
| </body> | |
| </html> | |
Hi Mike and Aaron,
Is it possible to remove the weekends from the chart(i.e., continuous candles)?
Thanks,
Tim
really appreciate the example; hope to build on it soon. thanks.
hi abeppu, could you provide the raw query that would work on http://developer.yahoo.com/yql/console/.
I need to see the format of the data Yahoo returns so I can format my data accordingly.
I have tried
and it gives me a 'No definition found for Table yahoo.finance.historicaldata' error
Nice example! For this to work as of today, I had to change this line:
data[i].timestamp = (new Date(data[i].date).getTime() / 1000);
to this
data[i].timestamp = (new Date(data[i]['Date']).getTime() / 1000);
Thank you for the code, how can I make this chart interactive like in this example: http://bl.ocks.org/andredumas/edf630690c10b89be390
Can anyone help please ?
Nice example! For getDateString, you can use d3.time.format. Something like:
You can also use the built-in Math.min and Math.max functions. And lastly, a handy trick for sorting numbers:
This has the nice property that it returns 0 if the timestamps are equal.