I am making bar charts using Highcharts and Google spreadsheets. I want to place the datalabels inside the bars, but sometimes the value is so small that the label won't fit nicely inside the bar, so in these cases, I want to place them outside of the bar. I know this can be done, as shown here: https://jsfiddle.net/o3cujptj/
But when I try to use this method with my chart, that uses Google sheets to get its data, it doesn't work, as chart.series[0].data returns empty. How can I make this work?
My js fiddle : https://jsfiddle.net/jmunger/sLk8nmo6/2/
const chart = Highcharts.chart('container', {
plotOptions: {
bar: {
dataLabels: {
x: -5,
align: 'right',
style: {
textOutline: 0
},
shadow: false,
borderWidth: 0,
inside: true,
enabled: true,
pointFormatter: function() {
return Highcharts.numberFormat(this.point.y, 0);
},
//format: 'n = {point.label}'
}
}
},
chart: {
events: {
load: function() {
const chart = this,
points = chart.series[0].data,
options = {
dataLabels: {
inside: false,
style: {
color: 'black'
}
}
};
points.forEach(function(point) {
if (point.shapeArgs.height < 30) {
point.update(options, false);
}
});
chart.redraw();
}
}
},
data: {
googleSpreadsheetKey: '1D0v11GK07TJu6fXcwbcofiPOo4FmRpATGBAaSBqNlZE',
googleSpreadsheetWorksheet: 3,
endColumn: 3,
seriesMapping: [{
color: 2,
label: 3 // Labels are pulled from column 2 and picked up in the dataLabels.format below
}],
complete: function (options) {
//?? anything to do here?
}
},
series: [{
dataLabels: {
inside: true,
enabled: true,
style: {
color: 'white'
}
},
type: 'bar'
}]
});
Option 2: Or upload your JavaScript file
Indentation level:
Brace style:
BEAUTIFY JAVASCRIPT BEAUTIFY JAVASCRIPT IN NEW WINDOW
Beautified JavaScript:
const chart = Highcharts.chart('container', {
plotOptions: {
bar: {
dataLabels: {
x: -5,
align: 'right',
style: {
textOutline: 0
},
shadow: false,
borderWidth: 0,
inside: true,
enabled: true,
pointFormatter: function () {
return Highcharts.numberFormat(this.point.y, 0);
},
//format: 'n = {point.label}'
}
}
},
chart: {
events: {
load: function () {
const chart = this,
points = chart.series[0].data,
options = {
dataLabels: {
inside: false,
style: {
color: 'black'
}
}
};
points.forEach(function (point) {
if (point.shapeArgs.height < 30) {
point.update(options, false);
}
});
chart.redraw();
}
}
},
data: {
googleSpreadsheetKey: '1D0v11GK07TJu6fXcwbcofiPOo4FmRpATGBAaSBqNlZE',
googleSpreadsheetWorksheet: 3,
endColumn: 3,
seriesMapping: [{
color: 2,
label: 3 // Labels are pulled from column 2 and picked up in the dataLabels.format below
}],
complete: function (options) {
//?? anything to do here?
}
},
series: [{
dataLabels: {
inside: true,
enabled: true,
style: {
color: 'white'
}
},
type: 'bar'
}]
});
The load event is fired when the chart is finished loading - not data.
You can use redraw or render event, which are called after data is loaded.
let allowChartUpdate = true;
const chart = Highcharts.chart('container', {
chart: {
events: {
render: function() {
const chart = this,
points = chart.series[0].points,
options = {...};
if (points.length && allowChartUpdate) {
allowChartUpdate = false;
points.forEach(function(point) {
if (point.shapeArgs.height < 30) {
point.update(options, false);
}
});
chart.redraw();
}
}
}
},
...
});
Live demo: https://jsfiddle.net/BlackLabel/tn98gwmj/
API Reference: https://api.highcharts.com/highcharts/chart.events.render
Related
I've created a donut chart using vue-highcharts/highcharts, and am trying to append text on mouseover to the center of the donut. I've got it appending static text, however I'm trying to return the data from the point I hover over, to display that in the center, however I can't seem to find any relevant data from within the event object. Does anyone know how I might be able to access that data?
chartOptions: {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
legend: {
align: 'right',
enabled: true,
layout: 'vertical',
verticalAlign: 'middle'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
center: ['50%', '50%'],
showInLegend: true,
events: {
mouseOver: (e) => {
const { chart } = this.$refs.highchartsRef;
const height = chart.chartHeight / 2;
const width = e.target.center[3];
console.log({ chart });
console.log({ e });
chart.renderer
.text('Top Test</br>Bottom Test', width, height, true)
.css({
color: '#4a4a4a',
fontSize: '16px',
fontWeight: 700
})
.addClass('highcharts-center-label text-center')
.add();
},
mouseOut: () => {
document.querySelector('.highcharts-center-label').remove();
}
}
}
},
series: [{
name: 'Categories',
colorByPoint: true,
size: '100%',
innerSize: '60%',
data: this.categories.map(category => {
return {
name: category.name,
y: calculateCategoryWeight(category)
};
})
}],
title: null,
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
}
}
Use point.events and a basic function instead of the arrow one.
plotOptions: {
pie: {
point: {
events: {
mouseOver: function() {
var point = this,
series = point.series,
chart = series.chart;
console.log(point.y);
}
}
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/7oub1xzj/
API Reference: https://api.highcharts.com/highcharts/plotOptions.pie.point.events
Add Plugin 'angular2-highcharts'
add code for highmaps
ERROR
Please use this code
ionViewDidLoad() {
var chart = Highcharts.mapChart('container', {
chart: {
map: 'custom/europe',
spacingBottom: 20
},
title: {
text: 'Europe time zones'
},
legend: {
enabled: true
},
plotOptions: {
map: {
allAreas: false,
dataLabels: {
enabled: true,
color: '#FFFFFF',
style: {
fontWeight: 'bold'
},
// Only show dataLabels for areas with high label rank
format: null,
formatter: function () {
if (this.point.properties && this.point.properties.labelrank.toString() < 5) {
return this.point.properties['iso-a2'];
}
}
},
tooltip: {
headerFormat: '',
pointFormat: '{point.name}: <b>{series.name}</b>'
}
}
},
})
}
I want to show tree map with different on different levels by using property 'colorByPoint' true.
Highcharts.chart('container', {
chart: {
marginTop: 50,
events: {
load: function() {
this.bread = {
'': makeNode('', this.series[0].name, this.series[0])
}
}
}
},
series: [{
type: 'treemap',
layoutAlgorithm: 'squarified',
allowDrillToNode: true,
animationLimit: 1000,
dataLabels: {
enabled: false
},
levelIsConstant: false,
levels: [{
level: 1,
dataLabels: {
enabled: true,
align:'left',
verticalAlign:'Top'
},
borderWidth: 1
},
{
level: 2,
colorByPoint: true,
dataLabels: {
enabled: true,
},
borderWidth: 1
}
],
data: points
}],
credits:false,
plotOptions: {
series: {
dataLabels: {
color: '#fff',
textOutline:0,
style: {
fontWeight: 'bold'
}
},
point: {
events: {
click: function(e) {
const hasChildren = !!this.node.childrenTotal
if (hasChildren) {
const bread = this.series.chart.bread
bread[this.id] = makeNode(this.id, this.name, this.series, bread[this.node.parent])
}
}
}
}
}
},
title: {
text: ''
}
});
Here is my js fiddle. https://jsfiddle.net/irfanbsse/8djawts9/
But I dont want show second level color on first level.Same for second level and so on. how i can do it ? Thanks
Here's a demo that shows how to change color of child nodes on point.click.event:
click: function() {
var points = this.series.points;
this.node.children.forEach(function(child, i) {
var point = points.find(function(point_) {
return child.id === point_.id
});
point.update({
color: color[i % (color.length - 1)]
});
});
Live demo: https://jsfiddle.net/BlackLabel/sgkah0fq/
The next thing to implement is reverting the original colors while clicking on the previous level in navigation (label with callout shape).
I was able change bubble color with following options.
plotOptions: {
mapbubble: {
marker: {
fillOpacity: 0.5,
fillColor: "#222",
lineColor: '#fff',
states: {
select: {
fillColor: "#5fdef9",
lineColor: '#135c78'
}
}
}
}
}
But how do I change text color of the bubble on select?
dataLabels are not changing when state of a point is changed. It is possible to extend Highcharts to update each point's dataLabels options (e.g. color) after state is changed to or from selected state. To avoid unnecessary redraws - single redraw can be called after series is clicked.
JSFiddle: http://jsfiddle.net/bfusb63m/
$(function () {
(function (H) {
H.wrap(H.Point.prototype, 'setState', function (proceed) {
var stateBefore = this.state;
// Run original proceed method
proceed.apply(this, [].slice.call(arguments, 1));
if (stateBefore !== 'select' && this.state === 'select') {
this.update({
dataLabels: {
color: 'red'
}
}, false);
} else if (stateBefore === 'select' && this.state !== 'select') {
this.update({
dataLabels: {
color: null
}
}, false);
}
});
}(Highcharts));
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=world-population.json&callback=?', function (data) {
var mapData = Highcharts.geojson(Highcharts.maps['custom/world']);
// Correct UK to GB in data
$.each(data, function () {
if (this.code === 'UK') {
this.code = 'GB';
}
});
$('#container').highcharts('Map', {
plotOptions: {
mapbubble: {
allowPointSelect: true,
dataLabels: {
enabled: true
},
marker: {
fillOpacity: 0.5,
fillColor: "#222",
lineColor: '#fff',
states: {
select: {
fillColor: "#5fdef9",
lineColor: '#135c78'
}
}
},
events: {
click: function () {
var chart = this.chart;
setTimeout(function () {
chart.redraw();
}, 0);
}
}
}
},
series: [{
name: 'Countries',
mapData: mapData,
color: '#E0E0E0',
enableMouseTracking: false
}, {
type: 'mapbubble',
mapData: mapData,
name: 'Population 2013',
joinBy: ['iso-a2', 'code'],
data: data,
minSize: 4,
maxSize: '12%',
tooltip: {
pointFormat: '{point.code}: {point.z} thousands'
}
}]
});
});
});
For some reason, the Chart's dataLabels are only displaying on bottom level of this drilldown. The dataLabels are set for 'column'. However, they don't display for every column rendered.
What do I need to change to get the dataLabels to display on all the levels of the drilldown?
Thanks.
See below for code and jsfiddle:
$('document').ready(function () {
var Drilldown = (function () {
var chart,
colors = Highcharts.getOptions().colors;
function setChart(name, categories, data, color, type) {
chart.xAxis[0].setCategories(categories);
for (var i = 0; i < chart.series.length; i++) {
chart.series[0].remove(true);
}
chart.addSeries({
name: name,
data: data,
color: color || 'white'
});
}
function buildDrillDown() {
var stores = ['92nd Gessner', 'Annco'],
dayparts = ['Breakfast','Lunch','Afternoon','Dinner','Late Night'],
categories = ['Gross Sales-06/18/2013','Qty Sold-06/18/2013','Gross Sales-06/19/2013','Qty Sold-06/19/2013'],
name = 'Gross Sales by Store Name',
moneyLabel = {
enabled: true,
color: '#89A54E',
style: {
fontWeight: 'bold'
},
formatter: function() {
return '$'+ Highcharts.numberFormat(this.y, 0);
}
},
data = [{
y: 9297.73,
color: colors[2],
drilldown: {
name: 'Gross Sales-06/18/2013',
dataLabels: moneyLabel,
categories: stores,
data: [{
y: 4567.05,
color: colors[0],
drilldown: {
name: "Gross Sales by Daypart",
categories: dayparts,
data: [310.71,1279.32,952.65,1059.91,964.46],
color: colors[0]
},
},
{
y: 4730.68,
color: colors[1],
drilldown: {
name: "Gross Sales by Daypart",
categories: dayparts,
data: [186.75,1629.05,881.34,1373.96,659.58],
color: colors[1]
},
}]
}
}];
chart = new Highcharts.Chart({
chart: {
renderTo: 'drilldown_display',
type: 'column'
},
title: {
text: 'Drillable Column Chart'
},
subtitle: {
text: 'Click the columns to view Stores. Click again to view Dayparts.'
},
xAxis: {
categories: categories
},
yAxis: { // Primary yAxis
labels: {
format: '${value}',
style: {
color: '#89A54E'
}
},
title: {
text: "Gross Sales",
style: {
color: '#89A54E'
}
}
},
plotOptions: {
column: {
dataLabels: {
enabled: true,
color: '#89A54E',
style: {
fontWeight: 'bold'
},
formatter: function() {
return '$' + this.y
}
},
cursor: 'pointer',
point: {
events: {
click: function() {
var drilldown = this.drilldown;
if (drilldown) { // drill down
setChart(drilldown.name, drilldown.categories, drilldown.data, drilldown.color);
} else { // restore
setChart(name, categories, data);
}
}
}
}
},
},
tooltip: {
formatter: function() {
var point = this.point,
s = this.x +':<b>Gross Sales: ' + this.y + '</b><br/>';
if (point.drilldown) {
s += 'Click to view '+ point.category;
} else {
s += 'Click to return to the beginning';
}
return s;
}
},
series: [{
name: name,
data: data,
color: 'white',
pointWidth: 75,
}],
exporting: {
buttons: {
customButton: {
text: 'Flat Chart',
onclick: function () {
$( "#chart_display" ).show();
$( "#drilldown_display").hide();
$("#pie_display").hide();
}
}
}
}
});
}
return {
buildDrillDown: buildDrillDown
};
})();
Drilldown.buildDrillDown();
});
http://jsfiddle.net/K9fQU/
Actually your code is kinda working. The data label behavior is inconsistent. When I play around your fiddle, the data label disappear for sure after I comment out enabled: true in dataLabels and run. However, if I added it back and run again, the data label shows up, hiding inside the plot area. Since you use the same color #89A54E for data label as the first level column, it's not quite obvious.
The reason that the data label hides inside the column is you didn't configure to handle the case when data label is overflow.
How to handle data labels that flow outside the plot area. The default is justify, which aligns them inside the plot area. For columns and bars, this means it will be moved inside the bar. To display data labels outside the plot area, set crop to false and overflow to "none". Defaults to justify.
So what you need to do is, set crop to false and overflow to "none":
plotOptions: {
column: {
dataLabels: {
overflow: 'none',
crop: false,
enabled: true,
color: '#89A54E',
style: {
fontWeight: 'bold'
},
formatter: function() {
return '$' + this.y
}
},
// other configuration
}