I'm trying to use NVD3 with d3.js to make a simple sparkline. I've successfully created several sparklines with .csv data, but when I tried to use a different data set, it gave a very strange looking sparkline. See here. If I change the first data value from 92 to 0, it successfully shows the sparkline.
Is this a bug in NVD3 or am I doing something wrong?
The problem was that the y values were strings. I changed
monthlyData.push({x: data[i].Month, y: data[i].Data});
to
monthlyData.push({x: data[i].Month, y: +data[i].Data});
so that the y value becomes a number. Here's the updated version.
Related
I am currently working with NVD3 using Angular Directive (angular-nvd3). I have a very simple line chart with very simple data.
The problem I have encountered now is that my data is wrongly aligned with the Axis. Example plunker available here: http://plnkr.co/edit/jWEYt6?p=preview ,
I am using dates on my xAxis, which are parsed using d3 library:
tickFormat: function(d) {return d3.time.format('%d/%m')(new Date(d))}
Description:
I would expect the xAxis labels to be correspondent to the grid.
In the example you can clearly notice that the xAxis is not evenly devided (values: 06/11, 08/11, 11/11, 13/11). So usually 2 days and sometimes 3 days :)
What is worse - the peaks are not matching the grid. Example: 06/11 tick is really not even close to the grid's line where I guess it is supposed to be.
I have also tried this on master's code from repo and it happens there too. There is a link in the HTML head section.
Is there a problem with my data, proper date formatting or something else? Thanks!
This bugged me for a while and I could not find an answer here. I even have opened a bug on GitHub: https://github.com/novus/nvd3/issues/1382#issuecomment-160694559 and I was clued in on the answer.
The problem:
The actual issue is hidden because of d3.time.format('%d/%m'). My example data is given in one tick per day manner, and the format was set accordingly. But d3 does not understand that. When drawing the grid it divides the max-min/someValue and the grid ticks does not have to occur on full day (midnight), but on any hour. And because of the formatting I could not see that.
The version showing this misconception is here: http://plnkr.co/edit/2iMHOp?p=preview
Solution:
So now, when I know what I could do, I managed to substitute the ticks by using tickValues parameter in nvd3 / angular wrapper.
The version with the solution is here:
http://plnkr.co/edit/23n3ll?p=preview
Yet another bug :)
Funny thing is that since the labels are too long to be displayed, I had to rotate them so they could fit. Another bug occurs here (I think). As you can see 2nd and last but one tick label is missing. First I tried using the solution mentioned here: NVD3 Line Chart X Axis Ticks Are Missing using the showMaxMin parameter but it does not work correctly. But if you rotate the labels to ~ -70 degrees the labels are displayed OK.
I guess this is not the end with my NVD3 journey ;)
Since the problem is, according to Atais:
The actual issue is hidden because of d3.time.format('%d/%m'). My example data is given in one tick per day manner, and the format was set accordingly. But d3 does not understand that. When drawing the grid it divides the max-min/someValue and the grid ticks does not have to occur on full day (midnight), but on any hour. And because of the formatting I could not see that.
I managed to pass the x's values as integer values (ex: 20160211) instead of formatted dates (ex: 2016-02-11 or similars) to nvd3, and then on tickFormatformat them to display properly.
I wrote another plunker with the problem and the commented solution (used momentjs):
Plunker with the simulated error: http://plnkr.co/edit/fXDQ0f?p=preview
Data is provided in format x: milliseconds, y: int, like {x: 1446418800000, y: 20}, and it is being formated with tickFormat:
xAxis: {
tickFormat: function(d) {
return moment(d).format('YYYY-MM-DD');
}
}
Plunker with the solution: http://plnkr.co/edit/KpALzo?p=preview
Data is provided in format x: int, y: int, like {x: 20160211, y: 20}, and it is being formated with tickFormat:
xAxis: {
tickFormat: function(d) {
moment(d, 'YYYYMMDD').format('YYYY-MM-DD');
}
}
Note that you can do it with time too, just by appending to the 'numeric date'.
As stated from #ajaybc, will not work well with dates from different months, since d3 will interpolate X axis with invalid filling dates (days 32, 33, 34 and so on)
I'm trying to draw a difference chart (like this one) but using a more modular style.
So far, I've got as far as reading in two dummy CSV files, combining the data, generating a chart, and am now trying to just draw a single line from one part of the data, but I keep getting an error. The full code is available on bl.ocks.org.
The error is:
Error: Problem parsing d="M0,221.73913043478262LNaN,182.60869565217394LNaN,195.6521739130435LNaN,156.52173913043478L500,91.30434782608697L500,91.30434782608697LNaN,156.52173913043478LNaN,195.6521739130435LNaN,182.60869565217394L0,221.73913043478262Z"
which occurs when doing this:
g.select('.line').attr('d', line);
At that point (as seen in the console), data is:
[{"year":1999,"imports":15,"exports":19},{"year":2000,"imports":18,"exports":20},{"year":2001,"imports":17,"exports":30},{"year":2002,"imports":20,"exports":32},{"year":2003,"imports":25,"exports":9}]
xScale.range() is:
[0, 500]
xScale.domain() is:
[1999, 2003]
yScale.range() is:
[300, 0]
and yScale.domain() is:
[9, 32]
I'm guessing there's a simple error somewhere in there, meaning the wrong data is being used to draw the line, but after several hours trying to fix this, I can't see what I've done wrong.
You are using an ordinal scale, which doesn't interpolate between values. The domain of that scale consists of two elements, and it will map those to the two elements in the output range. That is, 1999 is mapped to 0 and 2003 is mapped to 500. For any other inputs, the scale will return NaN as the value isn't in its input domain.
You can fix this by specifying all the years you want mapped in the domain and the corresponding output values in the range. In your case, the easiest would be to use a linear scale though as that seems to be what you're assuming will happen with your current scale. You would simply need to replace the definition of the scale and how the range is set. This is what I have done here.
Alternatively, you could use a time scale as that would give you potentially better labels.
I have plotted some JSON data using Morris.js. The graph works fine, however I'm trying to tweak the labels along the y-axis in a line chart.
Currently, the yLabels are being automatically generated by morris.js using the JSON data's range of values (where x-axis is time). In my example JSON, values range from 54 to -47, so the yLabels being generated are 54, 29, 4, -22, -47. Instead, however, I'd like to round these values to -50, -25, 0, 25, and 50. I would also like the "0" line to stand out, hopefully with a different colour.
As I'm dynamically creating the data, these won't be fixed, in another chart the values may range between -2.5 and +2.5 (in which case I'd want the labels along the y axis to be -2.5, -1.25, 0, 1.25, 2.5).
How would I round the labels morris.js is creating and make the "0" line red?
I have tried creating an array of yLabels (yLabels: ['-50','-25','0','25','50'],), but it didn't work, and even if it had I don't want to "hard-code" values because as I said, each chart will be different and dynamically generated.
Any help is greatly appreciated.
UPDATE
In the first example, I have been able to get what I want putting ymin and ymax of -50 and 50 respectively, but like I mentioned, I don't want to hard-code these values as the ymin/max will vary depending on the JSON being parsed. Is there a way I can always ensure the middle line is always 0, and morris determines the two y values above and below it?
I't cannot be done using Morris options. You will have to go into source and change drawGrid() function in morris.grid.coffee file.
I upped the numLines property of the gridDefaults in morris.js and was able to get everything in my Y-Axis to display. Perhaps you could play around with that property to display your Y-Axis differently.
I am trying to draw a line chart using big array list of objects with id,named values but something is going wrong. I can see following warnings in firebug window :
Unexpected value NaN parsing y attribute.
elem[setAttribute](prop, value);
http://jsfiddle.net/stGXM/19/
Why do those warnings are coming? Currently chart is not getting drawn even though I have mentioned all the necessary values.
Please help...
You should specify each point in your series in the form [x, y, ID].
I've modified your code: http://jsfiddle.net/Ut5C3/
Here's the Highcharts reference: http://api.highcharts.com/highcharts#series.type
http://chart.apis.google.com/chart?cht=lc&chs=600x400&chd=t:171,811,629,507,460,390,434,379,329,312,368,329,329,329,352,330,299,323,340,325,329,1895,1047,736,617,684,620,515
If you go there on your browser, you'll notice that you see a graph. However, the axis are messed up! And it seems like I can't see the ups and downs of my line graph. WHy?
I don't get what's wrong. I just want to plot the simple stuff on a line chart. Just those data points. Nothing more, nothing less!
If you use basic text format for the chart data, the range of data value is 0 - 100. Values above 100 are truncated to 100. The data values you provided are all above 100, so they are truncated to 100.
You should use text format with custom scaling. Try this one. The range of data values is set to 0 - 2000 using chds=0,2000.
http://chart.apis.google.com/chart?cht=lc&chs=600x400&chd=t:171,811,629,507,460,390,434,379,329,312,368,329,329,329,352,330,299,323,340,325,329,1895,1047,736,617,684,620,515&chds=0,2000