首页 文章

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

提问于
浏览
1

我实现了一个带有两个条形图的复合图表,其中一个条形图由具有不同颜色条的条形图组成 . 现在,我想创建一个表示每个颜色条的自定义图例(类似于用于饼图的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

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

    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如果它不起作用,我会很乐意跟进 .

相关问题