Highcharts how to get columns to show correctly? - javascript

I have this chart: http://jsfiddle.net/bfqe5/1/
var rangeStart = {1386828000000: 1333256400000}; //used in the tooltip
var rangeEnd = {1386828000000: 1364706000000}; //used in the tooltip
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: null
},
marginBottom: 25,
xAxis: {
type: 'datetime',
lineColor: '#000000',
lineWidth: 2,
labels: {
formatter: function () {
var myDate = new Date(this.value);
var newDateMs = Date.UTC(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate());
return Highcharts.dateFormat('%m/%Y', newDateMs);
},
style: {
fontWeight: 'bold',
color: '#000000'
}
},
title: {
text: 'Date',
style: {
color: 'black',
fontWeight: 'normal',
fontSize: '16px'
}
}
},
yAxis: {
title: {
text: null
},
labels: {
format: '{value} %',
step: 1,
style: {
fontWeight: 'bold',
color: '#000000'
}
},
allowDecimals: false,
endOnTick: false,
lineColor: '#000000',
lineWidth: 2,
gridLineColor: null,
minorGridLineWidth: 0,
minorTickInterval: 2,
minorTickColor: '#000000',
minorTickLength: 5,
minorTickWidth: 2,
minorTickPosition: 'inside'
},
tooltip: {
formatter: function () {
var start = new Date(rangeStart[this.x]);
var end = new Date(rangeEnd[this.x]);
var startDate = Date.UTC(start.getUTCFullYear(), start.getUTCMonth(), start.getUTCDate());
var endDate = Date.UTC(end.getUTCFullYear(), end.getUTCMonth(), end.getUTCDate());
return '<span style="font-size:14px; font-weight:bold;">' + this.series.name + ': ' + this.y + ' %</b></span><br /><span style="color:#2F7ED8;">Date range</span><br />' + Highcharts.dateFormat('%m/%e/%Y', start) + ' - ' + Highcharts.dateFormat('%m/%e/%Y', end);
},
valueSuffix: '%'
},
legend: {
symbolPadding: 10,
itemDistance: 23,
symbolWidth: 50,
backgroundColor: '#FFFFFF',
align: 'center',
borderWidth: 0,
verticalAlign: 'bottom',
floating: false,
width: 600
},
series: [{
name: 'data1',
data: [
[1386828000000, 1]/*,
[1389228000000, 0]*/ //if uncommented, mostly works
],
color: '#a3052c'
}, {
name: 'data2',
data: [
[1386828000000, 3]/*,
[1389228000000, 0]*/ //if uncommented, mostly works
],
color: '#faa738'
}, {
name: 'data1',
data: [
[1386828000000, 6]/*,
[1389228000000, 0]*/ //if uncommented, mostly works
],
color: '#002144'
}, {
name: 'data4',
data: [
[1386828000000, 3]/*,
[1389228000000, 0]*/ //if uncommented, mostly works
],
color: '#008001'
}]
});
It should be displaying with 4 individual columns (like http://jsfiddle.net/VrgW7/), but for some reason they all seem to be stacking on top of each other. I can get it to display mostly correct by using a hack (uncomment [1389228000000, 0] in each series), but then it's behaving like there are 2 sets of data.
I've tried adding:
plotOptions: {
column: {
stacking: 'null' //or 'normal' or 'percent'
}
},
but it didn't change the display as I want it to (it actually stacked them... I guess as expected).
Everything is correct in my jsfiddle (data values, tooltip) except the way it's displaying. Does anybody have any suggestions on what to change to get it to display correctly?

The issue here has to do with scaling I think. If we change all your timestamps to 15 we get individual columns. So, what I did was set the xAxis.min and xAxis.max to be just outside of the dates of your data:
xAxis: {
type: 'datetime',
min: 1386827000000,
max: 1389229000000,
....
See this jsFiddle.

Related

Add second series to highchart master detail

I'm using highcharts to create a master-detail chart, could you help me how to add another series type area to the chart? i have used example from official site, but i cant imagine how to add second area to this chart
const priceChart1 = Highcharts.getJSON(
'https://cdn.jsdelivr.net/gh/highcharts/highcharts#v7.0.0/samples/data/usdeur.json',
data => {
let detailChart;
// create the detail chart
function createDetail(masterChart) {
// prepare the detail chart
var detailData = [],
detailStart = data[0][0];
masterChart.series[0].data.forEach(point => {
if (point.x >= detailStart) {
detailData.push(point.y);
}
});
// create a detail chart referenced by a global variable
detailChart = Highcharts.chart('detail-container', {
chart: {
zoomType: "x",
spacingLeft: 10,
spacingRight: -20,
borderRadius: 10,
backgroundColor: "#F3F3F3",
borderColor: "#335cad",
height: priceChartHeight,
style: { fontFamily: "Manrope" },
style: {
position: 'absolute'
},
resetZoomButton: {
position: {
// align: 'right', // by default
// verticalAlign: 'top', // by default
x: -40,
y: 5
},
theme: {
fill: '#377DED',
stroke: 'transparent',
r: 0,
style: {
color: 'white',
borderRadius: 10
},
states: {
hover: {
fill: '#41739D',
style: {
color: 'white'
},
},
},
},
},
marginBottom: 90,
reflow: false,
marginLeft: 10,
style: {
position: 'absolute'
}
},
credits: {
enabled: false
},
title: {
text: null,
align: 'left'
},
subtitle: {
text: null,
align: 'left'
},
xAxis: {
type: 'datetime',
visible: false,
},
yAxis: {
title: {
text: null,
},
opposite: true,
gridLineColor: "rgba(87, 87, 87, 0.15)",
gridLineDashStyle: "dash",
left: -40
},
tooltip: {
formatter: function () {
var point = this.points[0];
return '' + '<br/>' + ' <span style="font-weight: 700;font-size: 14px; line-height: 19px; color: #377DED;"> ' + Highcharts.numberFormat(point.y, 2) + '</span> ' + '<span style="font-size: 9px; font-weight: 300; line-height: 12px; color: rgba(51,51,51, 0.25)">Nominal</span>' + '<br/> ' + '<span style="font-size: 9px; font-weight: 300; line-height: 12px; color: rgba(51,51,51, 0.25)">' + Highcharts.dateFormat('%e %B %Y', this.x) + '</span>' },
shared: true,
borderRadius: 5,
borderColor: 'transparent',
shadow: false,
backgroundColor: '#fff'
},
legend: {
enabled: false
},
plotOptions: {
series: {
marker: {
enabled: false,
states: {
hover: {
enabled: true,
radius: 3
}
}
}
}
},
series: [
{
name: 'Nominal',
data: detailData,
type: 'area',
},
],
exporting: {
enabled: false
}
}); // return chart
}
// create the master chart
function createMaster() {
Highcharts.chart('master-container', {
chart: {
reflow: false,
borderWidth: 0,
backgroundColor: null,
spacingLeft: 10,
spacingRight: 30,
borderRadius: 10,
zoomType: 'x',
events: {
// listen to the selection event on the master chart to update the
// extremes of the detail chart
selection: function (event) {
var extremesObject = event.xAxis[0],
min = extremesObject.min,
max = extremesObject.max,
detailData = [],
xAxis = this.xAxis[0];
// reverse engineer the last part of the data
this.series[0].data.forEach(point => {
if (point.x > min && point.x < max) {
detailData.push([point.x, point.y]);
}
});
// move the plot bands to reflect the new detail span
xAxis.removePlotBand('mask-before');
xAxis.addPlotBand({
id: 'mask-before',
from: data[0][0],
to: min,
color: 'rgba(0, 0, 0, 0)'
});
xAxis.removePlotBand('mask-after');
xAxis.addPlotBand({
id: 'mask-after',
from: max,
to: data[data.length - 1][0],
color: 'rgba(0, 0, 0, 0)'
});
xAxis.addPlotBand({
id: 'mask-after',
from: min,
to: max,
color: 'rgba(255, 255, 255, 1)',
borderColor: "#377DED",
borderWidth: 2
});
detailChart.series[0].setData(detailData);
console.log(min)
console.log(max)
return false;
}
}
},
title: {
text: null
},
accessibility: {
enabled: false
},
xAxis: {
type: "datetime",
labels: { format: '{value:%b %e }' },
crosshair: {
color: '#377DED80'
},
lineWidth: 0, minorGridLineWidth: 0, lineColor: 'transparent', minorTickLength: 0, tickLength: 0,
top: -5,
showLastTickLabel: true,
maxZoom: 14 * 24 * 3600000, // fourteen days
plotBands: [{
id: 'mask-before',
from: data[0][0],
to: data[data.length - 1][0],
color: 'rgba(0, 0, 0, 0)'
}],
title: {
text: null
},
},
yAxis: {
gridLineWidth: 0,
labels: {
enabled: false
},
title: {
text: null
},
min: 0.6,
showFirstLabel: false
},
tooltip: {
borderRadius: 50,
borderColor: 'red'
},
legend: {
enabled: false
},
credits: {
enabled: false
},
plotOptions: {
series: {
fillColor: {
linearGradient: [0, 0, 0, 70],
stops: [
[0, Highcharts.getOptions().colors[0]],
[1, 'rgba(255,255,255,0)']
]
},
lineWidth: 1,
marker: {
enabled: false
},
shadow: false,
states: {
hover: {
lineWidth: 1
}
},
enableMouseTracking: false
}
},
series: [{
type: 'area',
name: 'USD to EUR',
pointInterval: 24 * 3600 * 1000,
pointStart: data[0][0],
data: data
}],
exporting: {
enabled: false
}
}, masterChart => {
createDetail(masterChart);
}); // return chart instance
}
// make the container smaller and add a second container for the master chart
const container = document.getElementById('price-chart-main');
container.style.position = 'relative';
container.innerHTML += '<div id="detail-container" style="height: 100%"></div><div id="master-container" style="height: 90px; position: absolute; bottom: 0; width: 100%"></div>';
// create master and in its callback, create the detail chart
createMaster();
}
);
there is example that i used https://www.highcharts.com/demo/dynamic-master-detail
Adding a new series to a master-detail chart is very simple. You need to only add a new data set and connect it to the right series. For example:
var detailData = [
[],
[]
],
detailStart = data1[0][0];
masterChart.series.forEach((s, index) => {
s.points.forEach(point => {
if (point.x >= detailStart) {
detailData[index].push(point.y);
}
});
});
// create a detail chart referenced by a global variable
detailChart = Highcharts.chart('detail-container', {
chart: {
type: 'area',
...
},
...,
series: [{
data: detailData[0]
}, {
data: detailData[1]
}]
});
Live demo: https://jsfiddle.net/BlackLabel/97dxakfe/
API Reference: https://api.highcharts.com/highcharts/series

How to correspond tooltip title with the legends at the bottom in Highcharts?

The 3 labels that I have on the horizontal stacked bar, the data flow for label 1 is different than label 2 and 3. Compare to label 2 and 3, label 1 colors flow is different.
When I hover over label 1 bars, I see correct title getting displayed in the tooltip that matches with the legend at the bottom:
However, when I hover the bar for label 2 and 3, which in this dark red, I still see "Strongly Agree" showing up in the tooltip, whereas it should have been "Strongly Disagree" if go by the legends at the bottom:
Is this something that is managable to fix it in higcharts? If so, can someone please help me how I would fix the tooltip title for label 2 and 3?
https://jsfiddle.net/samwhite/a4wtr0zb/
let chart = Highcharts.chart('container1_1', {
chart: {
type: 'bar',
height: 300
},
credits: {
enabled: false
},
yAxis: {
title: { text: 'Response Rate' },
max: 100,
maxPadding: 0,
labels: {
format: '{value}%'
},
gridLineWidth: 0,
minorGridLineWidth: 0
},
tooltip: {
formatter: function () {
return '<b>'+ tooltip_titles[0][this.series.index] + '</b><br/>' + 'Response Rate: ' + (100*this.point.y).toFixed(2) + '\%';
}
},
plotOptions: {
series: {
stacking: 'percent',
pointWidth: 20,
borderWidth: 0,
},
bar: {
states: {
inactive: {
enabled: true
},
hover: {
opacity: .9
}
}
}
},
legend: {
reversed: true,
align: 'right'
},
title: {
align: 'left',
text: 'Progress on Diversity, Inclusion, and Opportunity in our Workplace',
style: {
fontSize: '20px',
fontWeight: 'bold',
}
},
xAxis: {
categories: labels,
labels: {
style: {
fontSize: '1em',
color: '#000',
width: 370,
float: 'left'
}
}
},
series: [{
name: 'Strongly Agree',
color: colors[4],
data: []
}, {
name: 'Agree',
color: colors[3],
data: []
}, {
name: 'Neither Agree nor Disagree',
color: colors[2],
data: []
}, {
name: 'Disagree',
color: colors[1],
data: []
}, {
name: 'Strongly Disagree',
color: colors[0],
data: []
}]
});
I made 2 changes to the fiddle
Change tooltip
Change to show the series name instead of referencing a list
formatter: function () {
return '<b>'+ this.series.name + '</b><br/>' + 'Response Rate: ' + (100*this.point.y).toFixed(2) + '\%';
}
Change setData()
Remove all the "colors" from setData to ensure consistency across categories.
series.setData([
{
name: tooltip_titles[s],
//color: colors[s],
y: dept_data["102"][4-s]
},
{
name: tooltip_titles[s],
// color: colors[Math.abs(s - 4)],
y: dept_data["104"][4-s]
},
{
name: tooltip_titles[s],
// color: colors[Math.abs(s - 4)],
y: dept_data["105"][4-s]
}]);
Here's the result:
For the first one:
For the second one:
The updated fiddle is here:

High chart (spark line) displaying "Created with High charts 4.0.1 No data to display" instead of display graph?

High chart (spark line) displaying Created with High charts 4.0.1 No data to display instead of display graph?
title: {
text: ''
},
credits: {
enabled: false
},
xAxis: {
lineWidth: 0,
minorGridLineWidth: 0,
lineColor: 'transparent',
gridLineColor: 'transparent',
min: 0,
title: {
text: ''
},
categories: ['a','b','c']
},
yAxis: [{
lineWidth: 0,
minorGridLineWidth: 0,
lineColor: 'transparent',
gridLineColor: 'transparent',
title: {
text: ''
},
labels:
{
enabled: false
}
},
{
lineWidth: 0,
minorGridLineWidth: 0,
lineColor: 'transparent',
gridLineColor: 'transparent',
title: {
text: ''
},
labels:
{
enabled: false
}
}],
series: [{
name: ' ',
yAxis: 1,
type: 'spline',
data: [1,2,3],
pointStart: 0
},
{
name: ' ',
yAxis: 1,
type: 'spline',
data: [4,5,6],
pointStart: 0
}],
legend: {
enabled: false,
width: 100,
floating: true,
align: 'left',
x: 0, // = marginLeft - default spacingLeft
itemWidth: 60
},
chart: {
height: 30,
width: 100,
marginBottom: 10
},
tooltip: {
positioner: function () {
return { x: -180, y: -25 };
},
shape: "square",
backgroundColor: '#FCE9CE',
borderWidth: 1,
borderColor: '#F90',
formatter: function () {
var bpValue = [];
var serviceDate;
$.each(this.points, function (i, point) {
bpValue.push('<span>' + point.y + '</span>');
serviceDate = point.x;
});
var content = "<span><b>Service:</b>" + serviceDate
+ "</span><br /><span><b>BP Value :</b></span>";
bpValue = bpValue.join('/');
return content + bpValue;
},
shared: true
}
Sometimes It is not displaying any line or dot. instead of that simply showing alternate text that is Created with Highcharts 4.0.1. What would be the issue? how can resolve this?

How to do a data overlap independently column in Highcharts

I would like to have something similar to the image below, but the columns representing the classes all stack together now. How do I separate them and allow them to load dynamically as well?
Also I need a legend that says green is band 1, yellow is band 2, orange is band 3 and red is band 4, how do i do that as well? My code is in the JS Fiddle page. I am not allowed to use jQuery, need to use pure JavaScript.
var options = {
chart: {
renderTo : 'container',
type: 'column'
},
title: {
text: 'Topic & Subtopic Mastery'
},
subtitle: {
text: 'Average Level-Stream Mastery vs Average Class Mastery'
},
xAxis: {
categories: topics
},
yAxis: {
min: 0,
max: 100,
title: {
text: 'Mastery'
}
},
legend: {
layout: 'vertical',
backgroundColor: '#FFFFFF',
align: 'left',
verticalAlign: 'top',
x: 100,
y: 70,
floating: true,
shadow: true
},
tooltip: {
shared: true,
valueSuffix: ' %'
},
plotOptions: {
column: {
grouping: false,
shadow: false
}
},
series: resultsData
};
http://jsfiddle.net/kscwx139/2/
I came up with a solution you are looking for with specifying x and y axis data for level and giving appropriate width to the point.
$(function() {
var chart;
$(document).ready(function() {
var i = 0;
Highcharts.getOptions().colors = Highcharts.map(Highcharts.getOptions().colors, function(color) {
if (i == 0) {
i++;
return Highcharts.Color(color)
.setOpacity(1)
.get('rgba');
} else {
i++;
return Highcharts.Color(color)
.setOpacity(0.5)
.get('rgba');
}
});
var colors = Highcharts.getOptions().colors;
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column',
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
borderColor: null
},
title: {
text: 'Mailboxes over Quota'
},
subtitle: {
text: 'Mailbox Size in MB'
},
exporting: {
enabled: false
},
credits: {
enabled: false
},
xAxis: {
categories: ["Overall Topic", "Topic 1", "Topic 2"],
title: {
text: null
}
},
yAxis: {
min: 0,
title: {
text: 'Total',
align: 'high'
},
allowDecimals: false,
},
tooltip: {
formatter: function() {
return '' +
this.series.name + ': ' + Highcharts.numberFormat(this.y, 0, '.', ',');
}
},
legend: {
enabled: true
},
credits: {
enabled: false
},
series: [{
name: 'Level',
color: colors[0],
data: [{
y: 86,
x: 0.25
}, {
y: 80,
x: 1.25
}, {
y: 95,
x: 2.25
}],
pointWidth: 80
}, {
name: '4A',
data: [90, 88, 97]
}, {
name: '4B',
data: [95, 78, 92]
}, {
name: '4C',
data: [80, 69, 84]
}]
});
});
});
To show in label inside your column you can use below code.
plotOptions: {
column: {
dataLabels: {
enabled: true,
formatter: function() {
return this.series.name;
},
y: 25,
}
}
}
You can see it in action at this JSFIddle

Set Colors of Different Points when Clicking on Pie Slice Legend

I would like to set all colors for the pie slices to gray except for the color pie slice clicked in the legend. I have been only able to figure out how to change the color of only the clicked legend item not the others.
I have tried setting id's to the data points and using e.target but that didn't provide the proper access.
Thanks for your help.
Here is my myFiddle.
$(document).ready(function () {
var myCharts = {
chart: {
renderTo: 'container',
type: 'pie',
backgroundColor: 'rgba(255, 255, 255, 0.1)',
borderColor: 'rgba(255, 255, 255, 0.1)',
margin: [38, 20, 20, 20],
width: 300,
height: 300,
shadow: true,
},
colors: [
'#0066FF',
'#33CC33',
'#FF0000',
'#FFFF00',
],
credits: {
enabled: false
},
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'top',
x: 0,
y: 0
},
title: {
text: 'Net Activations',
verticalAlign: 'bottom',
y: 10
},
subtitle: {
text: '7%',
verticalAlign: 'middle',
y: 30,
style: {
color: 'black',
fontSize: '40px'
}
},
yAxis: {
tickColor: '#FF0000',
tickWidth: 3,
tickInterval: 5
},
xAxis: {
tickColor: '#FF0000',
tickWidth: 3,
tickInterval: 5
},
plotOptions: {
pie: {
states: {
hover: {
enabled: false
}
},
point: {
events: {
legendItemClick: function () {
this.graphic.attr({
fill: '#CCCCCC'
});
return false
}
}
},
dataLabels: {
enabled: true,
distance: 0.1,
color: 'black',
formatter: function () {
return '<b>' + this.point.name + '</b>: ' + this.percentage + ' %';
},
},
innerSize: '60%',
shadow: true,
size: '100%',
allowPointSelect: true,
slicedOffset: 10,
}
},
tooltip: {
enabled: false
},
series: [{
data: [],
showInLegend: true,
}]
};
myCharts.chart.renderTo = 'container';
myCharts.title.text = 'Net Activations';
var actual = 52,
goal = 73 - actual,
ATB = 100 - goal - actual;
myCharts.series[0].data = [{
name: 'Actual',
y: actual,
id: 0
}, {
name: 'goal',
y: goal,
id: 1
}, {
name: 'ATB',
y: ATB,
id: 2
}];
new Highcharts.Chart(myCharts);
});
Instead of attacking the SVG directly with this.graphic.attr, you'd be better off using the API to update the slice. Point.update works well for this:
legendItemClick: function () {
var series = this.series;
for (var i=0; i < series.data.length; i++){
var point = series.data[i];
if (point == this){
// set back to old color
point.update({color: series.chart.options.colors[this.id]});
}else{
// make it gray
point.update({color: '#CCCCCC'});
}
}
return false;
}
Updated fiddle here.
Well, I can get you 50% of the way there:
point: {
events: {
click: function () {
if (event.point.sliced) {
$.each(this.series.data, function (i, e) {
if (!e.sliced) {
this.graphic.attr({
fill: '#CCCCCC'
});
}
});
}
}
}
This still breaks when you re-click the slice to slot it back in - the colors of the other slices are still grey until you click on them. Will need to look more into this.

Categories

Resources