Skip to content

Instantly share code, notes, and snippets.

@DeBraid
Created January 10, 2014 19:46
Show Gist options
  • Save DeBraid/8361294 to your computer and use it in GitHub Desktop.
Save DeBraid/8361294 to your computer and use it in GitHub Desktop.
Live: Grid & Select: candle/line/area charts
{"description":"Live: Grid & Select: candle/line/area charts","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"quote.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"sample.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"sample.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"style.css":{"default":true,"vim":false,"emacs":false,"fontSize":12},"buttons,js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"buttons.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"dropdown.js":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"pingpong","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"thumbnail":"http://i.imgur.com/W3cqIY2.png"}
// loading sample.json
var sample2 = tributary.sample.sample2;
// date manipulation to format UTC to js Date obj
sample2.forEach(function(d) { d.time = new Date(d.time * 1000); });
// helpers and constants
var margin = {"top": 50, "right": 100, "bottom": 50, "left": 50};
var width = 930 - margin.right - margin.left;
var height = 582 - margin.top - margin.bottom;
var timeFormat = d3.time.format("%c");
var X = width/sample2.length*0.25;
var bisectDate = d3.bisector(function(d) { return d.time; }).left;
// find data range
var xDomain = d3.extent(sample2, function (d, i){ return d.time; });
var yMin = d3.min(sample2, function(d){ return Math.min(d.low); });
var yMax = d3.max(sample2, function(d){ return Math.max(d.high); });
// scales, add 10pc padding to x-domain
var xScale = d3.time.scale()
.domain(xDomain);
xScale.domain([-0.05,1.05].map(xScale.invert))
.range([margin.left, width - margin.right]);
var yScale = d3.scale.linear()
.domain([yMin, yMax])
.range([height - margin.top, margin.bottom]);
// set up axes
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(5)
.tickPadding(5);
// .tickFormat(timeFormat)
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("right")
.ticks(5)
.tickFormat(function(d) { return "$" + d});
// set up chart types
var area = d3.svg.area()
.x(function(d){ return xScale(d.time); })
.y0(height- margin.bottom)
.y1(function(d){ return yScale(d.close); });
var line = d3.svg.line().interpolate("basis")
.x(function(d){ return xScale(d.time); })
.y(function(d){ return yScale(d.close); });
// create svg container and offset
var canvas = d3.select("svg")
.attr({"width": width, "height": height})
.append("g")
.attr("transform", "translate(" + margin.top/2 + "," + margin.left/2 + ")");
// grid plot
var grid = canvas.append("svg:rect")
.attr({
"width": width - margin.right - margin.left,
"height": height - margin.bottom - margin.top,
"class": "plot",
"transform": "translate(" + margin.top + "," + margin.bottom + ")"
});
grid.append("g").append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", 300)
.attr("height", 300);
canvas.selectAll("line.horizontalGrid").data(yScale.ticks(5))
.enter()
.append("line")
.attr({
"class":"horizontalGrid",
"x1" : margin.left,
"x2" : width - margin.right,
"y1" : function(d){ return yScale(d);},
"y2" : function(d){ return yScale(d);}
});
canvas.append("text").text("$GOOG")
.attr({"x": width*0.06, "dy": "1.5em" })
.style("font-size", "30")
// drop down menu
var chartOptions = ["candle", "line", "area"];
var dropDown = d3.select(".tributary_svg")
.append("foreignObject")
.attr({
"height": 500,
"width": 500,
"transform": "translate(" + (width*0.645) + "," + margin.top*0.6 + ")"
})
.append("xhtml:select")
.attr("id", "drop-down")
.selectAll("option")
.data(chartOptions)
.enter()
.append("option")
.text(function(d) { return d;})
.attr("value", function(d){ return d; });
// big daddy - draw the chart
function chartDraw () {
// chart options by type
var type = {
candle: function(){
canvas.selectAll("line.candle")
.data(sample2)
.enter()
.append("svg:line")
.attr({
"class": "candle alt-view",
"x1": function(d,i) { return xScale(d.time) - X*0.5; },
"x2": function(d,i) { return xScale(d.time) - X*0.5; },
"y1": function(d,i) { return yScale(d.high); },
"y2": function(d,i) { return yScale(d.low); },
"stroke": "black"
});
canvas.selectAll("rect.candle")
.data(sample2)
.enter()
.append("svg:rect")
.attr({
"class": "candle alt-view",
"width": function(d){ return X},
"x": function(d,i) { return xScale(d.time) - X; },
"y": function(d,i) { return yScale(Math.max(d.open, d.close)); },
"height": function(d,i) { return yScale(Math.min(d.open, d.close)) - yScale(Math.max(d.open, d.close)); },
"fill": function (d) { return d.open > d.close ? "#dc432c" : "#0CD1AA" },
"stroke": "black"
});
},
line: function(){
canvas.append("path")
.datum(sample2)
.attr("class", "line alt-view")
.attr("d", line);
},
area: function (){
canvas.append("linearGradient")
.attr("id", "temperature-gradient")
.attr("gradientUnits", "userSpaceOnUse")
.attr("x1", 0).attr("y1", yScale(yMin))
.attr("x2", 0).attr("y2", yScale(yMax))
.selectAll("stop")
.data([
{offset: "20%", color: "#DC432C"},
{offset: "45%", color: "#0CD1AA"}
])
.enter().append("stop")
.attr("offset", function(d) { return d.offset; })
.attr("stop-color", function(d) { return d.color; });
canvas.append("path")
.datum(sample2)
.attr("class", "area alt-view")
.attr("d", area);
}
};
// default chart
type.candle();
d3.select("#drop-down")
.on("change", function () {
d3.selectAll(".alt-view").remove();
selected = this.value;
if (selected == "line") { return type.line(); }
else if (selected == "area") { return type.area(); }
else if (selected == "candle") { return type.candle(); }
});
// draw axes
canvas.append('g').attr("class","x axis").call(xAxis)
.attr('transform', 'translate(0, ' + (height - margin.bottom) + ')');
canvas.append('g').attr("class","y axis").call(yAxis)
.attr('transform', 'translate(' + (width - margin.right) + ', 0)');
}
chartDraw();
// add cross hairs and floating value on axis
var focus = canvas.append("g")
.attr("class", "focus")
.style("display", "none");
var focusTextOpen = canvas.append("g")
.style("display", "none")
.attr("class","focus");
focusTextOpen.append("text")
.attr({"x": width*0.25, "dy": "2.5em" });
var focusTextClose = canvas.append("g")
.attr("class","focus")
.style("display", "none");
focusTextClose.append("text")
.attr({"x": width*0.4, "dy": "2.5em" });
// horizontal crosshair
focus.append("line")
.attr({
"x1": -width,
"y1": 0,
"x2": width,
"y2": 0,
"class": "h"
});
// vertical crosshair
focus.append("line")
.attr({
"x1": 0,
"y1": -height,
"x2": 0,
"y2": height,
"class": "v"
});
canvas.append("rect")
.attr({"class": "overlay" , "width": width , "height": height})
.on({
"mouseover": function() { focus.style("display", null); focusTextOpen.style("display", null); focusTextClose.style("display", null); },
"mouseout": function() { focus.style("display", "none"); focusTextOpen.style("display", "none"); focusTextClose.style("display", "none"); },
"mousemove": mousemove
});
function mousemove() {
var x0 = xScale.invert(d3.mouse(this)[0]),
i = bisectDate(sample2, x0, 1),
d0 = sample2[i-1],
d1 = sample2[i],
d = d1.date - x0 > x0 - d0.date ? d1 : d0;
focus.attr("transform", "translate(" + (d3.mouse(this)[0] -4) + "," + (d3.mouse(this)[1]) + ")");
focus.select(".h").attr({"x1": margin.left - d3.mouse(this)[0], "x2": width - margin.right - d3.mouse(this)[0]});
focus.select(".v").attr({"y1": margin.top - d3.mouse(this)[1], "y2": height - margin.bottom - d3.mouse(this)[1]});
focusTextClose.select("text").text("Close: $" + d.close);
focusTextOpen.select("text").text("Open: $" + d.open);
}
/*
scroll http://jsfiddle.net/KSAbK/1/
*/
{"sample2": [
{"time": 1387212120, "open": 368, "close": 275, "high": 380, "low": 231},
{"time": 1387212130, "open": 330, "close": 350, "high": 389, "low": 310},
{"time": 1387212140, "open": 213, "close": 253, "high": 289, "low": 213},
{"time": 1387212150, "open": 180, "close": 150, "high": 189, "low": 110},
{"time": 1387212160, "open": 310, "close": 350, "high": 389, "low": 310},
{"time": 1387212170, "open": 213, "close": 253, "high": 289, "low": 213},
{"time": 1387212180, "open": 190, "close": 150, "high": 189, "low": 110},
{"time": 1387212190, "open": 362, "close": 530, "high": 529, "low": 294},
{"time": 1387212200, "open": 409, "close": 426, "high": 438, "low": 225},
{"time": 1387212210, "open": 334, "close": 275, "high": 369, "low": 185},
{"time": 1387212220, "open": 304, "close": 389, "high": 389, "low": 310},
{"time": 1387212230, "open": 395, "close": 235, "high": 289, "low": 213},
{"time": 1387212240, "open": 339, "close": 148, "high": 189, "low": 110},
{"time": 1387212250, "open": 310, "close": 350, "high": 389, "low": 310},
{"time": 1387212260, "open": 283, "close": 241, "high": 289, "low": 213},
{"time": 1387212270, "open": 290, "close": 350, "high": 444, "low": 273},
{"time": 1387212280, "open": 448, "close": 550, "high": 594, "low": 390},
{"time": 1387212290, "open": 419, "close": 245, "high": 194, "low": 510},
{"time": 1387212300, "open": 150, "close": 163, "high": 189, "low": 145},
{"time": 1387212310, "open": 330, "close": 350, "high": 356, "low": 310},
{"time": 1387212320, "open": 213, "close": 253, "high": 289, "low": 213},
{"time": 1387212330, "open": 180, "close": 150, "high": 189, "low": 110},
{"time": 1387212340, "open": 310, "close": 350, "high": 389, "low": 310},
{"time": 1387212350, "open": 213, "close": 253, "high": 289, "low": 213},
{"time": 1387212360, "open": 190, "close": 150, "high": 230, "low": 110},
{"time": 1387212370, "open": 408, "close": 301, "high": 382, "low": 245},
{"time": 1387212380, "open": 330, "close": 356, "high": 404, "low": 230},
{"time": 1387212390, "open": 183, "close": 143, "high": 190, "low": 31},
{"time": 1387212400, "open": 183, "close": 265, "high": 271, "low": 165},
{"time": 1387212410, "open": 395, "close": 253, "high": 424, "low": 213},
{"time": 1387212420, "open": 339, "close": 379, "high": 446, "low": 275},
{"time": 1387212430, "open": 310, "close": 350, "high": 389, "low": 310},
{"time": 1387212440, "open": 283, "close": 253, "high": 289, "low": 213},
{"time": 1387212450, "open": 162, "close": 350, "high": 189, "low": 122},
{"time": 1387212460, "open": 452, "close": 361, "high": 525, "low": 329},
{"time": 1387212470, "open": 173, "close": 281, "high": 312, "low": 141},
{"time": 1387212480, "open": 183, "close": 265, "high": 271, "low": 165},
{"time": 1387212490, "open": 395, "close": 253, "high": 424, "low": 213},
{"time": 1387212500, "open": 339, "close": 379, "high": 446, "low": 275},
{"time": 1387212510, "open": 310, "close": 350, "high": 389, "low": 310},
{"time": 1387212520, "open": 283, "close": 253, "high": 289, "low": 213},
{"time": 1387212530, "open": 162, "close": 350, "high": 189, "low": 122},
{"time": 1387212540, "open": 452, "close": 361, "high": 542, "low": 329},
{"time": 1387212550, "open": 173, "close": 281, "high": 312, "low": 91},
{"time": 1387212560, "open": 183, "close": 265, "high": 271, "low": 165},
{"time": 1387212570, "open": 395, "close": 253, "high": 438, "low": 213}
]}
text {
fill: black;
font-family: 'Ubuntu', 'Helvetica', 'Arial', sans-serif !important;
}
.line {
fill: none;
stroke: #0CD1AA;
stroke-width: 3px;
}
.plot {
fill: #c9c9c9;
opacity: 0.5;
}
.horizontalGrid {
fill: none;
shape-rendering: crispEdges;
stroke: grey;
stroke-width: 1px;
stroke-dasharray: 6,3;
opacity: 0.33;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.area {
fill: url(#temperature-gradient);
opacity: 0.6;
}
.overlay {
fill: none;
pointer-events: all;
cursor: none;
}
.focus line {
fill: none;
stroke: black;
}
.focus text, .v, .h {
opacity: 0.5;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment