Target in barchart in dc.js - javascript

I'm using dc.js for charting, and it is great.
I'm currently trying to create barchart with target-lines for each bar, similar to bullet-charts, see http://bl.ocks.org/mbostock/4061961. I only need the target-line (+value); I can create the stacked bars perfectly.
I currently use a composite chart, where the target is a lineChart with interpolation set to step-before.
composite
.width(768)
.height(480)
.x(d3.scale.linear().domain([0,20]))
.yAxisLabel("The Y Axis")
.legend(dc.legend().x(80).y(20).itemHeight(13).gap(5))
.renderHorizontalGridLines(true)
.compose([
dc.barChart(composite)
.dimension(dim)
.colors('red')
.group(grp1, "Top Line"),
dc.lineChart(composite)
.dimension(dim)
.colors('blue')
.group(grp2, "Bottom Line")
.interpolate("step-before")
])
.brushOn(false)
.render();
However, this creates ugly vertical lines. Is there a better approach?

Sorry for answering my own question :) I currently have this (with some modificatios to dc.js's barchart, as it is really buggy calculating barwidth etc.:)
composite
.width(300)
.height(480)
.x(d3.scale.ordinal().domain(['01M','03M','06M','12M'] ))
.xUnits(dc.units.ordinal)
.compose([
dc.barChart(composite)
.dimension(dim)
.group(perf , "CatA")
.stack(local, "CatB")
.stack(akzo , "CatC")
.colors(d2acolors)
.gap(0)
,
dc.barChart(composite)
.dimension(dim)
.padding(16)
.group(perf , "Perf")
.colors("black")
.gap(0)
,
dc.barChart(composite)
.dimension(dim)
.colors("black")
.padding(8)
.target(true)
.gap(0)
.group(dateGroup, "Target")
.valueAccessor(function(p) {
return targets[p.key];
})
])
.yAxisLabel("Number of vendors")
.xAxisLabel("Inactive for")
.legend(dc.legend().x(540).y(10))
.colors(d2acolors)
.render();
The targets are basically also barcharts, but the bottom of the bar is rendered 5 px below the top, so it becomes a line. The 'padding' setting reduces the width of the bars on either side by the number of pixels that is entered.
I will try to publisch the changes I made in the dc.js's barchart somewhere.

Related

D3.js bar chart 'enter' appears to draw the new bars in wrong position

I have been following several tutorials / articles on D3.js to create a bar chart with drill-through type functionality. I have it working pretty much how I want it but have a problem that I just can't seem to figure out.
I have an example that I am working on here (this is cut down version from the main one I'm working on, just to show the issue): http://jsfiddle.net/MattFrewin/bobec00k/1/
You can see that the initial bar chart shows 1 bar for 'Team A', you can click on this to drill through to the next set of data - which shows 3 bars of data. The problem is that the new bars are all slightly out of place. You will notice that I am using a margin for the chart axis which offsets the bars, and from what I can tell it is this that is not being taken into account on the new bars. Here is the bit of code which I think is where the issues is:
//Create bars
chartBarData.enter()
.append("rect")
.attr({
"x": function (d) { return xScale(d.key); },
"y": height,
"width": xScale.rangeBand(),
"height": 0,
"fill": function (d) { return "rgb(0, 130, 0)"; }
})
.transition().delay(animDur).duration(animDur)
.attr({
"x": function (d) { return xScale(d.key); },
"y": function (d) { return yScale(d.values.count); },
"width": xScale.rangeBand(),
"height": function (d) { return height - yScale(d.values.count); },
"fill": function (d) { return "rgb(0, 130, 0)"; }
});
I have found a way around it by putting the margins into the 'x' and 'y' parts of the 'rect' attributes but this causes further similar issues when drilling further down into the data. I'm sure there is something obvious I am missing or probably just do not quite understand D3 fully yet! Any help is appreciated.
EDIT: I should also add that the D3 'update' section appears to work fine, using the same scales as the 'enter' section - which is confusing! As you will see on the jsfiddle link, the first bar is lined up correctly when you drill through but the other two are not.
It seems bars are not inserted into the proper location, in chart_drilldown function try to replace:
var chartBarData = theChart.selectAll("rect")
.data(groupedData);
with
var chartBarData = theChart.select("g").selectAll("rect")
.data(groupedData);
Modified JSFiddle

formatting nvd3.js colors and interactiveGuideLine

I've gotten lost amongst the d3.js weeds. I'm putting together a chart using nvd3.js (http://i.stack.imgur.com/ghueS.png).
But, while the colors appear correct in the legend, they do not in the chart. Additionally, there is significant white space in the hovering tooltip.
Looking into the object structure, I get what looks like one layer of keys too many, which makes me think the color issue and white space have to do with my actual keys being too far buried in the object (http://i.stack.imgur.com/k46CO.png).
I've looked into nest() and rollup(), but can't comprehend how they might help.
My javascript is as follows:
d3.csv("http://fwllc.wpstagecoach.com/wp-content/themes/frameworkcr/markers.csv",function(err,data){
var noDates = d3.keys(data[0]).filter(function(k){return k!="date"});
var dataToPlot = noDates.map(function(k){
return {"key":k,
"values":data.map(function(d){
return {
"x":d3.time.format("%m/%d/%y").parse(d.date),
"y":+d[k]
}
})}
})
console.log(d3.entries(dataToPlot));
nv.addGraph(function() {
var chart = nv.models.lineChart()
.margin({left: 100}) //Adjust chart margins to give the x-axis some breathing room.
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
// .transitionDuration(350) //how fast do you want the lines to transition?
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true) //Show the x-axis
;
chart.xAxis //Chart x-axis settings
.tickFormat(function(d) { return d3.time.format("%m/%d/%y")(new Date(d)); });
chart.yAxis //Chart y-axis settings
.axisLabel('Total Return Percent')
.tickFormat(d3.format('%'));
d3.select('#chart').append("svg")
.datum(dataToPlot)
.call(chart);
nv.utils.windowResize(function() { chart.update() });
return chart;
});
})
And a portion of my .csv file:
date,ESG,global100,outperformance
12/22/08,0,0,0
3/23/09,-0.059812891,-0.094081914,0.034269023
6/22/09,0.137426291,0.033160892,0.104265399
9/21/09,0.418041893,0.249191458,0.168850435
12/21/09,0.460914373,0.294278644,0.166635729
3/22/10,0.504442354,0.306489826,0.197952528
I copied you code to a plnkr, it seems correct...
<div id="chart" style="width:300px; height:300px"></div>
plnkr

nvd3 line chart not shown properly. (dots and shaded area)

So I am using nvd3 and I want to show 2 lines in one line chart. I know the code is alright as I am trying it on the live code of nvd3 and it works fine. I read in many places though that the code they use on the nvd3 live code is not the same as the api.
So the graph is shaded and has dots. However in the live code of nvd3 there are no dots and no shaded area.
Thus is my code :
nv.addGraph(function() {
var chart = nv.models.lineChart()
.useInteractiveGuideline(true)
.width(900)
.height(600)
.margin({
left: 75,
right: 50
})
.showLegend(true)
.showYAxis(true)
.showXAxis(true)
.width(800)
.height(900);
;
chart.xAxis
.tickFormat(d3.format(',r'))
;
chart.yAxis
.tickFormat(d3.format('.02f'))
;
//console.log(json);
d3.select('#Average_Life svg')
.datum([{"values":[{"x":0,"y":2042},{"x":173,"y":1922},{"x":347,"y":1873},{"x":526,"y":1907},
{"x":700,"y":1883},{"x":931,"y":1854},{"x":1058,"y":1710},{"x":1220,"y":1473},{"x":1399,"y":1792},
{"x":1584,"y":1869},{"x":1752,"y":2259},{"x":1983,"y":2288},{"x":2105,"y":2524},{"x":2284,"y":2770},
{"x":2469,"y":2857},{"x":2637,"y":2698},{"x":2811,"y":2760},{"x":3042,"y":2596},{"x":3169,"y":2500},
{"x":3331,"y":2408},{"x":3522,"y":2355},{"x":3690,"y":2500},{"x":3863,"y":2524},{"x":4095,"y":2447}],
"key":"dd","color":"#34418f"},{"values":[{"x":0,"y":3753},{"x":173,"y":3609},{"x":347,"y":3464},
{"x":526,"y":3315},{"x":700,"y":3170},{"x":931,"y":2977},{"x":1058,"y":2871},{"x":1220,"y":2736},
{"x":1399,"y":2587},{"x":1584,"y":2433},{"x":1752,"y":2293},{"x":1983,"y":2100},{"x":2105,"y":1999},
{"x":2284,"y":1849},{"x":2469,"y":1695},{"x":2637,"y":1555},{"x":2811,"y":1411},{"x":3042,"y":1218},
{"x":3169,"y":1112},{"x":3331,"y":977},{"x":3522,"y":818},{"x":3690,"y":678},{"x":3863,"y":534},
{"x":4095,"y":341}],"key":"ss","color":"#f9b800"}])
.transition().duration(500)
.call(chart);
//Update the chart when window resizes.
nv.utils.windowResize(function() {
chart.update()
});
return chart;
});
So I would like to know why the shaded area and the dots. And why I dont get to see the axis,
Cheers
Having the exact same issue on the shading. My solution is to just select all groups (the path elements are sorted into groups) and set fill: none right after i render the chart
This is my code
function test(data) {
/*These lines are all chart setup. Pick and choose which chart features you want to utilize. */
nv.addGraph(function () {
var chart = nv.models.lineChart()
.margin({left: 100}) //Adjust chart margins to give the x-axis some breathing room.
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
// .transitionDuration(350) //how fast do you want the lines to transition?
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true) //Show the x-axis
;
chart.xAxis //Chart x-axis settings
.axisLabel('Time (sec)')
.tickFormat(d3.format('.01f'));
chart.yAxis //Chart y-axis settings
.axisLabel('Torque (NM)')
.tickFormat(d3.format(',r'));
d3.select('#chart') //Select the <svg> element you want to render the chart in.
.datum(data) //Populate the <svg> element with chart data...
.call(chart); //Finally, render the chart!
d3.selectAll('g').style('fill', 'none');
//Update the chart when window resizes.
nv.utils.windowResize(function () {
chart.update()
});
return chart;
});
}

NVD3.js line graphs fail to scale y axis to max and min values

Building a page with multiple graphs, I've decided to use NVD3.
The problem is that NVD3 fails to find the maximum value, rendering some useless graphs.
http://jsfiddle.net/pxU8c/
function renderGraph(parent, data) {
function getGraph(svgElement, data) {
var height = 500;
var chart = nv.models.lineChart()
chart.options({
noData: "Not enough data to graph",
transitionDuration: 500,
showLegend: true,
showXAxis: true,
showYAxis: true,
rightAlignYAxis: false
});
chart.xAxis //Chart x-axis settings
.axisLabel(data['x-label'])
.tickFormat(function(d) {
return d3.time.format('%d.%m.%Y')(new Date(+d))
});
chart.yAxis //Chart y-axis settings
.axisLabel(data['y-label'])
.tickFormat(d3.format('.02f'))
;
svgElement //Select the <svg> element you want to render the chart in.
.datum(data['data']) //Populate the <svg> element with chart data...
.call(chart); //Finally, render the chart!
//Update the chart when window resizes.
nv.utils.windowResize(function() { chart.update() });
return chart;
}
var svgELement = d3.select('svg#chart_'+data['code']);
nv.addGraph(getGraph(svgELement, data));
}
I'm also using twitter bootstrap for layout, if it helps.
EDIT
following fiddle should be more useful since it contains less garbage
http://jsfiddle.net/Bh578/
the first and the seconds graphs are displaying the problem while the third is rendered accordingly to my expectations (i.e. you can see the whole line)
I have also added the useInteractiveGuideline: true option so it's more obvious that there are values outside of the visible graph area that I'd like to see on the chart too.
Values should be integers, not JSON-decoded-as-strings integers, then it works like a charm.

NVD3 piechart missing low percentage labels

I'm using NVD3 ver 3.1.7 for generating pieChart.
Everything works perfect except the chart labels. If the label value is of very low
percentage, it does not appear. I want to make it visible irrespective of its value.
This is my code.
nv.addGraph(function() {
var chart = nv.models.pieChart()
.x(function(d) { return d.label })
.y(function(d) { return d.value })
.showLabels(true);
d3.select("#chart svg")
.datum(data)
.transition().duration(1200)
.call(chart);
return chart;
});
Help would highly be appreciated.
I just managed to resolve this issue.
In nvd3 pieChart, there is a parameter
.labelThreshold(.05)
which sets percentage for chart labels to display or hide. By default this is set to
.02 => 2%.
I increased it to
.05 => 5%
which solved my problem.
You can use this option also.
.labelSunbeamLayout(true)

Categories

Resources