Change Color of Stacked Grouped Google Column Chart - google-visualization

Please look at http://jsfiddle.net/v1u1afzn/228/
google.load('visualization', '1.1', {
'packages': ['bar']
});
google.setOnLoadCallback(drawStuff);
function drawStuff() {
var data = new google.visualization.arrayToDataTable([
['Year', 'A', 'B', 'C', 'D'],
['2001', 321, 600, 816, 319],
['2002', 163, 231, 539, 594],
['2003', 125, 819, 123, 578],
['2004', 197, 536, 613, 298]
]);
var options = {
isStacked: true,
vAxis: {
viewWindow: {
max: 1100,
min: 0
}
},
vAxes: {
0: {
},
1: {
gridlines: {
color: 'transparent'
},
textStyle: {
color: 'transparent'
}
},
},
series: {
2: {
targetAxisIndex: 1
},
3: {
targetAxisIndex: 1
},
},
colors: ['blue', 'red'],
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
};
How do I change the faded / lighter blue (first column top stack) to say yellow?
I cannot find a way to change color of individual series that is grouped.
Any ideas?
Thanks in advance.

use the series option to change the color of an individual series / column / stack
series: {
0: {
color: 'yellow'
},
1: {
color: 'green'
},
2: {
color: 'blue',
targetAxisIndex: 1
},
3: {
color: 'red',
targetAxisIndex: 1
}
}
see following working snippet...
google.charts.load('current', {
packages: ['bar']
}).then(function () {
var data = new google.visualization.arrayToDataTable([
['Year', 'A', 'B', 'C', 'D'],
['2001', 321, 600, 816, 319],
['2002', 163, 231, 539, 594],
['2003', 125, 819, 123, 578],
['2004', 197, 536, 613, 298]
]);
var options = {
isStacked: true,
vAxis: {
viewWindow: {
max: 1100,
min: 0
}
},
vAxes: {
1: {
gridlines: {
color: 'transparent'
},
textStyle: {
color: 'transparent'
}
},
},
series: {
0: {
color: 'yellow'
},
1: {
color: 'green'
},
2: {
color: 'blue',
targetAxisIndex: 1
},
3: {
color: 'red',
targetAxisIndex: 1
}
}
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
note: jsapi should no longer be used to load the charts library,
according to the release notes...
The version of Google Charts that remains available via the jsapi loader is no longer being updated consistently. The last update, for security purposes, was with a pre-release of v45. Please use the new gstatic loader.js from now on.
this will only change the load statement, see above snippet...

Related

Fill gap between stacked bars in chart.js

I'm currently using chart.js with Vue 2 and I'm facing a problem when using border-radius with stacked bars.
I want to have a border-top radius but when doing that I get a "gap" between the border that was created and the bar above.
Is there any option that can fill that empty space?
Current behaviour
Expected behaviour
These are the current options I'm using for the graph.
options: {
responsive: true,
lineTension: 1,
plugins: {
legend: {
position: 'bottom',
// prevent filtering using labels
'onClick' : function (evt, item, legend) {
return;
},
labels: {
usePointStyle: 'circle',
},
}
},
elements: {
bar: {
borderRadius: {
topLeft: 4.6,
topRight: 4.6,
},
}
},
scales: {
y: {
stacked: true,
ticks: {
maxTicksLimit: 6,
callback: function(value, index, ticks) {
return value + ' min';
}
},
},
x: {
stacked: true,
grid: {
color: "rgba(0, 0, 0, 0)",
}
}
}
}
What you need it is not configurable by any options.
Nevertheless you can use a plugin to change the base of the bar to draw, taking care of the border radius.
EDIT: I have found a specific option in bar element, base, which should address the use case.
See snippet:
const ctx = document.getElementById("myChart");
// not used but leave it
const plugin = {
id: 'fillGaps',
beforeDatasetDraw(chart, args) {
if (args.index > 0) {
args.meta.data.forEach(function(item){
const pre = item.base;
item.base += 12;
});
}
},
};
//
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['January', 'Fabruary', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
label: 'user 1 online',
data: [50, 35, 45, 47, 10, 3, 27],
backgroundColor: 'rgba(40, 139, 170, 1)',
borderWidth: 0,
borderSkipped: 'start',
base: 0
},
{
label: 'user 2 online',
data: [50, 35, 45, 47, 10, 3, 27],
backgroundColor: 'orange',
borderWidth: 0,
borderSkipped: 'start',
base: 0
}]
},
options: {
elements: {
bar: {
borderRadius: {
topLeft: 12,
topRight: 12,
bottomLeft: 12,
bottomRight: 12
},
}
},
scales: {
y: {
stacked: true,
},
x: {
stacked: true,
}
}
}
});
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.9.1/dist/chart.min.js"></script>
<html>
<body>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"/>
</div>
</body>
</html>

Chartjs how to show scale label horizontally

Due to very poor documentation (https://www.chartjs.org/docs/latest/) I decided to ask Chart.js community this question.
How can I change the angle of the scale label?
This is my actual view
I would like to make those labels horizontal (see red labels how it should be).
The config is:
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: [this.label, this.valueUnit],
fontSize: 14,
},
afterFit: function(scaleInstance) {
scaleInstance.width = 120;
}
}]
You can define a second y-axis that is responsible for drawing the scale label horizontally.
The single yAxis.ticks label can be left aligned by defining mirror: true together with some padding.
ticks: {
mirror: true,
padding: 60,
...
To make the tick label visible on the chart area, the same padding needs to be defined left of the chart layout.
layout: {
padding: {
left: 60
}
},
Please take a look on the runnable code below and see hot it works.
new Chart(document.getElementById('myChart'), {
type: 'line',
data: {
labels: ['A', 'B', 'C', 'D'],
datasets: [{
data: [10, 12, 8, 6],
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgb(255, 99, 132)',
borderWidth: 1,
fill: false
}]
},
options: {
layout: {
padding: {
left: 60
}
},
legend: {
display: false
},
scales: {
yAxes: [{
},
{
ticks: {
stepSize: 0.5,
mirror: true,
padding: 60,
fontColor: 'red',
callback: v => v == 0.5 ? ['Horizontal', 'Label'] : undefined
},
gridLines: {
display: false
}
}
]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="50"></canvas>
The Plugin Core API offers a range of hooks that may be used for performing custom code. You can use the afterDraw hook to draw the scale label yourself directly on the canvas using CanvasRenderingContext2D.fillText().
afterDraw: chart => {
var ctx = chart.chart.ctx;
ctx.save();
let yAxis = chart.scales['y-axis-0'];
let y = yAxis.bottom / 2;
ctx.textAlign = 'left';
ctx.font = "14px Arial";
ctx.fillStyle = "gray";
ctx.fillText('Horizontal', 0, y - 8);
ctx.fillText('Label', 0, y + 8);
ctx.restore();
}
You'll also have to define some extra padding at the left of the chart to make sure, the scale label does not overlap the chart area.
options: {
layout: {
padding: {
left: 70
}
},
Please take a look at the following runnable code and see how it works.
new Chart(document.getElementById('myChart'), {
type: 'line',
plugins: [{
afterDraw: chart => {
var ctx = chart.chart.ctx;
ctx.save();
let yAxis = chart.scales['y-axis-0'];
let y = yAxis.bottom / 2;
ctx.textAlign = 'left';
ctx.font = "14px Arial";
ctx.fillStyle = "gray";
ctx.fillText('Horizontal', 0, y - 8);
ctx.fillText('Label', 0, y + 8);
ctx.restore();
}
}],
data: {
labels: ['A', 'B', 'C', 'D'],
datasets: [{
data: [10, 12, 8, 6],
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgb(255, 99, 132)',
borderWidth: 1,
fill: false
}]
},
options: {
layout: {
padding: {
left: 70
}
},
legend: {
display: false
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="50"></canvas>
There is no build in way to do this. If you want to achieve this behaviour you will have to draw it on the canvas yourself with an custom plugin

How to make a grouped bar stack with Google charts?

I'm using Google Charts API 1.1 but i simply can't make grouped stacks.
I've used the "targetAxisIndex" separating them into two axis and it kinda works but if i don't set max value for each yAxis they are scaled differently and it's useless once both of the grouped stacks actually refers to the same thing.
I'd like to know i can make something similar to this: http://www.highcharts.com/demo/column-stacked-and-grouped
If you use:
var options = {
isStacked: true,
vAxis: {
viewWindow: {
max: 1100,
min: 0
}
},
vAxes: {
1: {
gridlines: {
color: 'transparent'
},
textStyle: {
color: 'transparent'
}
},
},
series: {
2: {
targetAxisIndex: 1
},
3: {
targetAxisIndex: 1
},
},
};
That should force them to scale the same, and keep the same axis on both sides but hide the rightmost.
Where
var data = new google.visualization.arrayToDataTable([
['Year', 'A', 'B', 'C', 'D'],
['2001', 70, 600, 816, 319],
['2002', 163, 231, 539, 594],
['2003', 125, 819, 70, 578],
['2004', 397, 536, 313, 298]
]);
...
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
JSFiddle

Secondary y axis values not displayed in Google Charts

I am trying to use secondary y axis with google charts.
I have this code:
arrdata.addRows([
[ObservationDateTime, observationValueCD4, observationValueViralLoad]
]);
}
// start of drawchart()
var options2 = {
title: 'CD4 && ViralLoad v/s DateTime',
vAxes: [{
title: 'CD4',
textStyle: {
color: 'blue'
}
}, // Axis 0
{
title: 'Viral Load',
textStyle: {
color: 'red'
}
} // Axis 1
],
hAxis: {
title: "Date"
},
series: {
0: {
type: "bars",
targetAxisIndex: 0
},
1: {
type: "line",
targetAxisIndex: 1
}
}
};
However, I am a bit confused with what is rendered:
It just renders blue straight vertical lines pointing up and no red line.Though secondary y axes in rendered.
What I expect: I expect blue bars for values on left y axis and red line for values on right y axes.
Without more code or sample data I can't say for sure what your issue is but your options seem to be correct for what you want.
google.load("visualization", "1", {
packages: ["corechart"]
});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
["ObservationDateTime", "observationValueCD4", "observationValueViralLoad"],
[new Date(2015,1,1), 9, 4],
[new Date(2015,2,1), 11, 6],
[new Date(2015,3,1), 20, 2],
[new Date(2015,4,1), 21, 3]
]);
var options2 = {
title: 'CD4 && ViralLoad v/s DateTime',
vAxes: [{
title: 'CD4',
textStyle: {
color: 'blue'
}
}, // Axis 0
{
title: 'Viral Load',
textStyle: {
color: 'red'
}
} // Axis 1
],
hAxis: {
title: "Date"
},
series: {
0: {
type: "bars",
targetAxisIndex: 0
},
1: {
type: "line",
targetAxisIndex: 1
}
}
};
var chart = new google.visualization.LineChart(document.getElementById("chart"));
chart.draw(data, options2);
}
// start of drawchart()
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<div id="chart" style="width: 900px; height: 300px;"></div>

google charts vAxis to the right

I'm using google visualization
var data2 = new google.visualization.DataTable();
data2.addColumn('string', 'time');
data2.addColumn('number', 'amount');
data2.addColumn({ type: 'string', role: 'tooltip' });
data2.addRows(rows_data);
var options2 = {
vAxis: { textPosition: 'none', title: '', textStyle: { fontName: 'arial'} },
hAxis: { slantedText: false, textStyle: { color: '#E6EFFA' }, gridlines: { color: '#E6EFFA', count: 20} },
backgroundColor: '#E6EFFA',
legend: 'none',
chartArea: { top: 0 },
colors: ['#435988'],
chartArea: { width: 800 }
};
chart2 = new google.visualization.LineChart(document.getElementById('chart_div_volume'));
I want the vAxis position to be on the right.
is it possible ?
Short Answer: Yes, but it's tricky.
Long Answer:
You need to set up a multi-axis chart. Basically, you create a dummy axis with no labels or anything to make it look like an axis. Then you configure a secondary axis. You create one set of dummy values (hidden) to put on the first axis, and plot your real data on the second.
Here is an example:
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable([
['Year', 'Dummy', 'Sales', 'Expenses'],
['2004', 0, 1000, 400],
['2005', null, 1170, 460],
['2006', null, 660, 1120],
['2007', null, 1030, 540]
]);
var options = {
title: 'Company Performance',
series: { 0: {targetAxisIndex: 0, visibleInLegend: false, pointSize: 0, lineWidth: 0},
1: {targetAxisIndex: 1},
2: {targetAxisIndex: 1}
},
vAxes: {
0: {textPosition: 'none'},
1: {},
}
};
var chart = new google.visualization.LineChart(document.getElementById('visualization'));
chart.draw(data, options);
}
google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(drawVisualization);
function drawVisualization() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Productivity');
data.addColumn('number', 'Composite');
data.addColumn({ type: 'number', role: 'annotation' });
data.addColumn('number', 'Average(N=5)');
var compositeDataArry = [];
compositeDataArry.push(["Ravi", 11, 11, 5]);
compositeDataArry.push(["Wasif", 5, 5, 5]);
compositeDataArry.push(["Vipin", 2, 2, 5]);
compositeDataArry.push(["Ankur", 3, 3, 5]);
compositeDataArry.push(["Pankaj", 1, 1, 5]);
compositeDataArry.push(["Dheeraj", 4, 4, 5]);
data.addRows(compositeDataArry);
var options = {
title: 'My Chart',
titleTextStyle: { color: '#264158', fontSize: 24 },
seriesType: 'bars',
annotations: {
alwaysOutside: true,
textStyle: {
color: '#000000',
fontSize: 15
}
},
hAxis: {
slantedText: true,
slantedTextAngle: -45
},
series: {
0: { targetAxisIndex: 0, },
1: { targetAxisIndex: 1, type: 'line' }
},
vAxes: {
0: { textPosition: 'none' },
1: {}
}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
</head>
<body>
<div id="chart_div" style="height: 500px; width: 100%"></div>
</body>
</html>