UNPKG

dimple-js

Version:

Dimple is an object-oriented API allowing you to create flexible axis-based charts using [d3.js](http://d3js.org "d3.js").

132 lines (116 loc) 5.24 kB
<!DOCTYPE html> <meta charset="utf-8"> <html> <div id="chartContainer"> {scriptDependencies} <script type="text/javascript"> // This code should support any data in this structure changing the data here // should be dealt with by the the code below. The y axis min and max must // be able to contain the data required or the results will be incorrect. // Also the "bar" elements must have the correct value (sum of previous "bar" // + intervening "var" elements) var yMin = -400000, yMax = 400000, xLabel = "Bar", yLabel = "Value"; data = [ { "label":"2011", "value":200000, "type":"bar" }, { "label":"Alpha", "value":-100000, "type":"var" }, { "label":"Beta", "value":200000, "type":"var" }, { "label":"Delta", "value":-500000, "type":"var" }, { "label":"Gamma", "value":-100000, "type":"var" }, { "label":"2012", "value":-300000, "type":"bar" }, { "label":"Alpha", "value":150000, "type":"var" }, { "label":"Beta", "value":100000, "type":"var" }, { "label":"Delta", "value":-35000, "type":"var" }, { "label":"Gamma", "value":205000, "type":"var" }, { "label":"2013", "value":120000, "type":"bar" } ]; // Create the svg as usual var svg = dimple.newSvg("#chartContainer", 590, 400); // The waterfall requires some data manipulation in a similar // way that one would create a waterfall in Excel. The data // will be padded and rearranged for display var waterfallData = []; // Maintain a running total for padding var runningTotal = 0; // Calculate the base level of padding, this is to deal with // waterfalls which cross the x-axis var padBase = Math.abs(yMin); // Rearrange the data data.forEach(function (d, i) { // Add the padding bar, this will be removed later but is used // for positioning waterfallData.push({ x: i, y: padBase + (d.type === "var" ? runningTotal : 0) + (d.value < 0 ? d.value : 0), series: "pad" }); // Add the bar itself. The values are always positive here. The labels in // popups will be changed later. waterfallData.push({ x: i, y: Math.abs(d.value), series: (d.type === "bar" ? "bar" : (d.value < 0 ? "negative" : "positive")) }); // Move the running total for managing the flow runningTotal = (d.type === "var" ? runningTotal : 0) + d.value; }); // Create the chart from the updated data var myChart = new dimple.chart(svg, waterfallData); myChart.setBounds(60, 30, 510, 335) var x = myChart.addCategoryAxis("x", "x"); // By default bar charts are ordered by value, this forces the ordering by // name (which at this point includes a leading string for positioning) x.addOrderRule("x"); // We need 2 y axes. The bars will be positioned using // the second axis (all positive) and the first axis // will be used to draw the visible axis, In an all positive waterfall // both axes will be the same but for a negative the y2 axis will go from 0 // to abs(yMin) + yMax to allow axis crossing var y1 = myChart.addMeasureAxis("y", yLabel); y1.overrideMin = padBase * -1; y1.overrideMax = yMax; var y2 = myChart.addMeasureAxis("y", "y"); y2.overrideMin = 0; y2.overrideMax = padBase + yMax; y2.hidden = true; // Add the series var s = myChart.addSeries(["series"], dimple.plot.bar, [x, y2]); // Assign blue, red and green using the default colors, these can // be any colors. We could assign transparency to the "pad" bars but // to avoid tooltips we delete the bars after drawing instead myChart.assignColor("bar", myChart.defaultColors[0].fill); myChart.assignColor("negative", myChart.defaultColors[1].fill); myChart.assignColor("positive", myChart.defaultColors[3].fill); // Draw the chart. Code beyond this point manipulates the objects // and hacks some changes to the chart which would break in the event // of redrawing. myChart.draw(); // Remove the axis titles here x.titleShape.remove(); y1.titleShape.remove(); // Remove the leading numbers from the x axis text x.shapes.selectAll("text").text(function (d) { return (d === "" ? "" : data[parseInt(d)].label); }); // Remove the padding elements entirely svg.selectAll(".dimple-pad").remove(); // Change the measure name and the category names for the tooltips s.y.measure = yLabel; s.x.categoryFields = [xLabel]; // Remove the category fields from the series, to remove from the tooltips s.categoryFields = []; s.shapes.each(function (d) { // Get the index from the original data var j = parseInt(d.xField[0]); // Remove the unwanted x label prefixes from the shapes for the tooltips d.xField[0] = data[j].label; // Change the values back to negatives where necessary for tooltips d.height = data[j].value; }); </script> </div> </html>