Enter, exit and update by datasets. Using as a component (Angular, React, ...).
Last active
October 31, 2015 15:02
-
-
Save hironow/53e75d0b7cc254011e48 to your computer and use it in GitHub Desktop.
D3 linepoints chart by datasets
This file contains hidden or 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> | |
<html> | |
<head> | |
<meta charset="UTF-8" /> | |
<title>Title</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script> | |
<style> | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: #333; | |
shape-rendering: crispEdges; | |
} | |
.axis text { | |
font-family: sans-serif; | |
font-size: 11px; | |
} | |
path.line { | |
fill: none; | |
stroke: #333; | |
stroke-width: 2px; | |
} | |
text.label { | |
fill: #333; | |
stroke: none; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="container"></div> | |
<script src="main.js"></script> | |
</body> | |
</html> |
This file contains hidden or 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
var newDataSets = [ | |
{ | |
meta: { | |
id: 1, | |
name: 'A' | |
}, | |
data: [ | |
{x: 10, y: 10}, | |
{x: 20, y: 20}, | |
{x: 30, y: 30}, | |
{x: 40, y: 40}, | |
{x: 50, y: 50} | |
] | |
}, | |
{ | |
meta: { | |
id: 3, | |
name: 'C' | |
}, | |
data: [ | |
{x: 100, y: 10}, | |
{x: 200, y: 20}, | |
{x: 300, y: 30}, | |
{x: 400, y: 40}, | |
{x: 500, y: 50} | |
] | |
} | |
]; | |
var newDataSets2 = [ | |
{ | |
meta: { | |
id: 1, | |
name: 'A' | |
}, | |
data: [ | |
{x: 10, y: 10}, | |
{x: 20, y: 20}, | |
{x: 30, y: 30}, | |
{x: 40, y: 40}, | |
{x: 50, y: 50} | |
] | |
}, | |
{ | |
meta: { | |
id: 2, | |
name: 'B' | |
}, | |
data: [ | |
{x: 10, y: 1}, | |
{x: 20, y: 2}, | |
{x: 30, y: 3}, | |
{x: 40, y: 4}, | |
{x: 50, y: 5} | |
] | |
}, | |
{ | |
meta: { | |
id: 3, | |
name: 'C' | |
}, | |
data: [ | |
{x: 100, y: 10}, | |
{x: 200, y: 20}, | |
{x: 300, y: 30}, | |
{x: 400, y: 40}, | |
{x: 500, y: 50} | |
] | |
} | |
]; | |
var firstDataSets = [ | |
{ | |
meta: { | |
id: 1, | |
name: 'A' | |
}, | |
data: [ | |
{x: 10, y: 10}, | |
{x: 20, y: 20}, | |
{x: 30, y: 30}, | |
{x: 40, y: 40}, | |
{x: 50, y: 50} | |
] | |
}, | |
{ | |
meta: { | |
id: 2, | |
name: 'B' | |
}, | |
data: [ | |
{x: 10, y: 1}, | |
{x: 20, y: 2}, | |
{x: 30, y: 3}, | |
{x: 40, y: 4}, | |
{x: 50, y: 5} | |
] | |
} | |
]; | |
var __width = 500; | |
var __height = 500; | |
var _margin = {top: 50, right: 50, bottom: 50, left: 50}; | |
var getId = function(dataSet) { return dataSet.meta.id; }; | |
var getLabel = function(dataSet) { return dataSet.meta.name; }; | |
var getData = function(dataSet) { return dataSet.data; }; | |
var getLastData = function(dataSet) { return dataSet.data[dataSet.data.length - 1]; }; | |
var getX = function(data) { return data.x; }; | |
var getY = function(data) { return data.y; }; | |
var _width = __width - _margin.left - _margin.right; | |
var _height = __height - _margin.top - _margin.bottom; | |
var xScale = d3.scale.linear().range([0, _width]); | |
var yScale = d3.scale.linear().range([_height, 0]); | |
var line = d3.svg.line().interpolate('linear') | |
.x(function(data) { return xScale(getX(data)); }) | |
.y(function(data) { return yScale(getY(data)); }) | |
var svg = d3.select('#container') | |
.append('svg') | |
.attr('width', __width) | |
.attr('height', __height); | |
var g = svg.append('g') | |
.attr('transform', | |
'translate(' + _margin.left + ',' + _margin.top + ')'); | |
render(firstDataSets); | |
setInterval(function() { | |
var dataSetsArray = [newDataSets, newDataSets2, firstDataSets]; | |
var randDataSets = dataSetsArray[Math.floor(Math.random() * dataSetsArray.length)]; | |
render(randDataSets); | |
}, 2000); | |
function render(dataSets) { | |
var xs = _.chain(dataSets).map(getData) | |
.flatten().map(getX).value(); | |
var ys = _.chain(dataSets).map(getData) | |
.flatten().map(getY).value(); | |
xScale.domain(d3.extent(xs)); | |
yScale.domain(d3.extent(ys)); | |
var xAxis = d3.svg.axis().scale(xScale).orient('bottom'); | |
var yAxis = d3.svg.axis().scale(yScale).orient('left'); | |
if (g.selectAll('g.x.axis').empty()) { | |
g.append('g') | |
.classed('x axis', true) | |
.attr('transform', 'translate(0,' + _height + ')') | |
.call(xAxis); | |
} else { | |
g.selectAll('g.x.axis') | |
.transition().duration(1000) | |
.call(xAxis); | |
} | |
if (g.selectAll('g.y.axis').empty()) { | |
g.append('g') | |
.classed('y axis', true) | |
.call(yAxis); | |
} else { | |
g.selectAll('g.y.axis') | |
.transition().duration(1000) | |
.call(yAxis); | |
} | |
// bind dataset | |
var dataSetContainers = g.selectAll('g.dataset') | |
.data(dataSets, getId); | |
// enter | |
dataSetContainers | |
.enter().append('g') | |
.classed('dataset', true) | |
.style('opacity', 0.0) | |
.transition().duration(1000) | |
.style('opacity', 1.0); | |
dataSetContainers.selectAll('path.line') | |
.data(function(dataSet) { return [dataSet]; }) | |
.enter().append('path') | |
.classed('line', true) | |
.attr('d', function(dataSet) { return line(getData(dataSet)); }); | |
dataSetContainers.selectAll('circle.point') | |
.data(function(dataSet) { return getData(dataSet); }) | |
.enter().append('circle') | |
.classed('point', true) | |
.attr('cx', function(data) { return xScale(getX(data)); }) | |
.attr('cy', function(data) { return yScale(getY(data)); }) | |
.attr('r', 2); | |
dataSetContainers.selectAll('text.label') | |
.data(function(dataSet) { return [dataSet]; }) | |
.enter().append('text') | |
.classed('label', true) | |
.attr('x', function(dataSet) { return xScale(getX(getLastData(dataSet))); }) | |
.attr('y', function(dataSet) { return yScale(getY(getLastData(dataSet))); }) | |
.text(getLabel); | |
// exit | |
dataSetContainers | |
.exit() | |
.transition().duration(1000) | |
.style('opacity', 0.0) | |
.remove(); | |
// update | |
dataSetContainers | |
.selectAll('path.line') | |
.transition().duration(1000) | |
.attr('d', function(dataSet) { return line(getData(dataSet)); }); | |
dataSetContainers | |
.selectAll('circle.point') | |
.transition().duration(1000) | |
.attr('cx', function(data) { return xScale(getX(data)); }) | |
.attr('cy', function(data) { return yScale(getY(data)); }); | |
dataSetContainers | |
.selectAll('text.label') | |
.transition().duration(1000) | |
.attr('x', function(dataSet) { return xScale(getX(getLastData(dataSet))); }) | |
.attr('y', function(dataSet) { return yScale(getY(getLastData(dataSet))); }); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment