我正在尝试使用d3.js
复制this example到目前为止,我已设法构建一个显示所有数据的堆积条形图,但我的目的是过滤csv并根据用户在组合中选择国家/地区将新数据绑定到我的图表。
这是我的代码:
var outerWidth = 500;
var outerHeight = 250;
var margin = { left: 90, top: 30, right: 30, bottom: 40 };
var barPadding = 0.2;
var xColumn = "City";
var yColumn = "Population";
var colorColumn = "Year";
var layerColumn = colorColumn;
var innerWidth = outerWidth - margin.left - margin.right;
var innerHeight = outerHeight - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width", outerWidth)
.attr("height", outerHeight);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xAxisG = g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + innerHeight + ")");
var yAxisG = g.append("g")
.attr("class", "y axis");
var xScale = d3.scale.ordinal().rangeBands([0, innerWidth], barPadding);
var yScale = d3.scale.linear().range([innerHeight, 0]);
var colorScale = d3.scale.category10();
// Use a modified SI formatter that uses "B" for Billion.
var siFormat = d3.format("s");
var customTickFormat = function (d){
return siFormat(d).replace("G", "B");
};
var xAxis = d3.svg.axis().scale(xScale).orient("bottom")
.outerTickSize(0);
var yAxis = d3.svg.axis().scale(yScale).orient("left")
.ticks(5)
.tickFormat(customTickFormat)
.outerTickSize(0);
function render(data){
var nested = d3.nest()
.key(function (d){ return d[layerColumn]; })
.entries(data)
var stack = d3.layout.stack()
.y(function (d){ return d[yColumn]; })
.values(function (d){ return d.values; });
var layers = stack(nested);
xScale.domain(layers[0].values.map(function (d){
return d[xColumn];
}));
yScale.domain([
0,
d3.max(layers, function (layer){
return d3.max(layer.values, function (d){
return d.y0 + d.y;
});
})
]);
colorScale.domain(layers.map(function (layer){
return layer.key;
}));
xAxisG.call(xAxis);
yAxisG.call(yAxis);
var layerGroups = g.selectAll(".layer").data(layers);
layerGroups.enter().append("g").attr("class", "layer");
layerGroups.exit().remove();
layerGroups.style("fill", function (d){
return colorScale(d.key);
});
var bars = layerGroups.selectAll("rect").data(function (d){
return d.values;
});
bars.enter().append("rect")
bars.exit().remove();
bars
.attr("x", function (d){ return xScale(d[xColumn]); })
.attr("y", function (d){ return yScale(d.y0 + d.y); })
.attr("width", xScale.rangeBand())
.attr("height", function (d){ return innerHeight - yScale(d.y); })
}
function type(d){
d.Population = +d.Population;
return d;
}
d3.csv("data.csv", type, render);
</script>
以下是data.csv中的示例数据
Country City Year Population
US Dallas 2010 1000
US Dallas 2011 1200
UK London 2010 700
UK London 2011 850
US Chicago 2010 1250
US Chicago 2011 1300
答案 0 :(得分:0)
可以通过重新加载和重新分析CSV
并使用Highcharts官方data module来重新加载图表数据,但是加载和解析数据一次更有效,下次更新/重建图表需要时。
Example:
http://jsfiddle.net/1wgqyyg9/
// Emulate get
$.get = function(id, fn) {
fn(document.getElementById(id).innerHTML);
};
$(function() {
var chartOptions = {
chart: {
type: 'column'
},
xAxis: {
type: 'category'
},
yAxis: {
min: 0,
title: {
text: 'Total population over years'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
legend: {
align: 'right',
x: -30,
verticalAlign: 'top',
y: 25,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
headerFormat: '<b>{series.name}</b><br/>',
pointFormat: '{point.name}: {point.y}<br/>Total: {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px black'
}
}
}
},
series: []
};
//load CSV - emulated infile to show in JSFiddle
$.get('data.csv', function(data) {
// Split the lines
var lines = data.split('\n'),
countries = {};
// Iterate over the lines and create data sets - countries
$.each(lines, function(lineNo, line) {
var items = line.split(','),
yearFound = false,
country, city, year, population;
if (lineNo === 0) { // header line containes info
} // rest of lines contain data
else {
country = items[0],
city = items[1],
year = items[2],
population = items[3];
// check if new country
if(countries[country] === undefined) {
countries[country] = [{
name: year,
data: [{name: city, y: parseInt(population)}]
}];
} else {
$.each(countries[country], function(yearNo, countryYear){
if(year === countryYear.name) {
yearFound = true;
countryYear.data.push({name: city, y: parseInt(population)});
return false; //exit this each loop
}
});
if(!yearFound) { // new year
countries[country].push({
name: year,
data: [{name: city, y: parseInt(population)}]
});
}
}
}
});
// sort cities in year series
$.each(countries, function(countryName,country){
$('#selectCountry')
.append($("<option></option>")
.attr("value",countryName)
.text(countryName));
$.each(country, function(j,year){
year.data.sort(function(a,b){
a.name > b.name;
});
});
});
$("#selectCountry").change(function(){
var selected = this.value;
if(selected) {
chartOptions.series = $.extend(true, [], countries[selected]); // do deep copy to keep original data
Highcharts.chart('container',chartOptions);
}
});
});
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
<select id="selectCountry">
<option>Select country</option>
</select>
<pre id="data.csv" style="display: none">Country,City,Year,Population
US,Dallas,2010,1000
US,Dallas,2011,1200
UK,London,2010,700
UK,London,2011,850
US,Chicago,2010,1250
US,Chicago,2011,1300</pre>
&#13;