Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
301 views
in Technique[技术] by (71.8m points)

javascript - Multi-series bar chart in DC-js

I'm using DC.js ( lib on top of D3 ) and have a great example of a single series bar chart:

enter image description here

 var xf = crossfilter(data);
 var dim = xf.dimension(function (d) { return d["EmployeeName"]; });
 var group = dim.group().reduceSum(function (d) { return d["AverageSale"]; });

 var chart = dc.barChart(elm);
 chart.barPadding(0.1)
 chart.outerPadding(0.05)
 chart.brushOn(false)
 chart.x(d3.scale.ordinal());
 chart.xUnits(dc.units.ordinal);
 chart.elasticY(true);

 chart.dimension(dim).group(group);
 chart.render();

but I was wondering if it was possible to create a multi dimensional bar chart using this library. For example: Group by Store Name then Group By Employee then y-axis display average sale value ( already calculated by my backend ).

The data looks like:

 [{
    "EmployeeName": "Heather",
    "StoreName" : "Plaza",
    "AverageSaleValue": 200
 }{
    "EmployeeName": "Mellisa",
    "StoreName" : "Plaza",
    "AverageSaleValue": 240
 }, {
    "EmployeeName": "Sarah",
    "StoreName" : "Oak Park",
    "AverageSaleValue": 300
 } ... ]
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you have a static number of groups to graph, you can achieve the desired effect with a composite chart.

In the example below, I hard coded the gap between the bar charts - I can do this because I know there are 12 months being displayed.

            var actuals = dc.barChart(compositeChart)
                    .gap(65)
                    .group(group)
                    .valueAccessor(function (d) {
                        return d.value.Actual;
                    });

            var budgets = dc.barChart(compositeChart)
                    .gap(65)
                    .group(group)
                    .valueAccessor(function (d) {
                        return d.value.Budget;
                    });

I pass these bar charts to the compose method of a composite chart:

                compositeChart
                    .width(1000)
                    .height(300)
                    .dimension(monthDimension)
                    .group(group)
                    .elasticY(true)
                    .x(d3.time.scale().domain(timeExtent))
                    .xUnits(d3.time.months)
                    .round(d3.time.month.round)
                    .renderHorizontalGridLines(true)
                    .compose([budgets, actuals])
                    .brushOn(true);

Finally, I add a renderlet to move one of the charts to the right a few pixels:

              compositeChart
                    .renderlet(function (chart) {
                        chart.selectAll("g._1").attr("transform", "translate(" + 20 + ", 0)");
                        chart.selectAll("g._0").attr("transform", "translate(" + 1 + ", 0)");
                    });

I know this isn't the cleanest approach but it can work in a pinch.

I hope this helps.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...