Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-series in dimplejs

I am tinkering with a multi-series chart in dimplejs and got a bit stuck with the multi axis logic.

With the following data:

var data = [
  {"Month":"01/2013", "Revenue":2000, "Profit":2000, "Units":4},
  {"Month":"02/2013", "Revenue":3201, "Profit":2000, "Units":3},
  {"Month":"03/2013", "Revenue":1940, "Profit":14000, "Units":5},
  {"Month":"04/2013", "Revenue":2500, "Profit":3200, "Units":1},
  {"Month":"05/2013", "Revenue":800, "Profit":1200, "Units":4}
]

I try to get a chart showing, by months, my revenue and my profit on the same y axis and my units on a secondary y axis.

With the code below, I could manage to display the 3 series. But the Profit series isn't really on the same axis as the Revenue one, and the whole thing seems more like a hack than a proper solution.

var chart = new dimple.chart(svg, data);

chart.setBounds(60,20,680,330);

var x = chart.addCategoryAxis("x", "Month");
var y1 = chart.addMeasureAxis("y", "Revenue");
chart.addSeries("null", dimple.plot.line, [x,y1]);
var y2 = chart.addMeasureAxis("y", "Units");
chart.addSeries("null", dimple.plot.bar, [x,y2]);
var y3 = chart.addMeasureAxis("y", "Profit");
chart.addSeries("null", dimple.plot.line, [x,y3]);

I guess my logic might be wrong with how to rightly play with series. Any help would be great.

Thanks a lot, Xavier

Full code:

var svg = dimple.newSvg("body", 800, 400);

var data = [
    {"Month":"01/2013", "Revenue":2000, "Profit":2000, "Units":4},
    {"Month":"02/2013", "Revenue":3201, "Profit":2000, "Units":3},
    {"Month":"03/2013", "Revenue":1940, "Profit":14000, "Units":5},
    {"Month":"04/2013", "Revenue":2500, "Profit":3200, "Units":1},
    {"Month":"05/2013", "Revenue":800, "Profit":1200, "Units":4}
]

var chart = new dimple.chart(svg, data);

chart.setBounds(60,20,680,330);

var x = chart.addCategoryAxis("x", "Month");
var y1 = chart.addMeasureAxis("y", "Revenue");
chart.addSeries("null", dimple.plot.line, [x,y1]);
var y2 = chart.addMeasureAxis("y", "Units");
chart.addSeries("null", dimple.plot.bar, [x,y2]);
var y3 = chart.addMeasureAxis("y", "Profit");
chart.addSeries("null", dimple.plot.line, [x,y3]);

x.dateParseFormat = "%m/%Y";
x.addOrderRule("Date");

chart.draw();
like image 993
xav Avatar asked Sep 04 '13 17:09

xav


1 Answers

EDIT:

This is no longer required since version 2. You can now use composite axes.

ORIGINAL:

I see the problem here, the issue isn't with multiple axes, it is with trying to draw multiple measures against a single axis which Dimple doesn't really support yet. I'm afraid the best I can do for now is a bit of a data hack:

<div id="chartContainer">
  <script src="http://d3js.org/d3.v3.min.js"></script>
  <script src="/dist/dimple.v1.min.js"></script>
  <script type="text/javascript">
      var svg = dimple.newSvg("#chartContainer", 800, 400);

      // Data hack required to get revenue and profit on the same axis, units are
      // arbitrarily allocated to revenue but the values will be summed by date
      var data = [
          {"Month":"01/2013", "Metric":"Revenue", "Revenue/Profit":2000, "Units":4},
          {"Month":"02/2013", "Metric":"Revenue", "Revenue/Profit":3201, "Units":3},
          {"Month":"03/2013", "Metric":"Revenue", "Revenue/Profit":1940, "Units":5},
          {"Month":"04/2013", "Metric":"Revenue", "Revenue/Profit":2500, "Units":1},
          {"Month":"05/2013", "Metric":"Revenue", "Revenue/Profit":800, "Units":4},
          {"Month":"01/2013", "Metric":"Profit", "Revenue/Profit":2000, "Units":0},
          {"Month":"02/2013", "Metric":"Profit", "Revenue/Profit":2000, "Units":0},
          {"Month":"03/2013", "Metric":"Profit", "Revenue/Profit":14000, "Units":0},
          {"Month":"04/2013", "Metric":"Profit", "Revenue/Profit":3200, "Units":0},
          {"Month":"05/2013", "Metric":"Profit", "Revenue/Profit":1200, "Units":0}
      ];

      var chart = new dimple.chart(svg, data);
      chart.setBounds(60,20,680,330);

      // Add your x axis - nothing unusual here
      var x = chart.addCategoryAxis("x", "Month");
      // First y axis is the combination axis for revenue and profit
      var y1 = chart.addMeasureAxis("y", "Revenue/Profit");
      // Second is the units only
      var y2 = chart.addMeasureAxis("y", "Units");

      // Plot the bars first - the order of series determines their dom position
      // from back to front, this means bars are at the back.  It's important
      // to note that the string here "Unit Sales" is NOT in the data.  Any string
      // not in the data is just used to apply a label which can be used for colouring
      // as it is here and will also appear in tool tips
      var bars = chart.addSeries("Unit Sales", dimple.plot.bar, [x,y2]);
      // Use a simple line by metric for the other measures
      var lines = chart.addSeries("Metric", dimple.plot.line, [x,y1]);

      // Do a bit of styling to make it look nicer
      lines.lineMarkers = true;
      bars.barGap = 0.5;
      // Colour the bars manually so they don't overwhelm the lines
      chart.assignColor("Unit Sales", "black", "black", 0.15);

      x.dateParseFormat = "%m/%Y";
      x.addOrderRule("Date");


      // Here's how you add a legend for just one series.  Excluding the last parameter
      // will include every series or an array of series can be passed to select more than
      // one
      chart.addLegend(60, 5, 680, 10, "right", lines);

      chart.draw();

      // Once Draw is called, this just changes the number format in the tooltips which for these particular
      // numbers is a little too heavily rounded.  I assume your real data isn't like this
      // so you probably won't want this line, but it's a useful tip anyway!
      y1.tickFormat = ",d";

  </script>
</div>

This is currently a bit of a limitation but I've just had an idea for a really good implementation I can do to add proper support for composite axes like this. Hopefully that will be possible in the not too distant future.

Good luck

John

like image 155
John Kiernander Avatar answered Nov 10 '22 19:11

John Kiernander