I'm working on a Highchart map mixing Bubble map an mapline.
I use a first serie to show the map and color region depending on a measure range and a second serie to display a bubble on a region
var data = [
["05", 48810.00, 48810, 10, 19768, -1],
["09", 39239.00, 39239, 10, 13348, -1],
["10", 14974.00, 14974, 10, 7252, -1],
["11", 57124.00, 57124, 10, 26272, -1],
["14", 38821.00, 38821, 10, 17547, -1]
], maxSize = 0;
var all_codes = ["05", "09", "10", "11", "14"];
var Color = [];
Color[0] = "rgba(116, 171, 226, 0.8)";
Color[1] = "rgba(239, 141, 93, 0.8)";
Color[2] = "rgba(63, 182, 142, 0.8)";
Color[3] = "rgba(240, 106, 147, 0.8)";
Color[4] = "rgba(169, 125, 216, 0.8)";
Color[5] = "rgba(58, 181, 194, 0.8)";
Color[6] = "rgba(105, 115, 246, 0.8)";
Color[7] = "rgba(205, 89, 177, 0.8)";
Color[8] = "rgba(140, 162, 171, 0.8)";
Color[9] = "rgba(243, 135, 135, 0.8)";
Color[10] = "rgba(77, 120, 162, 0.8)";
Color[11] = "rgba(24, 102, 180, 0.8)";
Color[12] = "rgba(204, 67, 0, 0.8)";
Color[13] = "rgba(3, 115, 77, 0.8)";
Color[14] = "rgba(215, 9, 71, 0.8)";
Color[15] = "rgba(119, 42, 203, 0.8)";
Color[16] = "rgba(8, 119, 131, 0.8)";
Color[17] = "rgba(37, 49, 212, 0.8)";
Color[18] = "rgba(146, 20, 115, 0.8)";
serie_color = [{
from: 0,
to: 5254,
name: '< 5 254.00',
color: Color[0]
}, {
from: 5255,
to: 10509,
name: 'From 5 255.00 to 10 509.00',
color: Color[1]
}, {
from: 10510,
to: 15764,
name: 'From 10 510.00 to 15 764.00',
color: Color[2]
}, {
from: 15765,
to: 21019,
name: 'From 15 765.00 to 21 019.00',
color: Color[3]
}, {
from: 21020,
to: 26274,
name: '> 21 020.00',
color: Color[4]
}, ];
$(function() {
var chart = Highcharts.mapChart("container", {
chart: {
backgroundColor: "#ffffff",
animation: false
},
colorAxis: [{
dataClasses: serie_color
},
{
minColor: '#efecf3',
maxColor: '#990041',
}
],
mapNavigation: {
enabled: true
},
series: [{
mapData: Highcharts.maps["bret"],
data: data,
name: "States",
borderColor: "#319663",
nullColor: "#f7f7f7",
showInLegend: true,
joinBy: ["code", "CODE_REGION"],
keys: ["CODE_REGION", "DimGraphList_0", "z", "valSize", "value", "pieOffset"]
},
{
mapData: Highcharts.maps["bret"],
type: "mapbubble",
name: "Bubbles",
colorAxis: 1,
showInLegend: true,
joinBy: ["code", "CODE_REGION"],
keys: ["CODE_REGION", "DimGraphList_0", "z", "valSize", "value", "pieOffset"],
data: data,
minSize: "5%",
maxSize: "15%"
}
]
});
});
Result is fine (https://jsfiddle.net/vegaelce/f7neq2a1/) but I've a strange behavior, when the bubble is displayed on the map, the map is is off-centered.
On the jsfiddle, if you click on the "Bubble" value in the legend (to hide them), you'll see the map move and be centered (that should be the expected right position with the bubble displayed).
Any suggestion about this move ? I suspect an offset or something else but how to find/set it ?
Another tip concerns the legend : I'd like to move the 2 legends on different points :
the legend for the first serie (colored bullet points) on the bottom of the chart
the scalar legend for the bubbles on the left (or right) of the chart
Highchart considers that there is only one legend (grouping the 2 series), is it possible to dissociate them ?
Thanks in advance
The first issue looks like a Highcharts bug (related with wrong calculation of x-axis extremes), you can report it here: https://github.com/highcharts/highcharts/issues/new/choose
As a workaround use this code:
Highcharts.seriesTypes.mapbubble.prototype.useMapGeometry = true;
Live demo: https://jsfiddle.net/BlackLabel/oL1zahtm/
As to your second question - Highcharts doesn't have built-in support for multiple legends, but you can change some legend items position by manual translatation, for example:
chart: {
...,
events: {
render: function() {
this.legend.allItems[5].legendGroup.attr({
translateX: -50,
translateY: -50
});
this.legend.allItems[6].legendGroup.attr({
translateX: -50,
translateY: -70
});
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/m7zaeLrd/
Here is the code I have added to plot the bubble chart
{
chart: {
type: 'bubble',
plotBorderWidth: 1,
zoomType: 'xy',
},
title: {
text: 'Highcharts bubbles with radial gradient fill',
},
xAxis: {
gridLineWidth: 1,
min: 0,
},
yAxis: {
min: 0,
max: 100,
},
plotOptions: {
series: {
maxSize: 20,
cursor: 'pointer',
stickyTracking: false,
},
bubble: {
dataLabels: {
enabled: true,
format: '{point.y:,.0f}%',
inside: false,
align: 'center',
x: 0,
y: -8,
style: {
textOutline: 0,
fontWeight: '400',
color: 'black',
},
},
marker: {
lineWidth: 0,
},
},
},
series: [
{
data: [
[42, 38, 500],
[6, 18, 1],
[0, 93, 505],
[57, 2, 90],
[80, 76, 22],
[11, 74, 96],
[88, 56, 10],
[30, 47, 49],
[57, 62, 98],
[4, 16, 16],
[46, 10, 11],
[22, 187, 89],
[57, 191, 82],
[45, 15, 98],
],
},
],
}
There you might find 2 data points not showing up because y-axis range has been defined. I would also need those points to be rendered in the graph at boundary level (at 100). Is there any special property to set this (or) it is not working even if highcharts had default feature like that. Please help me with this.
You can preprocess your data to set y: 100 for values that are greater than 100 and save the original value to show it, for example in a tooltip:
var data = [
...
];
var processedData = data.map(el => ({
x: el[0],
y: el[1] > 100 ? 100 : el[1],
z: el[2],
realYVal: el[1]
}));
Highcharts.chart('container', {
...,
series: [{
data: processedData
}]
});
Live demo: http://jsfiddle.net/BlackLabel/jx0o7e1d/
I am using the predefined symbols for highcharts on a line chart, and would like to only have the symbol show. I do not want the line to show on there as well. I see that it is possible for a bubble chart, but when I change the chart type from bubble to line, the strikethrough appears: https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/bubble-symbol/. Any thoughts on to how I could combat this? Thanks in advance!
chart: {
type: 'bubble'
},
title: {
text: 'Highcharts Bubbles with symbols'
},
series: [{
data: [
[97, 36, 79],
[94, 74, 60],
[68, 76, 58],
[64, 87, 56],
[68, 27, 73],
[74, 99, 42],
[7, 93, 87],
[51, 69, 40],
[38, 23, 33],
{
x: 57,
y: 0,
z: 31,
marker: {
symbol: 'triangle',
lineColor: 'red',
fillColor: 'rgba(255,0,0,0.5)'
},
dataLabels: {
enabled: true,
format: 'Individual marker'
}
}
],
marker: {
symbol: 'square'
},
name: 'Square'
}, {
data: [
[25, 10, 87],
[2, 75, 59],
[11, 54, 8],
[86, 55, 93],
[5, 3, 58],
[90, 63, 44],
[91, 33, 17],
[97, 3, 56],
[15, 67, 48],
[54, 25, 81]
],
marker: {
symbol: 'diamond'
},
name: 'Diamond'
}, {
data: [
[47, 47, 21],
[20, 12, 4],
[6, 76, 91],
[38, 30, 40],
[57, 98, 64],
[61, 17, 10],
[83, 60, 13],
[67, 78, 75],
[64, 12, 10],
[30, 77, 82]
],
marker: {
symbol: 'url(https://www.highcharts.com/samples/graphics/earth.svg)'
},
name: 'Earth'
}]
});
I think that you can use the scatter series type to achieve it.
Demo: https://jsfiddle.net/BlackLabel/8gpnx90v/
chart: {
type: 'scatter'
},
API: https://www.highcharts.com/docs/chart-and-series-types/scatter-chart
Bit of a late answer but if you set symbolWidth to the same value as the radius of your symbols it will hide the lines in the legend:
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom',
symbolWidth: 6
},
plotOptions: {
line: {
marker: {
symbol: 'circle',
radius: 6
}
}
},
How to create vertical merged stacked bar in highchart.
Group Padding and Point Padding is not working in Highchart.
Expected:
Actual:
https://jsfiddle.net/sathishkumar_v/3woxcskg/
Highcharts.chart('container', {
chart: {
type: 'spline'
},
title: {
text: null
},
exporting:{
enabled: false
},
legend: {
align: 'right',
},
xAxis: {
categories: [
'6:00AM',
'7:00AM',
'8:00AM',
'9:00AM',
'10:00AM',
'11:00AM',
'12:00AM',
'1:00PM',
'2:00PM',
'3:00PM',
'4:00PM',
'5:00PM',
'6:00PM',
'7:00PM',
'8:00PM',
'9:00PM',
'10:00PM'
],
plotBands: [
{
from: 0,
to: 2,
color: '#D4E2F2'
},
{
from: 2,
to: 5,
color: '#EFC5CA'
},
{
from: 14,
to: 16,
color: '#D4E2F2'
},
{
from: 11,
to: 14,
color: '#EFC5CA'
},
]
},
yAxis: [
{
gridLineDashStyle: 'longdash',
// tickPositions: [0, 100, 200, 300, 400, 500, 600, 700, 800],
title: {
text: 'TRIPS'
}
},
{
gridLineDashStyle: 'longdash',
// tickPositions: [0, 100, 200, 300, 400, 500, 600, 700, 800],
title: {
text: 'DEMAND(PAX)'
},
opposite: true
}
],
tooltip: {
shared: true,
valueSuffix: ' units'
},
credits: {
enabled: false
},
plotOptions: {
areaspline: {
fillOpacity: 0.5
}
},
series: [{
name: 'Planned Trips',
yAxis: 1,
data: [0, 35, 80, 120, 230, 210, 175, 155, 130, 120, 150, 100, 175, 160, 175, 140, 180],
color: '#304894',
},
{
name: 'Actual Trips',
///yAxis: 2,
data: [0, 145, 165, 180, 190, 225, 195, 175, 150, 190, 200, 230, 175, 90, 115, 140, 120],
color: '#6FD1F6',
},
{
name: 'Actual Demand',
type: 'column',
stacking: 'normal',
data: [0, 25, 35, 80, 130, 150, 115, 100, 80, 70, 30, 80, 100, 75, 60, 75, 40],
color: '#6FD1F6',
pointWidth: 10
}, {
type: 'column',
name: 'Planned Demand',
stacking: 'normal',
data: [3, 35, 11, 11, 12, 14, 15, 21, 25, 25, 23, 21, 15, 13, 12, 5, 5],
color: '#304894',
pointWidth: 10
}]
});
I am using https://github.com/bellstrand/highcharts-border-radius for the border radius top - left and right
You can use a wrapper function to do this, like so:
(function (H) {
H.wrap(H.seriesTypes.column.prototype, 'drawPoints', function (proceed) {
console.log(this)
let borderRadius = this.points[0].pointWidth / 2;
this.options.borderRadius = borderRadius;
$.each(this.points, function (i,point) {
point.shapeArgs.y -= borderRadius; //move the point down by borderRadius pixels
point.shapeArgs.height += borderRadius * 2; //add borderRadius pixels to the total height of a point (to cover the gap)
});
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
});
}(Highcharts));
Which takes half of the initial width of the bar as the border radius and covers the gaps they would leave.
(function (H) {
H.wrap(H.seriesTypes.column.prototype, 'drawPoints', function (proceed) {
let borderRadius = this.points[0].pointWidth / 2;
this.options.borderRadius = borderRadius;
$.each(this.points, function (i,point) {
point.shapeArgs.y -= borderRadius; //move the point down by borderRadius pixels
point.shapeArgs.height += borderRadius * 2; //add borderRadius pixels to the total height of a point (to cover the gap)
});
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
});
}(Highcharts));
Highcharts.chart('container', {
chart: {
type: 'spline'
},
title: {
text: null
},
exporting:{
enabled: false
},
legend: {
align: 'right',
},
xAxis: {
categories: [
'6:00AM',
'7:00AM',
'8:00AM',
'9:00AM',
'10:00AM',
'11:00AM',
'12:00AM',
'1:00PM',
'2:00PM',
'3:00PM',
'4:00PM',
'5:00PM',
'6:00PM',
'7:00PM',
'8:00PM',
'9:00PM',
'10:00PM'
],
plotBands: [
{
from: 0,
to: 2,
color: '#D4E2F2'
},
{
from: 2,
to: 5,
color: '#EFC5CA'
},
{
from: 14,
to: 16,
color: '#D4E2F2'
},
{
from: 11,
to: 14,
color: '#EFC5CA'
},
]
},
yAxis: [
{
gridLineDashStyle: 'longdash',
// tickPositions: [0, 100, 200, 300, 400, 500, 600, 700, 800],
title: {
text: 'TRIPS'
}
},
{
gridLineDashStyle: 'longdash',
// tickPositions: [0, 100, 200, 300, 400, 500, 600, 700, 800],
title: {
text: 'DEMAND(PAX)'
},
opposite: true
}
],
tooltip: {
shared: true,
valueSuffix: ' units'
},
credits: {
enabled: false
},
plotOptions: {
areaspline: {
fillOpacity: 0.5
}
},
series: [{
name: 'Planned Trips',
yAxis: 1,
data: [0, 35, 80, 120, 230, 210, 175, 155, 130, 120, 150, 100, 175, 160, 175, 140, 180],
color: '#304894',
},
{
name: 'Actual Trips',
///yAxis: 2,
data: [0, 145, 165, 180, 190, 225, 195, 175, 150, 190, 200, 230, 175, 90, 115, 140, 120],
color: '#6FD1F6',
},
{
name: 'Actual Demand',
type: 'column',
stacking: 'normal',
data: [0, 25, 35, 80, 130, 150, 115, 100, 80, 70, 30, 80, 100, 75, 60, 75, 40],
color: '#6FD1F6',
pointWidth: 10
}, {
type: 'column',
name: 'Planned Demand',
stacking: 'normal',
data: [3, 35, 11, 11, 12, 14, 15, 21, 25, 25, 23, 21, 15, 13, 12, 5, 5],
color: '#304894',
pointWidth: 10
}]
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
Working example: https://jsfiddle.net/ewolden/3woxcskg/19/
If you have several charts in your page but only want this to affect one chart you can set a custom flag for that. You would then need to:
In the chart config:
chart: {
customFlag: 'wrap',
...
},
And in the wrapper:
(function (H) {
H.wrap(H.seriesTypes.column.prototype, 'drawPoints', function (proceed) {
console.log(this)
if(this.chart.options.chart.customFlag == 'wrap') {
let borderRadius = this.points[0].pointWidth / 2;
this.options.borderRadius = borderRadius;
$.each(this.points, function (i,point) {
point.shapeArgs.y -= borderRadius; //move the point down by borderRadius pixels
point.shapeArgs.height += borderRadius * 2; //add borderRadius pixels to the total height of a point (to cover the gap)
});
}
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
});
}(Highcharts));
(function (H) {
H.wrap(H.seriesTypes.column.prototype, 'drawPoints', function (proceed) {
console.log(this)
if(this.chart.options.chart.customFlag == 'wrap') {
let borderRadius = this.points[0].pointWidth / 2;
this.options.borderRadius = borderRadius;
$.each(this.points, function (i,point) {
point.shapeArgs.y -= borderRadius; //move the point down by borderRadius pixels
point.shapeArgs.height += borderRadius * 2; //add borderRadius pixels to the total height of a point (to cover the gap)
});
}
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
});
}(Highcharts));
Highcharts.chart('container', {
chart: {
type: 'spline',
customFlag: 'wrap'
},
title: {
text: null
},
exporting:{
enabled: false
},
legend: {
align: 'right',
},
xAxis: {
categories: [
'6:00AM',
'7:00AM',
'8:00AM',
'9:00AM',
'10:00AM',
'11:00AM',
'12:00AM',
'1:00PM',
'2:00PM',
'3:00PM',
'4:00PM',
'5:00PM',
'6:00PM',
'7:00PM',
'8:00PM',
'9:00PM',
'10:00PM'
],
plotBands: [
{
from: 0,
to: 2,
color: '#D4E2F2'
},
{
from: 2,
to: 5,
color: '#EFC5CA'
},
{
from: 14,
to: 16,
color: '#D4E2F2'
},
{
from: 11,
to: 14,
color: '#EFC5CA'
},
]
},
yAxis: [
{
gridLineDashStyle: 'longdash',
// tickPositions: [0, 100, 200, 300, 400, 500, 600, 700, 800],
title: {
text: 'TRIPS'
}
},
{
gridLineDashStyle: 'longdash',
// tickPositions: [0, 100, 200, 300, 400, 500, 600, 700, 800],
title: {
text: 'DEMAND(PAX)'
},
opposite: true
}
],
tooltip: {
shared: true,
valueSuffix: ' units'
},
credits: {
enabled: false
},
plotOptions: {
areaspline: {
fillOpacity: 0.5
}
},
series: [{
name: 'Planned Trips',
yAxis: 1,
data: [0, 35, 80, 120, 230, 210, 175, 155, 130, 120, 150, 100, 175, 160, 175, 140, 180],
color: '#304894',
},
{
name: 'Actual Trips',
///yAxis: 2,
data: [0, 145, 165, 180, 190, 225, 195, 175, 150, 190, 200, 230, 175, 90, 115, 140, 120],
color: '#6FD1F6',
},
{
name: 'Actual Demand',
type: 'column',
stacking: 'normal',
data: [0, 25, 35, 80, 130, 150, 115, 100, 80, 70, 30, 80, 100, 75, 60, 75, 40],
color: '#6FD1F6',
pointWidth: 10
}, {
type: 'column',
name: 'Planned Demand',
stacking: 'normal',
data: [3, 35, 11, 11, 12, 14, 15, 21, 25, 25, 23, 21, 15, 13, 12, 5, 5],
color: '#304894',
pointWidth: 10
}]
});
Highcharts.chart('container2', {
chart: {
type: 'column'
},
title: {
text: 'Monthly Average Rainfall'
},
subtitle: {
text: 'Source: WorldClimate.com'
},
xAxis: {
categories: [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec'
],
crosshair: true
},
yAxis: {
min: 0,
title: {
text: 'Rainfall (mm)'
}
},
tooltip: {
headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
'<td style="padding:0"><b>{point.y:.1f} mm</b></td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [{
name: 'Tokyo',
data: [49.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}, {
name: 'New York',
data: [83.6, 78.8, 98.5, 93.4, 106.0, 84.5, 105.0, 104.3, 91.2, 83.5, 106.6, 92.3]
}, {
name: 'London',
data: [48.9, 38.8, 39.3, 41.4, 47.0, 48.3, 59.0, 59.6, 52.4, 65.2, 59.3, 51.2]
}, {
name: 'Berlin',
data: [42.4, 33.2, 34.5, 39.7, 52.6, 75.5, 57.4, 60.4, 47.6, 39.1, 46.8, 51.1]
}]
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
<div id="container2" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
Working example: https://jsfiddle.net/ewolden/3woxcskg/24/
I'm trying to change yAxis type of a Highcharts 3.0ß bubble chart to logarithmic, but - when it displays something - it displays a single series, and a single bubble... here's an simple example, based on "official" bubble chart demo : http://jsfiddle.net/FtdYf/
$(function() {
$('#container').highcharts({
chart: {
type: 'bubble',
plotBorderWidth: 1,
zoomType: 'xy'
},
title: {
text: 'Highcharts bubbles with radial gradient fill'
},
xAxis: {
gridLineWidth: 1
},
yAxis: {
startOnTick: false,
endOnTick: false,
type:'logarithmic'
},
series: [{
data: [
[9, 81, 63],
[98, 5, 89],
[51, 50, 73],
[41, 22, 14],
[58, 24, 20],
[78, 37, 34],
[55, 56, 53],
[18, 45, 70],
[42, 44, 28],
[3, 52, 59],
[31, 18, 97],
[79, 91, 63],
[93, 23, 23],
[44, 83, 22]
],
marker: {
fillColor: {
radialGradient: { cx: 0.4, cy: 0.3, r: 0.7 },
stops: [
[0, 'rgba(255,255,255,0.5)'],
[1, 'rgba(69,114,167,0.5)']
]
}
}
}, {
data: [
[42, 38, 20],
[6, 18, 1],
[1, 93, 55],
[57, 2, 90],
[80, 76, 22],
[11, 74, 96],
[88, 56, 10],
[30, 47, 49],
[57, 62, 98],
[4, 16, 16],
[46, 10, 11],
[22, 87, 89],
[57, 91, 82],
[45, 15, 98]
],
color: 'rgba(170,70,67,0.5)',
marker: {
fillColor: {
radialGradient: { cx: 0.4, cy: 0.3, r: 0.7 },
stops: [
[0, 'rgba(255,255,255,0.5)'],
[1, 'rgba(170,70,67,0.5)']
]
}
}
}]
});
});
So here's my question : is logarithmic axis (X and Y) possible on a bubble chart, and if so, why do it displays just a single series and a single bubble ?
Thanks for help !
You can set tickPositions or create your own tickPositioner. For example: http://jsfiddle.net/Fusher/FtdYf/2/