How to create stacked row chart with one row with dc.js?
Asked Answered
F

3

9

On the DC.js github, Stock Market Selection Strategy by Lon Riesberg is listed as an example of using the dc.js library.

Lon was able to create a stacked row chart and display it as a single row.

enter image description here

I'd like to be able to accomplish the same thing. I've only been able to figure out how create a row chart, as shown in my codepen, and below.

HTML

<script src="https://rawgit.com/mbostock/d3/master/d3.js" charset="utf-8"></script>
<script type="text/javascript" src="https://rawgithub.com/NickQiZhu/dc.js/master/web/js/crossfilter.js"></script>
<script type="text/javascript" src="https://rawgit.com/dc-js/dc.js/master/dc.js" ></script>


<div id="rowChart"></div>

Javascript

items = [
            {Id: "01", Name: "Red", Price: "1.00", Quantity: "1",TimeStamp:111},
            {Id: "02", Name: "White", Price: "10.00", Quantity: "1",TimeStamp:222},
            {Id: "04", Name: "Blue", Price: "9.50", Quantity: "10",TimeStamp:434},
            {Id: "03", Name: "Red", Price: "9.00", Quantity: "2",TimeStamp:545},
            {Id: "06", Name: "Red", Price: "100.00", Quantity: "2",TimeStamp:676},
            {Id: "05",Name: "Blue", Price: "1.20", Quantity: "2",TimeStamp:777}
        ];


var ndx = crossfilter(items);


var Dim = ndx.dimension(function (d) {return d.Name;})


var RowBarChart1 = dc.rowChart("#rowChart")
RowBarChart1
  .width(250).height(500)
  .margins({top: 20, left: 15, right: 10, bottom: 20})
  .dimension(Dim)
  .group(Dim.group().reduceCount())
  .elasticX(true)
  .label(function (d) {return d.key + "  " + d.value;})
  .ordering(function(d) { return -d.value })
  .xAxis().tickFormat(function(v){return v}).ticks(3);




dc.renderAll();

How would I make this a stacked row chart where each section is 'Red','White,' or 'Blue' and is displayed in one row?

My goal is to have a working example that I can build off of. The answer thus far has helped, but I still haven't been able to build this.

Few answered 31/3, 2015 at 3:21 Comment(0)
A
4

you can create a div with d3.js and add the attribute for flex...

http://codepen.io/luarmr/pen/BNQYov

var chart = d3.select("#rowChart");

var bar = chart.selectAll("div")
    .data(data)
    .enter().append("div")
      .attr('style',function(d,i){
      return (
         'flex:' + d.Quantity + '; '
         + 'background:' + color(i) + ';'
        )
    })

The attr.style could improve.

You can add the prefix for webkit

http://caniuse.com/#search=flex

Edit

http://codepen.io/luarmr/pen/yNVZMN

Amelia answered 26/5, 2015 at 19:1 Comment(5)
The plus... You can control the size and other options by css.Melentha
I've attempted to utilize this, but can't seem to get it to work: codepen.io/chriscruz/pen/yNVZYL. It seems that it has lost some of the interactive features that Lon has created here (#29360542). For example, when I click on the bar that Lon created, it changes the other charts. Does that make sense?Few
Hey you have another codepen here codepen.io/luarmr/pen/yNVZMN I add the tooltips from cbracco.me/a-simple-css-tooltip And the action click as well. You only need repaint the graphs ... The problem is... what data Do you want to show?Melentha
Well, I want the sizing of the orange section of this code pen to change when i click on one of the bars in the row chart. For example in Lon's website, when you change the charts, the chart that we are trying to build changes. I'm looking into this as well, and I think this is on the right track: acrodatics.comFew
That it is easy. You can assign a new class in the onlick event. With a few simple styles, you have it. I update the codepen codepen.io/luarmr/pen/yNVZMNMelentha
C
3

The javascript code used to produce that stacked bar chart does not use DC.js at all. It only uses D3.js. This can be seen from a beautified conversion of app.min.js; one (or both?) of these functions are the ones producing that stacked bar chart:

G = function(e, t) {
        var r = (o - 40) / t;
        f = "";
        var a = d3.select("#categories-chart").append("svg").attr("height", 50).attr("width", o),
            s = 0;
        a.selectAll("rect").data(e).enter().append("rect").attr("category", function(e) {
            return e.key
        }).attr("x", function(e) {
            var t = s,
                a = Math.floor(r * e.value);
            return s += a, t
        }).attr("y", 7).attr("width", function(e) {
            var t = Math.floor(r * e.value);
            return t
        }).attr("height", 25).style("fill", function(e) {
            return "" != e ? "" === f || f === e.key ? d3.rgb(i[e.key]) : d3.rgb(i[e.key]).darker(1.75) : void 0
        }).on("click", function(e) {
            f = e.key, d3.select("#categories-chart").select(".reset").style("display", null), m.filter(f).top(t), C(m, t), dc.renderAll()
        }).on("mouseover", function() {
            d3.select(this).style("cursor", "pointer")
        }), $("rect").popover({
            container: "body",
            trigger: "hover",
            placement: "top",
            content: function() {
                return d3.select(this).attr("category")
            }
        })
    },
    C = function(e, t) {
        var r = (o - 40) / t,
            a = 0,
            s = d3.select("#categories-chart");
        s.selectAll("rect").data(e).transition().duration(150).attr("x", function(e) {
            var t = a,
                s = Math.floor(r * e.value);
            return a += s, t
        }).attr("y", 7).attr("width", function(e) {
            var t = Math.floor(r * e.value);
            return t
        }).attr("height", 25).attr("category", function(e) {
            return e.key
        }).style("fill", function(e) {
            return "" != e ? "" === f || f === e.key ? d3.rgb(i[e.key]) : d3.rgb(i[e.key]).darker(1.75) : void 0
        }), $("rect").popover({
            container: "body",
            trigger: "hover",
            placement: "top",
            content: function() {
                return d3.select(this).attr("category")
            }
        })
    },

As you can see, no DC.js. Looking around elsewhere, there doesn't seem to be a DC.js native solution to this. For now, you might have to use D3.js (e.g. jsFiddle).

Campbell answered 31/3, 2015 at 5:23 Comment(1)
Thanks @davidhwang. Second time this week someone has tried to use features from that example that are not actually dc.Hotbed
K
1

I didn't find any api to create stacked row chat from DC.js, so used D3.js with the help of https://www.dashingd3js.com/d3js-scales

var items = [
            {Id: "01", Name: "Red", Price: "1.00", Quantity: 1,TimeStamp:111},
            {Id: "02", Name: "Green", Price: "10.00", Quantity: 1,TimeStamp:222},
            {Id: "04", Name: "Blue", Price: "9.50", Quantity: 4,TimeStamp:434},
            {Id: "03", Name: "Orange", Price: "9.00", Quantity: 2,TimeStamp:545},
            {Id: "06", Name: "Red", Price: "100.00", Quantity: 2,TimeStamp:676},
            {Id: "05",Name: "purple", Price: "1.20", Quantity: 2,TimeStamp:777}
        ];



var max_x = 700; //maximum width of the graph
var height = 20; //maximum height

var temp_x = 0 ;
// calculating the quantity of all items
for (var i = 0; i < items.length; i++) {
  temp_x = temp_x + items[i].Quantity;
}


var svgContainer = d3.select("body").append("svg")
                                    .attr("width", max_x)
                                    .attr("height", height)

var rectangles = svgContainer.selectAll("rect")
                             .data(items)
                             .enter()
                             .append("rect");
//temporary variable to mark start and end of an item.
var start=0;
var end=0;
var end1=0;
var rectangleAttributes = rectangles
                          .attr("x", function (d) { 
                          // dynamically calculate the starting point of each item
                            start=end;
                            end=end+(d.Quantity * max_x)/temp_x;
                            return start; 
                          })
                          .attr("height", height)
                          .attr("width", function (d) { 
                           //dynamically calculate the width of each item
                            end1=(d.Quantity * max_x)/temp_x; 
                            return end1; })
                          .style("fill", function(d) { return d.Name; });

Html code

<script src="https://rawgit.com/mbostock/d3/master/d3.js" charset="utf-8">    </script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.js" ></script>
<div id="rowChart"></div>

example: http://codepen.io/anon/pen/vOXPBq?editors=101

Keffiyeh answered 23/5, 2015 at 6:58 Comment(1)
I've tried to implement, but it doesn't seem to work: codepen.io/chriscruz/pen/rVWPxx. It doesn't have the same interactive features that Lon was able to implement here: acrodatics.com. Notice that when i click on the bar, it changes the other components on the site.Few

© 2022 - 2024 — McMap. All rights reserved.