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.

Chris
  • 5,444
  • 16
  • 63
  • 119

3 Answers3

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

Community
  • 1
  • 1
Raúl Martín
  • 4,471
  • 3
  • 23
  • 42
  • The plus... You can control the size and other options by css. – Raúl Martín May 26 '15 at 19:05
  • I've attempted to utilize this, but can't seem to get it to work: http://codepen.io/chriscruz/pen/yNVZYL. It seems that it has lost some of the interactive features that Lon has created here (http://stackoverflow.com/questions/29360042/how-to-create-stacked-row-chart-with-one-row-with-dc-js). For example, when I click on the bar that Lon created, it changes the other charts. Does that make sense? – Chris May 27 '15 at 16:59
  • Hey you have another codepen here http://codepen.io/luarmr/pen/yNVZMN I add the tooltips from http://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? – Raúl Martín May 27 '15 at 17:28
  • 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: http://www.acrodatics.com/ – Chris May 27 '15 at 22:11
  • 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 http://codepen.io/luarmr/pen/yNVZMN – Raúl Martín May 27 '15 at 23:13
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).

davidhwang
  • 1,343
  • 1
  • 12
  • 19
  • 3
    Thanks @davidhwang. Second time this week someone has tried to use features from that example that are not actually dc. – Gordon Mar 31 '15 at 14:31
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

Pavan Kumar Jorrigala
  • 3,085
  • 16
  • 27
  • I've tried to implement, but it doesn't seem to work: http://codepen.io/chriscruz/pen/rVWPxx. It doesn't have the same interactive features that Lon was able to implement here: http://www.acrodatics.com/. Notice that when i click on the bar, it changes the other components on the site. – Chris May 27 '15 at 17:02