Reputation: 5804
Based on this question, I was able to create a bar chart using dc.js and d3.js with labels. However, I turned the bar chart into a stacked bar chart (based on this documentation), and I'm having difficulty showing the labels for each of the stacks.
For example each stack in the below chart should show the number, but it's showing [object Object]
See below for code and here for codepen
Javascript
var data = [{Category: "A", ID: "1A"}, {Category: "A", ID: "1A"}, {Category: "A", ID: "1A"}, {Category: "A", ID: "2B"}, {Category: "A", ID: "2B"}, {Category: "B", ID: "1A"}, {Category: "B", ID: "1A"}, {Category: "B", ID: "1A"}, {Category: "B", ID: "2B"}, {Category: "B", ID: "3C"}, {Category: "B", ID: "3C"}, {Category: "B", ID: "3C"}, {Category: "B", ID: "4D"}, {Category: "C", ID: "1A"}, {Category: "C", ID: "2B"}, {Category: "C", ID: "3C"}, {Category: "C", ID: "4D"}, {Category: "C", ID: "4D"}, {Category: "C", ID: "5E"}];
var ndx = crossfilter(data);
var XDimension = ndx.dimension(function (d) {return d.Category;});
var YDimension = XDimension.group().reduce(
function reduceAdd(p, d) {
p[d.ID] = (p[d.ID]|| 0) + 1;
return p;
},
function reduceRemove(p, d) {
p[d.ID] = (p[d.ID]|| 0) -1;
return p;
},
function reduceInitial() {
return {};})
dc.barChart("#Chart")
.width(480).height(300)
.dimension(XDimension)
.group(YDimension,"1A",function(d) {return d.value["1A"];})
.stack(YDimension,"2B",function(d) {return d.value["2B"];})
.stack(YDimension,"3C",function(d) {return d.value["3C"];})
.stack(YDimension,"4D",function(d) {return d.value["4D"];})
.stack(YDimension,"5E",function(d) {return d.value["5E"];})
.transitionDuration(500)
.xUnits(dc.units.ordinal)
.x(d3.scale.ordinal().domain(XDimension))
.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){
text_object = d3.select(d).data()[0].data.value
return text_object
})
.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.renderAll();
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/dc/1.7.0/dc.css" media="screen">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
<script src="https://rawgithub.com/NickQiZhu/dc.js/master/web/js/crossfilter.js"></script>
<script src="https://cdnjs.site44.com/dc3.js"></script>
<script src="https://rawgithub.com/NickQiZhu/dc.js/master/web/js/crossfilter.js"></script>
<script src="https://d3js.org/d3.v3.min.js"></script>
<body>
<div id='Chart'></div>
</body>
Upvotes: 2
Views: 1991
Reputation: 20120
Typically what I do in these situations is put a breakpoint on the line in question and poke around and see if the object contains the data that I want somewhere else.
It looks like you can use .datum().y
here:
text_object = d3.select(d).datum().y
http://codepen.io/gordonwoodhull/pen/EgNvNr?editors=1010
This is still kind of weird code (using DOM elements as data for a data join for some other elements is pretty hacky) but hopefully this will get you moving.
Upvotes: 4