Google charts y-axis color - google-visualization

I'm using google charts api (line chart) and I want to change y-axis color from black to grey.
(the same color as the grid lines)
my code:
google.load("visualization", "1", { packages: ["corechart"] });
google.setOnLoadCallback(drawChart);
var baseLineColor = '#a3d06e';
var lineColor = '#717171';
function drawChart() {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('number', 'date');
dataTable.addColumn('number', 'sale');
dataTable.addRows([
[1, 2],
[2, 3],
[3, 3],
[4, 4],
[5, 5]
]);
var options = {
enableInteractivity: false,
tooltip: {trigger: 'none'},
pointSize: 0,
legend: 'none',
chartArea:{width:'94%',height:'70%'},
backgroundColor: '#6AB5D1',
series: { 0: { color: lineColor, pointSize: 5, lineWidth: 4 }},
hAxis: { textPosition: 'none', gridlines: {color:"#CCCCCC"} },
vAxis: { textPosition: 'none', baseline: 3, baselineColor: baseLineColor, gridlines: {color:"#CCCCCC"}}
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(dataTable, options);
How can I do that?

Set the hAxis.baselineColor option:
hAxis: {
textPosition: 'none',
gridlines: {
color: "#CCCCCC"
},
baselineColor: '#CCCCCC'
}

you can change your x and y axis color in google api by setting the baselineColor and gridlineColor using these parameter.
vAxis:{
baselineColor: '#ccc',
gridlineColor: '#ccc',
}

Just a note: Remember that the baseline is the line that intersects the axis you are working with. So if you want to style the y-axis, you need to change the baselineColor of the h-axis.
I totally miss it at first.

Related

Legend on chart.js

I'm trying to make a legend with a perfect box, but I don't know how, the "NĂ­vel Op. Max" is not like the others,I think the reason this happens is because it's a dotted line and the others are solid lines.
Does anyone know if there is any property in chart.js that causes the square's edge to not be dotted?
My code:
legend: {
display: true,
labels: {
fontSize: 10,
boxWidth: 10
}
The way I want:
You can provide a custom generateLabels function and dont provide the setting for making the border dashed like so:
const options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderColor: 'orange',
borderDash: [2, 2]
}
]
},
options: {
plugins: {
legend: {
labels: {
generateLabels: (chart) => {
const datasets = chart.data.datasets;
const {
labels: {
usePointStyle,
pointStyle,
textAlign,
color
}
} = chart.legend.options;
return chart._getSortedDatasetMetas().map((meta) => {
const style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
const borderWidth = Chart.helpers.toPadding(style.borderWidth);
return {
text: datasets[meta.index].label,
fillStyle: style.backgroundColor,
fontColor: color,
hidden: !meta.visible,
lineCap: style.borderCapStyle,
lineDashOffset: style.borderDashOffset,
lineJoin: style.borderJoinStyle,
lineWidth: (borderWidth.width + borderWidth.height) / 4,
strokeStyle: style.borderColor,
pointStyle: pointStyle || style.pointStyle,
rotation: style.rotation,
textAlign: textAlign || style.textAlign,
borderRadius: 0,
datasetIndex: meta.index
};
})
}
}
}
}
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.2/chart.js"></script>
</body>

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

Chartjs Datasets overlapping and z-index

I have the below Chart implemented using chart.js version 3.x.
https://jsfiddle.net/Lxya0u98/12/
I have multiple datasets in my charts to achieve the behavior I want.
I am facing an issue with the datasets overlapping. In the chart, I have end of the blue color line overlapping with the green color dot dataset. Is there a way to avoid this issue?
I have the below two datasets:
// Data set for the Big Dot
{
showLine: false,
borderWidth: 0,
lineTension: 0,
borderColor: colorVal,
backgroundColor: colorVal,
pointBackgroundColor: colorVal,
pointBorderColor: colorVal,
pointBorderWidth: 2,
pointRadius: 15,
};
// Data set for the Connecting Lines
{
showLine: true,
lineTension: 0,
borderWidth: 5,
borderColor: colorVal,
pointRadius: 0,
pointBorderWidth: 0,
spanGaps: true,
};
Is there a Z-Index for the Datasets so that they appear on top of the previous one in the stack?
The option dataset.order has similar effect as the z-index.
Datasets with higher order are drawn first
Datasets with no or lower order are drawn last, hence appear on top
Therefore, adding order: 1 to your line datasets should solve the problem.
var newDataLine = {
...
order: 1
};
Instead of defining multiple datasets, you could proceed as follows:
First convert your line chart into a scatter chart.
Then draw the lines directly on the canvas using the Plugin Core API. The API offers a range of hooks that may be used for performing custom code. You can use the beforeDraw hook to draw connection lines of different colors between data points and to the open end of the chart.
Note that you have to define xAxes.ticks.max in order to obtain the open end line at the right of the chart.
Please take a look at below runnable code snippet and see how it works.
new Chart('line-chart', {
type: "scatter",
plugins: [{
beforeDraw: chart => {
var ctx = chart.chart.ctx;
ctx.save();
var xAxis = chart.scales['x-axis-1'];
var yAxis = chart.scales['y-axis-1'];
var dataset = chart.data.datasets[0];
var y = yAxis.getPixelForValue(0);
dataset.data.forEach((value, index) => {
var xFrom = xAxis.getPixelForValue(value.x);
var xTo;
if (index + 1 < dataset.data.size) {
xTo = xAxis.getPixelForValue(dataset.data[index + 1].x);
} else {
xTo = xAxis.right;
}
ctx.strokeStyle = dataset.backgroundColor[index];
ctx.lineWidth = 4;
ctx.beginPath();
ctx.moveTo(xFrom, y);
ctx.lineTo(xTo, y);
ctx.stroke();
});
ctx.restore();
}
}],
data: {
datasets: [{
data: [
{ x: 0, y: 0 },
{ x: 1, y: 0 },
{ x: 2, y: 0 }
],
backgroundColor: ['red', 'blue', 'green'],
borderColor: ['red', 'blue', 'green'],
pointRadius: 8,
pointHoverRadius: 8,
}],
},
options: {
layout: {
padding: {
left: 10,
right: 10
}
},
legend: {
display: false
},
tooltips: {
enabled: false
},
scales: {
yAxes: [{
ticks: {
display: false
},
gridLines: {
display: false,
}
}],
xAxes: [{
ticks: {
display: false,
max: 3
},
gridLines: {
display: false
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="line-chart" height="30"></canvas>

ChartJs line chart - display permanent icon above some data points with text on hover

I have a chart i need to draw that, in addition to the data points, i want an icon permanently above (some) data points with a custom text string.
I don't need the default value popover as i can make do with a custom legend, but i need to add an icon above one or two points, and on hover of the icon, display a popover. i need to build the popover text string from non-chart related data.
The custom data labels don't appear to be flexible enough to allow different icons/popovers on different data points, i may be wrong though.
Another possibility is chartjs-plugin-datalabels, but I'm not sure about that.
In case your chart (canvas) is of fixed size, you can easily solve this problem by adding an additional dataset that specifies nothing but the icons to be shown in the chart.
{
data: data2.map((v, i) => imageIndexes.includes(i) ? v + 1.2 : null),
fill: false,
pointStyle: icon,
pointRadius: 22,
pointHoverRadius: 22
}
Given the data array data2 and the array imageIndexes, the data of the icons dataset can be built using Array.map. Note that the values - where any - are derived from corresponding values in data2 but slightly increased to make the images appear on top of them.
data2.map((v, i) => imageIndexes.includes(i) ? v + 1.2 : null)
Further you'll need to define a tooltips object inside the chart options in order to style the popup and to make sure, tooltips are only displayed when the mouse hovers over the icons.
tooltips: {
filter: tooltipItem => tooltipItem.datasetIndex == 2,
titleFontSize: 16,
titleAlign: 'center',
callbacks: {
title: (tooltipItem) => tooltipItem.length == 0 ? null : tooltipText,
label: () => null
}
},
Please have a look at the runnable code snipped below.
const labels = ['A', 'B', 'C', 'D', 'E', 'F'];
const alerts = ['B', 'D'];
const data1 = [0, 2, 1, 3, 2, 1];
const data2 = [1, 3, 3, 4, 3, 2];
const imageIndexes = [1, 3];
const tooltipText = 'Efficiency of Standard Curve\nnot opimal';
var icon = new Image();
icon.src = 'https://i.stack.imgur.com/YvlWY.png';
const chart = new Chart(document.getElementById("myChart"), {
type: "line",
data: {
labels: labels,
datasets: [{
data: data1,
fill: false,
backgroundColor: 'blue',
borderColor: 'blue',
lineTension: 0,
pointRadius: 5,
pointHoverRadius: 5,
pointBorderWidth: 3,
pointHoverBorderWidth: 3,
pointBorderColor: 'white',
pointHoverBorderColor: 'white'
},
{
data: data2,
fill: false,
showLine: false,
backgroundColor: 'orange',
pointRadius: 4,
pointHoverRadius: 4
},
{
data: data2.map((v, i) => imageIndexes.includes(i) ? v + 1.2 : null),
fill: false,
pointStyle: icon,
pointRadius: 22,
pointHoverRadius: 22
}
]
},
options: {
responsive: false,
title: {
display: false
},
legend: {
display: false
},
tooltips: {
filter: tooltipItem => tooltipItem.datasetIndex == 2,
titleFontSize: 16,
titleAlign: 'center',
callbacks: {
title: (tooltipItem) => tooltipItem.length == 0 ? null : tooltipText,
label: () => null
}
},
scales: {
yAxes: [{
ticks: {
min: 0,
max: 6,
stepSize: 1
}
}],
xAxes: [{
gridLines: {
display: false
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" style="width: 500px; height: 200px"></canvas>

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>