Javascript HighChart:带下拉列表的堆叠柱形图
我正在尝试使用d3.js进行复制 到目前为止,我已经成功构建了一个显示所有数据的堆叠条形图,但我的目的是过滤csv,并根据用户在组合中选择的国家/地区将新数据绑定到我的图表 这是我的密码:Javascript HighChart:带下拉列表的堆叠柱形图,javascript,d3.js,highcharts,crossfilter,stacked-chart,Javascript,D3.js,Highcharts,Crossfilter,Stacked Chart,我正在尝试使用d3.js进行复制 到目前为止,我已经成功构建了一个显示所有数据的堆叠条形图,但我的目的是过滤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 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>
可以通过重新加载和重新分析
CSV
并使用Highcharts official来重新加载图表数据,但更有效的方法是一次加载和分析数据,然后在需要时更新/重建图表
示例:
//模拟获取
$.get=函数(id,fn){
fn(document.getElementById(id.innerHTML);
};
$(函数(){
var图表选项={
图表:{
类型:“列”
},
xAxis:{
类型:“类别”
},
亚克斯:{
分:0,,
标题:{
正文:“历年总人口”
},
堆叠标签:{
启用:对,
风格:{
fontWeight:'粗体',
颜色:(Highcharts.theme&&Highcharts.theme.textColor)| |“灰色”
}
}
},
图例:{
对齐:“右”,
x:-30,
垂直排列:“顶部”,
y:25,
浮动:是的,
背景颜色:(Highcharts.theme&&Highcharts.theme.background2)| |“白色”,
边框颜色:“#CCC”,
边框宽度:1,
影子:错
},
工具提示:{
headerFormat:“{series.name}
”,
pointFormat:“{point.name}:{point.y}
总计:{point.stackTotal}”
},
打印选项:{
专栏:{
堆叠:“正常”,
数据标签:{
启用:对,
颜色:(Highcharts.theme&&Highcharts.theme.dataLabelsColor)| |“白色”,
风格:{
textShadow:'0 0 3px黑色'
}
}
}
},
系列:[]
};
//加载CSV仿真内嵌以在JSFIDLE中显示
$.get('data.csv',函数(数据){
//分道扬镳
var lines=data.split('\n'),
国家={};
//迭代行并创建数据集-国家/地区
$.each(行,函数)(行号,行){
var items=line.split(','),
yearFound=false,
国家、城市、年份、人口;
如果(lineNo==0){//头行包含信息
}//其余行包含数据
否则{
国家=项目[0],
城市=项目[1],
年份=项目[2],
人口=项目[3];
//检查是否有新的国家/地区
if(国家[国家]==未定义){
国家[{
姓名:年份,,
数据:[{姓名:城市,y:parseInt(人口)}]
}];
}否则{
美元。每个(国家/地区),功能(国家/地区,国家/年){
如果(年份===countryYear.name){
yearFound=true;
countryYear.data.push({name:city,y:parseInt(population)});
return false;//在每个循环中退出此属性
}
});
如果(!yearfind){//新年
国家[国家].推动({
姓名:年份,,
数据:[{姓名:城市,y:parseInt(人口)}]
});
}
}
}
});
//按年份序列对城市进行排序
美元。每个(国家/地区,职能(国家/地区名称,国家/地区){
$(“#选择国家/地区”)
.append($(“”)
.attr(“值”,国家名称)
.文本(国家名称);
美元,每个(国家,职能(j,年度){
年份.数据.排序(函数(a,b){
a、 name>b.name;
});
});
});
$(“#selectCountry”).change(function(){
所选var=此值;
如果(选定){
chartOptions.series=$.extend(true,[],国家/地区[选定];//执行深度复制以保留原始数据
Highcharts.chart('容器',chartOptions);
}
});
});
});代码>
选择国家
国家、城市、年份、人口
美国达拉斯,20101000
美国达拉斯,20111200
英国,伦敦,2010700
英国,伦敦,2011850
美国芝加哥,20101250
美国芝加哥20111300
为什么是d3.js?为什么不是海图?Highcharts非常棒:你能给我展示一个使用Highcharts具有类似功能的示例吗?是的,如果你能解释一下如何进行选择,我可以给你展示一个使用Highcharts具有确切功能的示例,但它将基于系列数据的动态变化。它可以通过series.update()/series.setData()完成,或者如果您使用的是数据模块,并且希望加载不同的数据(尽管第一种方法似乎更为理想),那么我正在寻找与示例1非常类似的方法。如果您看到了我显示的示例数据,csv中的数据包含国家、城市、年份、人口等列。我想要的是带有国家名称的下拉列表。x轴上的城市,按年份分割每个城市的堆叠柱。例如,如果我选择我们,那么图表应该有两条横线,达拉斯和芝加哥,以及每年的人口堆栈。如果您能告诉我如何从csv中读取数据,而不是在变量中设置值,那就太好了。让我知道这是否有意义,或者你需要更多的信息。非常感谢你的帮助!我想我明白了。您发布的更多信息非常有用-谢谢。这是一个数据解析的问题。我发布了我的代码作为答案。非常感谢Kacper。还有两个问题:1。如何在图表上显示值/标签?2.考虑到我还有一个维度是性别,过滤器是一个单选按钮(男性或女性)。我是否需要为此创建另一个筛选函数?再一次我真的很感谢你。我从中学到了很多example@Glenn1.在图表上有(在列中)和(在堆栈顶部)-它们可以通过API定制,所以它们可以显示不同或更多的数据。也可以使用添加自定义标签。你想展示什么样的信息?“在哪里?”格伦2。有很多方法可以解决这个问题。其中之一可能是创建更大的数据结构,以容纳不同性别的不同数据集——Kacper,它是w
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