xxxxxxxxxx
<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