Skip to content

Instantly share code, notes, and snippets.

@alexr
Created October 12, 2013 19:30
Show Gist options
  • Save alexr/6953905 to your computer and use it in GitHub Desktop.
Save alexr/6953905 to your computer and use it in GitHub Desktop.
Dynamic computation chart sample

Simple example to show dynamically computed chart based on the data in another chart. TODO: add better computation than a slice of 10 original elements :)

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis line,
.axis path {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.bar {
fill: #3080c0;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
</style>
<body>
<div id="data"></div>
<div id="result"></div>
</body>
<script src="http://d3js.org/d3.v2.min.js"></script>
<script>
function o(f, g) { return function(x) { return g(f(x)) } }
function getx(d) { return d.x }
function gety(d) { return d.y }
// Generates array of n data elements of form
// [{x:0, y:?}, {x:1, y:?}, ..., {x:n-1, y:?}]
// where y represents random function f(x) forming several bumps.
// Inspired by Lee Byron's test data generator.
function randomData(n) {
function bump(a) {
var x = 1 / (.1 + Math.random()),
y = 2 * Math.random() - .5,
z = 10 / (.1 + Math.random());
for (var i = 0; i < n; i++) {
var w = (i / n - y) * z;
a[i] += x * Math.exp(-w * w);
}
}
var a = [], i;
for (i = 0; i < n; ++i) a[i] = 0;
for (i = 0; i < 10; ++i) bump(a);
return a.map(function(d, i) { return {x: i, y: Math.max(0, d)}; });
}
// Implements conventional margins concept http://bl.ocks.org/3019563.
// container - is a d3 selection of the element to contain chart's svg element,
// dims - defines chart area configuration,
// returns function to update chart's data
function chartArea(container, dims) {
var svg = container.append('svg')
.attr('width', dims.width + dims.left + dims.right)
.attr('height', dims.height + dims.top + dims.bottom),
g = svg.append('g')
.attr('transform', 'translate(' + dims.left + ',' + dims.top + ')'),
xaxis = g.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + dims.height + ')'),
yaxis = g.append('g')
.attr('class', 'y axis');
var ch = {
left: dims.left, top: dims.top, right: dims.right, bottom: dims.bottom,
width: dims.width, height: dims.height,
chart: g, svg: svg, xaxis: xaxis, yaxis: yaxis
}
return function (data) {
var x = d3.scale.linear()
.range([0, ch.width])
.domain([d3.min(data, getx), d3.max(data, getx) + 1]),
y = d3.scale.linear()
.range([ch.height, 0])
.domain([0, d3.max(data, gety)]),
xAxis = d3.svg.axis().scale(x).orient("bottom"),
yAxis = d3.svg.axis().scale(y).orient("left");
ch.xaxis.call(xAxis);
ch.yaxis.call(yAxis);
var sel = ch.chart.selectAll('.bar')
.data(data) // only 'y' and 'height' needs to change on update
.attr('y', function(d) { return y(d.y) })
.attr('height', function(d) { return ch.height - y(d.y) });
sel.enter()
.append('rect')
.attr('class', 'bar')
.attr('x', function(d) { return x(d.x) })
.attr('y', function(d) { return y(d.y) })
.attr('width', dims.barWidth || 1)
.attr('height', function(d) { return ch.height - y(d.y) });
sel.exit().remove();
}
}
// data
var N = 500,
D = randomData(N);
// Raw data chart
var dataChart = chartArea(
d3.select('#data'),
{
top: 20, right: 20, bottom: 40, left: 40,
width: N * 2, height: 100
})(D);
// Dynamic computation result chart
var resChart = chartArea(
d3.select('body'),
{
top: 20, right: 20, bottom: 40, left: 40,
width: 10 * 21, // 10 bars of 10+1 pix each
height: 100,
barWidth: 20,
});
resChart(D.slice(0, 10)); // initial data
// This is hacky, see how can implrove...
d3.select('body').on("mousemove", function() {
var svg = d3.select('body svg g');
var mouse = d3.mouse(svg[0][0]);
if( mouse[1] > 0 && mouse[1] < 100 && //dataChartDimensions.height &&
mouse[0] > 0 && mouse[0] < N*2) { //dataChartDimensions.width) {
var shift = ~~(mouse[0]/2);
if(shift + 10 > N) return; // not full range
resChart(D.slice(shift, shift + 10));
}
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment