在条形图中显示条形顶部的值

Show values on top of bars in a barChart

本文关键字:顶部 条形图 显示      更新时间:2023-09-26

我有一个x轴为有序比例尺的条形图。我想把y值显示在每个栏的顶部或底部。当鼠标悬停在条上时显示y值也是可以接受的。在dc.js中是否有一个函数或方法来做到这一点?这是jsfiddle,我的代码在pic>

下面编辑:这是我的代码:

<body>
    <div id='Chart'>
    </div>
</body>

JS

var data = [{
    Category: "A",
    ID: "1"
}, {
    Category: "A",
    ID: "1"
}, {
    Category: "A",
    ID: "1"
}, {
    Category: "A",
    ID: "2"
}, {
    Category: "A",
    ID: "2"
}, {
    Category: "B",
    ID: "1"
}, {
    Category: "B",
    ID: "1"
}, {
    Category: "B",
    ID: "1"
}, {
    Category: "B",
    ID: "2"
}, {
    Category: "B",
    ID: "3"
}, {
    Category: "B",
    ID: "3"
}, {
    Category: "B",
    ID: "3"
}, {
    Category: "B",
    ID: "4"
}, {
    Category: "C",
    ID: "1"
}, {
    Category: "C",
    ID: "2"
}, {
    Category: "C",
    ID: "3"
}, {
    Category: "C",
    ID: "4"
}, {
    Category: "C",
    ID: "4"
},{
    Category: "C",
    ID: "5"
}];
var ndx = crossfilter(data);
var XDimension = ndx.dimension(function (d) {
    return d.Category;
});
var YDimension = XDimension.group().reduceCount(function (d) {
    return d.value;
});

dc.barChart("#Chart")
    .width(480).height(300)
    .dimension(XDimension)
    .group(YDimension)
    .transitionDuration(500)
    .xUnits(dc.units.ordinal)
    .label(function(d) {return d.value})
    .x(d3.scale.ordinal().domain(XDimension)) 
dc.renderAll();

查看已更新的jsfield

.renderlet(function(chart){
    var barsData = [];
    var bars = chart.selectAll('.bar').each(function(d) { barsData.push(d); });
    //Remove old values (if found)
    d3.select(bars[0][0].parentNode).select('#inline-labels').remove();
    //Create group for labels 
    var gLabels = d3.select(bars[0][0].parentNode).append('g').attr('id','inline-labels');
    for (var i = bars[0].length - 1; i >= 0; i--) {
        var b = bars[0][i];
        //Only create label if bar height is tall enough
        if (+b.getAttribute('height') < 18) continue;
        
        gLabels
            .append("text")
            .text(barsData[i].data.value)
            .attr('x', +b.getAttribute('x') + (b.getAttribute('width')/2) )
            .attr('y', +b.getAttribute('y') + 15)
            .attr('text-anchor', 'middle')
            .attr('fill', 'white');
    }
})

如果你不想让标签在重新绘制条形图时可见(例如当用户过滤/点击其他图表后条形图发生变化时),你可以将旧值的检查从de renderlet移到predraw听众。

.on("preRedraw", function(chart){
    //Remove old values (if found)
    chart.select('#inline-labels').remove();
})

<标题>选择

D3-ish方式演示jsfiddle

.renderlet(function (chart) {
    
    //Check if labels exist
    var gLabels = chart.select(".labels");
    if (gLabels.empty()){
        gLabels = chart.select(".chart-body").append('g').classed('labels', true);
    }
    
    var gLabelsData = gLabels.selectAll("text").data(chart.selectAll(".bar")[0]);
    
    gLabelsData.exit().remove(); //Remove unused elements
    
    gLabelsData.enter().append("text") //Add new elements
    
    gLabelsData
    .attr('text-anchor', 'middle')
    .attr('fill', 'white')
    .text(function(d){
        return d3.select(d).data()[0].data.value
    })
    .attr('x', function(d){ 
        return +d.getAttribute('x') + (d.getAttribute('width')/2); 
    })
    .attr('y', function(d){ return +d.getAttribute('y') + 15; })
    .attr('style', function(d){
        if (+d.getAttribute('height') < 18) return "display:none";
    });
    
})

在dc.js版本3中。*。你可以用.renderLabel(true)。它将打印顶部

的值

这里有一个使用renderlet方法的破解解决方案。 jsFiddle : http://jsfiddle.net/tpsc5f9f/4/

JS

var barChart = dc.barChart("#Chart")
    .width(480).height(300)
    .dimension(XDimension)
    .group(YDimension)
    .transitionDuration(500)
    .xUnits(dc.units.ordinal)
    .x(d3.scale.ordinal().domain(XDimension)) 
dc.renderAll();
barChart.renderlet(function(chart){
    moveGroupNames();
});

function moveGroupNames() {
   var $chart = $('#Chart'),
       bar  = $chart.find('.bar');
    bar.each(function (i, item) {
        var bar_top    = this.height.baseVal.value;
        var bar_left   = this.width.baseVal.value;
        var bar_offset_x = 30;
        var bar_offset_y = 33;
        var bar_val = $(this).find('title').html().split(':')[1];
        $chart.append('<div class="val" style="bottom:'+(bar_top+bar_offset_y)+'px;left:'+((bar_left*i)+(bar_offset_x))+'px;width:'+bar_left+'px">'+bar_val+'</div>');
    });
}

添加CSS

body {
    margin-top:20px;
}
#Chart {
    position:relative;
}
#Chart .val {
    position:absolute;
    left:0;
    bottom:0;
    text-align: center;
}

如果您对图表使用专门化的valueAccessor,您可以在dimirc的"类似d3的方式"解决方案中进行以下替换。

改变
.text(function(d){
    return d3.select(d).data()[0].data.value
})

.text(function(d){
    return chart.valueAccessor()(d3.select(d).data()[0].data)
});

这个函数将把行图的标签重新定位到每行的末尾。对于使用"y"属性的条形图,可以使用类似的技术。

  • 标签随着行矩形动画,使用图表的transitionDuration
  • 使用图表的valueAccessor函数
  • 使用图表的xAxis比例来计算标签位置

rowChart.on('pretransition', function(chart) {
    var padding = 2;
        
    chart.selectAll('g.row > text') //find all row labels
        .attr('x', padding) //move labels to starting position
        .transition() //start transition
        .duration(chart.transitionDuration()) //use chart's transitionDuration so labels animate with rows
        .attr('x', function(d){ //set label final position
            var dataValue = chart.valueAccessor()(d); //use chart's value accessor as basis for row label position
            var scaledValue = chart.xAxis().scale()(dataValue); //convert numeric value to row width
            return scaledValue+padding; //return scaled value to set label position
        });
});