Howto move dataLabels to the border of the plot area? - javascript

I have a bar chart. I want the dataLabels to not stick onto the bars, but move it to the most right border of the plot area and have it text-aligned right.
This is what I have come to so far: (jsfiddle)
$(function () {
var cat = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug']; //, 'Sep', 'Oct', 'Nov', 'Dec', 'foo', 'bar', 'bla'];
var barWidth = 16;
chart = new Highcharts.Chart({
chart: {
type: "bar",
renderTo: 'container',
events: {
load: function() {
var plotHeight = this.plotHeight;
console.log('plotHeight = ' + plotHeight);
var catWidth = (barWidth-2) / (2*plotHeight/cat.length);
var plot = [];
for(var i=0; i<(cat.length); i+=1) {
var newPlot = {
color: 'grey',
width: 1,
value: i+catWidth //+(cat.length/($('#container').height()/10))
};
plot.push(newPlot);
this.xAxis[0].addPlotLine(newPlot);
}
//this.xAxis[0].addPlotLine(plot);
}
}
},
title: {
text: null
},
credits: {
text: null,
enabled: false
},
xAxis: {
categories: cat,
title: {
text: null,
enabled: false
}
},
yAxis: {
title: {
text: null,
enabled: false
},
labels: {
enabled: false
},
gridLineWidth: 0,
gridLineColor: 'none'
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
color: '#000',
formatter: function() {
return Math.abs(this.y).toFixed(1) + '%';
},
crop: false, // DIRTY!!! :(
overflow: 'justify', // DIRTY!!! :(
x: -360 // DIRTY!!! :(
}
}
},
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, 9.9, 9.9, 9.9],
pointWidth: barWidth
}]
});
});
I have to stick at mostly native Highcharts as I need to export the chart as svg to reuse in a pdf file. So using CSS and useHtml: true are out of question as well as dirty hacks like crop: false, overflow: 'justify', dataLabels.x: -360 (just to show you what I want to do - although it is not right aligned).
How am I able to accomplish that?

You can use workaround with the translating datalables like here:
var width = chart.plotWidth;
$.each(chart.series[0].data, function(i,d){
var bbox = d.dataLabel.getBBox().width;
d.dataLabel.attr({
x: width - bbox
});
});
http://jsfiddle.net/9YyVJ/2/

Related

How to set border in column chart - Highchart

Can anyone help how to set border in column chart, On click each bar to set a different border and color.
Please use this Reference Code:
plotOptions: {
series: {
allowPointSelect: true,
states: {
select: {
color: null,
borderWidth:5,
borderColor:'Blue'
}
}
}
},
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]
}]
});
Updating my previous Post.
Here I am using Highcharts default colors by index e.point.index value to set borders color of column and border width is also set by index e.point.index value by click on each column. You can also use custom array of border width and color and access this by e.point.index.
plotOptions: {
series: {
events: {
click: function(e) {
var chart = e.point.series.chart;
e.point.select(true, true);
chart.series[0].data[e.point.index].graphic.attr({
'stroke': colors[e.point.index],
'stroke-width': width[e.point.index],
'fill':Highcharts.defaultOptions.colors[e.point.index],
});
}
},
}
},
var colors= ['#4572A7', '#AA4643', '#89A54E', '#80699B', '#3D96AE',
'#DB843D', '#92A8CD', '#A47D7C', '#B5CA92'];
var width=[2,5,6,8,9,3,4] ;
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Stacked bar chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
}
},
legend: {
reversed: true
},
plotOptions: {
series: {
events: {
click: function(e) {
var chart = e.point.series.chart;
e.point.select(true, true);
chart.series[0].data[e.point.index].graphic.attr({
'stroke': colors[e.point.index],
'stroke-width': width[e.point.index],
'fill':Highcharts.defaultOptions.colors[e.point.index],
});
}
},
/*allowPointSelect: true,
states: {
select: {
borderWidth: 4,
borderColor: '#e4b0b2'
}
}*/
}
},
series: [{
name: 'John',
data: [3, 4, 4, 2, 5],
showInLegend: false,
name: 'Twitter Trending',
colorByPoint: true,
}]
});
<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>
You can use plotOptions.series.point.events.click callback function to update any of the point's properties (color, border etc.).
plotOptions: {
series: {
point: {
events: {
click: function() {
this.update({
color: Highcharts.defaultOptions.colors[Math.round(Math.random() * 10)]
});
}
}
}
}
}
Live demo: http://jsfiddle.net/kkulig/dtdw81L7/

How to show bar of graph in different colour when it reaches threshold level in high charts in JS?

how to display a bar of graph in different color when it reaches level 100. it should show in different color (red). how to change my code to show a bar in red color in High Charts. All normal level bars should be in one color and threshold reached levels in red color.
JS fiddle code
http://jsfiddle.net/h5t4c8hj/
code
var chart = Highcharts.chart('container', {
title: {
text: 'Chart.update'
},
subtitle: {
text: 'Plain'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
type: 'column',
colorByPoint: false,
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],
showInLegend: false
}]
});
$('#plain').click(function () {
chart.update({
chart: {
inverted: false,
polar: false
},
subtitle: {
text: 'Plain'
}
});
});
$('#inverted').click(function () {
chart.update({
chart: {
inverted: true,
polar: false
},
subtitle: {
text: 'Inverted'
}
});
});
$('#polar').click(function () {
chart.update({
chart: {
inverted: false,
polar: true
},
subtitle: {
text: 'Polar'
}
});
});
var chart = Highcharts.chart('container', {
title: {
text: 'Chart.update'
},
subtitle: {
text: 'Plain'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
type: 'column',
colorByPoint: false,
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],
showInLegend: false
}]
}, function(chart) {
$.each(chart.series[0].data, function(i, data) {
if (data.y >= 100)
data.update({
color: 'red'
});
})
});
$('#plain').click(function() {
chart.update({
chart: {
inverted: false,
polar: false
},
subtitle: {
text: 'Plain'
}
});
});
$('#inverted').click(function() {
chart.update({
chart: {
inverted: true,
polar: false
},
subtitle: {
text: 'Inverted'
}
});
});
$('#polar').click(function() {
chart.update({
chart: {
inverted: false,
polar: true
},
subtitle: {
text: 'Polar'
}
});
});
#container {
min-width: 320px;
max-width: 600px;
margin: 0 auto;
}
<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/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container"></div>
<button id="plain">Plain</button>
<button id="inverted">Inverted</button>
<button id="polar">Polar</button>
You can use data.update
I have found the following code on another SO thread:
let max = 100;
$.each(chart.series[0].data, function(i,data){
if(data.y > max)
data.graphic.attr({
fill:'red'
});
});
But it's not fully working when changing graph type. I'll get back to you when I have more information.
The easiest way would be to use zones.
API Reference:
http://api.highcharts.com/highcharts/plotOptions.area.zones
Example
http://jsfiddle.net/3o2845bw/

HighCharts column unknown number of series

I'm trying to populate a HighCharts dataset with results from SQL Server in Classic ASP.
When the number of series is known everything work OK but I can't get it work correctly for unknown number of series.
Here is my code for 4 series - 1 line and 3 columns.
<script type="text/javascript">
$(function () {
var DivName1 = '<%= DivName(1)%>'
var DivName2 = '<%= DivName(2)%>'
var DivName3 = '<%= DivName(3)%>'
var DivName4 = '<%= DivName(4)%>'
var DivN1 = parseInt('<%= DivN(1)%>')
var DivN2 = parseInt('<%= DivN(2)%>')
var DivN3 = parseInt('<%= DivN(3)%>')
var DivN4 = parseInt('<%= DivN(4)%>')
var DivTotal1 = parseFloat('<%= DivTotal(1)%>')
var DivTotal2 = parseFloat('<%= DivTotal(2)%>')
var DivTotal3 = parseFloat('<%= DivTotal(3)%>')
var DivTotal4 = parseFloat('<%= DivTotal(4)%>')
$('#DivCompTotalA').highcharts({
chart: {
type: 'column'
},
title: {
text: ''
},
credits: {
enabled: false
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
itemWidth: 180,
useHTML: true,
x: 0,
y: 40,
borderWidth: 0
},
xAxis: {
categories: ['']
},
yAxis: {
max: 7.01,
labels: {
enabled: false
},
gridLineColor: 'transparent',
plotLines: [{
value: DivTotal1,
color: '#333333',
width: 2,
label: {
text: 'Org.=' + DivTotal1 + '<br>N=' + DivN1,
align: 'right',
y: -5,
x: 0,
style: {
fontSize: '13px'
}
},
zIndex: 2
}],
title: {
text: ''
}
},
plotOptions: {
column: {
pointPadding: 0.2,
groupPadding: 0.10,
borderWidth: 0
},
series: {
dataLabels: {
enabled: true,
y: 5,
style: {
fontSize: '14px'
}
},
enableMouseTracking: false,
events: {
legendItemClick: function () {
return false;
}
}
}
},
series: [{
name: DivName2 + ' [' + DivN2 + ']',
color: '#c9e7ff',
data: [DivTotal2]
}, {
name: DivName3 + ' [' + DivN3 + ']',
color: '#4898a4',
data: [DivTotal3]
}, {
name: DivName4 + ' [' + DivN4 + ']',
color: '#ffd949',
data: [DivTotal4]
}]
});
});
My first question is How to replace these lines:
var DivName1 = '<%= DivName(1)%>'
var DivName2 = '<%= DivName(2)%>'
var DivName3 = '<%= DivName(3)%>'
var DivName4 = '<%= DivName(4)%>'
with a loop I tried this loop but with no success
var N = '<%=N %>'
var DivName = []
for (var i = 0; i <= N; i++) {
DivName[i] = '<%= DivName(i)%>';
}
How to write the "i" inside the '<%= DivName(i)%>' so it will be a variant
Try something like this:
Set series to nothing:
series: []
Fill it by script (where seriesData is array of prepared data. For format check documentation
$.each(Div, function(i){
var chart = $('#container').highcharts();
if (chart.series.length === 1) {
chart.addSeries({
name: Div[i].Name + i + ' [' + Div[i].N + ']',
color: '#c9e7ff',
data: Div[i].Total
});
}
});
Here an example how to add 1 series. You can add as many as you like with each loop.
$(function () {
$('#container').highcharts({
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
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]
}]
});
// the button handler
$('#button').click(function () {
var chart = $('#container').highcharts();
if (chart.series.length === 1) {
chart.addSeries({
data: [194.1, 95.6, 54.4, 29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4]
});
}
});
});

Highcharts disable click on column

I have a column chart. When clicking one of the vertical bars, the color of the selected bar changes. I want to disable this behaviour by disabling the detection of the 'click' event on the graph so when the user clicks there nothing happens.
Anyone knows how to do that?
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column',
backgroundColor: 'transparent',
container: {
onclick : null
}
},
colors: ['#27A1DE'],
title: {
text: null
},
credits : {
enabled: false
},
exporting : {
enabled: false
},
legend: {
enabled: false
},
xAxis: {
title: {
text: 'h',
align: 'high',
offset: -15
},
tickColor : 'transparent',
labels: {
style: {
fontWeight:'bold'
},
y: 12,
formatter: function() {
var index = this.axis.categories.indexOf(this.value);
var yValue = this.chart.series[0].yData[index];
if (yValue === 0){
return '<span>'+this.value+'</span>';
} else {
return '<span style="color:#009DE0;">'+this.value +'</span>';
}
}
},
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: {
min: 0,
labels: {
enabled: false
},
gridLineWidth: 0,
lineWidth: 1,
title: {
align: 'high',
rotation: 0,
text: 'kWh',
offset: 0,
y: -2
}
},
plotOptions: {
column: {
pointPadding: 0.05,
groupPadding: 0,
dataLabels : {
enabled: true,
crop :false,
overflow: 'none',
rotation: 270,
x:2,
y:-14,
style: {
color: '#009DE0',
fontSize: 'xx-small',
},
formatter: function() {
if (this.y != 0){
return '<span>'+this.y +'</span>';
} else {
return '<span style="display:none;">'+this.y +'</span>';
}
}
},
borderWidth: 0,
events: {
click: function(e){
//this.update({ color: '#27a1de' }, true, false);
e.preventDefault();
return false;
}
}
},
series: {
cursor: 'pointer',
point: {
events: {
click: function() {
}
}
}
}
},
series: [{
name: '',
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]
}],
tooltip: {
enabled: false
}
});
Fiddle : here
Thanks
the way I understood your problem, you want to remove the style change on mouse hover (as there is no color change on click in your fiddle unlike you described).
http://jsfiddle.net/6pur4o1w/
states: { hover: 'none' }
in the series should do what you want.

dynamically creating the values for high charts

I want to create dynamic data for high charts,
i need to generate dynamic values in the x-axis
xAxis: {
categories:['project1','project2']
},
This is my for loop,
var project = [];
for(var i=0;i<project.name;i++){
//new array
}
How do i create dynamic values in the x-axis.
You can pass an array variabile as parameter to the categories option of the chart.
Example:
// Original array
var categories1=['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
// Copy and/or modifify the second array content and do some stuff
var categories2=[];
for(var i=0;i<categories1.length;i++){
categories2.push(categories1[i]);
}
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container'
},
xAxis: {
categories: categories2 // reference categories to an array variabile
},
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]
}]
});
Working fiddle: http://jsfiddle.net/IrvinDominin/6c8Af/
Another approach:
var Series2 = [1,1,1,2,2,2];
var names=['O','A'];
var data1=Series2,seriesArray; //seriesArray is formed dynamically - array of int values
options.series = [{name: names, data: data1}]
This works properly
I'm using a JSON data and after a long time able to resolve it. My requirement was to get JSON data and then I create a Map Object based on my data requirement. And dynamically create series for chart. I was able to create Series but nothing was coming in chart.
This was because the numeric digits has to be converted to Int . When I used parseInt, it worked for me.
Step 1: I get the JSON data and after manipulation it looks like this: seriesData = {"O":series1}, {"A":Series2}, {"S":Series3}]
var options = {
chart: {
renderTo: 'demoGraph',
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: [1, 2, 3, 4, 5,6],
title: {
text: 'Severity'
},
},
yAxis: {
min: 0,
title: {
text: 'Total Defects with Severity - 1,2,3,4,5,6'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
legend: {
align: 'right',
x: -70,
verticalAlign: 'top',
y: 20,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
formatter: function () {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px black, 0 0 3px black'
}
}
}
},
series: [{},{},{},{},{},{}],
};
for(var i in seriesData ){
for(var j in seriesData [i]){
options.series[i].name = j;
options.series[i].data = seriesData [i][j];
break;
}
}
var chart = new Highcharts.Chart(options);

Categories