how to set labeloffset dynamically in chart Js - javascript

I am using Chart.js, I have to generate stack bar chart based on fromMonth to toMonth selection.
My bar chart option is:
{
"chartCanvasHeight": "200",
"chartOptions": {
"responsive": "true",
"tooltips": {
"mode": "nearest",
"callbacks": {
"label": null,
"title": {}
}
},
"legend": {
"position": "bottom",
"labels": {
"generateLabels": {}
}
},
"scales": {
"yAxes": [{
"ticks": {
"beginAtZero": "true",
"callback": {}
},
"scaleLabel": {
"display": true,
"labelString": ""
}
}],
"xAxes": [{
"id": "xAxis1",
"type": "category",
"ticks": {
"display": false
}
},
{
"id": "xAxis2",
"type": "linear",
"offset": true,
"ticks": {
"max": 12,
"beginAtZero": true,
"stepSize": 0.5,
"callback": {}
},
"gridLines": {
"offsetGridLines": true,
"color": "white",
"zeroLineColor": "white"
}
},
{
"id": "xAxis3",
"type": "linear",
"ticks": {
"beginAtZero": false,
"max": 12,
"stepSize": 1,
"callback": {}
},
"gridLines": {}
},
{
"id": "xAxis4",
"ticks": {
"display": false
},
"scaleLabel": {
"display": true,
"labelString": ""
},
"gridLines": {
"zeroLineColor": "white",
"color": "white",
"drawOnChartArea": false
}
}
]
},
"plugins": {
"datalabels": {
"align": "top",
"anchor": "end",
"textAlign": "center"
},
"afterDatasetsDraw": {}
}
},
"chartDataSets": [],
"chartLabels": [],
"chartType": "bar"
}
everything is coming but labels are not center aligned as months could be between Jan to Dec. how to center align both x-axis label or labeloffset dynamically.
drawOnChartArea is also not working.
Last stork is also not coming on months x-axis.

Related

Add and remove data simultaneously to ChartJS chart

For visualisation purposes I'm trying to add data to a chart and simultaneously remove the first data point from the chart every 500ms.
It works when I do either of .addData() or removeData() on their own, but when I try and combine them into one function to run at the same time, neither of them works.
Is there a way I can create this function to simultaneously add and remove data, or at a minimum remove the first data point shortly after I've added the new last data point?
Here's the data and setup:
var ctx = document.getElementById('myChart').getContext('2d');
ctx.height = 220;
var data = {
"labels": [
"0",
"1",
"2",
"3",
"4"
],
"datasets": [
{
"label": "2014",
"backgroundColor": "#0055FA",
"fill": true,
"data": [
"50",
"40",
"55",
"35",
"45",
"50",
"15",
"100"
],
"borderColor": "transparent",
"borderWidth": "0",
"pointBackgroundColor":"#ffffff"
}
]
};
var options = {
"title": {
"display": false,
"text": "Ad Revenue Comparison 2014-2015",
"position": "bottom",
"fullWidth": true,
"fontColor": "#aa7942",
"fontSize": 16
},
"legend": {
"display": false,
"fullWidth": true,
"position": "top"
},
"scales": {
"yAxes": [
{
"ticks": {
"beginAtZero": true,
"display": true
},
"gridLines": {
"display": false
},
"scaleLabel": {
"display": false,
"labelString": "USD in Millions"
},
"display": false
}
],
"xAxes": {
"0": {
"ticks": {
"display": false
},
"display": false,
"gridLines": {
"display": false
},
"scaleLabel": {
"display": false
}
}
}
},
"tooltips": {
"enabled": false
},
"elements": {
"arc": {
"backgroundColor": "#009BD0"
},
"line": {
"backgroundColor": "#009BD0",
"fill": true,
"borderColor": "#e2fdff"
},
"point": {
"radius": 3,
"pointStyle": "circle",
"backgroundColor": "#ffffff"
}
}
};
Here are the functions:
var myChart = new Chart(ctx, {
type: 'line',
data: data,
options: options
});
function removeData(chart) {
chart.data.labels.pop();
chart.data.datasets.forEach((dataset) => {
dataset.data.pop();
});
chart.update();
}
function addData(chart, label, data) {
chart.data.labels.push(label);
chart.data.datasets.forEach((dataset) => {
dataset.data.push(data);
});
chart.update();
}
setInterval(function(){
addData(myChart,"4",Math.floor(Math.random() * 60));
removeData(myChart);
}, 500);
//setInterval(function(){ removeData(myChart); }, 500);
</script>

Declaring minimal width of serie in treemap

I have treemap chart and it has two values Squadra2 with value of 13778.00 and Squadra1 with value of 16.00
Now when treemap renders it takes percentage difference between them and split them accordingly BUT now I ended up in situation where I need to be sniper precise in order to select Squadra1 with value of 16.00
As you can see in the picture
Is there a possibility to declare for example minimal width of Squadra1, and to disallow it to go under that value ( to remain clickable ) ?
Please let me know, thank you
{
"chart": {
renderTo:"container",
"backgroundColor": "#FFFFFF"
},
"colorAxis": {
"labels": {
"enabled": false
},
"tickLength": 0,
"gridLineWidth": 0,
"min": 0,
"max": 20,
"stops": [
[
-0.001,
"#ffffff"
],
[
0.5,
"#7cb5ec"
],
[
0.501,
"#7cb5ec"
],
[
0.499,
"#ffffff"
],
[
1,
"#434348"
],
[
1.001,
"#434348"
]
]
},
"legend": {
"enabled": true,
"itemStyle": {
"color": "#FFF"
}
},
"tooltip": {},
"series": [
{
"drillUpButton": {
"position": {
"align": "center",
"verticalAlign": "bottom"
},
"theme": {
"fill": "white",
"stroke-width": 1,
"stroke": "silver",
"r": 2,
"style": {
"fontSize": "12px"
},
"states": {
"hover": {}
}
}
},
"type": "treemap",
"layoutAlgorithm": "squarified",
"allowDrillToNode": true,
"dataLabels": {
"enabled": false
},
"levelIsConstant": false,
"levels": [
{
"level": 1,
"dataLabels": {
"enabled": true
},
"borderWidth": 6,
"borderColor": "#FFFFFF"
}
],
"data": [
{
"id": "id_0",
"name": "Squadra1",
"parentName": "Squadra1"
},
{
"id": "id_0_0",
"name": "ACC",
"parent": "id_0",
"parentName": "Squadra1",
"scale": 0,
"value": 1,
"colorValue": 1.8117836848479765
},
{
"id": "id_0_1",
"name": "FEB",
"parent": "id_0",
"parentName": "Squadra1",
"scale": 0,
"value": 0,
"colorValue": 5.48633338681632
},
{
"id": "id_0_2",
"name": "MAG",
"parent": "id_0",
"parentName": "Squadra1",
"scale": 0,
"value": 8,
"colorValue": 3.4398769612396007
},
{
"id": "id_0_3",
"name": "PAM",
"parent": "id_0",
"parentName": "Squadra1",
"scale": 0,
"value": 7,
"colorValue": 2.775814171372472
},
{
"id": "id_1",
"name": "Squadra2",
"parentName": "Squadra2"
},
{
"id": "id_1_0",
"name": "ACC",
"parent": "id_1",
"parentName": "Squadra2",
"scale": 10,
"value": 13778,
"colorValue": 13.595706940649173
}
],
"events": {},
"_colorIndex": 0
}
],
"subtitle": {
"text": "",
"align": "",
"style": {
"color": "",
"fontSize": "",
"fontFamily": "",
"fontStyle": "none",
"textDecoration": "none",
"fontWeight": "none"
}
},
"title": {
"text": "",
"align": "",
"style": {
"color": "",
"fontWeight": "none",
"fontSize": "",
"fontFamily": "",
"fontStyle": "none",
"textDecoration": "none"
}
},
"lang": {
"noData": ""
},
"noData": {
"style": {
"color": "",
"fontSize": "",
"fontFamily": "",
"fontStyle": "none",
"textDecoration": "none",
"fontWeight": "none"
},
"position": {
"align": "",
"verticalAlign": "middle"
}
},
"credits": {
"enabled": false
},
"plotOptions": {
"series": {
"turboThreshold": 5000,
"colorByPoint": false
}
}
}
Link of fiddle
http://jsfiddle.net/3k5fmrut/2/
The easiest way to achieve it is to set a smaller value for Squadra2 and add an additional property with real value to point object that can be used in tooltip.formatter callback to present the real value in the tooltip. Check demo and code posted below.
Code:
data:
{
"id": "id_1",
"name": "Squadra2",
"realValue": 13778,
"parentName": "Squadra2"
}, {
"id": "id_1_0",
"name": "ACC",
"parent": "id_1",
"parentName": "Squadra2",
"scale": 10,
"value": 137.78,
"colorValue": 13.595706940649173
}
tooltip.formatter:
tooltip: {
formatter: function() {
return this.point.realValue;
}
}
Demo:
https://jsfiddle.net/BlackLabel/trz96fy7/
You can define your own algorithm to build the treemap : Highcharts treemap series
You could choose an algorithm such that each element has a minimum width and height, and the biggest elements share the remaining space.

Calculating percentage value for each serie in highcharts

I am trying to calculate % values for each series, what I managed to find is function like
formatter:function() {
var pcnt = (this.y / dataSum) * 100;
return Highcharts.numberFormat(pcnt) + '%';
}
But what confuses me is how can I make dynamically this function so it can be applied on every serie object that is provided
Emphasize on dataSum from function above.
I tried googling just in case highcharts provide already some solution that they have in their documentation but sadly I did not find anything, only thing I found is to concatenate already provided value with + '%', and that is far beyond real value of percentage of that specific serie
$(function() {
var chart = new Highcharts.Chart(
{
"meta": {
"drilldownEnabled": false
},
"chart": {
renderTo:"container",
"additionalData": {
"dateTime": false,
"datetype": "string",
"cliccable": true,
"drillable": false,
"drillableChart": false,
"isCockpit": true,
"categoryColumn": "city",
"categoryGroupBy": "",
"categoryGroupByNamens": "",
"categoryName": "city",
"categoryOrderColumn": "",
"categoryOrderType": "",
"categoryStacked": "",
"categoryStackedType": ""
},
"zoomType": "xy",
"panning": true,
"type": "column",
"options3d": {
"enabled": false,
"alpha": 25,
"beta": 15,
"depth": 50,
"viewDistance": 25
},
"backgroundColor": "#FFFFFF",
"heightDimType": "pixels",
"widthDimType": "pixels",
"plotBackgroundColor": null,
"plotBorderWidth": null,
"plotShadow": false,
"borderColor": "#FFFFFF",
"style": {
"backgroundColor": "#FFFFFF",
"fontFamily": "",
"fontWeight": "",
"fontSize": ""
},
"events": {}
},
"colors": [
"#7cb5ec",
"#434348",
"#90ed7d",
"#f7a35c",
"#8085e9",
"#f15c80",
"#e4d354",
"#2b908f",
"#f45b5b",
"#91e8e1"
],
"title": {
"text": "",
"style": {
"align": "",
"color": "",
"fontFamily": "",
"fontSize": "",
"fontWeight": ""
}
},
"legend": {
"itemDistance": 0,
"symbolPadding": 25,
"enabled": false
},
"xAxis": [
{
"plotBands": [
{
"label": {
"text": "",
"align": "center"
},
"color": "",
"from": 0,
"to": 0
}
],
"plotLines": [
{
"label": {
"text": "",
"align": "center"
},
"color": "",
"dashStyle": "",
"value": 0,
"width": 0
}
],
"type": "category",
"id": 0,
"title": {
"customTitle": false,
"text": "city",
"style": {}
},
"labels": {
"style": {
"color": "",
"fontFamily": "",
"fontSize": "",
"fontWeight": ""
},
"align": ""
}
}
],
"yAxis": [
{
"plotBands": [
{
"label": {
"text": "",
"align": "center"
},
"color": "",
"from": 0,
"to": 0
}
],
"plotLines": [
{
"label": {
"text": "",
"align": "center"
},
"color": "",
"dashStyle": "",
"value": 0,
"width": 0,
"zIndex": 1
}
],
"title": {
"text": "",
"customTitle": false,
"style": {
"color": "",
"fontFamily": "",
"fontWeight": "",
"fontSize": ""
}
},
"labels": {
"style": {
"color": "",
"fontFamily": "",
"fontSize": "",
"fontWeight": ""
},
"align": ""
},
"gridLineDashStyle": "$convertedTypeline",
"minorGridLineDashStyle": "$convertedMinorTpeline"
}
],
"series": [
{
"name": "total_children",
"dataLabels": {
"style": {
"color": "",
"fontFamily": "",
"fontWeight": "",
"fontSize": "",
"fontStyle": ""
},
"enabled": true,
"labelFormat": "{y:,.2f}"
},
"data": [
{
"drilldown": false,
"y": 271,
"name": "Pomona",
"datetype": "string"
},
{
"drilldown": false,
"y": 237,
"name": "Port Hammond",
"datetype": "string"
},
{
"drilldown": false,
"y": 205,
"name": "Port Orchard",
"datetype": "string"
},
{
"drilldown": false,
"y": 239,
"name": "Portland",
"datetype": "string"
},
{
"drilldown": false,
"y": 265,
"name": "Puyallup",
"datetype": "string"
},
],
"selected": true,
"tooltip": {
"valueDecimals": 2,
"scaleFactor": "empty",
"ttBackColor": "#FCFFC5"
},
"yAxis": 0
},
{
"name": "num_cars_owned",
"dataLabels": {
"style": {
"color": "",
"fontFamily": "",
"fontWeight": "",
"fontSize": "",
"fontStyle": ""
},
"enabled": true,
"labelFormat": "{y:,.2f}"
},
"data": [
{
"drilldown": false,
"y": 228,
"name": "Acapulco",
"datetype": "string"
},
{
"drilldown": false,
"y": 189,
"name": "Albany",
"datetype": "string"
},
{
"drilldown": false,
"y": 212,
"name": "Altadena",
"datetype": "string"
},
{
"drilldown": false,
"y": 219,
"name": "Anacortes",
"datetype": "string"
},
{
"drilldown": false,
"y": 231,
"name": "Arcadia",
"datetype": "string"
},
],
"selected": true,
"tooltip": {
"valueDecimals": 2,
"scaleFactor": "empty",
"ttBackColor": "#FCFFC5"
},
"yAxis": 0
}
],
"tooltip": {
"borderWidth": 0,
"borderRadius": 0,
"followTouchMove": false,
"followPointer": true,
"useHTML": true,
"backgroundColor": null,
"style": {
"padding": 0
}
},
"lang": {
"noData": ""
},
"noData": {
"style": {
"fontFamily": "",
"fontSize": "",
"color": ""
},
"position": {
"align": "center",
"verticalAlign": "middle"
}
},
"credits": {
"enabled": false
},
"plotOptions": {
"line": {
"marker": {
"symbol": "circle",
"lineWidth": 2
}
},
"series": {
"events": {},
"showCheckbox": true,
"cursor": "pointer",
"point": {
"events": {}
},
"dataLabels": {
"allowOverlap": true
},
"turboThreshold": 2000
}
}
}
);
});
Has anyone ever step onto solution that provides % values of series by any case ?
I am trying to calculate % of total_children, and % of num_cars_owned serie as they are separated objects of serie array.
You can find code example on link HERE http://jsfiddle.net/JeLrb/538/
You need to calculate dataSum value:
tooltip: {
...,
formatter: function() {
var dataSum = 0,
pcnt;
this.series.points.forEach(function(point) {
dataSum += point.y;
});
pcnt = (this.y / dataSum) * 100;
return Highcharts.numberFormat(pcnt) + '%';
}
}
Live demo: http://jsfiddle.net/BlackLabel/9tbynahj/
API Reference: https://api.highcharts.com/highcharts/tooltip

How to display no data found in highcharts

In highcharts, if there is no data found in the json value, I want to display an error message.
I used this code:
if(options.series[0].data.length == 0) {
alert('nodatafound');
} else {
var chart = new Highcharts.Chart(options);
}
This error appears:
TypeError: options.series[0].data is undefined
Data from JSON:
{
"chart": {
"renderTo": "container2",
"type": "column",
"marginRight": 10,
"marginBottom‌": 125
},
"title": {
"text": "",
"x": -20
},
"exporting": {
"enabled": false
},
"credits": {
"enab‌led": false
},
"subtitle": {
"text": "",
"x": -20
},
"xAxis": {
"labels": {
"rotation": -90,
"sty‌le": {
"fontSize": "10px"
}
}
},
"yAxis": {
"title": {
"text": ""
},
"plotLines": [{
"width": 1,
"c‌olor": "#808080"
}]
},
"tooltip": {
"shared": true
},
"legend": {
"align": "right",
"verticalA‌lign": "top",
"x": 0,
"y": 20,
"borderWidth": 0
},
"plotOptions": {
"column": {
"stacking": "no‌rmal",
"dataLabels": {
"enabled": false,
"color": "white"
}
}
},
"series": [{
"name": "2015-16-Q1"
}, {
"name": "2015-16-Q2"
}, {
"name": "2015-16-Q3"
}, {
"na‌me": "2015-16-Q4"
}]
}
You can use no-data module which allows do that.
Ref: http://code.highcharts.com/modules/no-data-to-display.js
Example: http://jsfiddle.net/6o8o03fe/1/

Multiple Lines (long text) in Highcharts Categories

I have this graph :
http://jsfiddle.net/ZKGZb/
$(document).ready(function() {
chart16 = new Highcharts.Chart({
"chart": {
"renderTo": "right-22",
"type": "column",
"width": 550,
"height": 400,
},
"xAxis": {
"categories": ["a very long long text ", "2another long text", "dda", "bbb", "aaa"],
"allowDecimals": "0",
"title": {
"text": "Hello world",
"offset": -350,
"align": "left",
"style": {
"color": "red"
}
},
"labels":{"useHtml": true }
},
"yAxis": {
"allowDecimals": false,
"labels": {
"overflow": "justify"
},
"title": {
"text": " "
},
"max": 20
},
"tooltip": {
"formatter": function() {
return this.series.name + this.y + "";
}
},
"title": {
"text": "a very long long text",
"margin": 50
},
"plotOptions": {
"column": {
"groupPadding": null,
"borderWidth": null,
"dataLabels": {
"enabled": null,
"color": null,
"style": {
"fontSize": null,
"font-weight": "bold"
},
"formatter": function() {
return this.series.name + this.y + "";
}
}
}
},
"exporting": {
"enabled": false
},
"credits": {
"enabled": false
},
"labels": {
"enabled": null
},
"legend": {
"enabled": 0,
"layout": "vertical",
"align": "top",
"verticalAlign": "top",
"y": 0,
"x": 0,
"floating": false,
"borderWidth": 1,
"backgroundColor": "#FFFFFF",
"shadow": true
},
"series": [{
"data": [{
"y": 19,
},
{
"y": 0,
"name": ""},
{
"y": 0,
"name": ""},
{
"y": 1,
"name": ""},
{
"y": 0,
"name": ""}],
"name": "Total: "}]
}, function(chartObj) {});
});
How do I make the categories labels look good? I need to be able to show the whole text of each category but I cannot find a way to do it .
I tried adding and using "useHtml" option but it didn't work
Thanks in advance
"xAxis": {
"categories": ["a very long long text ", "2another long text", "dda", "bbb", "aaa"],
"allowDecimals": "0",
"title": {
"text": "Hello world",
"offset": -350,
"align": "left",
"style": {
"color": "red"
}
},
Removing the "title=>offset" fixes it..

Categories