Based on this question , I was able to create a diagram using dc.js and d3.js with labels. However, I turned the histogram into a complex histogram (based on this documentation ), and it's hard for me to show shortcuts for each stack.
For example, each stack in the table below should show a number, but it shows [Object]

See below 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>