Related
I'm using HighCharts to display the death rate. Comparison of death between Male and Female deaths with respect to age is already done and displayed.
Issue I'm facing is the values in y-axis of chart. Y-axis in the chart is the horizontal one. I want it to display values like ...,5,4,3,2,1,0,1,2,3,4,5,...
var categories = [
'0-10', '11-20', '21-30', '31-40',
'40-50', '50-60', '60-70', '70-80', '80-90',
'90+'
];
Highcharts.chart('male-female', {
chart: { type: 'bar' },
title: { text: 'Male Female Death Rate' },
xAxis: [{
categories: categories,
reversed: false,
labels: { step: 1 },
accessibility: { description: 'Age (male)' }
},
{ // mirror axis on right side
opposite: true,
reversed: false,
categories: categories,
linkedTo: 0,
labels: { step: 1 },
accessibility: { description: 'Age (female)' }
}],
plotOptions: {
series: { stacking: 'normal' }
},
series: [
{
name: 'Male',
data: [ 0, -2, -1, 0, -2, -2, -1, -4, -6, -3 ]
},
{
name: 'Female',
data: [ 2, 2, 2, 2, 2, 9, 3, 1, 9, 4 ]
}
]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/series-label.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<figure class="highcharts-figure">
<div id="male-female"></div>
</figure>
Another solution which you can implement is a creating an array with wanted ticks and use the yAxis.tickPositions feature to apply it.
Demo: https://jsfiddle.net/BlackLabel/mb5v2w1u/
code:
var ticks = [];
for(let i = -10; i <=10; i++){
ticks.push(i)
}
API: https://api.highcharts.com/highcharts/yAxis.tickPositions
You should use Math.abs() in your label formatter to get the absolute value.
Your yAxis must be set to :
yAxis: {
labels: {
formatter: function() {
return Math.abs(this.value);
}
}
}
You can use the same idea for the tooltip by using the formatter function.
tooltip: {
formatter: function() {
return '<b>' + this.series.name + ', age ' + this.point.category + '</b><br/>' +
'Population: ' + Highcharts.numberFormat(Math.abs(this.point.y), 1);
}
}
var categories = [
'0-10', '11-20', '21-30', '31-40',
'40-50', '50-60', '60-70', '70-80', '80-90',
'90+'
];
Highcharts.chart('male-female', {
chart: {
type: 'bar'
},
title: {
text: 'Male Female Death Rate'
},
xAxis: [{
categories: categories,
reversed: false,
labels: {
step: 1
},
accessibility: {
description: 'Age (male)'
}
},
{ // mirror axis on right side
opposite: true,
reversed: false,
categories: categories,
linkedTo: 0,
labels: {
step: 1
},
accessibility: {
description: 'Age (female)'
}
}
],
yAxis: {
labels: {
formatter: function() {
return Math.abs(this.value);
}
},
tickInterval: 1
},
plotOptions: {
series: {
stacking: 'normal'
}
},
tooltip: {
formatter: function() {
return '<b>' + this.series.name + ', age ' + this.point.category + '</b><br/>' +
'Population: ' + Highcharts.numberFormat(Math.abs(this.point.y), 1);
}
},
series: [{
name: 'Male',
data: [0, -2, -1, 0, -2, -2, -1, -4, -6, -3]
},
{
name: 'Female',
data: [2, 2, 2, 2, 2, 9, 3, 1, 9, 4]
}
]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/series-label.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<figure class="highcharts-figure">
<div id="male-female"></div>
</figure>
Try using yAxis.labels.formatter and Math.abs()
https://api.highcharts.com/highstock/yAxis.labels.formatter
yAxis: {
tickInterval: 1,
labels: {
formatter: function() {
return Math.abs(this.value);
}
}
},
var categories = [
'0-10', '11-20', '21-30', '31-40',
'40-50', '50-60', '60-70', '70-80', '80-90',
'90+'
];
Highcharts.chart('male-female', {
chart: {
type: 'bar'
},
title: {
text: 'Male Female Death Rate'
},
xAxis: [{
categories: categories,
reversed: false,
labels: {
step: 1
},
accessibility: {
description: 'Age (male)'
}
},
{ // mirror axis on right side
opposite: true,
reversed: false,
categories: categories,
linkedTo: 0,
labels: {
step: 1
},
accessibility: {
description: 'Age (female)'
}
}
],
yAxis: {
tickInterval: 1,
labels: {
formatter: function() {
return Math.abs(this.value);
}
}
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
name: 'Male',
data: [0, -2, -1, 0, -2, -2, -1, -4, -6, -3]
},
{
name: 'Female',
data: [2, 2, 2, 2, 2, 9, 3, 1, 9, 4]
}
]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/series-label.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<figure class="highcharts-figure">
<div id="male-female"></div>
</figure>
I'm trying to pass a secondary variable that's located in each point of my series' data-set. I've managed to that so far but when I try to hover on another data point on the chart, the same data gets printed for all points instead of showing the correct data for that specific point.
I've tried a variety of solutions and I would like to stick to this one, however I have this small hurdle which I can't seem to get over.
Here's a jsFiddle to show the problem I'm encountering: https://jsfiddle.net/Flik1/dfn51akc/47/
// Data gathered from http://populationpyramid.net/germany/2015/
// Age categories
var categories = [
'column 1', 'column 2', 'column 3', 'column 4'
];
Highcharts.chart('container', {
chart: {
type: 'bar',
followTouchMove: true,
spacingTop: 10,
spacingLeft: 5,
spacingRight: 5
},
xAxis: [{
reversed: true,
tickPosition: 'inside',
startOnTick: true,
endOnTick: true,
categories: categories,
labels: {
enabled: false
}
},
{ // mirror axis on right side
opposite: true,
reversed: true,
linkedTo: 0,
tickPosition: 'inside',
categories: [
'NIL'
],
labels: {
step: 1,
enabled: false
}
}
],
plotOptions: {
series: {
stacking: 'normal',
borderColor: '#fafafa'
}
},
tooltip: {
shared: true,
formatter: function() {
var points = this.points;
var series = this.series;
var pointsLength = points.length;
var tooltipMarkup = pointsLength ? '<span style=\'font-size: 10px\'>' + points[0].key + '</span><br/>' : '';
for (index = 0; index < pointsLength; index++) {
tooltipMarkup += '<b>' + this.points[index].series.name + ': </b>' + this.points[index].series.userOptions.data[0].tt + '<br/>';
}
return tooltipMarkup;
}
},
series: [{
data: [{
y: -2.2,
tt: "1"
}, {
y: -2.6,
tt: "2"
}, {
y: -1.3,
tt: "3"
}, {
y: -5.2,
tt: "4"
}]
}, {
color: '#FF0000',
dataLabels: {
enabled: true,
inside: true,
align: 'left',
format: '{x}'
},
data: [{
y: 1.3,
tt: "5"
}, {
y: 2.3,
tt: "6"
}, {
y: 4.3,
tt: "7"
}, {
y: 1.7,
tt: "8"
}]
}]
});
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; max-width: 800px; height: 400px; margin: 0 auto"></div>
I believe its a problem with this specific line of code as its displaying the first 'tt' variable from each series.
this.points[index].series.userOptions.data[0].tt
The expected outcome would be 1 and 5 for column 1, 2 and 6 for column 2, 3 and 7 for column 3 and 4 and 8 for column 4.
Try this.points[index].point.options.tt
// Data gathered from http://populationpyramid.net/germany/2015/
// Age categories
var categories = [
'column 1', 'column 2', 'column 3', 'column 4'
];
Highcharts.chart('container', {
chart: {
type: 'bar',
followTouchMove: true,
spacingTop: 10,
spacingLeft: 5,
spacingRight: 5
},
xAxis: [{
reversed: true,
tickPosition: 'inside',
startOnTick: true,
endOnTick: true,
categories: categories,
labels: {
enabled: false
}
},
{ // mirror axis on right side
opposite: true,
reversed: true,
linkedTo: 0,
tickPosition: 'inside',
categories: [
'NIL'
],
labels: {
step: 1,
enabled: false
}
}
],
plotOptions: {
series: {
stacking: 'normal',
borderColor: '#fafafa'
}
},
tooltip: {
shared: true,
formatter: function() {
var points = this.points;
var series = this.series;
var pointsLength = points.length;
var tooltipMarkup = pointsLength ? '<span style=\'font-size: 10px\'>' + points[0].key + '</span><br/>' : '';
for (index = 0; index < pointsLength; index++) {
tooltipMarkup += '<b>' + this.points[index].series.name + ': </b>' + this.points[index].point.options.tt + '<br/>';
}
return tooltipMarkup;
}
},
series: [{
data: [{
y: -2.2,
tt: "1"
}, {
y: -2.6,
tt: "2"
}, {
y: -1.3,
tt: "3"
}, {
y: -5.2,
tt: "4"
}]
}, {
color: '#FF0000',
dataLabels: {
enabled: true,
inside: true,
align: 'left',
format: '{x}'
},
data: [{
y: 1.3,
tt: "5"
}, {
y: 2.3,
tt: "6"
}, {
y: 4.3,
tt: "7"
}, {
y: 1.7,
tt: "8"
}]
}]
});
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; max-width: 800px; height: 400px; margin: 0 auto"></div>
I am trying to create a funnel visualization that would visualization the number of guests and also percent of prior visit for 3 categories of consumers: 1 Visit, 2 Visits, 3+ Visits.
Right now I have 2 labels for each category (sticking out to the right hand side) but I want 1 label for each category sticking out on the right hand side stating both the # of Guests and Percent of Prior Visit. I also want a box-shaped label for each block of the funnel so that when you hover over it it looks like:
[CATEGORY]
Percent of Prior Visit: [VALUE]
Guests: [VALUE]
Right now, the box-shaped label when I hover over the block just shows Percent of Prior visit. So I want the box to be fixed and the label to the right hand side to be just 1 per block. I hope this makes sense. How would I do something like this? Thanks in advance.
My code is at: https://jsfiddle.net/ug4rc6pn/150/
Using the style you tried with earlier makes this easier. That is, setting both value and percentage in the same series, like this:
series: [{
name: 'Guests',
data: [{
y: 352000,
yPercentage: 100,
name: '1 Visit',
color: "#ff0000",
},
...
]
}]
You can then format your datalabel like this:
dataLabels: {
enabled: true,
format: '<b>{point.name}</b> <br/>{point.y:,.0f} ({point.yPercentage} %)',
...
}
And your tooltip like this:
tooltip: {
headerFormat: '<span style="font-size: 10px"><b>{point.key}</b></span><br/>',
pointFormat: 'Percent of Prior Visit: {point.yPercentage} % <br/>Guests: {point.y:,.0f} '
}
Which gives you this:
Highcharts.chart('container', {
chart: {
type: 'funnel',
//Only for Pie Charts
options3d: {
enabled: false, // change to true to activate 3D
alpha: 40,
beta: 40,
depth: 100,
},
},
title: {
text: 'Guest Return Funnel'
},
plotOptions: {
funnel: {
depth: 100
},
series: {
events: {
legendItemClick: function() {
$.each(this.chart.series, function(i, serie) {
if (serie.visible)
serie.hide();
else
serie.show();
});
return false;
}
},
shadow: true,
allowPointSelect: true,
borderWidth: 18,
animation: {
duration: 400
},
dataLabels: {
enabled: true,
format: '<b>{point.name}</b> <br/>{point.y:,.0f} ({point.yPercentage} %)',
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black',
softConnector: true,
crop: false
},
center: ['50%', '50%'],
neckWidth: '40%',
neckHeight: '0%',
width: '65%',
height: '100%',
tooltip: {
headerFormat: '<span style="font-size: 10px"><b>{point.key}</b></span><br/>',
pointFormat: 'Percent of Prior Visit: {point.yPercentage} % <br/>Guests: {point.y:,.0f} '
}
}
},
legend: {
enabled: true
},
series: [{
name: 'Guests',
data: [{
y: 352000,
yPercentage: 100,
name: '1 Visit',
color: "#ff0000",
},
{
y: 88000,
yPercentage: 25,
name: '2 Visits',
color: "#FFA500",
},
{
y: 42000,
yPercentage: 48,
name: '3+ Visits',
color: "#32CD32"
}
]
}
]
});
/*
series: [{
name: 'Guests',
name2: 'Percent of Prior Visit',
data: [{
y:352000,
name: '1 Visit',
color: "#ff0000",
y2: 100,
name2: 'Percent of Prior Visit'
},
{
y: 88000,
name: '2 Visits',
color: "#FFA500",
y2: 25,
name2: 'Percent of Prior Visit',
},
{
y: 42000,
name: '3+ Visits',
color:"#32CD32",
y2: 48,
name2: 'Percent of Prior Visit'
}
]
}]
});
*/
<script src="https://code.highcharts.com/highcharts.js">
</script>
<script src="https://code.highcharts.com/highcharts-3d.js"></script>
<script src="https://code.highcharts.com/modules/funnel.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: 410px; max-width: 600px; height: 400px; margin: 0 auto"></div>
JSFiddle working example: https://jsfiddle.net/ewolden/org6quk9/
I have two y-axis.
using primary y-axis I have created column chart but when I am trying to create line chart using secondary y-axis with negative percentage data values my line chart is going down from x-axis I don't want that so do anyone know about this please help me as soon as possible ?
$(function () {
$('#container').highcharts({
colors: [ '#24CBE5','#FF9655'],
chart: {
type: 'column'
},
title: {
text: 'combine chart'
},
plotOptions: {
series: {
pointPadding:0,
groupPadding:0.3,
borderWidth: 1,
//shadow: false
}
},
xAxis: {
gridLineWidth: 0,
minorGridLineWidth: 0,
categories: ['Oct 15', 'Nov 15', 'Dec 15', 'Jan 15', 'Feb 15','March 15'],
},
yAxis: [{ // Primary yAxis
min: 0,
max: 4,
gridLineWidth: 0,
minorGridLineWidth: 0,
labels: {
formatter: function () {
return this.value + '$';
}
},
title: {
text: 'Million',
}
}, { // Secondary yAxis
tickInterval:5, //set ticks to 20
min: -30,
max: 10,
column :{
stacking:'percent'
},
title: {
text: '% Percantage',
},
labels: {
formatter: function () {
return this.value + '%';
}
},
opposite: true
}],
series: [
{
type: 'column',
name: 'AB',
data: [3, 3.5, 3.3, 3.6, 2.5,2]
}, {
type: 'column',
name: 'BC',
data: [3.3, 2, 3.3, 3.4, 2.9,3]
}, {
// USE THIS CODE TO GENERATE LINE CHART (I HAVE USED ONLY MILION AND CREATED LINE CHART BUT INSTEAD I WANT TO USE percentage )
type: 'line',
name: '% Percantage',
data: [0.5, 2, 0, 4, 3.7,2.6],
color: '#000000',
//border: 1,
marker: {
fillColor: '#FFFFFF',
lineWidth: 2,
lineColor: null // inherit from series
}
}]
});
});
You need to set alignTicks as false.
chart:{
alignTicks: false
}
I refer to http://jsfiddle.net/VJsjg/2/
$(function() {
$('#container').highcharts('StockChart', {
chart: {
zoomType: 'x',
marginTop: 100, //avoid overlapping with navigator
spacingLeft: 0
},
scrollbar: {
enabled: false
},
navigator: {
enabled: true,
top: 40
},
rangeSelector: {
selected: 1
},
yAxis:[{
top:140,
height:150
}],
series: [{
id:'msft',
name: 'MSFT',
data: MSFT
}]
});
$('#button').click(function() {
var chart = $('#container').highcharts();
chart.addAxis({
id:'secondY',
top:300,
height:150
});
chart.addSeries({
id:'adbe',
yAxis:'secondY',
name: 'ADBE',
data: ADBE
});
$(this).attr('disabled', true);
chart.addSeries(
// the event marker flags
{
type : 'flags',
data : [{
x : Date.UTC(2011, 3, 25),
title : 'H',
text : 'Euro Contained by Channel Resistance'
}, {
x : Date.UTC(2011, 3, 28),
title : 'G',
text : 'EURUSD: Bulls Clear Path to 1.50 Figure'
}],
onSeries : 'adbe',
shape : 'circlepin',
width : 16
});
});
});
Notice that the circlepin H and C are at the correct position of the bottom series. However, when we do a mouseover, the position of the tooltip followed the top series instead.
Has anyone encountered the same problem before?
I fixed my own problem by adding a
tooltip: {
followPointer:true
}
to the series.
Refer to http://jsfiddle.net/VGj9q/ for the solution.
Tooltip can follow yAxis by adding followingPointer:true, but in this way, the tooltip shape became 'square', not 'callout'.
I think this is a bug of highcharts, some similar issues can be found on github. But seems they didn't fix it for 'flag' series.
Refer to http://jsfiddle.net/4jt9jxs1/2/ for this issue.
Highcharts.stockChart('container', {
chart: {
height: 600,
},
navigator: {
enabled: false
},
yAxis: [{
id: "1",
height: 200,
},{
id: "2",
top: 300,
height: 200,
}],
tooltip:{
shared: false
},
series: [{
name: 'USD to EUR',
id: 'dataseries',
data: usdeur,
yAxis: "1"
},{
name: 'USD to EUR1',
id: 's1',
data: usdeur,
yAxis:"2"
}, {
type: 'flags',
data: [{
x: Date.UTC(2011, 1, 14),
title: 'A',
text: 'Shape: "squarepin"'
}, {
x: Date.UTC(2011, 3, 28),
title: 'A',
text: 'Shape: "squarepin"'
}],
onSeries: 'dataseries',
shape: 'squarepin',
width: 16
}, {
type: 'flags',
data: [{
x: Date.UTC(2010, 2, 1),
text: 'Shape: "circlepin"'
}, {
x: Date.UTC(2010, 9, 1),
text: 'Shape: "circlepin"'
}],
shape: 'circlepin',
onSeries: 's1',
yAxis:"2",
title: 'B',
tooltip: {
followPointer: true,
},
width: 16
}, {
type: 'flags',
data: [{
x: Date.UTC(2012, 2, 10),
title: 'C',
text: 'Shape: "flag"'
}, {
x: Date.UTC(2013, 3, 11),
title: 'C',
text: 'Shape: "flag"'
}],
yAxis:"2",
color: '#5F86B3',
fillColor: '#5F86B3',
onSeries: 's1',
width: 16,
style: { // text style
color: 'white'
},
states: {
hover: {
fillColor: '#395C84' // darker
}
}
}]
});
<div id="container" style="height: 400px; min-width: 600px"></div>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<script type="text/javascript" src="https://www.highcharts.com/samples/data/usdeur.js"></script>