change Axis domain/range doesn't work in nvds - d3.js

I'm trying nvd3 example at http://nvd3.org/livecode/index.html#codemirrorNav
Please click on plot 2 "Scatter/Bubble Chart".
Original Code for JavaScript is like:
nv.addGraph(function() {
var chart = nv.models.scatterChart()
.showDistX(true)
.showDistY(true)
.color(d3.scale.category10().range());
chart.xAxis.tickFormat(d3.format('.02f'));
chart.yAxis.tickFormat(d3.format('.02f'));
d3.select('#chart svg')
.datum(data(4,40))
.transition().duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
I tried to change xAxis range/scale/domain to see if it has anything. But somehow it doesn't work.
What I did was to add
var xScale = d3.scale.linear().domain([0,1]).range([1,4]);
chart.xAxis.scale(xScale);
chart.xAxis.tickValues([1,2,3]);
below yAxis line in original plot.
I can see tickValues work as expected. But somehow both domain and range doesn't work as expected.
I would like to see xAxis to start from a different value like 1 or 0. Please help.

Try something like
chart.forceX([minValue,maxValue])
Hope it helps.

Related

Change x-axis range to percent of bullet chart in NVD3

Please help me how can i change x-axis range of bullet chart to percentage?
i have this code of my NVD3.js bullet chart
nv.addGraph(function() {
var chart = nv.models.bulletChart();
chart.tooltip.valueFormatter(function(d){
return ''+ numberWithCommas(d)+''; //on hover show percentage and value
});
d3.select('#chart svg')
.datum(data)
.transition().duration(1000)
.call(chart);
return chart;
});
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
here's my data variable
var data = {
measureLabels: ["Total Obligated"]
measures:[0]
rangeLabels:["Available Amount"]
ranges:[28464000]
subtitle:"CODE"
title:"200000100003000"
}
i have tried to add this code
chart.xAxis.tickFormat(function(d) {
//return ranges * 100 / ranges
});
but it said that 'tickFormat' is not a function.
ok i figure out how to change it LOL!.
i added this code.
d3.selectAll('g.nv-tick').select('text').text(function (t) {
return (100 * t / data.ranges[0]).toFixed();
});
i tooks me half a day to figure it out T_T

Normalize the Graph axes in NVD3 Line with focus chart

I am having two lines in th graph like in the picture having different X axis points. I just want to compare the lines. So I need to bring the second line under the first line (Normalize the graph like the second picture)
I tried to use nvd3 domain and range option and some others too. But its not working. Could you guys tell me how to get those normalized graph. I dont worry about the Tick format as far as the lines are comparable.
PICTURE 1 (the graph I am having)
https://www.dropbox.com/s/sycwppnlachju2s/Screenshot%20from%202014-06-19%2014%3A21%3A40.png
PICTURE 2 (Graph I need)
https://www.dropbox.com/s/eoajf0yyk96w6y7/Screenshot%20from%202014-06-19%2014%3A20%3A21.png
nv.addGraph(function() {
var chart = nv.models.lineWithFocusChart();
chart.xAxis
.tickFormat(d3.format(',f'));
chart.yAxis
.tickFormat(d3.format(',.2f'));
chart.y2Axis
.tickFormat(d3.format(',.2f'));
d3.select('#chart svg')
.datum(data)
.transition().duration(500)
.call(chart)
;
nv.utils.windowResize(chart.update);
return chart;
});
This is my data file. data.json
[{"key":"Memory_FREEmyses1","values":[{"x":"1395426430","y":"200028"},
{"x":"1395426431","y":"199904"},{"x":"1395426432","y":"187620"},
{"x":"1395426434","y":"187504"},{"x":"1395426435","y":"187380"},
{"x":"1395426436","y":"187008"},{"x":"1395426437","y":"186760"},
{"x":"1395426438","y":"186512"},{"x":"1395426439","y":"186388"},
{"x":"1395426440","y":"186264"},{"x":"1395426441","y":"181804"},
{"x":"1395426443","y":"181084"},{"x":"1395426444","y":"181084"}]},
{"key":"Memory_FREEmyses2","values":[{"x":"1395426455","y":"178604"},
{"x":"1395426456","y":"178348"},{"x":"1395426457","y":"178356"},
{"x":"1395426458","y":"178232"},{"x":"1395426460","y":"178108"},
{"x":"1395426461","y":"177860"},{"x":"1395426462","y":"177480"},
{"x":"1395426463","y":"176992"},{"x":"1395426464","y":"176868"},
{"x":"1395426465","y":"176620"},{"x":"1395426466","y":"176612"},
{"x":"1395426467","y":"176620"}]}]
Try to map your data like:
data = data.map(function(series) {
var d0 = series.values[0].x;
var dN = series.values[series.values.length -1].x;
series.values = series.values.map(function(d) {
return {
x: 10*(d.x-d0)/(dN-d0),
y: d.y
}
});
return series;
})
See demo.

PieChart in DC.js with Queue.js not working

Here is an example using Queue.js to loading multiple csv in a dc.js : https://github.com/dc-js/dc.js/blob/master/web/examples/composite.html
Here is my version (javascript):
var composite = dc.compositeChart("#test_composed");
var composite2 = dc.compositeChart("#test_composed2");
var q = queue()
.defer(d3.csv, "morley.csv")
.defer(d3.csv, "morley2.csv");
q.await(function(error, exp1, exp2) {
var ndx = crossfilter();
ndx.add(exp1.map(function(d) {
return {x: d.Run};
}));
ndx.add(exp2.map(function(d) {
return {x: d.Run};
}));
var dim = ndx.dimension(dc.pluck('x')),
grp = dim.group().reduceCount(dc.pluck('x'));
composite
.width(768)
.height(480)
.x(d3.scale.linear().domain([0,200]))
.compose([
dc.barChart(composite)
.dimension(dim)
.group(grp)
])
.brushOn(false)
.render();
composite2
.width(768)
.height(480)
.x(d3.scale.linear().domain([0,200]))
.compose([
dc.lineChart(composite2)
.dimension(dim)
.group(grp)
])
.brushOn(false)
.render();
});
Using the same data, should be good as picture attached.
It worked very well for lineChart and barChart but not working for pieChart, rowChart...
Is there any similiar example for working pieChart?
Thanks!
I know this doesn't really solve your problem but I'm just letting you know of a different solution. Google code playground shows off some of the cool code google has for developers to use. Check out these links
Bar Chart: https://code.google.com/apis/ajax/playground/#bar_chart
Thanks for posting a jsfiddle. If you complete your fiddle, we can better help you troubleshoot it. ;-)
Looks like you are trying to create a composite chart with a pieChart. That's unusual - why do you want to do that? Normally a composite is for when you want to overlay different charts, but you've only got the one chart in your fiddle.
I'm not sure if the composite chart works with non-grid charts.

nvd3.js chart ajax data redraw - missing hovereffect + former yAxis scale

I am using nvd3 to draw a simple line chart with data receiving via an ajax request. It is working perfectly with the first drawing request but not on redrawing. The chart redraws by calling the same drawing function but with different data + differen max/min values.
When redrawing the chart with new data the "hover circle" does not appear, whereas the tooltip does. Furthermore when clicking on the legend of the chart and force a redraw by that the hover appears again, but the values of the yAxis are changed to these of the first drawn chart.
So far I assume that when redrawing the chart still holds the old max/min values - but only concerning the "hover" effect. The general chart looks fine so far also on redraw - the problem just faces the hover and that's it.
Sounds pretty confusing, but hopefully you will get the point.
Some code:
d3.json(queryurl, function(data2){
nv.addGraph(function(jsonData) {
if(chart){
chart.remove();
}
chart = nv.models.lineChart()
.x(function(d) { return d[0] })
.y(function(d) { return d[1] })
.color(d3.scale.category10().range());
chart.xAxis
.tickFormat(function(d) {
return d3.time.format('%x')(new Date(d))
});
chart.yAxis
.scale()
.tickFormat(d3.format(''));
chart.lines.yDomain([maxmin.max,maxmin.min]);
d3.select('#chart1 #chartsvg')
.datum(data2)
.transition().duration(600)
.call(chart);
nv.utils.windowResize(chart.update);
});
});
return chart;}
Try using .empty() on the svg element before redrawing.
I've only just started with NVD3 and D3 myself, however am doing a similar thing. What worked for me is to separate the data update function with the chart creation function. Do note the caveat below though...
I have the following to create the graph:
initGraph = function(url) {
d3.json(url, function(data) {
nv.addGraph(function() {
chart = nv.models.multiBarChart();
d3.select('#chart svg').datum(data).transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
});
};
And the following function to update it:
redrawGraph = function(url) {
d3.json(url, function(data) {
d3.select('#chart svg').datum(data).transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
});
};
I don't know if this is the recommended solution as I'm still at the "hack until it works" stage. With this, all the functions of the chart work after invocation of redrawGraph() (including axes redraw and tooltips).
Caveat: this seems to occasionally result in miscalculated ticks on recalculation:

NVD3 line chart with realtime data

I have a really simple line chart written using NVD3.js. I've written a simple redraw based on timer, pulled from examples I've seen, but I get the error
Uncaught TypeError: Cannot read property 'y' of undefined
The JS is
var data = [{
"key": "Long",
"values": getData()
}];
var chart;
nv.addGraph(function () {
chart = nv.models.cumulativeLineChart()
.x(function (d) { return d[0] })
.y(function (d) { return d[1] / 100 })
.color(d3.scale.category10().range());
chart.xAxis
.tickFormat(function (d) {
return d3.time.format('%x')(new Date(d))
});
chart.yAxis
.tickFormat(d3.format(',.1%'));
d3.select('#chart svg')
.datum(data)
.transition().duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
function redraw() {
d3.select('#chart svg')
.datum(data)
.transition().duration(500)
.call(chart);
}
function getData() {
var arr = [];
var theDate = new Date(2012, 01, 01, 0, 0, 0, 0);
for (var x = 0; x < 30; x++) {
arr.push([theDate.getTime(), Math.random() * 10]);
theDate.setDate(theDate.getDate() + 1);
}
return arr;
}
setInterval(function () {
var long = data[0].values;
var next = new Date(long[long.length - 1][0]);
next.setMonth(next.getMonth() + 1)
long.shift();
long.push([next.getTime(), Math.random() * 100]);
redraw();
}, 1500);
Second Answer (after comment)
I looked at source for cumulativeLineChart. You can see the display.y property get created during chart creation. It relies on a private method: "indexify". If some derivative of that method was made public, then perhaps you could do something like chart.reindexify() before redrawing.
As a temporary workaround, you could recreate the chart from scratch on every update. If you remove the transition, that seems to work okay. Example jsfiddle: http://jsfiddle.net/kaliatech/PGyKF/.
First Answer
I believe there is bug in cumulativeLineChart. It appears that the cumulativeLineChart adds a "display.y" property dynamically to data values in the series. However, it does not regenerate this property when new values are added to the series for a redraw. I don't know of anyway to make it do this, although I'm new to NVD3.
Do you really need a CumulativeLineChart, or would a normal line chart be sufficient? If so, I had to make the following changes to your code:
Change from cumulativeLineChart to lineChart
Change from using 2 dimension arrays of data, to using objects of data (with x,y properties)
(I'm not familiar enough with NVD3 to say what data formats is expects. The 2D array obviously works for initial loads, but I think it fails to work for subsequent redraws. This is likely related to the same issue you are having with cumulativeLineChart. I thought changing to objects would fix cumulativeLineChart as well, but it didn't seem to.)
I also changed the following, although not as important:
Modified your getData function to create a new instance of Date to avoid unexpected consequences of sharing a reference as the date gets incremented.
Modified the update interval function to generate new data in increments of days (not months) with y values in the same range as the getData function.
Here's a working jsfiddle with those changes:
http://jsfiddle.net/kaliatech/4TMMD/
I found what I think is a better solution. The problem occurs because the cumulative chart sets the y function during processing. Whenever your want to refresh the chart, first set it back to a default which returns the correct original y. In your redraw function do this before updating:
chart.y(function (d) { return d.y; });
Even better would be if the cumulative chart could do this for itself (store the original access function before setting the new one, and put it back before re-indexing). If I get a chance, I'll try to push a fix.
I ran into the same issue. I changed the y() function on the lines from
.y(function(d) { return d.display.y })
to
.y(function(d) { return d.display ? d.display.y : d.y })
This gets rid of the error. Obviously it won't be displaying the (non-existent) indexed value in the error case, but in my experience, the chart gets updated again with display defined, and it looks correct.

Resources