I'm pulling data from a csv where date(YYYYMMDD) and time (HHmm) are two of the columns. I already have a working parser that spits out array data points in [x, y] form. I just don't know how to parse my datetime (to use as the x-value) so Highcharts accepts it as a datetime. Just passing it in as one long number (YYYYMMDDHHmm) gives me a graph where all million points happen with a couple days in May...
You have two options depending on how is your data:
1) Set the correct data type as category
The documentation states:
The type of axis. Can be one of linear, logarithmic, datetime or category. In a datetime axis, the numbers are given in milliseconds, and tick marks are placed on appropriate values like full hours or days. In a category axis, the point names of the chart's series are used for categories, if not a categories array is defined.
To use it you would need your data in a millisecond format like:
[[1526688000000, 100], [1526774400000, 150], [1526860800000, 200]]
Fiddle: https://jsfiddle.net/y7kL4ccL/
Then to format your datetime, you can check here in the documentation.
2) Keeping the labels that way and provide a custom formatter
To do so you must set your xAxis.categories.type to category for Highcharts to use your point names as categories and then provide a custom xAxis.labels.formatter that transforms your string into whatever you want.
Example:
xAxis: {
type: 'category',
labels: {
formatter: function() {
var year = this.value.substring(0, 4);
var month = this.value.substring(4, 6);
var day = this.value.substring(6, 8);
return `${day}/${month}/${year}`;
}
}
},
Fiddle: https://jsfiddle.net/qpad3qh7/
Related
I am encountering a problem with my chart created with HighCharts (StockChart), and more precisely with the dates which do not apply for certain data series and are set by default in 1970.
I get the data from ajax request and I create my data series with the Highchart format as below:
data.forEach(element => {
var d = new Date(Date.parse(element[0]));
console.log("d : " + d);
timestampData.push([d, element[1]]);
});
console.log(timestampData);
timestampData = timestampData.sort((a, b) => a[0] - b[0]);
chart.series[0].setData(timestampData, true);
And here is the result for both cases the date format is exactly the same and yet the date applies for one series but not for the other
Here the date works
Here the date is to 1970 but when can see the date result in console is to 2019
This is strange because nothing is done differently for the two series and the conversion to Date format is good for the two series
About the logged dates, it's hard to debug without knowing the value of element iterator, but Date.parse() can have ambiguous results, depending on the format of its argument.
In general, my advice is to use js millisecond timestamps instead of Date objects like so:
data.forEach(element => {
var d = new Date(Date.parse(element[0]));
timestampData.push([d.valueOf(), element[1]]);
});
It's more universal and highcharts responds fine to it.
How can I format the labels that appear on AG-Grid chart's axis? I have a lot of time-series data so I expect users frequently to produce charts where the horizontal axis is a date. Unfortunately, this produces unreadable chart labels because the dates are not formatted (see attached image) - The labels look like "Thu Jan 09 2020 00:00:00 GMT+0000 (Greenwich Mean Time)" when all I would like is simply "2020-01-09". My The dates in the grid look fine thanks to a valueFormatter for dates.
It is also very common for users to produce pivot tables using the date. This produces similarly terrible results for the labels, but I've found I can use "processSecondaryColGroupDef" to format dates that appear in the column headers. Is there a similar way to do this for charts?
Thankyou,
Troy.
From the docs -
For time axes, a format string can be provided, which will be used to
format the data for display as axis labels
You can either explicitly set the axis type to 'time', but you can also remove this and the chart will still use the time axis as it automatically detects the axis type from the data in the Date column.
You can implement processChartOptions callback and add your customizations -
processChartOptions(params) {
var options = params.options;
var dateFormatter = function(params) {
return params.value.value && para[enter link description here][1]ms.value.value.toLocaleDateString
? params.value.value.toLocaleDateString()
: params.value;
};
if (["line"].indexOf(params.type) < 0) {
if (options.xAxis && options.yAxis) {
options.xAxis.label.formatter = dateFormatter;
options.yAxis.label.formatter = dateFormatter;
}
} else {
options.xAxis.type = "time";
options.xAxis.label.format = "%d %B";
}
Example and details here
Is is possible to make Highcharts skip empty date values?
I have a stacked column chart with amounts on the Y axis and dates on the X axis. But the dates are very much spread making the chart extremely wide if all values are to be seen clearly.
See this example: http://jsfiddle.net/8j1ar44L/13/
If all values are in 2016 it looks nice, but to demonstrate the problem I changed the last dataset to 2017. In the real use case, it is actually much worse as we span several years.
Setting ordinal true doesn't work:
xAxis: {
type: "datetime",
tickInterval: 24 * 3600 * 1000,
ordinal: true
},
How can I make Highcharts simply ignore missing dates and thus ignore white space between the columns?
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 will try to explain better, starting with this image, that should make you understand better what i want to display in the graph. (the data will be taken from a database, but that's not important)
For every single day (and this graph represents a single day) I would like to see on the chart all the users (at most are 5-6) who have made at least one "action". These "actions" have a start time and an end time.
In this case, users are the series.And every series is a list of intervals (of time) of all actions made by the user on that day.
Example of series of a user who has made three actions on this day (yes, the time stamp will be multiplied by 1000)
[["1430362800","1430366400"],["1430391600","1430398800"],["1430424000","1430425800"]]
To view on the x-axis the interval 00:00 - 24:00 i will do
xAxis: {
type: 'datetime',
tickInterval: 3600 * 1000
}
Each horizontal line must be a user. To do that I should set the maximum and minimum of the y-axis. And , for example , if the users are 3 i'll do something like that (i will add only one axis, and the value (y) of each user must be 1,2,3...).
chart.addAxis({
min: 1,
max : 3,
ceiling:1,
tickInterval: 1,
labels: {
formatter: function() {
if (this.value <= 3){
return "";
}else{
return null;
}
}
}
});
The problem is that i don't know which type of chart used to display this type of data. Thanks