Shading Area Between Two Vertical Lines - javascript

Using Google Charts API, I have made a line chart. Is there any way to be able to shade between two vertical lines? I know I most likely have to use a combo chart, but can anyone make a simple jsfiddle of an Area Chart that shades the middle of two vertical lines? Thank you!

following is a snippet that draws a bell curve based on the input range.
vertical lines are drawn to identify the Mean and Standard Deviation ranges.
shading is added to highlight the areas within 1, 2, & 3 Standard Deviations from the Mean.
google.charts.load('43', {
callback: function () {
document.getElementById('range-draw').addEventListener('click', loadBellCurve, false);
window.addEventListener('resize', loadBellCurve, false);
loadBellCurve();
},
packages:['controls', 'corechart']
});
function loadBellCurve() {
// build data sample
var rangeMin = parseInt(document.getElementById('range-min').value);
var rangeMax = parseInt(document.getElementById('range-max').value);
var step = 0.05;
var dataChart = new google.visualization.DataTable({
cols: [
{label: 'Sample', type: 'string'},
{label: 'Value', type: 'number'},
{label: 'Var', type: 'number'},
{label: 'X', type: 'number'},
{label: 'Y', type: 'number'}
]
});
for (var i = rangeMin; i <= rangeMax; i=i+step) {
dataChart.addRow([i.toString(), i, null, null, null]);
}
// find sample mean
var dataMean = google.visualization.data.group(
dataChart,
[{column: 0, type: 'string', modifier: function () {return '';}}],
[{column: 1, type: 'number', aggregation: google.visualization.data.avg}]
);
var sampleMean = dataMean.getValue(0, 1);
// find sample standard deviation
for (var i = 0; i < dataChart.getNumberOfRows(); i++) {
dataChart.setValue(i, 2, Math.pow(dataChart.getValue(i, 1) - sampleMean, 2));
}
var dataVar = google.visualization.data.group(
dataChart,
[{column: 0, type: 'string', modifier: function () {return '';}}],
[{column: 2, type: 'number', aggregation: google.visualization.data.avg}]
);
var sampleStdDev = Math.sqrt(dataVar.getValue(0, 1));
// set standard deviation ranges 1-3
var sampleRange = [];
sampleRange.push([
sampleMean - sampleStdDev,
sampleMean + sampleStdDev
]);
sampleRange.push([
sampleMean - (sampleStdDev * 2),
sampleMean + (sampleStdDev * 2)
]);
sampleRange.push([
sampleMean - (sampleStdDev * 3),
sampleMean + (sampleStdDev * 3)
]);
// set X/Y coordinates
for (var i = 0; i < dataChart.getNumberOfRows(); i++) {
dataChart.setValue(i, 3, dataChart.getValue(i, 1) * sampleStdDev + sampleMean);
dataChart.setValue(i, 4, getNormalDistribution(dataChart.getValue(i, 1) * sampleStdDev + sampleMean, sampleMean, sampleStdDev));
}
// fill-in standard deviation areas
var stdDevCols = {};
stdDevCols['1_SD'] = dataChart.addColumn({label: '1 Std Dev', type: 'number'});
stdDevCols['2_SD'] = dataChart.addColumn({label: '2 Std Dev', type: 'number'});
stdDevCols['3_SD'] = dataChart.addColumn({label: '3 Std Dev', type: 'number'});
for (var i = Math.floor(sampleRange[2][0]); i <= Math.ceil(sampleRange[2][1]); i=i+0.05) {
var rowIndex = dataChart.addRow();
dataChart.setValue(rowIndex, 3, i);
if (((i) >= sampleRange[0][0]) && ((i) < sampleRange[0][1])) {
dataChart.setValue(rowIndex, stdDevCols['1_SD'], getNormalDistribution(i, sampleMean, sampleStdDev));
} else if (((i) >= sampleRange[1][0]) && ((i) < sampleRange[1][1])) {
dataChart.setValue(rowIndex, stdDevCols['2_SD'], getNormalDistribution(i, sampleMean, sampleStdDev));
} else {
dataChart.setValue(rowIndex, stdDevCols['3_SD'], getNormalDistribution(i, sampleMean, sampleStdDev));
}
}
// add vertical lines for mean and standard deviations
addVerticalLine('MEAN', sampleMean);
addVerticalLine('< 1 SD', sampleRange[0][0]);
addVerticalLine('> 1 SD', sampleRange[0][1]);
addVerticalLine('< 2 SD', sampleRange[1][0]);
addVerticalLine('> 2 SD', sampleRange[1][1]);
// series options
var markersArea = {
enableInteractivity: false,
pointsVisible: false,
tooltip: false,
type: 'area'
};
var markersLine = {
enableInteractivity: false,
lineWidth: 3,
pointsVisible: false,
tooltip: false,
type: 'line',
visibleInLegend: false
};
// combo chart
var chartCombo = new google.visualization.ChartWrapper({
chartType: 'ComboChart',
containerId: 'chart-combo',
options: {
animation: {
duration: 1000,
easing: 'linear',
startup: true
},
colors: ['#1565C0', '#43A047', '#FFB300', '#E53935', '#43A047', '#FFB300', '#FFB300', '#E53935', '#E53935'],
explorer: { actions: ['dragToZoom', 'rightClickToReset'] },
hAxis: {
format: '#,##0'
},
height: 340,
legend: {
textStyle: {
color: '#676767',
fontSize: 10
}
},
series: {
0: {
pointShape: {
type: 'star',
sides: 4,
dent: 0.3
},
pointSize: 12,
pointsVisible: true,
type: 'scatter'
},
1: markersArea,
2: markersArea,
3: markersArea,
4: markersLine,
5: markersLine,
6: markersLine,
7: markersLine,
8: markersLine
},
seriesType: 'scatter',
theme: 'maximized',
title: 'Normal Distribution',
titleTextStyle: {
color: '#676767',
bold: false,
fontSize: 10
},
tooltip: {
isHtml: true
},
vAxis: {
format: '#,##0.0000'
},
width: '100%'
}
});
// range filter
var controlRangeFilter = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'chart-control-range',
options: {
filterColumnIndex: 0,
ui: {
chartType: 'AreaChart',
chartOptions: {
annotations: {
highContrast: false,
stem: {
color: 'transparent',
length: 0
},
textStyle: {
color: 'transparent'
}
},
chartArea: {
left: 0,
width: '100%'
},
colors: ['#1565C0', '#43A047', '#FFB300', '#E53935', '#43A047', '#FFB300', '#FFB300', '#E53935', '#E53935'],
height: 72,
width: '100%'
}
}
}
});
// chart data view
var viewChart = new google.visualization.DataView(dataChart);
viewChart.setColumns([3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]);
// draw dashboard
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
dashboard.bind(controlRangeFilter, chartCombo);
dashboard.draw(viewChart);
function getNormalDistribution(x, Mean, StdDev) {
return Math.exp(-((x - Mean) * (x - Mean)) / (2 * StdDev * StdDev)) / (Math.sqrt(2 * Math.PI) * StdDev);
}
function addVerticalLine(colLabel, xVal) {
var yCol = dataChart.addColumn({label: colLabel, type: 'number'});
var annCol = dataChart.addColumn({role: 'annotation', type: 'string'});
var rowIndex = dataChart.addRow();
dataChart.setValue(rowIndex, 3, xVal);
dataChart.setValue(rowIndex, yCol, getNormalDistribution(xVal, sampleMean, sampleStdDev));
dataChart.setValue(rowIndex, annCol, xVal.toFixed(2) + ' %');
rowIndex = dataChart.addRow();
dataChart.setValue(rowIndex, 3, xVal);
dataChart.setValue(rowIndex, yCol, 0);
}
}
input {
font-family: Arial;
font-size: 10px;
}
input[type=number] {
text-align: right;
width: 48px;
}
label {
font-family: Arial;
font-size: 10px;
font-weight: bold;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
<div>
<label for="range-min">Min:</label> <input type="number" id="range-min" value="-4" />
<label for="range-max">Max:</label> <input type="number" id="range-max" value="4" />
<input type="button" id="range-draw" value="Draw Chart" />
</div>
<div id="chart-combo"></div>
<div id="chart-control-range"></div>
<div id="chart-table"></div>
</div>

Related

Hiding chart lines with no value

How can I hide the lines that go below value 1 so the chart doesn't look like the one below?. My chart shows a product sales over period of time. Some products don't have enought data which produces weirdly looking charts.
I have added vAxis: { viewWindowMode: 'pretty' } and this is helping to some extent to make it "pretty" but it isn't enough.
I've tried with data view and I thought that was the solution but the view is hiding some extra rows. My code for view where I convert the 0 row to date and trying to limit the min and max values:
let view = new google.visualization.DataView(dataYear);
view.setColumns([{
calc: function(dataYear, row) {
return new Date(dataYear.getValue(row, 0));
},
label: dataYear.getColumnLabel(0),
type: 'date'
}, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
view.setRows(view.getFilteredRows([{
column: 1,
minValue: 1,
maxValue: 500
}]));
I am a bit confused how view exactly works after many tries of tweaking up different columns and min/maxValues. In addition, I can target only 1 column at a time with the view? Bonus question: I would like also to hide the data points that are with 0 value (the one appearing on the x axis)
My chart code:
function chartYear(dataYear) {
// Display the total number of products sold for each chart/period
function getSum(dataYear, column) {
var total = 0;
for (i = 0; i < dataYear.getNumberOfRows(); i++)
total = total + dataYear.getValue(i, column);
return total;
}
let name = document.querySelectorAll('.google-visualization-table-tr-sel td')[2].textContent;
let interval = 1;
let dataRange = dataYear.getColumnRange(9);
let vTicks = [];
for (var i = dataRange.min; i <= dataRange.max + interval; i = i + interval) {
vTicks.push(i);
};
var chart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chartYear',
options: {
title: "6 months sales: " + name + "\nTotal: " + getSum(dataYear, 9),
curveType: "function",
pointsVisible: true,
pointSize: 5,
snapToData: true,
// pointBackgroundColor: '#FF0000',
titleTextStyle: {
fontName: 'Verdana',
fontSize: 13,
italic: true
},
vAxis: {
viewWindowMode: 'pretty',
ticks: vTicks,
minValue: 1
},
hAxis: {
// minValue: 1, // THROWS ERROR a.getTime() is not a function
// viewWindowMode: 'pretty',
slantedText: 1,
slantedTextAngle: 60
},
series: {
0: {
color: '#DC3912'
},
1: {
color: '#FF9900'
},
2: {
color: '#109618'
},
3: {
color: '#990099'
},
4: {
color: '#bbe9ff'
},
5: {
color: '#43459d'
},
6: {
color: '#C60AD3'
},
7: {
color: '#1c91c0'
},
8: {
color: '#3366CC'
},
}
}
});
var dateSlider = new google.visualization.ControlWrapper({
'controlType': 'ChartRangeFilter',
'containerId': 'chartRangeFilter',
'options': {
filterColumnLabel: 'Dato',
ui: {
chartType: 'LineChart',
chartOptions: {
snapToData: true,
height: 50,
chartArea: {
width: '80%'
},
series: {
0: {
color: '#DC3912'
},
1: {
color: '#FF9900'
},
2: {
color: '#109618'
},
3: {
color: '#990099'
},
4: {
color: '#bbe9ff'
},
5: {
color: '#43459d'
},
6: {
color: '#C60AD3'
},
7: {
color: '#1c91c0'
},
8: {
color: '#3366CC'
},
}
}
}
}
});
var formatter_long = new google.visualization.DateFormat({
pattern: 'yyyy-MM-dd'
});
formatter_long.format(dataYear, 0);
google.visualization.events.addListener(chart, 'error', function(googleError) {
google.visualization.errors.removeError(googleError.id);
});
let view = new google.visualization.DataView(dataYear);
view.setColumns([{
calc: function(dataYear, row) {
return new Date(dataYear.getValue(row, 0));
},
label: dataYear.getColumnLabel(0),
type: 'date'
}, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
view.setRows(view.getFilteredRows([{
column: 1,
minValue: 0,
maxValue: 500
}]));
var dashboard2 = new google.visualization.Dashboard(document.getElementById('dashboard2'));
dashboard2.bind(dateSlider, chart);
dashboard2.draw(view);
}
The chart is drawn when the user clicks on a table row. I send the product id with ajax and get back data for this product. I can add the select handler if needed.

Bubbles chart: how to avoid bubbles being cut off? google visualization

I'm using google visualization for bubble chart, data to x axis and Y axis is dynamic. I'm facing issue here is that bubbles get cut-off and there size is also not uniform.
using following options
options = {
'title': 'Chart',
'width': '100%',
'height': 550,
legend: {position: 'right'},
vAxis: {
title: 'Score',
viewWindow: {
min: 0,
max: 5
},
baselineColor: {
color: '#4c78c6',
},
sizeAxis : {minValue: 0, maxSize: 15},
ticks: [1, 2, 3, 4, 5]
},
hAxis: {
title: 'Years',
baselineColor: {
color: '#4c78c6',
}
},
sizeAxis : {minValue: 0, maxSize: 15},
bubble: {
textStyle: {
color: 'none',
}
},
tooltip: {
isHtml: true,
},
colors: colors,
chartArea: { width: "30%", height: "50%" }
};
EDIT data passed to
var rows = [
['ID','YEAR','SCORE', 'AVG1', 'AVG']
['Deka marc', 2.5, 5, '76-100%', 100]
['Max cala', 28.2,3.4,'76-100%', 77]
['shane root',4.2, 1, '0-25%', 0]
]
var data = google.visualization.arrayToDataTable(rows);
from above array I'm removing element 3 on hover as do not wish to show in tooltip. AVG1 column is for legend
getting o/p like this
use
var rangeX = data.getColumnRange(1);
to know the range of column
and then use
hAxis: {
viewWindow: {
min: rangeX.min-10,
max: rangeX.max+10
}
},
}
do similarly for yAxis
https://jsfiddle.net/geniusunil/nt4ymrLe/4/
Add inside hAxis the viewWindow option.
This is a sample code:
viewWindow: {
min: 0,
max: 40
}
You can change max according your biggest value in your dataset you want to show. I mean if is 30 (as in your example) you can set max: 40, or if is 75 you can set max equal to 85.
JSfiddle here.
to find the range of each axis dynamically, use data table method --> getColumnRange
then you can use the ticks option to increase the range.
var rangeX = data.getColumnRange(1);
var ticksX = [];
for (var i = (Math.floor(rangeX.min / 10) * 10); i <= (Math.ceil(rangeX.max / 10) * 10); i = i + 10) {
ticksX.push(i);
}
var rangeY = data.getColumnRange(2);
var ticksY = [];
for (var i = Math.floor(rangeY.min) - 1; i <= Math.ceil(rangeY.max) + 1; i++) {
ticksY.push(i);
}
to make the size of the bubble uniform, set minSize & maxSize to the same value.
sizeAxis : {minSize: 15, maxSize: 15},
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var rows = [
['ID','YEAR','SCORE', 'AVG1', 'AVG'],
['Deka marc', 2.5, 5, '76-100%', 100],
['Max cala', 28.2,3.4,'76-100%', 77],
['shane root',4.2, 1, '0-25%', 0]
];
var data = google.visualization.arrayToDataTable(rows);
var rangeX = data.getColumnRange(1);
var ticksX = [];
for (var i = (Math.floor(rangeX.min / 10) * 10); i <= (Math.ceil(rangeX.max / 10) * 10); i = i + 10) {
ticksX.push(i);
}
var rangeY = data.getColumnRange(2);
var ticksY = [];
for (var i = Math.floor(rangeY.min) - 1; i <= Math.ceil(rangeY.max) + 1; i++) {
ticksY.push(i);
}
var options = {
title: 'Chart',
width: '100%',
height: 550,
legend: {position: 'right'},
vAxis: {
title: 'Score',
baselineColor: {
color: '#4c78c6',
},
sizeAxis : {minSize: 15, maxSize: 15},
ticks: ticksY
},
hAxis: {
title: 'Years',
baselineColor: {
color: '#4c78c6',
},
ticks: ticksX
},
sizeAxis : {minSize: 10, maxSize: 10},
bubble: {
textStyle: {
color: 'none',
}
},
tooltip: {
isHtml: true,
},
//colors: colors,
chartArea: { width: "30%", height: "50%" }
};
var chart = new google.visualization.BubbleChart(document.getElementById('chart_div'));
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
Add 10% of the difference between the max and min
vAxis: {
viewWindow: {
min: rangeY.min - ((+rangeY.max - rangeY.min) * 10 / 100),
max: rangeY.max + ((+rangeY.max - rangeY.min) * 10 / 100)
}
},
hAxis: {
viewWindow: {
min: rangeX.min - ((+rangeX.max - rangeX.min) * 10 / 100),
max: rangeX.max + ((+rangeX.max - rangeX.min) * 10 / 100)
}
},

Multiple group on AxisX with javascript

I'm trying to create a chart with multiple AxisX with a javascript library (google or chartjs preferable).
I have made an example on excel to illustrate what i'm looking for, here is the example:
I've tried the next fiddle but obviously without success.
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawVisualization);
function drawVisualization() {
// Some raw data (not necessarily accurate)
var data = google.visualization.arrayToDataTable([
['Month', ['Activo, inactivo'], ['Activo, inactivo'], ['Activo, inactivo'], ['Activo, inactivo']],
['Gestor A', [165,100], [938,800], [522,100], [998, 1000]],
['Gestor B', [135,90], [1120,1000], [599,1000], [1268,700]],
['Gestor C', [157,70], [1167,800], [587,400], [807,900]],
['Gestor D', [139,160], [1110,1200], [615,500], [968,1000]],
['Gestor E', [136,200], [691,800], [629,700], [1026,1200]]
]);
var options = {
title : 'Monthly Coffee Production by Country',
vAxis: {title: 'Cups'},
hAxis: {title: ['Month']},
seriesType: 'bars',
series: {5: {type: 'line'}}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
google charts does not offer multiple group labels
but you can add them manually on the chart's 'ready' event
see following working snippet,
the position of the x-axis labels are used to draw the group labels and lines
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Month', 'Gestor A', 'Gestor B', 'Gestor C', 'Gestor D', 'Gestor E'],
['Activo', 165, 135, 157, 139, 136],
['Inactivo', 100, 90, 70, 160, 200],
['Activo', 938, 1120, 1167, 1110, 691],
['Inactivo', 800, 1000, 800, 1200, 800],
['Activo', 522, 599, 587, 615, 629],
['Inactivo', 100, 1000, 400, 500, 700],
['Activo', 998, 1268, 807, 968, 1026],
['Inactivo', 1000, 700, 900, 1000, 1200]
]);
var options = {
chartArea: {
bottom: 64,
left: 48,
right: 16,
top: 64,
width: '100%',
height: '100%'
},
hAxis: {
maxAlternation: 1,
slantedText: false
},
height: '100%',
legend: {
alignment: 'end',
position: 'top'
},
seriesType: 'bars',
title : 'Title',
width: '100%'
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.ComboChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
var chartLayout = chart.getChartLayoutInterface();
var chartBounds = chartLayout.getChartAreaBoundingBox();
var indexGroup = 0;
var indexRow = 0;
var months = ['Janeiro', 'Fevereiro', 'Marco', 'Abril'];
var xCoords = [];
Array.prototype.forEach.call(container.getElementsByTagName('text'), function(text) {
// process x-axis labels
var xAxisLabel = data.getFilteredRows([{column: 0, value: text.textContent}]);
if (xAxisLabel.length > 0) {
// save label x-coordinate
xCoords.push(parseFloat(text.getAttribute('x')));
// add first / last group line
if (indexRow === 0) {
addGroupLine(chartBounds.left, chartBounds.top + chartBounds.height);
}
if (indexRow === (data.getNumberOfRows() - 1)) {
addGroupLine(chartBounds.left + chartBounds.width, chartBounds.top + chartBounds.height);
}
// add group label / line
if ((indexRow % 2) !== 0) {
// calc label coordinates
var xCoord = xCoords[0] + ((xCoords[1] - xCoords[0]) / 2);
var yCoord = parseFloat(text.getAttribute('y')) + (parseFloat(text.getAttribute('font-size')) * 1.5);
// add group label
var groupLabel = text.cloneNode(true);
groupLabel.setAttribute('y', yCoord);
groupLabel.setAttribute('x', xCoord);
groupLabel.textContent = months[indexGroup];
text.parentNode.appendChild(groupLabel);
// add group line
addGroupLine(chartBounds.left + ((chartBounds.width / 4) * (indexGroup + 1)), chartBounds.top + chartBounds.height);
indexGroup++;
xCoords = [];
}
indexRow++;
}
});
function addGroupLine(xCoord, yCoord) {
var parent = container.getElementsByTagName('g')[0];
var groupLine = container.getElementsByTagName('rect')[0].cloneNode(true);
groupLine.setAttribute('x', xCoord);
groupLine.setAttribute('y', yCoord);
groupLine.setAttribute('width', 0.8);
groupLine.setAttribute('height', options.chartArea.bottom);
parent.appendChild(groupLine);
}
});
window.addEventListener('resize', function () {
chart.draw(data, options);
});
chart.draw(data, options);
});
html, body {
height: 100%;
margin: 0px 0px 0px 0px;
overflow: hidden;
padding: 0px 0px 0px 0px;
}
.chart {
height: 100%;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="chart" id="chart_div"></div>
note: elements drawn manually will not show when using chart method getImageURI,
if you need an image of the chart, you can use html2canvas
Exemple with chartjs - https://jsfiddle.net/6c0L1yva/392/
JAVASCRIPT -
var ctx = document.getElementById('c');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Active;January", "Inactive;January", "Active;February", "Inactive;February", "Active;March", "Inactive;March"],
datasets: [{
label: "Gestor A",
backgroundColor: "blue",
data: [3, 7, 4, 2, 3, 1]
}, {
label: "Gestor B",
backgroundColor: "red",
data: [4, 3, 5, 3, 1, 2]
}, {
label: "Gestor C",
backgroundColor: "green",
data: [7, 2, 6, 8, 2, 1]
}]
},
options:{
scales:{
xAxes:[
{
id:'xAxis1',
type:"category",
ticks:{
callback:function(label){
var state = label.split(";")[0];
var user = label.split(";")[1];
return state;
}
}
},
{
id:'xAxis2',
type:"category",
gridLines: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
ticks:{
callback:function(label){
var state = label.split(";")[0];
var user = label.split(";")[1];
if(state === "Inactive"){
return user;
}else{
return "";
}
}
}
}],
yAxes:[{
ticks:{
beginAtZero:true
}
}]
}
}
});

Highcharts: Value will not be updated

i have the next problem with Highcharts. This is a new Highchart for an other site.
See here: https://imgur.com/a/VQQLU
The arrow show to -3 Megawatts but the value at the bottom shows another value. At the first pageload the values are identical, but there comes all 5 seconds new values. And they are not updated at the bottom.
Edit: The tolltip will be updated correctly.
My code:
$(function () {
$.getJSON('jsonlive.php', function(chartData) {
var ADatum; var Eheit; var AktL; var MinL; var MaxL; var chartValue; var i;
ADatum = chartData[0].AktDatum;
Eheit = chartData[0].Einheit;
AktL = chartData[0].AktuelleLeistung;
MinL = chartData[0].MinLeistung;
MaxL = chartData[0].MaxLeistung;
var tMin = (MinL*-1); var tMax = MaxL;
var ttt = new Array();
if (tMin < tMax) { chartValue = tMax; } else if (tMin > tMax) { chartValue = tMin; } // Ermitteln ob neg/pos Zahl die größere ist.
ttt[0] = (chartValue*-1); // Skala mit Zahlen beschriften
for (i = 1; i < chartValue; i++) { ttt[i] = (i*-1); }
var tz = ttt.length ;
for (i = 0; i < chartValue; i++) { ttt[(tz+i)] = i; }
ttt[ttt.length] = chartValue;
var gaugeOptions = {
chart:{ events: {
load: function () { setInterval(function () {
$.getJSON('jsonlive.php', function(chartData) {
ADatum = chartData[0].AktDatum;
AktL = chartData[0].AktuelleLeistung;
var point = $('#inhalt').highcharts().series[0].setData([AktL], true);
});}, 5000);}
}, type: 'gauge' },
title: null,
pane: {
center: ['50%', '85%'], size: '140%', startAngle: -90, endAngle: 90,
background: [{
backgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [[0, '#00fb00'],[1, '#003f00']]},
borderWidth: 2,
outerRadius: '109%',
innerRadius: '102%', shape: 'arc' }]
},
series: [{
data: [AktL],
dataLabels: { borderWidth: 0,align: 'center',x: 0,y: 110,
format: '<div style="text-align:center;font-size:24px;color:black">'+AktL+' ' +Eheit+'</span></div>'
}
}],
tooltip: {
formatter: function () { return 'Datum: <b>' + (new Date(ADatum).toLocaleString("de-DE", { timeZone: 'UTC' })) +
'</b> <br>Leistung <b>' + AktL + ' ' + Eheit + '</b>';}, enabled: true },
yAxis: {lineWidth: 10, minorTickInterval: null, tickPixelInterval: 100, tickWidth: 5, title: { y: -250 }, labels: { y: 2 }}
};
// Anzeige
$('#inhalt').highcharts(Highcharts.merge(gaugeOptions, {
yAxis: {
min: (chartValue*-1),max: chartValue,tickPositions: ttt,tickColor: '#666',minorTickColor: '#666',
plotBands: [{ // optionaler Bereich, zeigt von 0-1 grün, 1 bis hälfte maximum gelb, und hälfte max bis max rot
from: 0, to: -1, color: '#55BF3B' }, { // green
from: -1, to: ((chartValue*-1)/2), color: '#DDDF0D' }, { // yellow
from: ((chartValue*-1)/2),to: (chartValue*-1),color: '#DF5353' }, { // red
from: 0,to: 1,color: '#55BF3B' }, { // green
from: 1,to: (chartValue/2),color: '#DDDF0D' }, { // yellow
from: (chartValue/2),to: chartValue,color: '#DF5353' }],// red
title: { style: { color: 'black', fontWeight: 'bold', fontSize: '24px' }, text: 'Leistung in '+Eheit },
labels: { formatter: function () { return this.value; }}},
credits: { enabled: false } // Link auf highcharts rechts unten an/aus
}));
});
});
</script>
The problem here is that you use a hard-coded value (AktL) in your dataLabels.format. In your example format is just a string that's used all the time.
Use {point.y} to have the label updated on every setData():
series: [{
data: [val],
dataLabels: {
// format: val // WONT WORK
format: '{point.y}'
}
}],
Live demo: http://jsfiddle.net/BlackLabel/v28q5n09/

Google Charts - custom tooltip value for Pie Chart

I am trying to present formatted data for the tooltip value of a Pie Chart. My data consists of a name and size (size is number of bytes).
The default tooltip does not let me use a custom formatter for the size value. If I use string I lose the Percentage value and Name of legend in the tooltip. Is there a way to do this?
I want to maintain the Legend Color, Name and Percentage, but have the value formatted to a more readable form
Current Wrong
Desired
var entries = [{name: 'Test1', size: 1234}, {name: 'Test2', size: 324563425}, {name: 'Test3', size: 321453452345}, {name: 'Test4', size: 789078}]
var drawChart = function(entries, elementId) {
var options = {
width: "100%",
height: 148,
fontSize: 8,
tooltip: { textStyle: { bold: true, color: '#000000', fontSize: 13 }, showColorCode: true, isHtml: true, ignoreBounds: true, text: 'both', trigger: 'selection' },
legend: { position: 'right', textStyle: { fontSize: 10 } },
chartArea: { left: 5, top: 10, right: 5, bottom: 10, height: "148", width: "100%" },
sliceVisibilityThreshold: 0,
pieSliceText: 'none',
//pieHole: 0.4,
};
var chart = new google.visualization.PieChart(document.getElementById(elementId));
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Size');
data.addColumn({ type: 'string', role: 'tooltip' });
data.addRows(entries.length);
var i = 0;
$.each(entries, function () {
data.setCell(i, 0, this.name);
data.setCell(i, 1, this.size);
// How to make this display correctly?
// If it stays like this i lose percentage and legend name from tooltip
data.setCell(i, 2, formatBytes(this.size));
i++;
});
chart.draw(data, options);
}
var formatBytes = function (bytes, precision) {
if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) return '-';
if (typeof precision === 'undefined') precision = 1;
var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
number = Math.floor(Math.log(bytes) / Math.log(1024));
return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + ' ' + units[number];
};
provide the formatted value in the last argument of setCell
the tooltip will show the formatted value by default
see following working snippet...
google.charts.load('current', {
callback: function () {
drawChart([{name: 'Test1', size: 1234}, {name: 'Test2', size: 324563425}, {name: 'Test3', size: 321453452345}, {name: 'Test4', size: 789078}], 'chart_div');
},
packages: ['corechart']
});
var drawChart = function(entries, elementId) {
var options = {
width: "100%",
height: 148,
fontSize: 8,
tooltip: { textStyle: { bold: true, color: '#000000', fontSize: 13 }, showColorCode: true, isHtml: true, ignoreBounds: true, text: 'both', trigger: 'selection' },
legend: { position: 'right', textStyle: { fontSize: 10 } },
chartArea: { left: 5, top: 10, right: 5, bottom: 10, height: "148", width: "100%" },
sliceVisibilityThreshold: 0,
pieSliceText: 'none',
//pieHole: 0.4,
};
var chart = new google.visualization.PieChart(document.getElementById(elementId));
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Size');
data.addRows(entries.length);
var i = 0;
$.each(entries, function () {
data.setCell(i, 0, this.name);
data.setCell(i, 1, this.size, formatBytes(this.size, 1));
i++;
});
chart.draw(data, options);
}
var formatBytes = function(bytes, precision) {
if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) return '-';
if (typeof precision === 'undefined') precision = 1;
var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
number = Math.floor(Math.log(bytes) / Math.log(1024));
return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + ' ' + units[number];
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Categories