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
}
}]
}
}
});
Related
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)
}
},
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>
I have a requirement as below.
I need to input time series data (day data) using a graph. The data is usually like below but the profile can be changed depending upon the situation.
Right now the data is being manually entered in textboxes which makes it very difficult.
I am wondering whether there are solutions that let user draw on a chart and generate the data in the back. In other words, the user picks certain points and the profile is drawn.
see following working snippet, click on the chart to add a data point...
google.charts.load('current', {
callback: function () {
var data = new google.visualization.DataTable({
"cols": [
{"label": "x", "type": "number"},
{"label": "y", "type": "number"}
]
});
var axisMax = 10;
var ticks = [];
for (var i = 0; i <= axisMax; i = i + 0.5) {
ticks.push(i);
}
var options = {
chartArea: {
bottom: 64,
height: '100%',
left: 64,
top: 24,
width: '100%'
},
hAxis: {
format: '0.0',
textStyle: {
fontSize: 9
},
ticks: ticks,
title: data.getColumnLabel(0),
viewWindow: {
min: 0,
max: axisMax
}
},
height: 600,
legend: {
position: 'top'
},
pointSize: 4,
vAxis: {
format: '0.0',
textStyle: {
fontSize: 9
},
ticks: ticks,
title: data.getColumnLabel(1),
viewWindow: {
min: 0,
max: axisMax
}
}
};
var tableDiv = document.getElementById('table_div');
var table = new google.visualization.Table(tableDiv);
var chartDiv = document.getElementById('chart_div');
var chart = new google.visualization.LineChart(chartDiv);
var chartLayout = null;
google.visualization.events.addListener(chart, 'ready', function () {
chartLayout = chart.getChartLayoutInterface();
});
google.visualization.events.addListener(chart, 'click', function (sender) {
data.addRow([
chartLayout.getHAxisValue(sender.x),
chartLayout.getVAxisValue(sender.y)
]);
drawChart();
});
function drawChart() {
chart.draw(data, options);
table.draw(data);
}
window.addEventListener('resize', drawChart, false);
drawChart();
},
packages:['corechart', 'table']
});
div {
text-align: center;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
<div id="table_div"></div>
See the example code:
var data = new google.visualization.DataTable();
data.addColumn('string', 'Mac');
data.addColumn('number', 'Score');
data.addColumn({ type: 'string', role: 'style' });
data.addRows([
['Mac model 12', 200, 'color: #8bba30; opacity: 0.75;'],
['Another Mac Model', 110, 'color: #ffcc33; opacity: 0.75;'],
]);
var options = {
title: '',
width: 500,
height: data.getNumberOfRows() * 40 + 100,
hAxis: {
minValue: 0,
maxValue: 255,
ticks: [0, 75, 150, 255],
textPosition: 'out',
side: 'top'
},
series: {
0: { axis: 'Mac' },
1: { axis: 'Score' }
},
chartArea: {
top: 0,
bottom: 50,
right: 50,
left: 150
},
legend: { position: 'none' },
fontSize: 12,
bar: {groupWidth: '75%'},
};
var chart = new google.visualization.BarChart(document.getElementById('apple_div'));
chart.draw(data, options);
}
This is the output:
See, there are different colors for different bars. But I want different color and/or background-color for different legends on left side.
Can someone help me with this please?
I found following answer, Is it possible to show each legend in different color in google pie chart.
But it suggests on breaking down the chart(i.e. to draw separate charts for each rows), which is not desirable as there are large numbers of rows.
Not sure what you mean by breaking the chart, but...
You can modify the chart svg, once the 'ready' event fires.
This example changes the color of the legend text to match the bar color.
google.charts.load('current', {
callback: drawChart,
packages: ['corechart']
});
function drawChart() {
var colors = ['#8bba30', '#ffcc33'];
var data = new google.visualization.DataTable();
data.addColumn('string', 'Mac');
data.addColumn('number', 'Score');
data.addColumn({ type: 'string', role: 'style' });
data.addRows([
['Mac model 12', 200, 'color: ' + colors[0] + '; opacity: 0.75;'],
['Another Mac Model', 110, 'color: ' + colors[1] + '; opacity: 0.75;'],
]);
var options = {
title: '',
width: 500,
height: data.getNumberOfRows() * 40 + 100,
hAxis: {
minValue: 0,
maxValue: 255,
ticks: [0, 75, 150, 255],
textPosition: 'out',
side: 'top'
},
series: {
0: { axis: 'Mac' },
1: { axis: 'Score' }
},
chartArea: {
top: 0,
bottom: 50,
right: 50,
left: 150
},
legend: { position: 'none' },
fontSize: 12,
bar: {groupWidth: '75%'},
};
var chartContainer = document.getElementById('apple_div');
var chart = new google.visualization.BarChart(chartContainer);
google.visualization.events.addListener(chart, 'ready', function () {
var labels = chartContainer.getElementsByTagName('text');
var colorIndex = 0;
for (var i = 0; i < labels.length; i++) {
if (labels[i].getAttribute('text-anchor') === 'end') {
labels[i].setAttribute('fill', colors[colorIndex]);
colorIndex++;
}
}
});
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="apple_div"></div>
As for background color, SVG elements do not have background
so you would have to draw your own rect for that...
I'm currently working on a chart using google chart api, but i struggle at making a twice positive horizontal scale.
Like : 50 25 0 25 50 with a stacked chart bar centered on the '0' in the scale.
I kind of got it centered using a "dummy" invisible bar to push everything, but i can't find a way to get the horizontal axis label customized without editing the windowsview.
here's my actual code :
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.setOnLoadCallback(drawAnnotations);
function findMax(arr) {
var max = 0;
for (var n in arr) {
if (n > 0) {
var cMax = arr[n][2];
if (cMax > max)
max = cMax
}
}
return (max);
}
function findLine(arr) {
var max = 0;
for (var n in arr) {
if (n > 0) {
var cMax = arr[n][2] + arr[n][3] + arr[n][4];
if (cMax > max)
max = cMax
}
}
return (max / 2);
}
function space(arr, maxL) {
var max = findMax(arr);
for (var n in arr) {
if (n > 0) {
arr[n][1] = max - arr[n][2] + (maxL);
}
}
}
function drawAnnotations() {
var raw_data = [];
raw_data.push( ['Compétence', 'invisible', 'Expert', 'Certifié', 'Non certifié'] );
raw_data.push( ['Java', 0, 24, 31, 12] );
raw_data.push( ['PHP', 0, 17, 22, 10] );
raw_data.push( ['JavaScript', 0, 6, 10, 22] );
raw_data.push( ['Cpp', 0, 0, 0, 50] );
raw_data.push( ['C#', 0, 5, 10, 15] );
var maxL = findLine(raw_data);
space(raw_data, maxL);
var data = google.visualization.arrayToDataTable(raw_data);
var options = {
isStacked: true,
enableInteractivity: false,
width: 600, height: 400,
legend : 'none',
bar: { groupWidth: '85%' },
colors: ['ffffff','gray', 'yellow', 'red'],
hAxis: {
title: '',
baselineColor: '#fff',
gridlineColor: '#fff'
},
vAxis: {
title: '',
baselineColor: '#fff',
gridlineColor: '#fff'
}
};
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
JSfiddle Link
Currently i got what i want exept for the horizontal scale which is not set as i wish it to be.
(I tried to use multiple axes but it has proven to be unseccessfull).
edit: I add a link to an image of what kind of chart (scale) i'm looking to do.
UPDATE
I kinda got it working now :
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<meta charset=utf-8 />
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawAnnotations);
function drawAnnotations() {
var raw_data = [];
raw_data.push( ['Compétence', 'Expert', 'Certifié', 'Non certifié'] );
raw_data.push( ['Java', -24, 45, 12] );
raw_data.push( ['PHP', -17, 22, 10] );
raw_data.push( ['JavaScript', -6, 10, 22] );
raw_data.push( ['Cpp', -0, 0, 50] );
raw_data.push( ['C#', -5, 10, 15] );
var data = google.visualization.arrayToDataTable(raw_data);
var options = {
isStacked: true,
width: $(window).width() * 0.8, height: 400,
legend : 'none',
bar: { groupWidth: '85%' },
colors: ['gray', 'yellow', 'red'],
interpolateNulls: true,
hAxis: {
title: 'Number',
gridlines: {
color: 'transparent'
}
}
};
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
$(window).load(function() {
$('text').each(function(i, el) {
if ($(this).text()[0] == '-')
$(this).text($(this).text().substr(1));
});
});
</script>
</head>
<body>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
I had to change the google lib i was using :
previously was :
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
and now i'm using :
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
I'm not sure why it change something but without this change $(window).load was unable to reach "text" and i wasn't able to edit it.
Now i'm just converting a part of my chart to negative (the one i wanted on the left) and change the "negative" values from the scale using jquery.
There's just one thing left , the tooltip still show the negative value when you point on the "gray" area of the chart.
I still hope it may help someone else who struggle with this particular problem.
In fact, instead of modifying axis text via jQuery you could customize it via ticks feature as shown below:
hAxis: {
ticks: [{ v: -25, f: '25' }, 0, 25, 50, 75]
}
Regrading customizing tooltip label, you could consider the following solution to display non-negative value:
1) Attach onmouseover event to Google Chart:
google.visualization.events.addListener(chart, 'onmouseover', function (e) {
setTooltipContent(data, e);
});
2) Override tooltip negative value:
function setTooltipContent(data, e) {
if (e.row != null && e.column == 1) {
var val = Math.abs(data.getValue(e.row, 1));
var tooltipTextLabel = $(".google-visualization-tooltip-item-list li:eq(1) span:eq(1)");
tooltipTextLabel.text(val.toString());
}
}
Complete example
google.load("visualization", "1", { packages: ["corechart"] });
google.setOnLoadCallback(drawAnnotations);
function drawAnnotations() {
var raw_data = [];
raw_data.push(['Compétence', 'Expert', 'Certifié', 'Non certifié']);
raw_data.push(['Java', -24, 45, 12]);
raw_data.push(['PHP', -17, 22, 10]);
raw_data.push(['JavaScript', -6, 10, 22]);
raw_data.push(['Cpp', -0, 0, 50]);
raw_data.push(['C#', -5, 10, 15]);
var data = google.visualization.arrayToDataTable(raw_data);
var options = {
isStacked: true,
width: $(window).width() * 0.8, height: 400,
legend: 'none',
bar: { groupWidth: '85%' },
colors: ['gray', 'yellow', 'red'],
interpolateNulls: true,
tooltip: {isHtml: true},
hAxis: {
title: 'Number',
gridlines: {
color: 'transparent'
},
ticks: [{ v: -25, f: '25' }, 0, 25, 50, 75]
}
};
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data, options);
google.visualization.events.addListener(chart, 'onmouseover', function (e) {
setTooltipContent(data, e);
});
}
function setTooltipContent(data, e) {
if (e.row != null && e.column == 1) {
var val = Math.abs(data.getValue(e.row, 1));
var tooltipTextLabel = $(".google-visualization-tooltip-item-list li:eq(1) span:eq(1)");
tooltipTextLabel.text(val.toString());
}
}
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
JSFiddle