【问题标题】:d3js stacked bar chart with groupsd3js 堆叠条形图与组
【发布时间】:2025-12-12 18:45:01
【问题描述】:

我是学习 d3 的新手,因此,我将不胜感激任何有关改善图表中任何低效问题的建议。我正在使用 d3js 生成具有两个色标的水平堆叠条形图。

在此示例中,有两支球队,共有 8 名球员。我们首先根据总得分来绘制球员图表,然后是每场比赛的得分。然后,我还使用了两个不同的色标来显示他们属于哪个团队。

我使用这个堆栈栏示例作为参考:http://bl.ocks.org/mbostock/3886208

...但是为了使用与团队相关的色标为每个玩家(y 轴)着色,我必须首先删除应用于为每个游戏制作的每个包装组的填充。然后我必须将每个 stack() 系列的键添加到该系列中的每个数据数组中。

在绘制单个 s 时,我必须执行 if 并硬编码 if 条件,告诉它在哪种情况下使用哪个色标。

这是我的块:https://bl.ocks.org/Ognami/2128772d2d7c1d2708d973b9401e8e1f

我的问题是,最重要的是,有没有一种更简单的方法可以将此密钥传递给每个系列中的所有数据数组?有没有办法绕过条件来选择哪个比例?

【问题讨论】:

    标签: d3.js


    【解决方案1】:

    这里有一些小的优化。将色阶存储在对象中:

    var z = {
      'a': d3.scaleOrdinal()
        .range(["#8cb6d9", "#4787ba", "#216297"]),
      'b': d3.scaleOrdinal()
        .range(["#ff5555", "#ff1122", "#990022"])
    };
    

    将域分配为:

    for (key in z){
     z[key].domain(key);
    }
    

    只需将数据向下传递给子选择并从父级获取“密钥”:

    g.append("g")
      .selectAll("g")
      .data(d3.stack().keys(keys)(data))
      .enter().append("g")
      .selectAll("rect")
      .data(d => d)
      .enter().append("rect")
      .attr("fill", function(d, i) {
        var key = d3.select(this.parentNode).datum().key;
        return z[d.data.team](key);
      });
    

    现在随着团队数量的增加或减少,您只需编辑z 以包含该团队的颜色。

    完整代码here.

    【讨论】:

    • 谢谢!我用你的建议更新了这个块,虽然我无法让 object.values() 位工作,但我认为它是一个对象而不是数组或其他东西有一些问题。但奇怪的是,它似乎根本不需要域集?我省略了那部分,它似乎相处得很好......?
    • @Ognami, Object 大写 O?它会抛出什么错误?
    • 是的,上面写着Uncaught TypeError: Object.values is not a function
    • @Ognami,我的错,没有意识到跨浏览器没有很好的支持。查看更新的答案。