Don't show data label if not enough room - highcharts

I am trying to create a stacked bar chart using Highcharts.
I also want to display data labels in the bars, but I only want to display the labels if the bars are long enough to contain them. If the text is longer than the bar, I want to hide the text
Here is an example of the chart I am trying to build:
Highcharts.chart('container', {
chart: {
type: 'bar'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
plotOptions: {
series: {
stacking: 'normal',
dataLabels: {
enabled: true,
formatter: function(){
return 'text for value '+this.point.y;
}
}
}
},
series: [{
data: [1,2,3,4,5,6,7,8,9,10,11,12]
},{
data: [12,11,10,9,8,7,6,5,4,3,2,1]
}]
});
And here is the jsfiddle link: http://jsfiddle.net/xyszd7p4/
How can I hide the data points if they are too long? In my example, I want to hide the "text for value 1" data label because it does not fit inside the bar.

This answer shows one way of hiding labels that are too long: https://stackoverflow.com/a/49750334. That does not work directly for a bar chart (or for multiple series). But by editing it a little, like this:
chart: {
events: {
load: function() {
this.series.forEach(function(series) {
var points = series.points
points.forEach(function(point) {
console.log(point);
if (point.shapeArgs.height < point.dataLabel.width) { //using shapeArgs.height since this is a bar chart (would be width otherwise)
point.dataLabel.hide();
}
});
});
}
},
type: 'bar'
},
You can acheive what you are after.
Working JSFiddle example: http://jsfiddle.net/ewolden/87c2t4uy/

Related

Vuejs Data Update

I am trying to update highcharts data from a vuex-store, but the issue is that when the click event is triggered, the data in the vuex store state is mutated, but it only reflects in my highcharts component when i make some changes to the code and save the changes.
I am working on a dashboard using Vue and Highcharts.
<template>
<div>
<vue-highcharts :options="options" ref="lineCharts"></vue-highcharts>
<v-btn>{{parts}}</v-btn>
</div>
</template>
<script>
import VueHighcharts from 'vue2-highcharts';
import Vue from 'vue';
export default {
components: {
VueHighcharts,
},
data() {
return {
options: {
chart: {
type: 'spline',
title: 'Hassaan',
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
},
yAxis: {
title: {
text: '',
},
labels: {
formatter() {
return `${this.value}°`;
},
},
},
tooltip: {
crosshairs: true,
shared: true,
},
credits: {
enabled: false,
},
plotOptions: {
spline: {
marker: {
radius: 4,
lineColor: '#666666',
lineWidth: 1,
},
},
},
series: [],
},
};
},
created() {
Vue.set(this.options, 'series', this.$store.state.parts);
},
};
</script>
I want the data to be updated without making any changes to the code and saving it.
You should use a computed to get the value with reactivity from the store, that way you don't need the created hook anymore. Also you should never access values from your store directly through the state, instead create a getter.
I'm not sure what are you trying to do, however this should be the right structure. If you only want to set this.options.series = this.$store.getters.parts. Like you are already doing with the Vue.set(this.options, 'series', this.$store.state.parts), in that case, add a watcher for the computed property and set the new property value.
{
watch: {
parts (updatedParts) {
this.series.parts = updatedParts;
}
},
computed: {
parts () {
return this.$store.getters.parts;
}
}
}

Adding Default values to x Axis

I am creating a trend report in jasper studio using highcharts reports and I have ran into an issue on how to display default date range when there is no data.
Basically I need to show 6 data points on my x-axis(6 months) as default. This is fine except the data set I am using is dynamic(taken from a mysql query) so sometimes there will be data points for all 6 months but for others there may only be a data point for one month.
How can I get the report to show all 6 months on the x axis even when there are no associated data points?
So after the sql returns my results it would look something like this:
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container'
},
xAxis: {
categories: ['Jan']
},
yAxis: {
max: 200
},
series: [{
data: [29.9]
}]
});
So this will just display Jan on the x-axis but I need to display following 5 months also(no data points on the report, they are just labels).
You'll need to fill out the categories and set the xAxis max
$('#container').highcharts({
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
max: 5,
min: 0
},
series: [{
data: [29.9]
}]
});
http://jsfiddle.net/omw2enjf/

How to Make a Dashed Bar Chart Border in Highcharts

I have a stacked bar graph with two data attributes. I want to make the second bar looked grayed out with a dashed border. I've tried "dashStyle: 'longdash' but that and anything else i've tried doesn't work.
This is the look i'm going for:
In general it's not supported, but simple hack can enable this: http://jsfiddle.net/ztRF5/132/ (note: required is latest version from github).
// mapping between SVG attributes and the corresponding options
Highcharts.seriesTypes.bar.prototype.pointAttrToOptions.dashstyle = 'dashStyle';
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'bar'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
plotOptions: {
bar: {
stacking: 'percent'
}
},
series: [{
data: [29.9],
borderColor: 'black',
borderWidth: 2,
dashStyle: 'dash'
}, {
data: [13]
}]
});
Notice that in the latest version of HighCharts, Highcharts.seriesTypes.bar.prototype.pointAttrToOptions is no longer defined, thus the code will error out. You can simply comment out the first line (Highcharts.seriesTypes.bar.prototype.pointAttrToOptions.dashstyle = 'dashStyle';) and it will work. (http://jsfiddle.net/willieliao/6c48x39v/)
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'bar'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
plotOptions: {
bar: {
stacking: 'percent'
}
},
series: [{
data: [29.9],
borderColor: 'black',
borderWidth: 2,
dashStyle: 'dash'
}, {
data: [13]
}]
});

want to render an array (not hard coded) on a line chart

I want to render a histogram/line chart using HighCharts.
I don't want to hard code the array which is used by series.
My data that I wish to render is in the object display, which looks like:
0: o, 107983,
1: 1, 347923,
2: 2, 182329,
.
.
.
My code is here:
function RenderChart(display) {
myDisplay = display;
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line'
},
title: {
text: 'Metric histogram'
},
xAxis: {
//categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
minPadding: 0.05,
maxPadding: 0.05
},
plotOptions: {
line: {
animation: false
},
column: {
groupPadding: 0,
pointPadding: 0,
borderWidth: 0
}
},
series: [{
data: [myDisplay]
}]
});
};
This doesn't render the line chart. It renders an empty chart.
run a routine such that the response you get is processed as accepted by the highchart. then you can assign the resultant to the data directly.
try this, it will work

Highcharts: Click to update column color --- need a mouseover?

I tried to plot a chart with column type with one series. The data can be both positive and negative. I tried to update the color of points that are larger than 0 (or less than 0) with one click. With the following example:
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function() {
for (var i = 0; i < this.series.data.length; i++) {
if (this.y < 0) {
if (this.series.data[i].y < 0)
this.series.data[i].update({ color: '#ECB631' }, false, false);
}else {
if (this.series.data[i].y > 0)
this.series.data[i].update({ color: '#ECB631' }, false, false);
}
}
}
}
}
}
},
series: [{
data: [29.9, -71.5, 106.4, -129.2, 144.0, 176.0, -135.6, 148.5, -216.4, 194.1, 95.6, 54.4],
negativeColor: '#FF0000'
}]
});
Here is the link. http://jsfiddle.net/CkkbF/57/
I found that something interesting and weird:
If the point data is positive, the clicked column color will be changed, but other columns with positive data have slightly different color (seem highlighted.)
If the point data is negative, the clicked column color will stay the same (red in my example) until you mouse out of it. The other columns with negative data stays the same unless you try to mouse in/out of them.
Possibly a bug? How can I update them correctly?
I think you want to update series color, or series negativeColor, take a look: http://jsfiddle.net/CkkbF/60/
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function () {
if (this.y > 0) {
this.series.update({
color: "#ECB631"
});
} else {
this.series.update({
negativeColor: "#ECB631"
});
}
}
}
}
}
},

Resources