UPDATE: My question is the opposite of this one, which it's been suggested might be a duplicate. I want not to use interpolation.
I am using Highcharts 4.1.7. I have a line chart with two time series. One series has a missing (not null, missing) data point.
By default in Highcharts, the line chart joins the points on either side and ignores the missing value. Is there any way to tell Highcharts not to join points where they are missing a value present in the other series?
I know that I can manually insert null values (and the default setting of connectNulls: false will do the rest), but it seems odd that Highcharts would interpolate between missing values by default - it's definitely visually misleading.
Code:
$('#container').highcharts({
xAxis: {
type: 'datetime',
dateTimeLabelFormats: {
month: '%b \'%y'
}
},
series: [{
data: [{ x: 1362096000000, y: 29.9}, { x: 1364774400000, y: 71.5}, { x: 1367366400000, y: 106.4}, { x: 1370001600000, y: 99.9}, { x: 1372636800000, y: 108.4}]
},
{
data: [{ x: 1362096000000, y: 19.9}, { x: 1364774400000, y: 44.5}, { x: 1367366400000, y: 88.4}, { x: 1372636800000, y: 76.4}]
}]
});
JSFiddle here: http://jsfiddle.net/rnshabuf/
Renders like this:
The chart has no way of knowing what you consider "missing".
There are any number of reasons that a data set may have very valid gaps of any size between points - not all data occurs at regular intervals.
You need to pre-process your data and fill in what's missing according to the definition of your specific data, and how you want to handle it (how missing values should be treated in a time series is a wide topic with a lot of varied opinions).
Related
I'm getting some troubles to set icons on my series over,infront,top,bot (anywhere) it.
I'm using an API (agromonitoring.com) to get the Data with XHTML request parsing it to JSON then showing using Highcharts, the main problem is that most of the examples to add Icons or Images are using xAxis Categorized, but in my case I'm using an xAxis "date-time" which is always changing that's why I can't use this example (https://www.highcharts.com/demo/spline-symbols) of course I tried,but it doesn't work.
So Here it's the Example of Highcharts
https://codepen.io/pen/?editors=0010
and this is my example(both sites same)
https://playcode.io/447786 (love PlayCode couse integrates console)
https://jsfiddle.net/Miguel5tuxD/afgrzLv7/
I'm trying to useiconUrl getting from that Switch to then parse around 40 icons to the Highchart
Expecting something like the example but with all points an Icon
The problem is that you don't set icons URL for point markers anywhere. So the solution is to pass points array like that (spline series):
[{
x: x,
y: y,
marker: {
symbol: url
}
}, ...]
In your example:
{
name: 'Temperatura',
type: 'spline',
data: datos3.map((item, index) => {
return {
x: item[0],
y: item[1],
marker: {
symbol: datos[index],
width: 20,
height: 20
}
}
}),
tooltip: {
valueSuffix: ' °C',
valueDecimals: 2,
},
marker: {
enabled: true
},
color: Highcharts.getOptions().colors[2],
}
Demo:
https://jsfiddle.net/BlackLabel/c81qz5vr/
I have a very simple bar graph where each data point consists of a date (day) and a number. Maybe the only speciality is that not every date is covered (i.e. for some days there is no data point).
When drawing the graph, only those days are shown that have a data point associated with them. All other days are simply omitted. So the x axis is not evenly distributed and skips values.
How can I make sure the X axis is truly linear and does not leave any days out?
PS: This is how my graph is defined:
chartData.datasets[0].data.push( {t: new Date('2019-02-01'), y: value});
// And so on...
var chart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
annotation: {
annotations: []
},
legend: {
display: false
},
scales: {
xAxes: [{
type: 'time',
unitStepSize: 1,
distribution: 'series',
time: {
unit: 'day'
},
}]
}
}
});
Here is a working solution to this issue, adapted for new version of Chart.js v3.x
Chart.js v3.2.1 (not backwards compatible with v2.xx)
const ctx = document.getElementById('timeSeriesChart').getContext('2d');
const chartData = [
{x:'2019-01-08', y: 4},
{x:'2019-01-13', y: 28},
{x:'2019-01-14', y: 8},
{x:'2019-01-15', y: 18},
{x:'2019-01-16', y: 68},
{x:'2019-01-18', y: 48},
{x:'2019-01-19', y: 105},
{x:'2019-01-21', y: 72},
{x:'2019-01-23', y: 36},
{x:'2019-01-24', y: 48},
{x:'2019-01-25', y: 17},
{x:'2019-01-28', y: 30},
{x:'2019-01-29', y: 28},
{x:'2019-01-30', y: 25},
{x:'2019-01-31', y: 18},
{x:'2019-02-04', y: 25},
{x:'2019-02-05', y: 22},
{x:'2019-02-06', y: 17},
{x:'2019-02-07', y: 15}
];
const chart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [{
data: chartData,
backgroundColor: 'rgb(189,0,53)'
}]
},
options: {
plugins: {
legend: { //watch out: new syntax in v3.2.0, `legend` within `plugins`
display: false
},
title: { //watch out: new syntax in v3.2.0, `title` within `plugins`
display: false
}
},
scales: {
x: { //watch out: new syntax in v3.2.0 for xAxis
type: 'timeseries', // `time` vs `timeseries` later in images
time: {
unit: 'day'
},
ticks: { // Edit: added this to avoid overlapping - thanks for comment
minRotation: 85, // <-- just try any number
maxRotation: 90 // <-- just try any number
}
}
}
}
});
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<!-- gets you latest version of Chart.js (now at v3.2.1) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment"></script>
<!-- for x-Axis type 'time' or 'timeseries' to work, you need additional libraries -->
<!-- (like moment.js and its adapter) -->
<div>
<canvas id="timeSeriesChart"></canvas>
</div>
Time Cartesian Axis
x: {
type: 'time'
Makes x-Axis "linear" as you requested, days without data are still displayed
Source: https://www.chartjs.org/docs/latest/axes/cartesian/time.html
Time Series Axis
x: {
type: 'timeseries'
Makes data-points equidistant and justifies x-Axis accordingly for bars to show equally distributed
Source: https://www.chartjs.org/docs/latest/axes/cartesian/timeseries.html
Edit: following avoiding overlapping of x-Axis ticks in reply to comment:
So far to show difference between types time and timeseries
I had a similar issue once, the solution that worked for me was first instantiating an array filled with 0s (My array held data for five working days, so I created array of size 5, filled with 0s. Then later on in code the array was overwritten if data for specific day existed. Otherwise it had the value 0).
I imagine this may work for you if the data you're passing is of known size, so you can create it beforehand and fill with 0s.
Bear in mind this may not be the best solution
I am trying to pass the dates to the Navigator, but by default the timestamp is passing to the navigator could any one please help me how to pass the dates to the navigator, i.e. as per dates that are there in x-axis.
this is the jsfiddle link : `http://jsfiddle.net/hj22wbe5/16/`
please find the jsfiddle.
Thanks
Why are you not sending in your data as time/value? This way navigator does this for you automatically? You have an array of strings for dates that you then parse in the xAxis.label function to display text - but your time in the data series is an integer starting from 0. Then you want to send in this modified date stamp into your navigator as a string? And you have duplicate values in your dates array. You are making much more work for yourself.
Send in data like below with your x as Date.UTC():
series: [{
name: 'RNA',
data: [{
x: Date.UTC(2014, 5, 14),
y: 99.43,
extprop: 'power issue'
}, {
x: Date.UTC(2014, 5, 19),
y: 99.40,
extprop: 'flood'
}...
See update jsFiddle demo. I assume you meant the time to go up without duplicates.
You can refer to navigator xaxis and use the same formatter, but better is using datetime type of xAxis as wergeld suggested.
navigator: {
enabled: true,
xAxis: {
labels: {
rotation: 90,
align: "left",
formatter: function () {
return dates[this.value];
},
},
tickInterval: 1
},
},
http://jsfiddle.net/hj22wbe5/18/
Curve goes sometimes outside the box. I tried to play with margins and height to give it more space but couldn't get my way arround it..
Any ideas fellas ?
Try setting different values for yAxis max parameter. For example, set it to 2 or some greater value:
yAxis: {
title: {
text: 'messages'
},
labels: {
y: 20
},
min: 0,
max: 2,
...
I'm trying to update a point[x,y] in the chart.
What's the problem?
Ok, I chart and its chart series are like this:
series: [
{
enableMouseTracking: false,
name: 'Line1',
type: 'line',
color: '#5d5d5d',
yAxis: 1,
data: [[12000, 55.068493], [15064, 42.842]],
marker: {
symbol: 'circle'
}
},
{
enableMouseTracking: false,
name: 'Line2',
type: 'line',
color: '#5d5d5d',
yAxis: 1,
marker: {
symbol: 'circle'
},
data: [[12000, 57.671527], [16000, 42.620069]]
},{
name: 'TOM',
//type: 'line',
color: '#ff4100',
yAxis: 1,
marker: {
symbol: 'url(icons/tom.png)'
},
data: [
{
id:'tom_point',
color: '#00FF00',
y: fi_variable,
x: tom_variable
}
]
}
Now the thing is that, I'm checking if fi_variable or tom_variable has changed and if its true, update these two variables, and finally update the chart.
I have tried already, some methods like chart.series[0].data[0].update(y = 10); and its working for some points with fixed x,y values, but no luck for the rest of the points.
For Instance I use chart.series[0].data[1].update(y = 10); will work ok,
but this chart.series[0].data[3].update(y = 10); will not work.
1- Is there any way to replace the data[0] from the above code line with an id of a point in our case tom_point ?
Also I've tried this chart.series[0].setData([[tom_variable,fi_variable, 'tom_point']]);
and again it wont working when the point is with an id or without fixed values.
But If I try chart.series[0]data[0].setData([[tom_variable,fi_variable]]); it works but again not on 3rd element (in our case - as shown above) of the series.
I can get the values for this point with the following,
var tomPoint = chart.get('tom_point').y;
but I can't set any x,y values back to chart and update it (the chart).
I have also tried to check if the variables have changed and to redraw the chart with chart.redraw but nothing.
Any Ideas how can I get this to work?
Am I losing something?
Thank you in Advance for your time.
First of all you try to update point (data[3]) which doens't exist in serie. Secondly in case when you update you need to use
chart.series[0].data[1].update(10); or chart.series[0].data[1].update({y:10}); but not yoru figure
if you want to change the x value also then use
chart.series[0].data[0].update({
x: 10,
y: 100
})
this will update both x and y values like in this example http://jsfiddle.net/DCA8W/
Hope this is what you are looking for.
Ok, the solution finally was simple.
I've managed to update the point:
The third element in the series with the name TOM corresponds to
chart.series[2].
{ // chart.series[2]
name: 'TOM',
//type: 'line',
color: '#ff4100',
yAxis: 1,
marker: {
symbol: 'url(icons/tom.png)'
},
data: [
{
id:'tom_point',
color: '#00FF00',
y: fi_variable,
x: tom_variable
}
]
}
So in order to update [x,y] values of this point, you have to do it like that:
// TOM Point
`chart.series[2].data[0].update({x:var_x, y:var_y});`