基于dc.js复合图表中条形颜色的自定义图例

时间:2017-12-20 05:47:06

标签: d3.js legend dc.js

我实现了一个带有两个条形图的复合图表,其中一个条形图由具有不同颜色条的条形图组成。 现在,我想创建一个代表每个颜色条的自定义图例(类似于用于饼图的https://dc-js.github.io/dc.js/examples/pie-external-labels.html)。 以下是我到目前为止所做的代码片段:

var buttonPress = dc.barChart(composite)
    .dimension(joyTimeDimension)
    //.renderlet(colorRenderlet)
    //.colors('red')
    .colors(colorbrewer.Set1[5])
    .colorDomain([101, 105])
    .colorAccessor(function (d) {
        return d.value;
    })
    .group(btnGroup, "Button Press")
    .keyAccessor(function(d) {return d.key[0];})
    .valueAccessor(function (d) {
        return d.value;
    })
    .title( function(d){ 
        return [
            "Time: "+d.key[0],
            "button Name: "+d.key[1],
            "button: "+ d.value
        ].join('\n')
    });


var joyStick = dc.barChart(composite)
    .dimension(joyTimeDimension)
    .colors('blue')
    .group(stepperGroup,"Joy Stick Movement")
    .keyAccessor(function(d) {return d.key[0];})
    .title( function(d){ 
        return [
            "Time: "+d.key[0],
            "Stepper Position: "+ d.value
        ].join('\n')
  });
  composite
    .width(1200)
    .transitionDuration(500)
    .margins({top: 30, right: 50, bottom: 25, left: 40})
    .x(d3.time.scale().domain([startDate,currDate]))
    .xUnits(function(){return 150;})
    //.xUnits(d3.time.second)
    .elasticY(true)
    .legend(dc.legend().x(1000).y(4).itemHeight(13).gap(5))
    .renderHorizontalGridLines(true)
    .renderTitle(true)
    .shareTitle(false)
    .compose([buttonPress, joyStick])
    .brushOn(false)

Composite chart looks like this

有没有办法为此方案创建自定义图例? 提前谢谢。

1 个答案:

答案 0 :(得分:0)

让我提供一些关于如何构建图例的背景知识。

dc.js中的传奇并不是那么复杂。它只是在图表上调用.legendables(),图表决定在图例中显示哪些项目。

每个图表都有自己的专用代码。

如果我们查看source for compositeChart.legendables(),它只是递归地获取每个子图表的图例并将它们连接起来:

_chart.legendables = function () {
    return _children.reduce(function (items, child) {
        if (_shareColors) {
            child.colors(_chart.colors());
        }
        items.push.apply(items, child.legendables());
        return items;
    }, []);
};

饼图creates a legendable for each pie slice

_chart.legendables = function () {
    return _chart.data().map(function (d, i) {
        var legendable = {name: d.key, data: d.value, others: d.others, chart: _chart};
        legendable.color = _chart.getColor(d, i);
        return legendable;
    });
};

条形图的图例来自堆栈mixin,creates a legendable for each stack

_chart.legendables = function () {
    return _stack.map(function (layer, i) {
        return {
            chart: _chart,
            name: layer.name,
            hidden: layer.hidden || false,
            color: _chart.getColor.call(layer, layer.values, i)
        };
    });
};

鉴于目前无法获得显示饼图图例的条形图,我认为最简单的方法是使用自定义颜色覆盖条形图的legendables

buttonPress.legendables = function() {
    return btnGroup.all().map(function(kv) {
        return {
            chart: buttonPress,
            // display the value as the text (not sure what you want here)
            name: kv.value,
            // apply the chart's color scale to get the color
            color: buttonPress.colors()(kv.value)
        };
    })
};

可能还有一些细节需要解决,比如如果相同的值出现两次怎么办?我假设您可以只读取组中的输入数据并.map(),但您可能需要以不同的方式生成数据。

但这应该给出一般的想法。 Lmk如果它不起作用,我会很乐意跟进。