Highcharts is formating x axis text values as dates - highcharts

For some reason, Highcharts is formatting my text categories as dates.
Background Info
I am getting my data from a Google Spreadsheet. The labels should say Grade 12, Grade 11, etc. I know I can overwrite the xAxis labels with the categories function, but I want I sustainable solution so that my end users can change the labels as they wish.
CodePen
$(function() {
Highcharts.setOptions({
chart: {
defaultSeriesType: 'bar',
backgroundColor: '#fff',
shadow: false
}
});
$('#ms-highschool').highcharts({
data: {
googleSpreadsheetKey: '1Nx8zcIi0ULxytLmra0A9N11-llzJCDVH2-7SbK_k5-U',
startColumn: 0,
endColumn: 1,
startRow: 0,
googleSpreadsheetWorksheet: 5
},
title: {
text: 'Charter School Makret Share for High School Grades, SY 2014-15'
},
yAxis: {
min: 0,
max: 40,
tickInterval: 10,
title: {
text: 'PCS Share'
}
},
xAxis: {
labels: {
enabled: true,
}
}
});
});
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/data.js"></script>
<script>
</script>
</head>
<body>
<div id="ms-highschool"></div>
</body>

You can specify type of x axis explicitly to have the problem solved.
xAxis: {
labels: {
enabled: true,
},
type: "category"
}

Related

highcharts view as table without annotation column

I have generated a bar chart with Highcharts.
On this bar chart, I'm using an annotation to mark the 50% threshold with these words: "conformité partielle".
The problem is that in the data table, I don't want an "annotations" column.
Is there a way to avoid this?
Thanks very much for your help.
The option to exclude from the generated table, as well as other data export formats is includeInDataExport: false.
To exclude a data series it should be added to that series object, at the top level.
To exclude annotation labels, it should be placed in the labelOptions object, inside the annotation object:
document.addEventListener('DOMContentLoaded', function () {
Highcharts.chart('container', {
chart: {
type: 'bar'
},
title: {
text: 'Fruit Consumption'
},
xAxis: {
categories: ['Apples', 'Bananas', 'Oranges']
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: [{
name: 'Jane',
data: [1, 0, 4],
//includeInDataExport: false
}, {
name: 'John',
data: [5, 7, 3],
}],
annotations: [{
labels: [{
point: { x: 2, y: 5, yAxis: 0 },
text: 'My annotation'
}],
labelOptions: {
includeInDataExport: false
}
}],
exporting: {
showTable: true
}
});
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/annotations.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="width:100%; height:300px;"></div>
The above is the standard solution for this question. What follows might be relevant for a larger category of related problems that
require the manipulation of the generated table in non-standard ways.
If one has to manipulate the table after its html was generated, one may add a handler for the chart's render event. The annotation can be deleted this way:
document.addEventListener('DOMContentLoaded', function () {
Highcharts.chart('container', {
chart: {
type: 'bar',
events: {
render() {
const tableDiv = this.dataTableDiv,
seriesLength = this.series.length;
if(tableDiv && tableDiv.querySelectorAll('thead th').length === seriesLength+2){
tableDiv.querySelectorAll('th:last-child, td:last-child, tbody>tr:last-child').forEach(el=>el.remove())
}
}
},
},
title: {
text: 'Fruit Consumption'
},
xAxis: {
categories: ['Apples', 'Bananas', 'Oranges']
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: [{
name: 'Jane',
data: [1, 0, 4],
}, {
name: 'John',
data: [5, 7, 3],
}],
annotations: [{
labels: [{
point: { x: 2, y: 5, yAxis: 0 },
text: 'My annotation'
}]
}],
exporting: {
showTable: true
}
});
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/annotations.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="width:100%; height:300px;"></div>
One has to take into consideration the fact that the handler for render is typically called multiple times, including for instance when the mouse pointer moves inside the chart div - so if the table content is to be modified by addition or deletion one has to make sure that it happens only once. In this case we delete the last column and the last row of the table only when the number of rows is equal to the number of series + 2 -- this assumes that no series has {includeInDataExport: false}. Alternative conditions can be thought of, like searching for the text of the annotation.
Finally, a mention should be made for the exportData
event handler, that might be useful in some cases. The problem in this particular case is that it doesn't offer access to the table heads and indeed the argument doesn't contain anything about the annotations (although it is filled up in the same object after the execution of the handler).
Since at the time when exportData handler is called, the chart's dataTableDiv was created, albeit it is empty, one can exploit it in a rather hacky manner:
document.addEventListener('DOMContentLoaded', function () {
Highcharts.chart('container', {
chart: {
type: 'bar',
events: {
exportData: function() {
const tableDiv = this.dataTableDiv,
seriesLength = this.series.length;
setTimeout(function(){
if(tableDiv && tableDiv.querySelectorAll('thead th').length === seriesLength+2){
tableDiv.querySelectorAll('th:last-child, td:last-child, tbody>tr:last-child').forEach(el=>el.remove())
}
}, 0);
}
}
},
title: {
text: 'Fruit Consumption'
},
xAxis: {
categories: ['Apples', 'Bananas', 'Oranges']
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: [{
name: 'Jane',
data: [1, 0, 4],
}, {
name: 'John',
data: [5, 7, 3],
}],
annotations: [{
labels: [{
point: { x: 2, y: 5, yAxis: 0 },
text: 'My annotation'
}]
}],
exporting: {
showTable: true
}
});
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/annotations.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="width:100%; height:300px;"></div>

Highcharts/Highstock How to show original OHLC values in tooltip for chart drawn using adjusted OHLC values?

This snippet shows both original OHLC and adjusted OHLC data in separate plots:
<html>
<head>
<title>
How to show original values in tooltip?
</title>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/modules/data.js"></script>
</head>
<body>
<div id="chart-container" style="width: 100%; height: 100%; margin: 0 auto"></div>
<pre id="csv" style="display: none">
date,open,high,low,close,volume,ex_dividend,split_ratio,adj_open,adj_high,adj_low,adj_close,adj_volume
2014-05-30,637.98,644.17,628.9,633.0,20143600.0,0.0,1.0,85.783881043984,86.616199022075,84.562968727173,85.114261733663,141005200.0
2014-06-02,633.96,634.83,622.5,628.65,13191100.0,0.0,1.0,85.243344974207,85.36032666095,83.702413790213,84.529353299948,92337700.0
2014-06-03,628.46,638.74,628.25,637.54,10453900.0,0.0,1.0,84.503805575257,85.886071942748,84.475568616388,85.724717892068,73177300.0
2014-06-04,637.44,647.89,636.11,644.82,11981500.0,0.0,1.0,85.711271721178,87.116396579183,85.532437648341,86.70359913286,83870500.0
2014-06-05,646.2,649.3699,642.61,647.35,10850200.0,0.0,1.0,86.889156291142,87.315386462184,86.406438756191,87.043787256377,75951400.0
2014-06-06,649.9,651.26,644.47,645.57,12497800.0,0.0,1.0,87.386664614072,87.569532538176,86.656537534745,86.804445414535,87484600.0
2014-06-09,92.7,93.88,91.75,93.7,75414997.0,0.0,7.0,87.252202905172,88.362856620685,86.358032540987,88.193434867471,75414997.0
2014-06-10,94.73,95.05,93.57,94.25,62777000.0,0.0,1.0,89.16290378864,89.464098016576,88.071074712372,88.711112446736,62777000.0
2014-06-11,94.13,94.76,93.47,93.86,45681000.0,0.0,1.0,88.59816461126,89.191140747509,87.976951516142,88.344031981439,45681000.0
2014-06-12,94.04,94.12,91.9,92.29,54749000.0,0.0,1.0,88.513453734653,88.588752291637,86.499217335332,86.866297800629,54749000.0
2014-06-13,92.2,92.44,90.88,91.28,54525000.0,0.0,1.0,86.781586924022,87.007482594974,85.539160733786,85.915653518706,54525000.0
2014-06-16,91.51,92.75,91.45,92.2,35561000.0,0.0,1.0,86.132136870035,87.299264503287,86.075662952297,86.781586924022,35561000.0
</pre>
<script type="text/javascript">
Highcharts.stockChart('chart-container', {
title: {
text: 'Plot Title',
align: 'left',
floating: false
},
exporting: {
enabled: true,
sourceWidth: 900,
sourceHeight: 600
},
legend: {
enabled: false,
floating: true,
verticalAlign: 'top',
align:'center'
},
rangeSelector: {
buttons: [{
type: 'month',
count: 6,
text: '6m'
}, {
type: 'year',
count: 1,
text: '1y'
}, {
type: 'year',
count: 2,
text: '2y'
}, {
type: 'year',
count: 3,
text: '3y'
}, {
type: 'year',
count: 4,
text: '4y'
}, {
type: 'all',
text: 'All'
}],
selected: 3
},
credits: {
enabled: false
},
plotOptions: {
series: {
visible: false,
turboThreshold: 0 // Comment out this code to display error
},
ohlc: {
color: 'black'
}
},
data: {
csv: document.getElementById('csv').innerHTML,
firstRowAsNames: false,
startRow: 1,
seriesMapping: [{
x: 0,
open: 1,
high: 2,
low: 3,
close: 4
}, {
x: 0,
open: 8,
high: 9,
low: 10,
close: 11
}, {
x: 0,
y: 9
}, {
x: 0,
y: 10
}]
},
series: [{
name: 'Values',
type: 'ohlc', // bars
visible: true,
// set color in plotOptions
tooltip: {
// set tooltip options here
}
}, {
name: 'Adj_Values',
type: 'ohlc', // bars
visible: true,
// set color in plotOptions
tooltip: {
// set tooltip options here
}
}, {
name: 'Adj_High',
type: 'line', // high
visible: false,
color: 'blue'
}, {
name: 'Adj_Low',
type: 'line', // low
visible: false,
color: 'gray'
}]
});
</script>
</body>
</html>
If possible I want to (1) make the original OHLC plot invisible; (2) plot only the adjusted OHLC bars; and (3) show the original OHLC values in the tooltip attached to the adjusted OHLC bars shown in the plot.
I can find examples of a shared tooltip but no information on the options that would replace the adjusted OHLC with original OHLC data. Alternatively I might want to add original OHLC data to show both original and adjusted in the tooltip associated with the adjusted data plot.
You can disable visible property for the first series and use tooltip's formatter function to find a matched point from the hidden series and show it's values.
tooltip: {
formatter: function(tooltip) {
const originalFormat = tooltip.defaultFormatter.call(this, tooltip);
const point = this.points[0].point;
const originalPoint = tooltip.chart.series[0].points.find(
p => p.x === point.x
);
originalFormat[1] = `<span style="color:black">●</span> <b> ${point.series.name}</b><br/>Open: ${originalPoint.open}<br/>High: ${originalPoint.high}<br/>Low: ${originalPoint.low}<br/>Close: ${originalPoint.close}<br/>`;
return originalFormat;
}
},
series: [{
name: 'Values',
type: 'ohlc',
visible: false
}, {
name: 'Adj_Values',
type: 'ohlc',
visible: true
}, ...]
Live demo: http://jsfiddle.net/BlackLabel/k2mhvdp6/
API Reference: https://api.highcharts.com/highcharts/tooltip.formatter

Highstock tooltip 'a tag' doesn't get rendered

I am trying to add anchor tag in tooltip of highstock flags.
I am facing couple of problems with that:
Anchor tags are not displayed in tooltip.
When I try to hover over the tooltip, the tooltip disappears.
My code looks like:
$.getJSON('https://cdn.rawgit.com/highcharts/highcharts/057b672172ccc6c08fe7dbb27fc17ebca3f5b770/samples/data/usdeur.json', function (data) {
var year = new Date(data[data.length - 1][0]).getFullYear(); // Get year of last data point
// Create the chart
Highcharts.stockChart('container', {
rangeSelector: {
selected: 4
},
title: {
text: 'USD to EUR exchange rate'
},
yAxis: {
title: {
text: 'Exchange rate'
}
},
series: [{
name: 'USD to EUR',
data: data,
id: 'dataseries',
tooltip: {
valueDecimals: 4
}
},{
type: 'flags',
data: [{
x: Date.UTC(year, 11, 1),
title: 'B',
text: 'make me clickable'
}, {
x: Date.UTC(year, 11, 1),
title: 'B',
text: '<a>make me clickable</a>'
}],
shape: 'circlepin',
onSeries: 'dataseries',
width: 16,
tooltip: {
pointFormat: '{point.text}'
} ,
style:{
border:'1px solid green'
}
}]
});
});
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<div id="container" style="height: 400px"></div>
What am I doing wrong?
You have to set useHTML to true for the tooltip. To easier hover on tooltip, increase hideDelay value and disable stickyTracking on series:
tooltip: {
useHTML: true,
hideDelay: 5000
}
Live demo: http://jsfiddle.net/BlackLabel/ncrgwvzu/
API:
https://api.highcharts.com/highstock/series.line.stickyTracking
https://api.highcharts.com/highstock/tooltip.useHTML

omit top border of highcharts chart

I have a columns chart and I need to draw the left, right and bottom lines of the chart (x/y axes) but need to either omit the top line
or ...
draw a white line to cover the top line. Viewing the raw data in Chrome, I can see the box is drawn using <rect>.
Is it possible to use JS to locate that and get the x,y,width attributes to draw a white line or remove it and replace with 3 black lines
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Annual Performance</title>
<!-- this code to include Highcharts with jQuery-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<!-- <script src="/js/jquery.min.js"></script> -->
<!--this code is the required highcharts javascript file -->
<script src="http://code.highcharts.com/highcharts.js"></script>
<!-- <script src="/js/highcharts.js"></script> -->
<script src="http://code.highcharts.com/highcharts-3d.js"></script>
<script>
$(function () {
// Set up the chart
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column',
margin: 50,
plotBorderWidth: 3,
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
format: '{y:.2f} %'
}
}
},
legend: {enabled: false},
yAxis: {
title: {text: null},
max: 4,
allowDecimals: false,
labels: {
enabled: true,
formatter: function() {
return this.value + ' %';
}
}
},
title: {
text: 'Annual Performance'
},
subtitle: {
text: 'XXX Shares'
},
series: [{
data: [
[2008, 2.17],
[2009, 0.15],
[2010, 0.00],
[2011, 0.00],
[2012, 0.01],
[2013, 0.01],
[2014, 0.01],
[2015, 0.00],
[2016, 0.00],
[2017, 0.38]
],
}]
});
});
</script>
</head>
<body>
<div id="container" style="width:100%; height:400px;"></div>
</body>
</html>
You can create additional yAxis and use lineWidth and offset properties to acheve needed result:
xAxis: {
lineWidth: 3
},
yAxis: [{
lineWidth: 3,
offset: -2,
title: {
text: null
},
max: 4,
allowDecimals: false,
labels: {
enabled: true,
formatter: function() {
return this.value + ' %';
}
}
}, {
opposite: true,
title: {
text: ''
},
offset: -2,
lineWidth: 3,
}],
Live demo: http://jsfiddle.net/BlackLabel/cj497k6s/
API Reference: https://api.highcharts.com/highcharts/xAxis.lineWidth

How get data name in Highcharts pie chart legend instead of "Slice" using array of values?

I am creating a pie chart in Highcharts with a legend. When I specify the series as an array of values (my preferred method), the legend displays the string "Slice" for each value. If I instead specify the series as a list of objects with named values, I correctly see the data names. Can I see the data names if I specify the series as an array of values?
Here is the code that doesn't work but that I would like to use:
<html>
<head>
<title>HighCharts pie</title>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script>
Highcharts.setOptions({
lang: {
decimalPoint: '.',
thousandsSep: ','
}
});
$(function () {
$('#container').highcharts({
chart: {
type: 'pie',
height: '500',
width: '750',
borderColor: '#EBBA95',
borderWidth: 2
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
showInLegend: true,
dataLabels: {
enabled: true,
format: '{point.y:,.0f}'
}
}
},
title: {
text: 'Rental Amounts for Paramount Directors'
},
legend: {
enabled: true
},
xAxis: {
categories: ["BADHAM, J", "COPPOLA, F", "GUILERMAN, J", "HILLER, A",
"SPIELBERG, S"],
},
series: [{
name: 'Directors',
data: [74100000, 30673000, 36915000, 50000000, 90434000],
}]
});
});
</script>
</head>
<body>
<div id="container" style="width:600px; height:400px;"></div>
</body>
</html>
Here is the code that does work when I specify the series as a list of objects with named values:
<html>
<head>
<title>HighCharts pie</title>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script>
Highcharts.setOptions({
lang: {
decimalPoint: '.',
thousandsSep: ','
}
});
$(function () {
$('#container').highcharts({
chart: {
type: 'pie',
height: '500',
width: '750',
borderColor: '#EBBA95',
borderWidth: 2
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
showInLegend: true,
dataLabels: {
enabled: true,
format: '{point.y:,.0f}'
}
}
},
title: {
text: 'Rental Amounts for Paramount Directors'
},
legend: {
enabled: true
},
series: [{
name: "Directors",
slicedOffset: 20,
data: [{
name: "BADHAM, J",
y: 74100000
}, {
name: "COPPOLA, F",
y: 30673000
}, {
name: "GUILERMAN, J",
y: 36915000
}, {
name: "HILLER, A",
y: 50000000
}, {
name: "SPIELBERG, S",
y: 90434000
}]
}]
});
});
</script>
</head>
<body>
<div id="container" style="width:600px; height:400px;"></div>
</body>
</html>
You can do this with tooltip.formatter and legend.labelFormatter and accessing the highchart options.
For the tooltip text:
tooltip: {
formatter: function() {
var sliceIndex = this.point.index;
var sliceName = this.series.chart.axes[0].categories[sliceIndex];
return 'The value for <b>' + sliceName +
'</b> is <b>' + this.y + '</b>';
}
},
And for the legend:
legend: {
enabled: true,
labelFormatter: function() {
var legendIndex = this.index;
var legendName = this.series.chart.axes[0].categories[legendIndex];
return legendName;
}
},
Live demo.
as of 5 years later, do this:
legend: {
enabled: true,
labelFormatter: function() {
let legendName = this.series.chart.axes[0].categories[this.x];
return legendName;}}

Resources