Search code examples
javascriptd3.jstooltipdc.js

DC js composite chart tooltip


I've plotted multiple charts linked together using dc & crossfilter js. One last chart is a composite chart (bar and line) I'm not able to get the tooltip properly on it.

Currently, in the form of tooltip, it shows : During [object object], P1[object object]

(During and P1 are my dimensions)

My code :

//Composite chart to show 2 metrics
    chart4
    .width(990) // (optional) define chart width, :default = 200
    .height(200) // (optional) define chart height, :default = 200
    .transitionDuration(500) // (optional) define chart transition duration, :default = 500
    // (optional) define margins
    .margins({top: 10, right: 50, bottom: 30, left: 40})
    .dimension(dateDimension) // set dimension
    .group(rechfreqGroup) // set group
    // (optional) whether chart should rescale y axis to fit data, :default = false
    .elasticY(true)
    // (optional) when elasticY is on whether padding should be applied to y axis domain, :default=0
    .yAxisPadding(100)
    // (optional) whether chart should rescale x axis to fit data, :default = false
    //.elasticX(true)
    // (optional) when elasticX is on whether padding should be applied to x axis domain, :default=0
    .xAxisPadding(500)
    // define x scale
    .x(d3.scale.ordinal())
    .xUnits(dc.units.ordinal)
    // (optional) render horizontal grid lines, :default=false
    .renderHorizontalGridLines(true)
    // (optional) render vertical grid lines, :default=false
    .renderVerticalGridLines(true)
    // compose sub charts, currently composite chart only supports line chart & bar chart
    ._rangeBandPadding(1) //workaround to fix visual stuff (dc js issues)
    .compose([

        dc.barChart(chart4).group(rechrevGroup).gap(2).centerBar(true).valueAccessor(function (p) {
        return p.value.count > 0 ? p.value.rechtotal / p.value.count : 0;
        }),
        // you can even include stacked bar chart or line chart in a composite chart
        dc.lineChart(chart4).group(rechfreqGroup).useRightYAxis(true).colors('#000000').valueAccessor(function (p) {
        return p.value.count > 0 ? p.value.rechfreq / p.value.count : 0;
        })
    ])
    // (optional) whether this chart should generate user interactive brush to allow range
    // selection, :default=true.
    .brushOn(true);

What am I missing here? Should I use d3.tip here to solve these issues? Any approach/feedback is highly appreciated


Solution

  • Whenever your reduction creates objects instead of straight values, you will need to specify a .title function in order to get the built-in tooltips to work properly.

    This is because the default title function just prints the key and value.

    From the .title documentation:

    // default title function just return the key
    chart.title(function(d) { return d.key + ': ' + d.value; });
    

    Actually it's a little bit smarter:

    var _title = function (d) {
        return _chart.keyAccessor()(d) + ': ' + _chart.valueAccessor()(d);
    };
    

    https://github.com/dc-js/dc.js/blob/develop/src/base-mixin.js#L45-L47

    Note that by default, titles are shared from the composite chart down to the child charts (depending on shareTitle). The tricky thing to consider here is that the function is defined in the parent chart, so if the titles are shared, the function will use the keyAccessor and valueAccessor of the parent, which is why your valueAccessors on the children are having no effect.