I have been using FLOT for many great things. Recently, i have needed to use it for time based plots. It worked perfect last month, but this month, i noticed that my last tick was smaller than the others. Also, i noticed that the tick label was not there.
Here is a JSFIDDLE of the issue for you to look at.
Due to the large amount of Javascript, i will keep all the code inside the Fiddle; unless the information is requested.
However, me and a friend thought of a simple workaround :
if(% 2 === 0) {
/*
Check if the data can be divided by 2
Repeat this for 3 as well (return the value and
plug it in the tickSize: [val, 'day'];
*/
}
The only drawback i see here if for months that have 31 days.
How would i fix this issue, or what did i do wrong that is causing this effect?
How about always making the chart 31 days wide (which means 30 days between first and last day and 15 ticks each 2 days wide)? You get that by setting the x axis maximum if your month does not have 31 days by itself:
xaxis: {
mode: "time",
timeformat: "%b %d",
tickSize: [2, 'day'],
max: 1398902400000
},
See this updated fiddle.
Related
It's quite straight-forward to get them (eg. looping through data) if ticks are always every week (d3.time.weeks). I would like to know is there a generic solution, if tick intervals (d3.time.months, d3.time.weeks, etc) are different based on period length of data.
In the example below the value 6 is the maximum value of the week (January 1 - January 7).
How can force nvd3 graph to have certain number of ticks to be displayed, for example, please find below the image of the graph plotted:
as seen below I have 7 values pushed to the array holding the 7 days of the week. However looks like they have more number of ticks than the actual values. What I'm looking for is something similar to this:http://nvd3.org/examples/line.html
However when i hover over these ticks they are misaligned as shown:
thats where the graph line should be and thats where the hovered tick shows the tooltip.but for some reason i dont get 7 ticks displayed instead gets 10 ticks displayed and all the hovered tooltips get misaligned.I also tried to force nvd3 to have specific # of ticks but didnt work.
chart2.xAxis
.ticks(7)
.tickFormat(function(d) {
return d3.time.format.utc('%b %d')(new Date(d));
});
here is the fiddle: http://jsfiddle.net/86hr7h1s/4/
I should ideally display 7 days and 7 ticks on the graph as oppose to duplicate days and 10 ticks on the graph.
Any ideas whats wrong and how to correct this?
EDIT::::::
I was able to fix my issue for 7 days with the below answer, using the tickValues() instead of ticks(). However, for large values, say display a graph data of 2 months, i'll have 30 data points. I still see that my graph ticks on hover dont align:
As you can see above the hover points still dont align with the vertical ticks. I dont want to force the ticksValues for more than 7 days on the graph.
Ay ideas how this could be achieved?
FYI:
I used this to make nvd3 display 7 values:
var datas = this.graphFunction(data);
chart2.xAxis.tickValues(datas[0].xAxisTickValues);
http://jsfiddle.net/86hr7h1s/5/
Thanks!
If you want to control the ticks precisely, you should use .tickValues() rather than ticks().
API Doc
I understand that the question was asked a long time ago, but I recently faced the same issue and found a good solution for it.
The reason of the issue with inaccurate ticks on the x-axis is the inaccurate internal numeric representation of dates that we want to display on the x-axis. As we can see here
https://nvd3.org/examples/line.html
when values on the x-axis are numbers, all ticks are displayed accurately. When we want to display dates on the x-axis, we also need to convert dates to some numeric representation. Typically dates are converted to the numeric representation via the Date.prototype.getTime() function and then labels are formatted using a code like this
chart.xAxis.tickFormat(d3.time.format('%b %Y')(date))
But the accuracy which the getTime() function provides to us is redundant in most cases. Assume we want to display only months and years on the x-axis and have a sorted list of dates where different items always have different moths but the item with a particular month may have any day and time. So, there may be a situation, where two adjacent list items have though have different months are very close to each other (for example, "Feb 28" and "Mar 1"). When we convert these list items to numeric representation using the getTime() function, the resulting list of big numbers remembers how far adjacent list items stand apart from each other. As the distance between adjacent chart points is always equal in NVD3 charts, NVD3 tries to fine-tune labels display to provide the info that some numbers are close to each other, but others are not. It leads to inaccurately displayed labels or even to duplicated labels if a chart has few points.
The solution is to omit redundant information about date and time when we convert dates to numbers. I needed to display only months and years on the x-axis and this code works great for me.
function getChartData(data) {
var values = data.map(function(val) {
return {
x: val.x.getUTCFullYear() * 12 + val.x.getUTCMonth(),
y: val.y
}
});
return [{
values: values,
key: 'date'
}];
}
function formatDate(numericValue) {
var year = Math.floor(numericValue / 12);
var month = numericValue % 12;
return shortMonthNames[month] + ' ' + year;
}
nv.addGraph(function() {
var data = [
...
{
x: new Date(2020, 2, 15, 15, 12),
y: 90
},
{
x: new Date(2020, 3, 3, 3, 54),
y: 50
},
...
];
var chart2 = nv.models.lineChart()
.showXAxis(true)
.showYAxis(true);
chart2.xAxis.tickFormat(formatDate);
d3.select('svg#svg')
.datum(getChartData(data))
.call(chart2);
return chart2;
});
Here we don't use the .tickValues() NVD3 function and so don't interfere to the default rendering engine, so the NVD3 lib can automatically add or remove axis labels when the viewport width is changed, and ticks and corresponding vertical lines are displayed exactly on the place where they should be.
Here is the full working example
http://jsfiddle.net/AlexLukin/0ra43td5/48/
I have a chart where I have on the x-axis a datetime and on the y-axis a value in seconds, like 10, 200 or 4500. This works fine.
What I need is something like the behavior of the datetime, that when you have a date range it shows the days between that range, but if the range is really small, it displays the hours between that range. My request is that I would like to do the same but having a number in seconds, and if the range is huge, like maybe between 100 and 2500, it should be converted to minutes, what I have now is the following:
yAxis: {
title: {
text: 'Minutes',
margin: 10
},
min: 0,
tickInterval: 60,
labels:{
formatter: function(){
var minutes = ""
if (this.value > 59){
minutes = Highcharts.numberFormat((this.value/60), 0)
}
return minutes;
}
}
}
which is great for range between 60 and 500, but when the range is longer, it draws a lot of lines to display the minutes.
Any ideas? Can I change the tickInterval depending on some value?
I already have seen this reply Plotting seconds, minutes and hours on the yAxis with Highcharts, but I don't want to handle a datetime object on that axis.
I would really recommend using the inbuilt datetime axis type if you can. It takes away a lot of hassle with things like the issue you are asking about.
Failing that, you are on the right track in looking at the tickInterval. You could try not specifying a tickInterval at all, and let highcharts decide for you. It will usually find something sensible.
If that doesn't work well for you, then you will have to look at your data range and choose a sensible tickInterval yourself. One algorithm you could use is:
if (range < 500)
tickInterval = 60
else
tickInterval = 120
Obviously, if your range can go even bigger, you may need to have another case which switches the tickInterval to 300 or higher.
I have been trying a lot in Highchart js and still cant find a way to reduce the number of elements in the series.
If i get more than 15 days data i have to reduce it back and show to user as 15 days data so that user can see the data without crowding of data. Max 90 days will be given in the series which i have to reduce to 15 days.
check my current code here in http://jsfiddle.net/MULZL/
can any one give me a solution for it ?
P.S: I dont want to reduce it to first 15 days or last 15 days. I want to do it just because getting 90days in the chart looks crowded and i dont want zoom functions to apply. I want the solution for ignoring some data (days) to make it 15days if it is more than 15 days
You can programmatically zoom into the required time range using the Axis.setExtremes method. In your case you may want to do it on load
Here is how you would do it, if you want to zoom into the 1st 15 days of the given data, you can easily modify to zoom into last 15 days.
function zoomTo15Points(chart){
var points=chart.series[0].points;
if(points.length<15) return;
var min=points[0].x;
var max=points[14].x;
// If you wish to zoom to 15 days and not 15 points, you can modify max as
// var max=min + 1000*60*60*24*14
chart.xAxis[0].setExtremes(min,max);
chart.showResetZoom();
}
If you do not want to let the user zoom out, you can disable the last line, but you also will have to disable zooming, else the button would appear if user zooms inside the 15 days.
Highchart Zoom on Load # jsFiddle
You can try dataGrouping feature of highStock
var dataGrouping = {
groupPixelWidth: 40,
units: [[
'day',
[1, 2, 3,4,5,6]
]]
};
Highcharts would make sure all your columns are at least the specified width (40), if the number of coulmns is large, such that it's not possible to have that width, it will group data using the units, so it will group data of 1 day into 1 column or 2 days into 1 column and so on.
Not sure if you really want exactly 15 plots, but I think you concern was to avoid crowding of data, this does exactly that, but the number of columns will vary based on the width you specify, the width of the plotArea and allowed units and its multiples. Tweak the values as per your data and width of your chart.
jsFiddle
I have a HighChart chart which contains a series which is made up of date/value pairs. Each date in the pairs is different. When there are data pairs which have dates which are not within the same week they dates are displayed as they should (mm/dd/yyyy) but when the data set contains only a view pairs which are all within the same week or days right next to each other instead of displaying dates in the (mm/dd/yyyy) format the chart switches to what looks like a time display and shows 00:00, 08:00, 16:00 instead of the full dates.
I already scoured the HighCharts forum and cannot find nor get an answer to this strange behaviour. Maybe someone here can help.
You can see the chart at http://jsfiddle.net/schleichermann/DkgVr/
This is a foible of the auto-scaling algorithm.
Basically, it starts with the smallest unit and stops looking too soon in some cases (like yours)1.
If you know, in advance, the timescale of interest, you can tweak the xAxis settings to compensate.
In this case adding:
day: '%b %e',
hour: '%b %e',
May be adequate. See: jsfiddle.net/DkgVr/4/ .
Or setting tickInterval: 24 * 3600 * 1000 (one day) might be good enough.
See: jsfiddle.net/DkgVr/5/ .
1 It should probably work largest to smallest. Consider making a feature-request or bug report.