如何在dc.js中为不同颜色的条形图添加图例?

时间:2018-01-19 08:06:03

标签: bar-chart legend dc.js

以下是带有彩条的条形图的代码段:

    var Dim2 = ndx.dimension(function(d){return [d.SNo, d.something ]});
    var Group2 = Dim2.group().reduceSum(function(d){ return d.someId; });

    var someColors = d3.scale.ordinal().domain(["a1","a2","a3","a4","a5","a6","a7","a8"])
.range(["#2980B9","#00FFFF","#008000","#FFC300","#FF5733","#D1AEF1","#C0C0C0","#000000"]);

         barChart2
                    .height(250)
                    .width(1000)
                    .brushOn(false)
                    .mouseZoomable(true)
                    .x(d3.scale.linear().domain([600,800]))
                    .elasticY(false)
                    .dimension(Dim2)
                    .group(Group2)
                    .keyAccessor(function(d){ return d.key[0]; })
                    .valueAccessor(function(d){return d.value; })
                    .colors(someColors)
                    .colorAccessor(function(d){return d.key[1]; });

如何在此图表中添加图例?

BarChart:

1 个答案:

答案 0 :(得分:1)

在crossfilter中使用复合键非常棘手,除非你确实需要,否则我不推荐它。

Crossfilter只能识别标量,所以即使你可以生成数组的维度和组密钥,并正确检索它们,crossfilter也会强制将这些数组强制转换为字符串,这会造成麻烦。

在这里,发生的事情是Group2.all()按字符串顺序迭代您的数据,因此您按顺序获取密钥

[1, "a1"], [10, "a3"], [11, "a4"], [12, "a5"], [2, "a3"], ...

在不改变数据形状的情况下,解决此问题的一种方法是对legendables函数中的数据进行排序:

barChart2.legendables = function() { 
    return Group2.all().sort((a,b) => a.key[0] - b.key[0])
        .map(function(kv) { 
            return { 
                chart: barChart2, 
                name: kv.key[1], 
                color: barChart2.colors()(kv.key[1]) }; }) };

一个不相关的问题是dc.js非常字面地取X域,所以即使[1,12]包含所有值,也没有显示最后一个条,因为右边在12处结束并且绘制了条形图在12到13之间。

所以:

  .x(d3.scale.linear().domain([1,13]))

现在图例与数据匹配!

legend matches data[1]

Fork of your fiddle (also with dc.css)

编辑:当然,您也希望图例项目是唯一的。您可以像这样定义uniq

function uniq(a, kf) {
    var seen = [];
    return a.filter(x => seen[kf(x)] ? false : (seen[kf(x)] = true));
}

legendables添加步骤:

barChart2.legendables = function() { 
      var vals = uniq(Group2.all(), kv => kv.key[1]),
          sorted = vals.sort((a,b) => a.key[1] > b.key[1] ? 1 : -1);
          // or in X order: sorted = vals.sort((a,b) => a.key[0] - b.key[0]);
      return sorted.map(function(kv) { 
                    return { 
                        chart: barChart2, 
                        name: kv.key[1], 
                        color: barChart2.colors()(kv.key[1]) }; }) };

请注意,我们按d.something的字符串值排序key[1]。如注释所示,也可以按x顺序(d.SNokey[0])排序。我不建议按y排序,因为那是reduceSum

结果,排序和未完成:

sorted and uniq'd

New fiddle.