Highcharts: Double side's legend - javascript

I'm trying to display company's balance sheet with Highcharts.
I want to put legend on left side and right side like this.
I couldn't not find the way to do that.
Please help me

You can achieve it using this approach:
Set appropriate legend options:
legend: {
floating: true,
align: 'left',
itemMarginBottom: 15,
width: 200,
padding: 0
}
Then, the legend will be rendered in two columns. Loop through chart series in render event callback and translate each legend element that has translateX property greater than 0 to another side of the chart. Note that chart margins (left and right) should be set. Check the code and demo posted below.
Highcharts.chart('container', {
chart: {
type: 'column',
marginLeft: 150,
marginRight: 100,
spacingLeft: 10,
events: {
render: function() {
var chart = this,
offsetLeft = 20,
element,
itemX,
translateX,
translateY;
chart.series.forEach(function(series) {
element = series.legendItem.parentGroup;
translateY = element.translateY;
if (element.translateX > 0) {
translateX = chart.plotWidth + chart.plotLeft + offsetLeft;
element.translate(translateX, translateY);
}
});
}
}
},
legend: {
floating: true,
align: 'left',
itemMarginBottom: 15,
width: 200,
padding: 0
},
series: [
{ data: [6, 4, 2], name: 'First' },
{ data: [7, 3, 2], name: 'Second' },
{ data: [9, 4, 8], name: 'Third' },
{ data: [1, 2, 6], name: 'Fourth' },
{ data: [4, 6, 4], name: 'Fifth' },
{ data: [1, 2, 7], name: 'Sixth' },
{ data: [4, 2, 5], name: 'Seventh' },
{ data: [8, 3, 2], name: 'Eighth' },
{ data: [4, 5, 6], name: 'Ninth' },
{ data: [6, 4, 2], name: 'First' },
{ data: [7, 3, 2], name: 'Second' },
{ data: [9, 4, 8], name: 'Third' },
{ data: [1, 2, 6], name: 'Fourth' },
{ data: [4, 6, 4], name: 'Fifth' },
{ data: [1, 2, 7], name: 'Sixth' },
{ data: [4, 2, 5], name: 'Seventh' },
{ data: [8, 3, 2], name: 'Eighth' },
{ data: [4, 5, 6], name: 'Ninth' }
]
});
#container {
min-width: 310px;
max-width: 800px;
height: 400px;
margin: 0 auto
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>
API reference
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGElement#translate
https://api.highcharts.com/highcharts/chart.marginLeft
https://api.highcharts.com/highcharts/chart.marginRight

Related

Shared tooltip on multiple charts not formatting correctly

I have multiple highcharts in one container and wanted to use a shared tooltip for it.
I am able to generate a shared tooltip for am not able to format it to how I want.
This is my code:
Highcharts.chart('container', {
yAxis: [{
title: {
text: 'Pressure'
},
height: '50%',
lineWidth: 2
}, {
title: {
text: 'Temperature'
},
top: '50%',
height: '50%',
offset: 0,
lineWidth: 2
}],
series: [{
type: 'spline',
name: 'TemperatureIn',
id: 'TemperatureIn',
val: 'temp-one',
showInLegend: true,
chart_pl: 'top',
data: [1, 2, 3, 4, 9, 6, 7, 8, 15, 6, 3, 2, 7, 6, 3, 1],
}, {
type: 'spline',
name: 'TemperatureOut',
id: 'TemperatureOut',
val: 'temp-one',
showInLegend: true,
chart_pl: 'top',
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 3, 2, 4, 6, 3, 1],
}, {
type: 'spline',
name: 'TemperatureIn',
id: 'TemperatureIn',
val: 'temp-two',
showInLegend: false,
linkedTo: 'TemperatureIn',
chart_pl: 'bottom',
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 3, 2, 4, 6, 3, 1],
yAxis: 1,
}, {
type: 'spline',
name: 'TemperatureOut',
id: 'TemperatureOut',
val: 'temp-two',
showInLegend: false,
linkedTo: 'TemperatureOut',
chart_pl: 'bottom',
data: [2, 3, 4, 5, 6, 2, 3, 4, 5, 2, 1, 3, 5, 3, 2, 1],
yAxis: 1,
}],
tooltip: {
formatter: function () {
return this.points.reduce(function (s, point) {
// console.log(point.series.userOptions.val);
return `${s}<br/>${point.series.userOptions.val}<br/>${point.series.name}: ${point.y}m`;
}, `<b>${this.x}</b><br><br>`);
},
shared: true
},
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>
Now my tooltip looks like this:
x axis value
temp-one
TemperatureIn: y axis value
temp-one
TemperatureOut: y axis value
temp-two
TemperatureIn: y axis value
temp-two
TemperatureOut: y axis value
How do I format my tooltip to look like:
x axis value
temp-one
TemperatureIn: y axis value
TemperatureOut: y axis value
temp-two
TemperatureIn: y axis value
TemperatureOut: y axis value
temp-one and temp-two are values stored in point.series.userOptions.val. I am just not sure how to format my tooltip to look like that.
In the tooltip formatter function, try comparing the series name to that of the previous point and only include it if different, e.g.:
Highcharts.chart('container', {
yAxis: [{
title: {
text: 'Pressure'
},
height: '50%',
lineWidth: 2
}, {
title: {
text: 'Temperature'
},
top: '50%',
height: '50%',
offset: 0,
lineWidth: 2
}],
series: [{
type: 'spline',
name: 'TemperatureIn',
id: 'TemperatureIn',
val: 'temp-one',
showInLegend: true,
chart_pl: 'top',
data: [1, 2, 3, 4, 9, 6, 7, 8, 15, 6, 3, 2, 7, 6, 3, 1],
}, {
type: 'spline',
name: 'TemperatureOut',
id: 'TemperatureOut',
val: 'temp-one',
showInLegend: true,
chart_pl: 'top',
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 3, 2, 4, 6, 3, 1],
}, {
type: 'spline',
name: 'TemperatureIn',
id: 'TemperatureIn',
val: 'temp-two',
showInLegend: false,
linkedTo: 'TemperatureIn',
chart_pl: 'bottom',
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 3, 2, 4, 6, 3, 1],
yAxis: 1,
}, {
type: 'spline',
name: 'TemperatureOut',
id: 'TemperatureOut',
val: 'temp-two',
showInLegend: false,
linkedTo: 'TemperatureOut',
chart_pl: 'bottom',
data: [2, 3, 4, 5, 6, 2, 3, 4, 5, 2, 1, 3, 5, 3, 2, 1],
yAxis: 1,
}],
tooltip: {
formatter: function () {
return this.points.reduce(function (s, point, i, points) {
// console.log(point.series.userOptions.val);
var series = (i == 0 || point.series.userOptions.val != points[i - 1].series.userOptions.val) ? `${point.series.userOptions.val}<br/>` : '';
return `${s}<br/>${series}${point.series.name}: ${point.y}m`;
}, `<b>${this.x}</b><br><br>`);
},
shared: true
},
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>

Reading external source of data in Highchart 3D bar

This is the code of 3D bar chart where the data is loaded manually but I want to import data from external source.Can you help me in this code. I have also posted the jsfiddle link of this chart below the code.Thanks!
$(function () {
$('#container').highcharts({
chart: {
type: 'column',
margin: 75,
options3d: {
enabled: true,
alpha: 35,
beta: 15,
depth: 110
}
},
plotOptions: {
bar: {
depth: 40,
stacking: true,
grouping: false,
groupZPadding: 10,
dataLabels:{enabled:true}
}
},
series: [{
data: [1, 2, 4, 3, 2, 4],
stack: 0
}, {
data: [5, 6, 3, 4, 1, 2],
stack: 1
}, {
data: [7, 9, 8, 7, 5, 8],
stack: 2
}]
});
http://jsfiddle.net/4dccq/481/

Text overflow issue with highcharts

I was wondering how to make the text in a highcharts legend clip or make an ellipsis after certain amount of characters. I know that I can set the legend style but not sure how to make it so that it works in this situation
http://jsfiddle.net/t96zj1yr/
'hidden',$(function () {
$('#container').highcharts({
chart: {
marginBottom: 120,
width: 500
},
legend: {
itemWidth: 100,
itemStyle: {
color: '#7CB57C',
fontWeight: 'bold',
width: '70px',
textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap"
},
useHTML: true
},
series: [{
data: [6, 4, 2],
name: 'Firstasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf'
}, {
data: [7, 3, 2],
name: 'Second'
}, {
data: [9, 4, 8],
name: 'Third'
}, {
data: [1, 2, 6],
name: 'Fourth'
}, {
data: [4, 6, 4],
name: 'Fifth'
}, {
data: [1, 2, 7],
name: 'Sixth'
}, {
data: [4, 2, 5],
name: 'Seventh'
}, {
data: [8, 3, 2],
name: 'Eighth'
}, {
data: [4, 5, 6],
name: 'Ninth'
}]
});
});
Any help would be appreciated!!
Thank you
Use maxWidth: '70px' instead of width: '70px'.
You should be able to set the item style of the legend to include
max-width: 10ch;
Which should approximate a number of characters
Edit:
You can use Jquery to edit the contents of the spans based on the number of characters in its contents. This should add ellipsis for anything longer than 10 characters after the 10th character.
$('.highcharts-legend-item').find('span').each(function() {
var content = $(this).html();
if(content.length > 10)
{
$(this).html(content.substring(0, 10) + "...");
}
});
Give this a whirl - you'll just need to change the character limits to desired length. Seems to be working fine

highcharts datetime x-axis extents differ between two charts with same range

In my jsfiddle, example I've got two instances of the same chart. Each has two series of data - one common to both with the same max and min and the other different but with values wholey within the extents of the first series. What i'm expecting is to see the two graphs to the same scale. What I get is the first shrunk to the middle of the graph range and the second full width.
I've tried all sorts - setting the max and min etc, but really, I don't understand what the issue is so i'm having trouble figuring out what to do about it
Can anyone tell me what's going one - why don't they scale the same and what can I do to force them to? I've added some buttons to print the extremes and they report as being the same. I've tried setting min and max on the series to the min and max values from my data - but to no avail.
var gc2 = [
[1421680291000, 5],
[1421690785000, 5],
[1421713693000, 1],
[1421746462000, 6],
[1421747928000, 6],
[1421754240000, 6],
[1421775733000, 6],
[1421782226000, 6],
[1421798460000, 6],
[1421884860000, 3],
[1421971260000, 6],
[1422057660000, 6],
[1422144060000, 6],
[1422230460000, 6],
[1422268738000, 3],
[1422273729000, 1],
[1422316860000, 1],
[1422663082000, 5],
[1422748860000, 6],
[1422835260000, 3],
[1422921660000, 6],
[1423180860000, 3],
[1423267260000, 5],
[1423353660000, 3],
[1423440060000, 5],
[1423872060000, 5],
[1423958460000, 5]
];
var bad = [
[1421971260000, 1],
[1422057660000, 1],
[1422144060000, 1],
[1422230460000, 1],
[1422268738000, 1],
[1422748860000, 1]
];
var good = [
[1421746462000, 1],
[1421747928000, 1],
[1421754240000, 1],
[1421775733000, 1],
[1421782226000, 1],
[1421798460000, 1]
];
$(document).ready(function () {
checkOrder(gc2);
checkOrder(good);
checkOrder(bad);
});
function checkOrder(series) {
var xlow = 0;
for (var i = 0; i < series.length; i++) {
if (series[i][0] < xlow) {
console.log("out of order");
} else {
xlow = series[i][0];
}
}
}
$(function () {
$('#container1').highcharts('StockChart', {
chart: {
defaultSeriesType: 'column',
backgroundColor: 'transparent'
},
rangeSelector: {
selected: 1
},
title: {
text: 'not working'
},
xAxis: {
type:'datetime'
},
yAxis: {
min: 0,
max: 10
},
series: [{
name: 'x1',
data: gc2,
tooltip: {
valueDecimals: 2
}
}, {
name: 'x2',
data: bad,
tooltip: {
valueDecimals: 2
}
}]
});
});
$(function () {
$('#container2').highcharts('StockChart', {
chart: {
defaultSeriesType: 'column',
backgroundColor: 'transparent'
},
rangeSelector: {
selected: 1
},
title: {
text: 'working'
},
xAxis: {
type:'datetime'
},
yAxis: {
min: 0,
max: 10
},
series: [{
name: 'x1',
data: gc2,
tooltip: {
valueDecimals: 2
}
}, {
name: 'x',
data: good,
tooltip: {
valueDecimals: 2
}
}]
});
});

Change highlight behavior in Highcharts

I am trying to make a web page that displays some data in a graph. For this I'm using the javascript library Highcharts.
It's working quite well, but I want to change the highlight behaviour of the graph and I can't get it to stick so to speak. I found a code snippet that does that here:
https://highcharts.uservoice.com/forums/55896-general/suggestions/3166396-improve-series-highlight-on-legend-hover-event-by
I can get that to work, but when I redraw the graph with new data, that behaviour is gone.
Some example code:
$(function () {
var chart;
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
marginRight: 130,
marginBottom: 25
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: [{
name: 'One',
data: [[1,2.3],[2,6.7],[3,10],[4,2.5]]
}, {
name: 'Two',
data: [[1,20],[2,10],[3,11],[4,12]]
}, {
name: 'Three',
data: [[1,21],[2,23],[3,10],[4,4]]
}, {
name: 'Four',
data: [[1,12],[2,2],[3,4],[4,6]]
}]
},
function(chart){
$(chart.series).each(function(i, serie){
$(serie.legendItem.element).hover(function(){
highlight(chart.series, serie.index, true);
}, function(){
highlight(chart.series, serie.index, false);
});
});
function highlight(series, index, hide) {
$(series).each(function (i, serie) {
if(i != index) {
$.each(serie.data, function (k, data) {
if(data.series) {
data.series.graph && data.series.graph.attr("stroke", (hide ? "#D4D4D4": serie.color));
data.series.markerGroup && data.series.markerGroup.attr("visibility", (hide ? "hidden": "visible"));
}
});
} else {
serie.group.toFront();
$.each(serie.data, function (k, data) {
if(data.series) {
data.series.graph && data.series.graph.attr("stroke", serie.color);
}
});
}
});
}
});
});
var new_series = [{
name: 'One_2',
data: [[1,3.3],[2,4.7],[3,20],[4,6]]
}, {
name: 'Two_2',
data: [[1,20],[2,0],[3,10],[4,5]]
}, {
name: 'Three_2',
data: [[1,21],[2,5],[3,10],[4,12]]
}, {
name: 'Four_2',
data: [[1,12],[2,15],[3,20],[4,12]]
}]
$('#redraw').click(function() {
while(chart.series.length > 0)
chart.series[0].remove(true);
for (var i = 0; i < new_series.length; i++){
chart.addSeries(new_series[i],false);
}
chart.redraw();
});
});
Here's a fiddle that shows my problem: http://jsfiddle.net/qpByN/34/
When clicking redraw the highlighting behaviour is back to normal. How do I make it stick?
I'm very much a javascript newbie, so I know there's a lot I'm missing about things work, but working with it is the best way to learn. This particular problem I haven't been able to solve though, and it might very well be because I don't know the terms to search for, so I'm asking how to do it here.
It's caused by not adding highlight to new items in a legend. In plugin it's working each time when legend is redrawn, but in your case only once - when chart is loaded. Upgraded code: http://jsfiddle.net/qpByN/35/
One note: when you remove series, detach events, to not make dead references.
Code:
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
marginRight: 130,
marginBottom: 25
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 0
},
series: [{
name: 'One',
data: [
[1, 2.3],
[2, 6.7],
[3, 10],
[4, 2.5]
]
}, {
name: 'Two',
data: [
[1, 20],
[2, 10],
[3, 11],
[4, 12]
]
}, {
name: 'Three',
data: [
[1, 21],
[2, 23],
[3, 10],
[4, 4]
]
}, {
name: 'Four',
data: [
[1, 12],
[2, 2],
[3, 4],
[4, 6]
]
}]
}, addEvents);
});
var new_series = [{
name: 'One_2',
data: [
[1, 3.3],
[2, 4.7],
[3, 20],
[4, 6]
]
}, {
name: 'Two_2',
data: [
[1, 20],
[2, 0],
[3, 10],
[4, 5]
]
}, {
name: 'Three_2',
data: [
[1, 21],
[2, 5],
[3, 10],
[4, 12]
]
}, {
name: 'Four_2',
data: [
[1, 12],
[2, 15],
[3, 20],
[4, 12]
]
}]
$('#redraw').click(function () {
while (chart.series.length > 0)
chart.series[0].remove(true);
for (var i = 0; i < new_series.length; i++) {
chart.addSeries(new_series[i], false);
}
chart.redraw();
addEvents(chart);
});
function addEvents(chart) {
$(chart.series).each(function (i, serie) {
$(serie.legendItem.element).hover(function () {
highlight(chart.series, serie.index, true);
}, function () {
highlight(chart.series, serie.index, false);
});
});
}
function highlight(series, index, hide) {
$(series).each(function (i, serie) {
if (i != index) {
$.each(serie.data, function (k, data) {
if (data.series) {
data.series.graph && data.series.graph.attr("stroke", (hide ? "#D4D4D4" : serie.color));
data.series.markerGroup && data.series.markerGroup.attr("visibility", (hide ? "hidden" : "visible"));
}
});
} else {
serie.group.toFront();
$.each(serie.data, function (k, data) {
if (data.series) {
data.series.graph && data.series.graph.attr("stroke", serie.color);
}
});
}
}

Categories

Resources