Built with blockbuilder.org
Last active
December 10, 2015 20:51
-
-
Save HectorLS/c6e555ccfb95203cd105 to your computer and use it in GitHub Desktop.
Understanding Data Join
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
<link rel="stylesheet" type="text/css" href="styles.css"> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
svg { width: 100%; height: 100%; } | |
</style> | |
</head> | |
<body> | |
<script> | |
var dataset = [ | |
{datetime: "2013-01-01T11:56:00+00:00", amount: 200, pageViews: 412, enabled: true}, | |
{datetime: "2013-03-10T12:34:00+00:00", amount: 50, pageViews: 412, enabled: true}, | |
{datetime: "2013-05-21T13:00:00+00:00", amount: 1250, pageViews: 412, enabled: true}, | |
{datetime: "2013-06-23T17:00:00+00:00", amount: 300, pageViews: 3500, enabled: true}, | |
{datetime: "2013-10-25T19:00:00+00:00", amount: 600.456, pageViews: 412, enabled: true}, | |
{datetime: "2013-12-29T21:15:00+00:00", amount: 550, pageViews: 412, enabled: true}, | |
{datetime: "2013-12-30T23:11:00+00:00", amount: 233, pageViews: 412, enabled: true}, | |
]; | |
function getRandomInt(min, max) { | |
for(var i = 0; i < dataset.length; i++){ | |
var newval = Math.floor(Math.random() * (max - min)) + min; | |
dataset[i].pageViews = newval; | |
dataset[i].amount = newval; | |
} | |
console.log(dataset[0].pageViews); | |
update(dataset); | |
return dataset; | |
} | |
// SVG config | |
// --------------------------------------------------------------- // | |
// Set the margin for the svg content | |
var margin = {top: 35, right: 40, bottom: 50, left: 50}, | |
svgWidth = 920, | |
svgHeight = 480, | |
contentWidth = svgWidth - margin.left - margin.right, | |
contentHeight = svgHeight - margin.top - margin.bottom; | |
svg = d3.select("#chart--01") | |
.append("svg") | |
.attr("class", "chart sample-chart") | |
.attr("width", svgWidth) | |
.attr("height", svgHeight) | |
.append('g') | |
.attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')'); // Centering | |
// Static Config ( No data dependency ) | |
// --------------------------------------------------------------- // | |
// Set the $Ranges // | |
var xScale = d3.time.scale.utc().range([0, contentWidth]), | |
yScale = d3.scale.linear().range([contentHeight, 0]), | |
yScale1 = d3.scale.linear().range([contentHeight, 0]); | |
// Set the $Axes // | |
var xAxis = d3.svg.axis().scale(xScale).orient("bottom").ticks(5), | |
yAxisLeft = d3.svg.axis().scale(yScale).orient("left" ).ticks(5).tickFormat(d3.format("s")), | |
yAxisRight = d3.svg.axis().scale(yScale1).orient("right").ticks(5).tickFormat(d3.format("s")); | |
// Set the $Grids // | |
function xGrid() { return d3.svg.axis().scale(xScale).orient("bottom").ticks(5); } | |
function yGrid() { return d3.svg.axis().scale(yScale).orient("left" ).ticks(5); } | |
// Dynamic Config ( data dependency ) | |
// --------------------------------------------------------------- // | |
function update(data) { | |
// $Parse Date // | |
var parseDate = d3.time.format.utc("%Y-%m-%dT%H:%M:%S+00:00").parse; | |
dataset.forEach(function (d) { | |
d.datetime = parseDate(d.datetime); | |
d.amount = +d.amount; | |
d.pageViews = +d.pageViews; | |
}); | |
// $Scale the $Range // | |
xScale.domain(d3.extent(dataset, function (d) { return d.datetime; })).nice(); | |
yScale.domain([0, d3.max(dataset, function (d) { return Math.max(d.amount, d.pageViews); })]); | |
yScale1.domain([0, d3.max(dataset, function (d) { return Math.max(d.amount, d.pageViews); })]); | |
// Set the $Line and $Area // | |
var valueline = d3.svg.line() | |
.interpolate("cardinal") | |
.x(function (d) { return xScale(d.datetime); }) | |
.y(function (d) { return yScale(d.amount); }); | |
var valueline2 =d3.svg.line() | |
.interpolate("cardinal") | |
.x(function (d) { return xScale(d.datetime); }) | |
.y(function (d) { return yScale1(d.pageViews);}); | |
svg.append("path") | |
.attr("class", "line line1") | |
.attr("d", valueline(dataset)); | |
svg.append("path") | |
.attr("class", "line line2") | |
.attr("d", valueline2(dataset)); | |
// Draw the x Grid lines | |
svg.append("g") | |
.attr("class", "grid") | |
.attr("transform", "translate(0," + contentHeight + ")") | |
.call(xGrid() | |
.tickSize(-contentHeight, 0, 0) | |
.tickFormat("") | |
); | |
// Draw the y Grid lines | |
svg.append("g") | |
.attr("class", "grid") | |
.call(yGrid() | |
.tickSize(-contentWidth, 0, 0) | |
.tickFormat("") | |
); | |
var axes = svg.selectAll(".axis") | |
.data(dataset, function(d) { return d; }); | |
var lines = svg.selectAll("path") | |
.data(dataset, function(d) { return d; }); | |
// == Data Join | |
// Join new data with old elements, if any. | |
// == Data Update | |
// Update old elements as needed. | |
// Draw Axes // | |
svg.append("g") | |
.attr("class", "axis x") | |
.attr("transform", "translate(0, " + contentHeight + ")") | |
.call(xAxis); | |
svg.append("g") | |
.attr("class", "axis y left") | |
.call(yAxisLeft); | |
svg.append("g") // Add the Y Axis Right | |
.attr("class", "axis y right y1") | |
.attr("transform", "translate(" + contentWidth + " ,0)") | |
.call(yAxisRight); | |
// == Data Enter | |
// Create new elements as needed. | |
lines.select(".line") | |
.transition() | |
.duration(750) | |
.attr("d", valueline(dataset)); | |
lines.select(".line2") | |
.transition() | |
.duration(750) | |
.attr("d", valueline2(dataset)); | |
axes.select(".axis.x") | |
.transition() | |
.duration(750) | |
.call(xAxis); | |
axes.select(".axis.y.left") | |
.transition() | |
.duration(750) | |
.call(yAxisLeft); | |
axes.select(".axis.y.right") | |
.transition() | |
.duration(750) | |
.call(yAxisRight); | |
// == Data Enter | |
// Appending to the enter selection expands the update selection to include | |
// entering elements; so, operations on the update selection after appending to | |
// the enter selection will apply to both entering and updating nodes. | |
// == Date Exit | |
// Remove old elements as needed.. | |
} | |
// The initial display and the refresh interval | |
// --------------------------------------------------------------- // | |
update(dataset); | |
setInterval(function() { getRandomInt(0, 5000); }, 3000) | |
</script> | |
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* { | |
box-sizing: border-box; | |
} | |
body { | |
width:100%; | |
height:100%;å | |
background: silver; | |
margin: 0 auto; | |
} | |
#chart--01 { | |
width :100%; | |
height :220px; | |
background-color: gold; | |
margin : 10px auto; | |
padding : 2% 0; | |
border : 1px solid black; | |
text-align: center; | |
} | |
/* Temporal para testing*/ | |
svg.chart { | |
border: 1px solid blue; | |
background-color: azure; | |
} | |
/* Chart */ | |
.line { | |
stroke : steelblue; | |
stroke-width : 1; | |
fill : none; | |
} | |
.line2 { | |
stroke :red; | |
} | |
/* Axes lines*/ | |
.axis path, | |
.axis line { | |
fill : none; | |
stroke : grey; | |
stroke-width: 1; | |
shape-rendering: crispEdges; | |
} | |
.axis.y path { | |
stroke-width: 0; | |
} | |
/* Axes Content */ | |
.axis .tick text { | |
fill: black; | |
font-size: 11px; | |
} | |
/* Grid */ | |
.grid .tick { | |
stroke: lightgrey; | |
stroke-opacity: 0.4; | |
shape-rendering: crispEdges; | |
stroke-dasharray: 3,3; | |
/*stroke-width: 1;*/ | |
} | |
.grid path { | |
stroke-width: 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment