Multiple D3 Graphs, Two Axis', No Category's - javascript

I am working with dimple js and trying to get two object variables to use the same axis while graphing. I have provided and example data set, it does not include category's, simply the name of the test (x axis) and two values that need to be graphed separately. I am considering a very hackish solution of duplicating all the data and adding separate category's to each set. If you have a cleaner solution I would really appreciate it.
Test Data
var data=[
{name:"test 1",firstAccuracy:33,accuracy:50},
{name:"test 2",firstAccuracy:38,accuracy:60},
{name:"test 3",firstAccuracy:45,accuracy:50},
{name:"test 4",firstAccuracy:55,accuracy:80},
{name:"test 5",firstAccuracy:52,accuracy:72},
{name:"test 6",firstAccuracy:60,accuracy:70},
{name:"test 7",firstAccuracy:54,accuracy:82},
{name:"test 8",firstAccuracy:60,accuracy:60},
{name:"test 9",firstAccuracy:70,accuracy:85}
]
Relevant Javascript
function drawGraph(){
var svg = dimple.newSvg("#chartContainer", 590, 400);
var myChart = new dimple.chart(svg, data);
myChart.setBounds(60, 30, 505, 305);
var x = myChart.addCategoryAxis("x", "name");
var y1 = myChart.addMeasureAxis("y", "accuracy");
var y2 = myChart.addMeasureAxis("y", "firstAccuracy");
var s1 = myChart.addSeries("Result Accuracy", dimple.plot.line,[x,y1]);
var s2 = myChart.addSeries("First Result Accuracy", dimple.plot.line,[x,y2]);
myChart.draw();
}
What it currently looks like
What I'm Aiming for

I think the real answer is to have data contain two sets for result and firstResult with a series parameter to tell them apart, somewhat like in this example.
http://dimplejs.org/examples_viewer.html?id=lines_horizontal_stacked
However if reformatting the data object is out of the question you can do the following:
var svg = dimple.newSvg("#chartContainer", 590, 400);
var myChart = new dimple.chart(svg, data);
myChart.setBounds(60, 30, 505, 305);
var x = myChart.addCategoryAxis("x", "name");
var y1 = myChart.addMeasureAxis("y", "accuracy");
y2 = Object.create(y1);
y2.measure = "firstAccuracy";
var s1 = myChart.addSeries("Result Accuracy", dimple.plot.line,[x,y1]);
var s2 = myChart.addSeries("First Result Accuracy", dimple.plot.line,[x,y2]);
myChart.draw();
This works for me in FireFox, although I think that using Object.create like this is pretty messy.

Related

Representing 2 or more dimple.js charts

Im a noob and currently I'm practicing with dimple.js.
The problem I'm facing is that I can't represent 2 charts side by side on the same page, it just appears one chart. How can I fix this?
I named each div with two different ID and also considered this on the script.
<body>
<section>
<div id="chartContainer1" class="container">
<script type="text/javascript">
var svg = dimple.newSvg("#chartContainer1", 590, 400);
d3.tsv("/data/example_data.tsv", function (data) {
data = dimple.filterData(data, "Owner", ["Aperture", "Black Mesa"])
var myChart = new dimple.chart(svg, data);
myChart.setBounds(60, 30, 505, 305);
var x = myChart.addCategoryAxis("x", "Month");
x.addOrderRule("Date");
myChart.addMeasureAxis("y", "Unit Sales");
var s = myChart.addSeries("Channel", dimple.plot.line);
s.interpolation = "cardinal";
myChart.addLegend(60, 10, 500, 20, "right");
myChart.draw();
});
</script>
</div>
<div id="chartContainer2" class="container">
<script type="text/javascript">
var svg = dimple.newSvg("#chartContainer2", 590, 400);
d3.tsv("/data/example_data.tsv", function (data) {
data = dimple.filterData(data, "Owner", ["Aperture", "Black Mesa"])
var myChart = new dimple.chart(svg, data);
myChart.setBounds(60, 30, 505, 305);
var x = myChart.addCategoryAxis("x", "Month");
x.addOrderRule("Date");
myChart.addMeasureAxis("y", "Unit Sales");
var s = myChart.addSeries("Channel", dimple.plot.line);
s.interpolation = "cardinal";
myChart.addLegend(60, 10, 500, 20, "right");
myChart.draw();
});
</script>
</div>
</section>
EDIT: I cleaned up the code to help make it more maintainable for you going down the road.
http://jsfiddle.net/gv615hcL/
--
So the problem is in the variable naming. You're overriding your variables. In the second declaration you want to change the names of the new dimple svg, for example instead of naming it:
var svg = dimple.newSvg("#chartContainer2", 590, 400);
name it:
var svg2 = dimple.newSvg("#chartContainer2", 590, 400);
Also, make sure you continue to reference the variables properly.
I made a quick JsFiddle for you here: http://jsfiddle.net/fq4p7t2x/

How to make axis ticks clickable in d3.js/dimple.js

I'm very new to d3js. I wish to know how to make axis tick labels to clickable so that clicking on the labels I can load new charts( yes I need to get the axis value, ie month name here in my case)
Below is the code. X axis are months and once I click on a month, I need to load chart of that month, which is another HTML page.
d3.csv("data/data_1.CSV", function (data) {
var myChart = new dimple.chart(svg, data);
myChart.setBounds(90, 70, 490, 320);
var x = myChart.addTimeAxis("x", "Month", "%d-%b-%Y %H:%M:%S", “%b-%Y");
var y = myChart.addMeasureAxis("y","Value");
x.overrideMin = new Date("2013-11-30");
var s = myChart.addSeries("Value type", dimple.plot.line);
s.lineMarkers = true;
myChart.addLegend(180, 30, 360, 20, "left");
myChart.draw();
});
I don't know anything about dimple.js, but in d3 you can just select all of the tick marks and attach a click handler to them.
svg.selectAll('.tick')
.on('click', function(d) { console.log(d); });
This will write the Date object that the tick represents to the console.
This will autoplay all months, and log x-Axis value on click.
d3.csv("data/data_1.CSV", function (data) {
var myChart = new dimple.chart(svg, data);
myChart.setBounds(90, 70, 490, 320);
var x = myChart.addTimeAxis("x", "Month", "%d-%b-%Y %H:%M:%S", "%b-%Y");
x.overrideMin = new Date("2013-01-01");
x.addOrderRule("Date");
var y = myChart.addMeasureAxis("y","Value");
var s = myChart.addSeries("Value type", dimple.plot.line);
s.lineMarkers = true;
myChart.addLegend(180, 30, 360, 20, "left");
s.addEventHandler("click", function (e) {
console.log(e.xValue);
});
var myStoryboard = myChart.setStoryboard("Month");
myStoryboard.frameDuration = 15000;
myStoryboard.autoplay = true;
myChart.draw();
});

dimple js straight line y-axis over bar chart

I am trying to draw Average, High and Low value straight line on a dimple js bar chart. I have no clue how they can be drawn on y-axis (cost) as straight line that will cut through the bars. Here is the fiddle that has high, low and average values saved into corresponding variable that needed to be drawnon the chart. Any solution? jsfiddle link: http://jsfiddle.net/Ra2xS/14/
var dim = {"width":590,"height":450}; //chart container width
var data = [{"date":"01-02-2010","cost":"11.415679194952766"},{"date":"01-03-2010","cost":"10.81875691467018"},{"date":"01-04-2010","cost":"12.710197879070897"}];
//y- axis (cost) values to plot as straight line over bar chart in different colours
var avg = "11.65";
var high= "12.71";
var low = "10.82";
function barplot(id,dim,data)
{
keys = Object.keys(data[0]);
var xcord = keys[0];
var ycord = keys[1];
var svg = dimple.newSvg(id, dim.width, dim.height);
var myChart = new dimple.chart(svg,data);
myChart.setBounds(60, 30, 505, 305);
var x = myChart.addCategoryAxis("x", xcord);
x.addOrderRule(xcord);
x.showGridlines = true;
var y = myChart.addMeasureAxis("y", ycord);
y.showGridlines = true;
y.tickFormat = ',.1f';
var s = myChart.addSeries(null, dimple.plot.bar);
var s1 = myChart.addSeries(null, dimple.plot.line);
s1.lineWeight = 3;
s1.lineMarkers = true;
myChart.draw(1500);
}
barplot("body",dim,data);
You can do it by adding a separate series with it's own data, unfortunately there's a bug with multiple line series in version 1.1.5 which means line markers go haywire (so I've removed them from the code below). The good news is I've just finished rewriting all the line chart code and this problem will be fixed in the next version (coming in a week or so), also the line will animate properly by rising from the x axis instead of fading in from black.
var dim = {"width":590,"height":450}; //chart container width
var data = [{"date":"01-02-2010","cost":"11.415679194952766"},{"date":"01-03-2010","cost":"10.81875691467018"},{"date":"01-04-2010","cost":"12.710197879070897"}];
function barplot(id,dim,data)
{
keys = Object.keys(data[0]);
var xcord = keys[0];
var ycord = keys[1];
var svg = dimple.newSvg(id, dim.width, dim.height);
var parser = d3.time.format("%d-%m-%Y")
var dateReader = function (d) { return parser.parse(d[xcord]); }
var start = d3.time.month.offset(d3.min(data, dateReader), -1);
var end = d3.time.month.offset(d3.max(data, dateReader), 1);
var myChart = new dimple.chart(svg,data);
myChart.setBounds(60, 30, 505, 305);
//var x = myChart.addCategoryAxis("x", xcord);
var x = myChart.addTimeAxis("x", xcord, "%d-%m-%Y","%b %Y");
x.overrideMin = start;
x.overrideMax = end;
x.addOrderRule(xcord);
x.showGridlines = true;
x.timePeriod = d3.time.months;
x.floatingBarWidth = 100;
var y = myChart.addMeasureAxis("y", ycord);
y.showGridlines = true;
y.tickFormat = ',.1f';
var s1 = myChart.addSeries(null, dimple.plot.bar);
var s2 = myChart.addSeries(null, dimple.plot.line);
s2.lineWeight = 3;
var s3 = myChart.addSeries("Price Break", dimple.plot.line);
s3.data = [
{ "Price Break" : "high", "cost" : 12.71, "date" : parser(start) },
{ "Price Break" : "high", "cost" : 12.71, "date" : parser(end) },
{ "Price Break" : "avg", "cost" : 11.65, "date" : parser(start) },
{ "Price Break" : "avg", "cost" : 11.65, "date" : parser(end) },
{ "Price Break" : "low", "cost" : 10.82, "date" : parser(start) },
{ "Price Break" : "low", "cost" : 10.82, "date" : parser(end) }
];
myChart.draw(1500);
}
barplot("body",dim,data);
http://jsfiddle.net/Ra2xS/28/

dimple js x-axis date issue with bar chart

My bar chart bars on x-axis is adding to the right positions but the x-axis ticks are duplicating month and year in the dimple js. How can I adjust the x-axis as I have only three values in this data? Here is the jfiddle: http://jsfiddle.net/Ra2xS/17/
Any suggestions?
var dim = {"width":590,"height":450}; //chart container width
var data = [{"date":"01-02-2010","cost":"11.415679194952766"},{"date":"01-03-2010","cost":"10.81875691467018"},{"date":"01-04-2010","cost":"12.710197879070897"}];
function barplot(id,dim,data)
{
keys = Object.keys(data[0]);
var xcord = keys[0];
var ycord = keys[1];
var svg = dimple.newSvg(id, dim.width, dim.height);
var myChart = new dimple.chart(svg,data);
myChart.setBounds(60, 30, 505, 305);
//var x = myChart.addCategoryAxis("x", xcord);
var x = myChart.addTimeAxis("x", xcord, "%d-%m-%Y","%b %Y");
x.addOrderRule(xcord);
x.showGridlines = true;
var y = myChart.addMeasureAxis("y", ycord);
y.showGridlines = true;
y.tickFormat = ',.1f';
var s = myChart.addSeries(null, dimple.plot.bar);
var s1 = myChart.addSeries(null, dimple.plot.line);
s1.lineWeight = 3;
s1.lineMarkers = true;
myChart.draw(1500);
}
barplot("body",dim,data);
You can prevent the excess ticks/labels by setting the time period for the axis to months:
x.timePeriod = d3.time.months;
Complete demo here.

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();
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

Categories