D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
AlexDaGr8
Full window
Github gist
Trying reusable
<!DOCTYPE html> <body> <div id="charts"></div> <div id="chart"></div> <script src="https://d3js.org/d3.v4.min.js"></script> <script> var m = 40, w = 960 - m*2, h = 500 - m*2; var svg = d3.select('#charts').append('svg') .attr('width', w + m*2).attr('height', h + m*2) .append('g') .attr('transform', 'translate(' + [m,m] + ')'); var data = []; for (var i = 0; i< 50; i++) { data.push({ index: i + '', value: Math.floor(Math.random() * 10), radius: Math.floor(Math.random() * 2) }); } data.forEach(function(d) { d.index = +d.index; }) var color = d3.scaleOrdinal(d3.schemeCategory10); lineChart(data) barChart(data); function lineChart(data) { var lineChart = svg.append('g') .attr('class', 'lineChart'); var lineW = w/2 - m; var x = d3.scaleLinear() .range([0,lineW]); var y = d3.scaleLinear() .range([h,0]); var radius = d3.scaleLinear() .range([5,10]); var line = d3.line() .x((d,i) => x(i)) .y((d) => y(d.value)); //x.domain([-5,data.length]); x.domain([0, d3.max(data, (d) => d.index)]) y.domain([0,d3.max(data,(d,i) => d.value)]) radius.domain(d3.extent(data,(d) => d.radius)); lineChart.append('g') .attr('class', 'y-axis') .attr('transform', 'translate(' + x(0) + ',0)') .call(d3.axisLeft(y)) lineChart.append('g') .attr('class', 'x-axis') .attr('transform', 'translate(0,' + h + ')') .call(d3.axisBottom(x)) lineChart.append('path') .data([data]) .attr('d', line) .attr('fill', 'none') .attr('stroke', 'black') .attr('stroke-width', 3) lineChart.selectAll('.circle') .data(data) .enter().append('circle') .attr('class', 'circle') .attr('cx', (d) => x(d.index)) .attr('cy', function(d,i) { return y(d.value); }) .attr('r', (d) => radius(d.radius)) .attr('fill', 'white') .attr('stroke', (d) => color(d.radius)) .attr('stroke-width', 5) } function barChart(data) { var barW = w/2 - m; var barChart = svg.append('g') .attr('class', 'barChart') .attr('transform', 'translate(' + (barW + m) + ',0)'); var nest = d3.nest() .key((d) => d.radius) .sortKeys(d3.ascending) .entries(data); var y = d3.scaleLinear() .range([h,0]) .domain([0,d3.max(nest, (d) => d.values.length)]); var x = d3.scaleBand() .range([0,barW]) .domain(nest.map((d) => d.key)) .padding(.2); barChart.append('g') .attr('transform', 'translate(0,' + h + ')') .call(d3.axisBottom(x)) barChart.selectAll('rect') .data(nest) .enter().append('rect') .attr('x', (d) => x(d.key)) .attr('y', (d) => y(d.values.length)) .attr('width', x.bandwidth()) .attr('height', (d) => h - y(d.values.length)) .attr('fill', (d) => color(d.key)) } var updatableChart = line_chart() .x('index') .y('value') console.log(data) d3.select('#chart') .datum(data) .call(updatableChart); window.setTimeout(function() { updatableChart.y('value'); }, 1000); // window.setTimeout(function() { // updatableChart.x('radius'); // }, 2000); // Using Mike Bostock's Towards Reusable Charts Pattern function line_chart() { var margin = {top:20,right:20,bottom:20,left:30}, width = 960 - margin.right - margin.left, height = 500 - margin.top - margin.bottom; var x, y, svg, fillColor = 'steelblue'; var updateY; function chart(selection){ selection.each(function (data) { var xScale = d3.scaleLinear().range([0,width]), yScale = d3.scaleLinear().range([height,0]); var line = d3.line().x((d) => xScale(d[x])).y((d) => yScale(d[y])); xScale.domain([0, d3.max(data, (d) => d[x])]) yScale.domain([0,d3.max(data,(d,i) => d[y])]) svg = d3.select(this).append('svg') .attr('height', height + margin.right + margin.left) .attr('width', width + margin.top + margin.bottom) .append('g') .attr('transform', 'translate(' + [margin.left, margin.top] + ')'); var xAxis = svg.append('g') .attr('transform', 'translate(0, ' + height + ')') .call(d3.axisBottom(xScale)); var yAxis = svg.append('g') .call(d3.axisLeft(yScale).ticks(3)) var linePath = svg.append('path') .datum(data) .attr('class', 'line-path') .attr('d', line) .attr('fill', 'none') .attr('stroke', fillColor); updateX = function () { xScale.domain([0, d3.max(data,(d) => d[x])]); line.x((d) => xScale(d[x])); xAxis.transition() .duration(500) .call(d3.axisBottom(xScale)) svg.select('.line-path') .transition().duration(500) .attr('d', line(data.sort((a,b) => a.value - b.value).sort((a,b) => a.radius - b.radius))); } updateY = function () { yScale.domain([0, d3.max(data,(d) => d[y])]); line.y((d) => yScale(d[y])); yAxis.transition() .duration(500) .call(d3.axisLeft(yScale)) svg.select('.line-path') .transition().duration(500) .attr('d', line(data)); } }); } chart.width = function(value) { if (!arguments.length) return width; width = value; return chart; }; chart.height = function(value) { if (!arguments.length) return height; height = value - margin.top - margin.bottom; return chart; }; chart.x = function(value) { if (!arguments.length) return x; x = value; if (typeof updateX === 'function') updateX(); return chart; }; chart.y = function(value) { if (!arguments.length) return y; y = value; if (typeof updateY === 'function') updateY(); return chart; }; chart.fillColor = function(value) { if (!arguments.length) return fillColor; fillColor = value; return chart; }; return chart; } </script> </body>
https://d3js.org/d3.v4.min.js