Javascript HighChart:带下拉列表的堆叠柱形图

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

我正在尝试使用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 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