Highcharts elements are not aligned - javascript

I am trying to split the data contained in a dict into multiple charts. Each chart has two series: column and marker. If represent all the data in a single chart, everything works fine, but if I try to split it, the columns and the marker don't get aligned for some reason
function setup_chart(chart_container){
return new Highcharts.chart(chart_container, {
chart: {
alignTicks: false,
type: 'columnrange',
inverted: true,
zoomType: 'y',
panning: true,
},
credits: {
enabled: false
},
title: {
text: null
},
xAxis: {
categories: [],
className: 'chart-axis-title',
title: {
align:'high'
},
offset: -10
},
navigation: {
buttonOptions: {
x: 5,
y: -12
}
},
yAxis:[{
minRange: 1,
max:null,
min:null,
allowDecimals: false,
title: {
text: 'Days'
},
labels:{
formatter:function(){
if(this.value !=0){
return this.value;
}
}
}
},{
tickPositions: [0, 100],
visible: false
}],
tooltip: {
},
exporting: {
scale: 3,
chartOptions: {
legend: {
enabled: true
}
}
},
legend: {
enabled: false
},
series: [{
yAxis: 1,
data:[]
},{
name: 'Days',
data: [],
stickyTracking: true
}]
});
}
I'm passing the data via jinja2 and populate the chart in the following way:
var options_data_cm = {{options|tojson|safe}}[k]['cms'];
var cm_groups = {{cm_group_dict}};
var cms_details = {};
for(var key in cm_groups){
cms_details[key] = {
"data":[],
"left":[],
"right":[],
"cols":[],
"categories":[]
}
}
for(var key in cms_details){
var crtChart = $('#'+key).highcharts();
crtChart.xAxis[0].update({title:{ text: ""+cm_groups[key] }});
crtChart.addSeries({
type: 'column',
yAxis: 1,
data: cms_details[key]['cols'],
zIndex: 1,
minPointLength: 10,
threshold: -0.1,
pointPadding: 0,
pointRange: 0,
groupPadding: 0,
showInLegend: false,
tooltip: {
pointFormat: false
},
states: {
hover: {
enabled: false
}
}
});
crtChart.addSeries({
name: "Study Days",
dataLabels: {
enabled: false,
padding: 10,
borderWidth: 0,
useHTML:false,
formatter:function(){
if(this.y != 0)
return this.y;
}
},
stickyTracking: false,
data: cms_details[key]['data'],
borderWidth: 0,
zIndex: 5,
maxPointWidth: 5,
tooltip:{
followPointer:true
},
point: {
events: {
click: function() {
if (url != "")
window.open(url,'_blank');
}
}
}
});
crtChart.addSeries({
type:'scatter',
stickyTracking:false,
tooltip:{snap:0},
data:cms_details[key]['left'],
zIndex: 1
});
crtChart.addSeries({
type:'scatter',
stickyTracking:false,
tooltip:{snap:0},
data:cms_details[key]['right'],
zIndex: 1
});
crtChart.xAxis[0].setCategories(cms_details[key]['categories']);
}
Here are two pictures, the first one is with assignment without breaking the data into multiple charts, the second one is an attempt to split it :
I've tried to inspect the content of the data and it seems OK in the sense that both have the same coordinates, however they are shifted.
EDIT:
Here's the link to the jsfiddle

I have managed to solve the issue by adding pointPlacement: 0.2 to the series which was displaced.

Related

Highcharts js Y axis start from last value

I'm working with highchart and I have the following chart working.
However, I need the next value starts at the point of the previous value.
Can someone help me please?
I use this function to generate chart
function generateChart(chartUrl, id) {
let options = {};
$.ajax({
url: chartUrl,
data: {name: id},
success: function (data) {
options.series[0].data = data;
// Get categories dynamicaly, not harcoded
for(let i=0;i<data.length;i++){
options.xAxis.categories.push(data[i][0]);
}
$(`#${id}`).highcharts(options);
}
});
}
And this code to Generate Data and Efects on chart
function generateEfectsChart() {
let options = {
chart: {
type: 'column'
},
title: {
text: ''
},
exporting: {
enabled: false
},
credits: {
enabled: false
},
xAxis: {
lineColor: '#FFFFFF',
lineWidth: 0,
gridLineColor: '#DADBDF',
categories: [],
},
yAxis: {
lineColor: '#FFFFFF',
lineWidth: 0,
gridLineColor: '#DADBDF',
plotBands: [{
color: '#000000', // Color value
from: 0, // Start of the plot band
to: 0 // End of the plot band
}],
title: {
text: ''
},
legend: {
enabled: false
},
plotOptions: {
column: {
dataLabels: {
enabled: true,
color: '#000000'
},
colorByPoint: true,
pointWidth: 150
},
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
format: '{point.y}'
},
turboThreshold: 0
}
},
series: [{
negativeColor: '#ED4D5F'
}]
};
return options;
}
Use the waterfall series type.
Highcharts.chart('container', {
chart: {
type: 'waterfall'
},
...,
});
Live demo: https://www.highcharts.com/demo/waterfall
Docs: https://www.highcharts.com/docs/chart-and-series-types/waterfall-series

Highcharts how to add treemap upon click event on line chart?

Anyone know how to add treemap upon click event on line chart point? Here's my JSFiddle link:
https://jsfiddle.net/ssoj_tellig/d6pfv1bg/19/
When I click on the line chart on the point 0.63 at the third week of sample5, I'd like a treemap to appear at the bottom with the values loaded in var mytreemap_data (or any other values for the demo, doesn't matter). I'd like to understand how it'd work.
Many thanks for your help!
var mytreemap_data = [1528675200000,0.1,0.2,0.3,0.15,0.25]
// How can we show a tree map at the bottom with the values above
// upon clicking on the point 0.63 for the third week of sample 5 ??
const chart_1 = new Highcharts.stockChart('mychart_1', {
chart: {
zoomType: 'x',
type: 'spline',
},
xAxis: {
type: 'datetime',
tickInterval: 86400000 * 7, //show each week
ordinal: false,
labels:{
formatter: function() {
return Highcharts.dateFormat('%d %b %Y', this.value);
},
align: 'right',
rotation: -90,
},
},
yAxis: {
opposite: false,
min: 0,
max: 1,
tickInterval: 0.1,
title: {
text: 'Score'
}
},
legend: {
enabled: true,
layout: 'vertical',
align: 'right',
verticalAlign: 'top'
},
credits : {
enabled : false
},
navigator :{
enabled: true
},
scrollbar :{
enabled: true
},
rangeSelector: {
enabled: true,
allButtonsEnabled: true,
buttons: [{
type: 'month',
count: 1,
text: '1m'
}, {
type: 'all',
text: 'All'
}],
selected: 1
},
series: [{
name: 'sample1',
data: [[1527465600000,0.42242020440407213],[1528070400000,0.38747025807155444],[1528675200000,0.42678078180915674],[1529280000000,0.4091743882448146],
[1529884800000,0.4238743811604633],[1530489600000,0.39724984766613747],[1531094400000,0.39441610665405447],[1531699200000,0.41417484302834673],
[1532304000000,0.39208450506752085],[1532908800000,0.4026164523657783]],
}, {
name: 'sample2',
data: [[1527465600000,0.44242020440407213],[1528070400000,0.40747025807155444],[1528675200000,0.44678078180915674],[1529280000000,0.4291743882448146],
[1529884800000,0.4438743811604633],[1530489600000,0.41724984766613747],[1531094400000,0.41441610665405447],[1531699200000,0.43417484302834673],
[1532304000000,0.41208450506752085],[1532908800000,0.4226164523657783]],
}, {
name: 'sample3',
data: [[1527465600000,0.42242020440407213],[1528070400000,0.42747025807155444],[1528675200000,0.46678078180915674],[1529280000000,0.4491743882448146],
[1529884800000,0.4638743811604633],[1530489600000,0.43724984766613747],[1531094400000,0.43441610665405447],[1531699200000,0.45417484302834673],
[1532304000000,0.43208450506752085],[1532908800000,0.4426164523657783]],
}, {
name: 'sample4',
data: [[1527465600000,0.52242020440407213],[1528070400000,0.48747025807155444],[1528675200000,0.52678078180915674],[1529280000000,0.5091743882448146],
[1529884800000,0.5238743811604633],[1530489600000,0.49724984766613747],[1531094400000,0.49441610665405447],[1531699200000,0.51417484302834673],
[1532304000000,0.49208450506752085],[1532908800000,0.5026164523657783]],
}, {
name: 'sample5',
data: [[1527465600000,0.62242020440407213],[1528070400000,0.58747025807155444],[1528675200000,0.62678078180915674],[1529280000000,0.6091743882448146],
[1529884800000,0.6238743811604633],[1530489600000,0.59724984766613747],[1531094400000,0.59441610665405447],[1531699200000,0.61417484302834673],
[1532304000000,0.59208450506752085],[1532908800000,0.6026164523657783]],
}],
plotOptions: {
series: {
label: {
connectorAllowed: false,
},
pointstart: 1527465600000,
// pointInterval = 2,
tooltip: {
valueDecimals: 2
},
}
},
responsive: {
rules: [{
condition: {
maxWidth: 500
},
}]
}
});
document.getElementById('button').addEventListener('click', e => {
var series = chart_1.series[0];
var series1 = chart_1.series[1]
var series2 = chart_1.series[2];
if (series.visible & series1.visible & series2.visible) {
series.hide();
series1.hide();
series2.hide();
e.target.innerHTML = 'Show samples 1-3';
} else {
series.show();
series1.show();
series2.show();
e.target.innerHTML = 'Hide samples 1-3';
}
})
Use click event callback function for a point and create another chart with treemap series, for example:
plotOptions: {
series: {
point: {
events: {
click: function() {
Highcharts.chart('treemapContainer', {
series: [{
type: 'treemap',
data: mytreemap_data
}]
})
}
}
},
...
}
}
Live demo: https://jsfiddle.net/BlackLabel/rh7cfxLj/
API Reference: https://api.highcharts.com/highcharts/plotOptions.series.point.events.click

high charts starting new line from each point

I am using high charts to show energy data but i think due to some negative value high caharts starting a new line from each new point and lines not have any connection between them.
here is the picture of my results.
problem Image
you can see in the image there should be only one line.
here's my data for this.
I have 4 series's to show in graph but here i am only providing one because each line have same issue
var data={'vt':[[1588273200000, 0],[1586372400000, 245],[1586286000000, 200],[1586199600000, 7],[1586113200000, 4],[1586026800000, 1],[1585940400000, 4],[1588186800000, 40],[1585854000000, 7],[1588100400000, 30],[1588014000000, 155],[1587927600000, 38],[1587841200000, 57],[1587754800000, 35],[1587668400000, 66],[1587582000000, 68],[1587495600000, 35],[1587409200000, 40],[1587322800000, 62],[1585767600000, 8],[1587236400000, 37],[1587150000000, 44],[1587063600000, 72],[1586977200000, 13],[1586890800000, 5],[1586804400000, 58],[1586718000000, 90],[1586631600000, 41],[1586545200000, 186],[1586458800000, -498]]};
and here's how i initialize the highcharts object.
$('#'+id).highcharts({
title: {
text: titletext
},
time: {
timezone: 'Asia/Karachi'
},
chart: {
zoomType: 'x',
title: 'Meter 1'
},
xAxis: {
labels: {
formatter:function(){
return Highcharts.dateFormat("%b %e", this.value);
}
},
title: {
text: 'Date'
},
showLastLabel: true,
tickmarkPlacement: 'on',
tickPosition: 'inside',
tickWidth: 0,
tickPixelInterval: 60,
lineWidth: 2,
lineColor: 'rgba(255,205,255,0.6)',
minPadding: 0,
gridLineWidth: 0,
offset: 20,
type: 'datetime',
tickInterval: 24 * 3600 * 1000,
endOnTick: true,
},
yAxis: {
gridLineColor: 'black',
gridLineWidth: 0,
title: {
enabled: true,
text: cap
},
labels: {
enabled: true
}
},
tooltip: {
backgroundColor: 'white',
borderColor: 'black',
shadow: true,
style: {
color: 'black',
fontSize: '12px',
padding: '8px'
},
enabled: true,
crosshairs: false,
shared: false,
snap: 30,
},
plotOptions: {
flags: {
shape: 'squarepin'
}
},
series: [
{
name: 'Total kwh',
data: data.vt
},
{
name: 'Day kwh',
data: data.dt
},
{
name: 'Peak kwh',
data: data.pt
},
{
name: 'Off Peak kwh',
data: data.opt
}
],
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
y: 30,
navigation: {
enabled: true
},
adjustChartSize: true,
},
exporting: {
filename: titletext+'_'+"<?php echo $_SESSION['username']; ?>"+'_'+todayDate(),
buttons: {
contextButton: {
menuItems: ["viewFullscreen",
"separator",
"downloadJPEG",
"separator",
"downloadXLS",
]
}
}
},
credits: {
enabled: false
}
}
)
You need to provide an external graph value for z-index which will identify its position
Please go through this fiddle link with ur dataset. I have improved ur code.
So you can review it.
https://jsfiddle.net/vishalanand77/f6dnua28/32
You have unsorted data - Highcharts error #15: https://www.highcharts.com/errors/15/
You can sort it in this way:
data.vt.sort(function(a, b) {
return a[0] - b[0];
});
Live demo: http://jsfiddle.net/BlackLabel/6m4e8x0y/4993/

Highstock when multiple lines share a y axis one line is drawn at an offset

I am using Highstock/Highchart and if I draw two lines on a graph, who share a single Y axis, one of the lines isn't displayed on the Y axis properly. It is offset to higher values. For example, a value is 120 but the dot shows up on the 200 line. I would post a pic but I can't yet.
I have tried setting the Y axis max by the highest value but the line goes off the chart because it's still rendered with an offset.
Here is my config for the chart :
$scope.chartConfig = {
options: {
style: {
fontSize: '12px'
},
chart: {
alignTicks: true,
type: 'spline'
},
rangeSelector: {
inputEnabled: true, //$('#container').width() > 480,
selected: 0,
buttons: [{
type: 'week',
count: 1,
text: '1w'
},
{
type: 'month',
count: 1,
text: '1m'
},
{
type: 'month',
count: 3,
text: '3m'
}, {
type: 'month',
count: 6,
text: '6m'
}, {
type: 'ytd',
text: 'YTD'
}, {
type: 'year',
count: 1,
text: '1y'
}, {
type: 'all',
text: 'All'
}]
},
navigator: {
enabled: true
},
tooltip: {
animation: true,
enabled: true,
shadow: true,
shared: false,
useHTML: false,
xDateFormat: '%m/%d/%Y'
},
colors: ['#51324e', '#6e6e6e', '#3d2b3b', '#515151', '#342d3d', '#3e3e3e', '#413451', '#4f4b4b', '#351032', '#3e3e3e'],
plotOptions: {
pointStart: 0,
'line': {
'cursor': 'pointer',
'marker': {
'lineWidth': 1.5,
},
'lineWidth': 1
},
column: {
grouping: true
},
series: {
stacking: 'normal',
}
}
},
xAxis: {
title: {
text: ''
},
},
yAxis: {
//min: 10,
max: null,
title: {
text: ''
}
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
}
},
useHighStocks: true,
series: [{
//type: 'column',
marker : {
enabled : true,
radius : 4,
fillColor: {},
lineColor: {},
lineWidth: 3,
symbol: 'diamond'
},
name: '',
data: [[
0,0
]],
dataGrouping: {
units: [[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]]
}
},
{
//type: 'column',
marker : {
enabled : true,
radius : 4,
fillColor: {},
lineColor: {},
lineWidth: 3,
symbol: 'diamond'
},
name: '',
data: [[
0,0
]],
dataGrouping: { // TODO: delete me?
units: [[
'week', // unit name
[1]
], [
'month',
[1, 2, 3, 4, 6]
]]
}
}
],
title: {
style: {
color: '#51324e'
}
},
credits: {
enabled: false
}
};
In the HTML:
<highchart id="chart" class="hiChart-container" config="chartConfig"></highchart>
And all I change is the data and series name to update the chart...
I am only importing Highstock and using Highchart-ng.
I cannot do var chart = new Chart($scope.chartConfig) because my javascript framework is AngularJS and hence we are using Highchart-ng
How do I adjust the lines to be scaled to the Y axis?

highcharts: epoch time not properly connected to Xaxis

When i have inconsistent data coming in (when for example the server that gathers the data is down) highcharts does not plot the X correctly.
It still plots like there is data on the X while there is not.
It should afcouse plot the correct hour when there actually is data.
Here is the fiddle: http://jsfiddle.net/ZVwFK/
Data variable is inconsistant!
Can someone show me how i can correct this error?
$(function () {
var chart;
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'spline',
margin: [50,130,90,100]
},
title: {
text: 'Weather Today'
},
credits: {
enabled: false
},
subtitle: {
text: 'test'
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats: {
day: '%H:%M'
},
tickInterval: 3600 * 1000,
labels: {
rotation: -45,
align: 'right',
style: {
fontSize: '10px',
fontFamily: 'Verdana, sans-serif'
}
}
},
yAxis: [{
title: {
text: 'Temperature C'
},
opposite: false,
minorGridLineWidth: 0
}, {
title: {
text: 'Humidity %'
},
minorGridLineWidth: 0,
opposite: true
}, {
opposite: true,
title: {
text: 'Air Pressure hPa',
minorGridLineWidth: 0,
},
}],
tooltip: {
formatter: function() {
if(this.series.name === 'Temperature')
{
return ''+ Highcharts.dateFormat('%H:%M',this.x) +': '+ this.y + ' C';
}
if(this.series.name === 'Humidity')
{
return ''+ Highcharts.dateFormat('%H:%M',this.x) +': '+ this.y + ' %';
}
if(this.series.name === 'Air Pressure')
{
return ''+ Highcharts.dateFormat('%H:%M',this.x) +': '+ this.y + ' hPa';
}
}
},
plotOptions: {
spline: {
lineWidth: 4,
states: {
hover: {
lineWidth: 3
}
},
marker: {
enabled: false,
states: {
hover: {
enabled: true,
symbol: 'circle',
radius: 3,
lineWidth: 1
}
}
}
}
},
series: [{
name: 'Temperature',
data: temp,
type: 'spline',
/* yAxis: 0, */
shadow: true,
showInLegend: true,
pointInterval: 60 * 1000,
/* pointStart: Date.UTC(2006, 0, 1),*/
dashStyle: 'solid',
marker: {
enabled: false
}
} , {
name: 'Humidity',
data: hum,
yAxis: 1,
shadow: false,
showInLegend: true,
pointInterval: 60 * 1000,
type: 'line',
dashStyle: 'dot',
marker: {
enabled: false
}
}, {
name: 'Air Pressure',
data: bar,
yAxis: 2,
shadow: false,
showInLegend: true,
pointInterval: 60 * 1000,
type: 'line',
dashStyle: 'shortdot',
marker: {
enabled: false
}
}],
navigation: {
menuItemStyle: {
fontSize: '6px'
}
}
});
});
});
There are two ways of specifying time data for Highcharts and I think you are using the wrong way for the problem. It's the second style you should use when having gaps in the data.
A compact array without gaps only containing the values for each time-point
data: [2, 5, 3, 6, 1]
Then you specify the time-point for the first measure together with the interval. eg:
pointStart: Date.UTC(2013,1,12), // start point in milliseconds
pointInterval: 3600 // interval in milliseconds
You cannot have different length between the time-points this way.
A two dimensional array with both time-points and measure
data: [[Date.UTC(2013,1,12), 2],
[Date.UTC(2013,1,12), 5],
[Date.UTC(2013,1,12), 3],
...]
This way of specifying the array can have gaps where there's no data.
See the reference here
and example here.

Categories