Google Chart - Bar Series Title Different Color - charts

I have a chart which has 4 series (Fiddle link below). Currently, it has Title1, Title2, Title3, and Title4. I want to change the different color for each title text name (Not the bar); for example, Title1 is red, Title2 is blue, Title3 is green, and Title4 is black. Is there a way to change all these titles with different colors?
https://jsfiddle.net/milacay/e4fe4hsz/21/
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test Google Chart</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {callback: drawChart, packages: ['corechart']});
function drawChart() {
var array = [
["", "Today", "Goal"],
["Title1", 4553, 4151],
["Title2", 5560, 6150],
["Title3", 850, 920],
["Title4", 10505, 12320]
];
var data = new google.visualization.arrayToDataTable(array);
var formatTooltip = new google.visualization.NumberFormat({
pattern : '#,##0'
});
formatTooltip.format(data, 1);
formatTooltip.format(data, 2);
var formatShort = new google.visualization.NumberFormat({
pattern : 'short'
});
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc : function (dt, row) {
return formatShort.formatValue(dt.getValue(row, 1));
},
type : "string",
role : "annotation"
},
2, {
calc : function (dt, row) {
return formatShort.formatValue(dt.getValue(row, 2));
},
type : "string",
role : "annotation"
},
]);
var options = {
chart: {
title: ' ',
animation: {
duration: 2000,
easing: "out",
startup: true,
}
},
chartArea: {right:0
, width: "80%"
, height: "80%"
},
bar: {
groupWidth: 55 // Set the width for each bar
},
legend: {position:'top'},
hAxis: {
format: 'short',
//title: 'Month',
textStyle : {
bold: true,
fontSize: 10 // fontsize for the vAxis label.
//color: 'darkblue',
},
},
vAxis: {
format: 'short',
title: 'Progress To-Date',
gridlines: { count: 8 }
},
width:320,
height:300,
bars: 'vertical',
colors: ["lightblue", "lightgray"]
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(view, options);
}
</script>
</head>
<body>
<div id="chart_div"></div>
</body>
</html>

if you want to change the color of the axis labels,
change those manually when the chart's 'ready' event fires,
see following working snippet...
google.charts.load('current', {
callback: drawChart,
packages: ['corechart']
});
function drawChart() {
var array = [
["", "Today", "Goal"],
["Title1", 4553, 4151],
["Title2", 5560, 6150],
["Title3", 850, 920],
["Title4", 10505, 12320]
];
var data = new google.visualization.arrayToDataTable(array);
var formatTooltip = new google.visualization.NumberFormat({
pattern : '#,##0'
});
formatTooltip.format(data, 1);
formatTooltip.format(data, 2);
var formatShort = new google.visualization.NumberFormat({
pattern : 'short'
});
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc : function (dt, row) {
return formatShort.formatValue(dt.getValue(row, 1));
},
type : "string",
role : "annotation"
},
2, {
calc : function (dt, row) {
return formatShort.formatValue(dt.getValue(row, 2));
},
type : "string",
role : "annotation"
},
]);
var options = {
chart: {
title: ' ',
animation: {
duration: 2000,
easing: "out",
startup: true,
}
},
chartArea: {right:0
, width: "80%"
, height: "80%"
},
bar: {
groupWidth: 55 // Set the width for each bar
},
legend: {position:'top'},
hAxis: {
format: 'short',
//title: 'Month',
textStyle : {
bold: true,
fontSize: 10 // fontsize for the vAxis label.
//color: 'darkblue',
},
},
vAxis: {
format: 'short',
title: 'Progress To-Date',
gridlines: { count: 8 }
},
width:320,
height:300,
bars: 'vertical',
colors: ["lightblue", "lightgray"]
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.ColumnChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
var colorIndex = 0;
var colorPallette = ['red', 'blue', 'green', 'black'];
Array.prototype.forEach.call(container.getElementsByTagName('text'), function (label) {
if ((label.getAttribute('text-anchor') === 'middle') && (label.getAttribute('fill') !== '#404040')) {
label.setAttribute('fill', colorPallette[colorIndex]);
colorIndex++;
}
});
});
chart.draw(view, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
note: the label color (#404040) is used to differentiate the x-axis labels from the annotation labels...

Related

Custom tooltip title based on dictionary mapping of values

MWE: See a graph below with countries in the x-axis. What is the best way to show the whole name in the tooltip instead of the acronym? (Show "Germany" instead of "GER", France instead of "FRA", etc.). I have like 10 or 15 of those.
SEE FULL CODE IN jsfiddle
var example2 = [229, 113, 109];
var labels2 = ["GER", "FRA", "LT"];
https://jsfiddle.net/user3507584/6zpb715x/6/
You can add an object with translations where the key is the value from the label and the value is the full country name:
var example2 = [229, 113, 109];
var labels2 = ["GER", "FRA", "LT"];
var translations = {
GER: 'Germany',
FRA: 'France',
LT: "Italy"
}
var barChartData2 = {
labels: labels2,
datasets: [{
label: 'Student Count',
backgroundColor: '#ccece6',
data: example2
}]
};
function drawChart(el, data, title) {
var ctx = document.getElementById(el).getContext("2d");
var bar = new Chart(ctx, {
type: 'bar',
data: data,
options: {
// Elements options apply to all of the options unless overridden in a dataset
// In this case, we are setting the border of each bar to be 2px wide and green
elements: {
rectangle: {
borderWidth: 2,
borderColor: '#98c4f9',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'bottom',
},
title: {
display: true,
text: title
},
scales: {
yAxes: [{
ticks: {
beginAtZero: 0,
min: 0
}
}],
xAxes: [{
ticks: {
// Show all labels
autoSkip: false,
callback: function(tick) {
var characterLimit = 20;
if (tick.length >= characterLimit) {
return tick.slice(0, tick.length).substring(0, characterLimit - 1).trim() + '...';;
}
return tick;
}
}
}]
},
tooltips: {
callbacks: {
title: function(tooltipItem) {
return translations[tooltipItem[0].xLabel];
}
}
}
}
});
console.log(bar);
};
drawChart('canvas0', barChartData2, 'example title');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.2/Chart.js"></script>
<div id="container">
<canvas id="canvas0"></canvas>
</div>

Dual Axis Stacked Column Chart

I'm trying to create a dual axis stacked column Chart using Google's Classic Charts.
just like the Google's Material charts.
but there seems in classic one, the new stacks gets render over the previous one.
check the code below: Switch in between classic and material, you will find the difference.
Why classic? As it support tooltip modification unlike Material Chart.
Is it possible to have all stacks adjacent to the previous stack in classic chart?
google.charts.load('current', {
'packages': ['corechart', 'bar']
});
google.charts.setOnLoadCallback(drawStuff);
function drawStuff() {
var button = document.getElementById('change-chart');
var chartDiv = document.getElementById('chart_div');
var data = google.visualization.arrayToDataTable([
['Galaxy', 'Distance', 'Brightness', 'Contrast', {
type: 'string',
role: 'tooltip',
'p': {
'html': true
}
}],
['Canis Major Dwarf', 8000, 23.3, 2.8, 'Irregular galaxy'],
['Sagittarius Dwarf', 24000, 3.5, 6.6, '5,000 ly'],
['Ursa Major II Dwarf', 30000, 14.3, 10.67, 'Half-light radius'],
['Lg. Magellanic Cloud', 50000, 0.9, 3.6, null],
['Bootes I', 60000, 13.1, 10.23, null]
]);
var materialOptions = {
width: 900,
isStacked: true,
chart: {
title: 'Nearby galaxies',
subtitle: 'distance on the left, brightness on the right'
},
series: {
0: {
axis: 'distance'
}, // Bind series 0 to an axis named 'distance'.
1: {
axis: 'brightness'
}, // Bind series 1 to an axis named 'brightness'.
2: {
axis: 'brightness'
} // Bind series 1 to an axis named 'brightness'.
},
axes: {
y: {
distance: {
label: 'parsecs'
}, // Left y-axis.
brightness: {
side: 'right',
label: 'apparent magnitude'
} // Right y-axis.
}
}
};
var classicOptions = {
width: 900,
isStacked: true,
series: {
0: {
targetAxisIndex: 0
},
1: {
targetAxisIndex: 1
},
2: {
targetAxisIndex: 1
}
},
title: 'Nearby galaxies - distance on the left, brightness on the right',
vAxes: {
// Adds titles to each axis.
0: {
title: 'parsecs'
},
1: {
title: 'apparent magnitude'
}
}
};
function drawMaterialChart() {
var materialChart = new google.charts.Bar(chartDiv);
materialChart.draw(data, google.charts.Bar.convertOptions(materialOptions));
button.innerText = 'Change to Classic';
button.onclick = drawClassicChart;
}
function drawClassicChart() {
var classicChart = new google.visualization.ColumnChart(chartDiv);
classicChart.draw(data, classicOptions);
button.innerText = 'Change to Material';
button.onclick = drawMaterialChart;
}
drawMaterialChart();
};
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
</script>
</head>
<body>
<button id="change-chart">Change to Classic</button>
<br><br>
<div id="chart_div" style="width: 800px; height: 500px;"></div>
</body>
</html>

Google Charts API Area Chart display only max and min values in annotation

I'm using a Google Charts API Area Chart to display a simple Google Spreadsheet: Column 0 stores dates and Column 1 values. Actually the chart is displaying all values in annotation by default. But I only want to display the min and max value of column 1 in annotation.
I can't find the solution for my problem and maybe you can help me with my sourcecode.
Thanks Mags
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
function initialize() {
var opts = {sendMethod: 'auto'};
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/MYSPREADSHEET', opts);
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
type: 'string',
role: 'annotation',
sourceColumn: 1,
calc: 'stringify'
}]);
var options = {
title: '',
curveType: 'function',
legend: {position: 'none'},
lineWidth: 4,
backgroundColor: '#2E4151',
colors:['white'],
fontSize: '26',
fontName: 'Open Sans',
animation:{
"startup": true,
duration: 800,
easing: 'inAndOut',
},
hAxis: {
gridlines: {color: 'transparent', count: 4},
textStyle: {color: '#FFF'}
},
vAxis: {
gridlines: {color: 'white', count: 5},
viewWindow: {min: 87, max: 101},
textStyle: {
color: '#FFF',
fontSize: 18
},
},
trendlines: {
0: {
type: 'polynomial',
color: 'yellow',
lineWidth: 5,
opacity: 0.7,
showR2: true,
visibleInLegend: true
}
}
};
var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
chart.draw(view, options);
}
google.setOnLoadCallback(initialize);
</script>
</head>
<body>
<div id="chart_div" style="width:100%; height:100%"></div>
</body>
</html>
you can use data table method --> getColumnRange(columnIndex)
this will return an object with the min & max values of the column.
then you can use the calc function on the data view,
to determine if the value matches either the min or max,
and return the formatted value for the annotation.
return null if it does not, see following snippet...
var data = response.getDataTable();
var range = data.getColumnRange(1);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
type: 'string',
role: 'annotation',
sourceColumn: 1,
calc: function (dt, row) {
var value = dt.getValue(row, 1);
if ((value === range.min) || (value === range.max)) {
return dt.getFormattedValue(row, 1);
}
return null;
}
}]);

Google Charts - Apply margin on y-axis values

What I'd like to do, is to increase the margin between the y-axis values and the corresponding bar within the chart.
So if I have a bar in the chart which has a value of "Python" on the Y- axis, I want to increase the space between the string "Python" and the visual bar.
Now:
Python__========================================================
My goal:
Python___________=========================================================
___ represents the space between y-axis label and visual bar
I tried to use chartArea{right:200} and textPosition:out in the options section of the chart.
var options = {
chartArea:{right: 200},
'vAxis': {
title:'',
textStyle : {
fontSize: 25
},
textPosition: 'out'
},
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Coding-Skills', 'Skill-Level'],
['C', {v: 0.3, f:'low'}],
['Python', {v: 1, f:'medium'}],
['Javascript', {v: 1.5, f:'medium'}],
['HTML/CSS', {v: 1.5, f:'medium'} ]
]);
var options = {
chartArea: {
left: 1400
},
'hAxis': {
gridlines:{
count: 0},
textStyle : {
fontSize: 25
}
},
'vAxis': {
title:'',
textStyle : {
fontSize: 25
}
},
chart: {
},
bars: 'horizontal',
axes: {
x: {
0: { side: 'bottom', label: 'Years of experience'} ,
textStyle : {
fontSize: 35
}
}
}
};
var chart = new google.charts.Bar(document.getElementById('barchart_material'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
Applying margin-right
no options for label margins,
but you can move them manually on the chart's 'ready' event
find the labels and change the 'x' attribute
see following working snippet,
here, the chartArea option is used to ensure there is enough room...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Language', 'Skill-Level'],
['C', 20],
['Python', 35],
['Javascript', 50]
]);
var container = document.getElementById('chart_div');
var chart = new google.visualization.BarChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
var labels = container.getElementsByTagName('text');
Array.prototype.forEach.call(labels, function(label) {
// move axis labels
if (label.getAttribute('text-anchor') === 'end') {
var xCoord = parseFloat(label.getAttribute('x'));
label.setAttribute('x', xCoord - 20);
}
});
});
var options = {
chartArea: {
left: 100,
right: 200
},
colors: ['#aaaaaa'],
hAxis: {
baselineColor: 'transparent',
gridlines: {
count: 0
},
textStyle: {
color: '#aaaaaa'
}
},
height: 400,
legend: {
textStyle: {
color: '#aaaaaa'
}
},
vAxis: {
textStyle: {
color: '#aaaaaa'
}
}
};
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
Quick addition to existing answer:
$('.transactionValuationChart text').each(function(){
if( $(this).attr('text-anchor') == 'middle' ){
$(this).attr('y', parseFloat($(this).attr('y')) + 20 );
}else{
$(this).attr('x', parseFloat($(this).attr('x')) - 20 );
console.log("left");
}
});
This is a jQuery example which adds 20px of spacing to both x & y axis

Google Bar chart bars & axis do not correlate to data

https://i.imgur.com/qKcSRjS.png
The values of the bars, from top to bottom, are 66, 77, 91, 0
As you can see, the labels on the X axis are not to scale and seem to simply indicate the value of each bar, and the bars are also not scaled to their value they seem to simply stack in a staircase fashion. The bottom bar should be 'empty' as it is 0.
The data is dynamically generated but here is the resulting code:
function drawRightY() {
var data = google.visualization.arrayToDataTable([ ['Date', 'Received'], ['1/15/2018', '66'],['1/22/2018', '77'],['1/29/2018', '91'],['2/5/2018', '0'] ]);
var materialOptions = {
chart: {
hAxis: {
title: 'Date',
minValue: 0,
scaleType: 'log'
},
vAxis: {
title: 'Received'
},
bars: 'horizontal',
legend: {
position: 'none'
},
axes: {
y: {
0: { side: 'left' }
}
}
};
the values in the data should be numbers, not strings (remove single quotes)
['1/15/2018', '66'] // <-- string
['1/15/2018', 66] // <-- number
see following working snippet...
google.charts.load('current', {
packages:['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([ ['Date', 'Received'], ['1/15/2018', 66],['1/22/2018', 77],['1/29/2018', 91],['2/5/2018', 0] ]);
var materialOptions = {
hAxis: {
title: 'Date',
minValue: 0,
scaleType: 'log'
},
vAxis: {
title: 'Received'
},
bars: 'horizontal',
legend: {
position: 'none'
},
axes: {
y: {
0: { side: 'left' }
}
}
};
var chart = new google.visualization.BarChart(document.getElementById('chart'));
chart.draw(data);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>