Two different x-axes using charts.js and react - javascript

I'm trying to create a chart component for weather in React using chart.js. I want two different x-axes with the temp above the chart, and the times below the chart. The data is correct in how I want it, I just want to use two different labels along the top and the bottom of the x-axes. How would I do this?
import React from "react";
import { Line } from "react-chartjs-2";
class WeatherOverview extends React.Component {
constructor(props) {
super(props);
this.state = {
chartData: {
labels: [
"15:00",
"18:00",
"21:00",
"00:00",
"03:00",
"06:00",
"09:00",
"12:00",
], //time
datasets: [
{
data: [18, 19, 18, 16, 15, 15, 16, 17, 18], //temp
},
],
},
};
}
render() {
return (
<div className="chart">
<Line
data={this.state.chartData}
options={{
scales: {
yAxes: [
{
gridLines: {
drawOnChartArea: false,
},
ticks: {
suggestedMin: 13, // lowest from data minus 2/3
display: false,
},
},
],
xAxes: [
{
gridLines: {
drawOnChartArea: false,
},
},
{ position: "top" },
],
},
}}
/>
</div>
);
}
}
export default WeatherOverview;
I want something like the google weather widget -

To match the Google Weather example with values floating over data points, what you really need is a plugin like chartjs-plugin-datalabels.
Install it via npm:
npm install chartjs-plugin-datalabels --save
Import:
import 'chartjs-plugin-datalabels';
And include it in your options object:
plugins: {
datalabels: {
display: true
}
}
This will add data labels on top of your data points. See the documentation for further information on how to customize the data labels.
I've made your chart look like the Google Weather chart with a couple other changes. Here's a full example using your data:
Some of the changes I made include:
Added datalabels plugin
Set colors accordingly
Set pointRadius to 0 on your dataset
Removed your extra X axis
On each axis, set drawBorder: false and tickMarkLength: 0
{
type: 'line',
data: {
labels: ['15:00', '18:00', '21:00', '00:00', '03:00', '06:00', '09:00', '12:00'], //time
datasets: [{
data: [18, 19, 18, 16, 15, 15, 16, 17, 18], //temp
backgroundColor: '#fff5cc',
borderColor: '#fc0',
pointRadius: 0,
}],
},
options: {
scales: {
yAxes: [{
gridLines: {
drawOnChartArea: false,
drawBorder: false,
tickMarkLength: 0,
},
ticks: {
suggestedMin: 13, // lowest from data minus 2/3
display: false
}
}],
xAxes: [{
gridLines: {
drawOnChartArea: false,
drawBorder: false,
tickMarkLength: 0,
},
ticks: {
fontColor: '#bababa',
}
}]
},
legend: {
display: false
},
layout: {
padding: {
top: 20
}
},
plugins: {
datalabels: {
align: 'top',
color: '#bababa',
font: {
weight: 'bold'
},
display: true,
},
},
}
}

This is my approach:
var chartData = {
labels: ['15:00', '18:00', '21:00', '00:00', '03:00', '06:00', '09:00', '12:00'],
datasets: [
{
fillColor: "#FFF5D7",
strokeColor: "#FFCC01",
data: [18, 19, 18, 16, 15, 15, 16, 17, 18]
}
]
};
var ctx = document.getElementById("myChart1").getContext("2d");
var myLine = new Chart(ctx).Line(chartData, {
scaleOverride : true,
scaleSteps : 10,
scaleStepWidth : 3,
scaleStartValue : 0,
showTooltips: false,
onAnimationComplete: function () {
var ctx = this.chart.ctx;
ctx.font = this.scale.font;
ctx.fillStyle = this.scale.textColor
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
this.datasets.forEach(function (dataset) {
dataset.points.forEach(function (points) {
ctx.fillText(points.value, points.x, 20);
});
})
}
});
https://jsfiddle.net/MartinGK/u4Lr8gzw/31/
Maybe it will help you get started.
I recommend to continue reading the documentation.

Related

Show x axis label on top of stacked bar and custom tooltip on chart js

I want to show the total value and x axis label on top of my stacked bar chart so it look like this
but right now, i'm only can show the total value, i don't know how to add the x axis label, so far mine look like this
i'm also want to custom my tooltip to look like this
Here's my code:
export default {
name: 'BarAllYear',
data() {
return {
BarAllYearData,
};
},
mounted() {
const ctx = document.getElementById('bar-all-year').getContext('2d');
const BarChart = {
type: 'bar',
data: this.BarAllYearData,
plugins: [ChartDataLabels],
options: {
borderWidth: 1,
responsive: true,
plugins: {
legend: {
display: false,
},
tooltip: {
xAlign: 'center',
yAlign: 'bottom',
backgroundColor: '#FFF',
displayColors: false,
titleFont: {
size: 20,
},
bodyFont: {
size: 18,
},
titleColor(tooltipItem) {
const titleLabelColor = tooltipItem.tooltip.labelColors[0].backgroundColor;
return titleLabelColor;
},
bodyColor() {},
},
datalabels: {
color: '#666666',
align: 'top',
anchor: 'end',
offset: 1,
formatter(value, context) {
const sumValue = context.chart.config.data.datasets.map((datapoint) => datapoint.data[context.dataIndex]);
function totalSum(total, datapoint) {
return total + datapoint;
}
const sum = sumValue.reduce(totalSum, 0);
return `${sum}`;
},
font: {
weight: 'bold',
size: 16,
},
},
},
scales: {
x: {
ticks: {
color: 'black',
font: {
weight: 'bold',
size: 16,
},
},
stacked: true,
},
y: {
ticks: {
stepSize: 1,
font: {
size: 18,
},
},
stacked: true,
},
},
layout: {
padding: 20,
},
},
};
/* eslint-disable no-new */
new Chart(ctx, BarChart);
},
};
and this is the BarAllYearData:
const DonutAllYearData = {
labels: [
'Butuh Perhatian Khusus',
'Dalam Proses',
'Selesai',
],
datasets: [{
label: 'My First Dataset',
data: [16, 3, 5],
backgroundColor: [
'#FF7A00',
'#23C4DB',
'#666666',
],
hoverOffset: 4,
}],
};
export default DonutAllYearData;
I'm using vue 3 by the way.
Anyway, thanks for the help

How to align vertical axis area on two charts in chart.js

in chart.js I'd like to have 2 charts (one under another) with ticks syncronized. Currently it looks so
as you can see dates are not aligned. Setting equal min-max values is impossible here since values are too different.
I think the solution would be to set equal width to both y-axes. The case is complicated by the second y-axes in upper chart, but may be it's possible to place an empty right scale on the bottom chart?
My current options for the top chart are
options: {
tooltips: {
enabled: true,
trigger: 'axis',
intersect: false,
mode : 'index'
},
responsive: true,
maintainAspectRatio: false,
layout: {
padding: {
// left: 500,
right: 0,
top: 0,
bottom: 0,
},
},
scales: {
xAxes: [
{
boundaryGap : false,
gridLines: {
display: false,
},
ticks: {
// Include a dollar sign in the ticks
callback: function(value, index, values) {
return value.split('.').slice(0,2).join('.');
}
},
},
],
yAxes: [
{
id: keys[0],
position: "left",
gridLines: {
drawBorder: false,
zeroLineColor: "rgba(147, 147, 147, 0.2)",
color: "rgba(147, 147, 147, 0.2)",
},
ticks: {
padding: 20,
fontColor: "#2C71C3",
beginAtZero: false,
},
}, {
id: keys[1],
position: "right",
gridLines: {
drawBorder: false,
color: "rgba(147, 147, 147, 0)",
},
ticks: {
padding: 20,
fontColor: "#C6C6C6",
beginAtZero: false,
},
},
],
},
and for the bottom one
options: {
tooltips: {
enabled: true,
trigger: 'axis',
intersect: false,
mode : 'index'
},
responsive: true,
maintainAspectRatio: false,
layout: {
padding: {
// left: 500,
right: 0,
top: 0,
bottom: 0,
},
},
scales: {
yAxes: [
{
ticks: {
reverse: true,
},
},
],
xAxes: [
{
gridLines: {
display: false,
},
ticks: {
// Include a dollar sign in the ticks
callback: function(value, index, values) {
return value.split('.').slice(0,2).join('.');
}
},
},
],
},
I dont know how to or if it is even possible to define a width for a scale, but what you can do is add a second Y axis on the right with the grid dissabled and the callback returning a few spaces for spacing
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1
}
]
},
options: {
scales: {
yAxes: [{
position: 'left'
},
{
position: 'right',
gridLines: {
display: false
},
ticks: {
callback: () => (' ')
}
}
]
}
}
}
var 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/2.9.4/Chart.js"></script>
</body>
Little late to the party, but it is possible to set a fixed width. I updated #LeeLenalee snippet with an example (both y axis have a 100px width in this case). This way, it is possible to align both graphs without any problem. Make sure to set a width that isn't too small for the labels though!
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1
}
]
},
options: {
scales: {
yAxes: [{
position: 'left',
afterFit: (scaleInstance) => scaleInstance.width = 100,
},
{
position: 'right',
afterFit: (scaleInstance) => scaleInstance.width = 100,
gridLines: {
display: false
},
ticks: {
callback: () => ''
}
}
]
}
}
}
var 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/2.9.4/Chart.js"></script>
</body>

How to draw a line in line chart for single value in Charts.JS

I need to plot a single value in line chart. Currently i am using charts.JS library for line graph purpose.
The data will be varied some times i'll get the single data inside the data set at that time i need to plot the single value in the line chart.
I had tried with the charts.js annotation plugin but it didn't meet my requirements. which is like it wis overlapping the plotted point in the graph area.
My code
createLineChart() {
this.lineChart = new Chart(this.lineCanvas.nativeElement, {
type: "line",
data: {
labels:[],
datasets: [
{
fill: false,
backgroundColor: "#0168FF",
borderColor: "#0168FF",
pointBackgroundColor: "white", // wite point fill
pointBorderWidth: 1, // point border width
lineTension: 0,
pointBorderColor: "blue",
pointRadius: 4,
},
],
},
options: {
scales: {
yAxes: [
{
ticks: {
padding: 20,
beginAtZero: true,
min: 0,
stepSize: 100,
},
gridLines: {
drawBorder: false,
},
},
],
xAxes: [
{
// offset: true,
ticks: {
display: false,
//beginAtZero: true,
min: 0,
},
gridLines: {
zeroLineColor: "transparent",
drawBorder: false,
display: false,
},
//offset:true,
},
],
legend: {
display: false,
},
tooltips: {
enabled: false,
},
},
drawTime: "afterDraw", // (default)
} as ChartOptions,
// plugins: [ChartAnnotation]
},
});
}
To plot the data dynamically:
generateRandomDataSet(size) {
let yaxisArr = [];
let xaxisArr = [];
let random_data:any = this.getRandomData(size)
let maxYTickVal = Math.max.apply(Math, random_data.map((val) => {return val.yaxis}));
let maxVal = Math.ceil((maxYTickVal+1) / 10) * 10
for(let data of random_data) {
yaxisArr.push(data.yaxis)
xaxisArr.push(data.xaxis)
}
this.lineChart.data.datasets[0].data = yaxisArr
this.lineChart.config.data.labels = []
this.lineChart.config.data.labels = xaxisArr
this.lineChart.config.options.scales.yAxes[0].ticks.max =maxVal
this.lineChart.config.options.scales.yAxes[0].ticks.stepSize = maxVal/2
this.lineChart.update()
}
What i required
What i am getting
Thankyou.
There exists different approaches to solve this problem.
According to the answer I gave to a similar question, you can define an animation.onComplete function to draw the line.
In a comment on before mentioned answer, Lakshmansundeep suggested an approach where he defines the same data value three times but makes sure, pointRadius for the leading and ending data point is zero.
datasets: [{
data: [120, 120, 120],
...
pointRadius: [0, 4, 0],
pointHoverRadius: [0, 4, 0],
}],
For the second approach, please have a look at the code below.
new Chart('line-chart', {
type: "line",
data: {
labels: [null, 'A', null],
datasets: [{
data: [120, 120, 120],
fill: false,
backgroundColor: "#0168FF",
borderColor: "#0168FF",
pointBackgroundColor: "white",
pointBorderWidth: 1,
lineTension: 0,
pointBorderColor: "blue",
pointRadius: [0, 4, 0],
pointHoverRadius: [0, 4, 0],
}],
},
options: {
legend: {
display: false
},
tooltips: {
enabled: false
},
scales: {
yAxes: [{
ticks: {
padding: 20,
min: 0,
stepSize: 100
},
gridLines: {
drawBorder: false
}
}],
xAxes: [{
ticks: {
display: false
},
gridLines: {
zeroLineColor: "transparent",
drawBorder: false,
display: false
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="line-chart" height="80"></canvas>

Is there any way to remove extra space and Horizontal line from Bar chart of Chart.js?

I am using Bar chart of Chart.js which is creating unwanted spacing on left and right side. I have tried to remove that by making canvas width and height to 100% as mentioned chartjs-is-there-any-way-to-remove-blank-space-around-pie-charts here. But it's not removing in my case.
I also need to remove horizontal line below the chart. Is there any way to do so?
Here's what i tried:
//Bar Chart
var bar = document.getElementById("bar-canvas");
var barChart = new Chart(bar, {
type: 'bar',
data: {
labels: ["Jackets", "Pants", "Headwear", "Shirts", "Footwear"],
datasets: [{
label: 'Dataset 1',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'#A7E3FF',
'#A7E3FF',
'#A7E3FF',
'#A7E3FF',
'#A7E3FF'
],
borderColor: [
'#A7E3FF',
'#A7E3FF',
'#A7E3FF',
'#A7E3FF',
'#A7E3FF'
],
borderWidth: 1
},
{
label: 'Dataset 2',
data: [20, 19, 10, 52, 2, 13],
backgroundColor: [
'#FD99EE',
'#FD99EE',
'#FD99EE',
'#FD99EE',
'#FD99EE'
],
borderColor: [
'#FD99EE',
'#FD99EE',
'#FD99EE',
'#FD99EE',
'#FD99EE'
],
borderWidth: 1
}]
},
responsive: true,
options: {
legend: {
display: false
},
tooltips: {
callbacks: {
label: function(tooltipItem) {
return tooltipItem.yLabel;
}
}
},
scales: {
xAxes: [{
stacked: true,
gridLines: {
color: "rgba(0, 0, 0, 0)"
},
ticks: {
fontColor: '#0071bc'
},
barThickness: 110
}],
yAxes: [{
stacked: true,
gridLines: {
color: "rgba(0, 0, 0, 0)"
},
scaleLabel: {
display: false
},
ticks: {
display: false
}
}
]
}
}
});
<canvas id="bar-canvas"></canvas>
Managed to remove the bottom line, but somehow could not remove the padding, - commented an area, which removes a little bit, but then you lose the ticks (which is obviously bad)
Just adding a fiddle, hope it helps at least somehow!
https://jsfiddle.net/aokzss3c/1/
..xAxes..
ticks: {
display: true, // removing this
fontColor: '#0071bc',
},

How to Remove axis Lines from chart in chart js

I drawn a chart using chart js like below
In this above chart i want to make a line thicker ( Pink Marked ) like other lines and also i want to remove x axis line ( Green Marked ). How can i do this please Help me.
Please see the fiddle Here Live Chart
var ganttchart = document.getElementById('bar-chart');
new Chart(ganttchart, {
type: 'line',
data: {
datasets: [
{
label: 'Scatter Dataset',
backgroundColor: "rgba(246,156,85,1)",
borderColor: "rgba(246,156,85,1)",
fill: false,
borderWidth : 15,
pointRadius : 0,
data: [
{
x: 0,
y: 9
}, {
x: 3,
y: 9
}
]
},
{
backgroundColor: "rgba(208,255,154,1)",
borderColor: "rgba(208,255,154,1)",
fill: false,
borderWidth : 15,
pointRadius : 0,
data: [
{
x: 3,
y: 7
}, {
x: 5,
y: 7
}
]
},
{
label: 'Scatter Dataset',
backgroundColor: "rgba(246,156,85,1)",
borderColor: "rgba(246,156,85,1)",
fill: false,
borderWidth : 15,
pointRadius : 0,
data: [
{
x: 5,
y: 5
}, {
x: 10,
y: 5
}
]
},
{
backgroundColor: "rgba(208,255,154,1)",
borderColor: "rgba(208,255,154,1)",
fill: false,
borderWidth : 15,
pointRadius : 0,
data: [
{
x: 10,
y: 3
}, {
x: 13,
y: 3
}
]
}
]
},
options: {
legend : {
display : false
},
scales: {
xAxes: [{
type: 'linear',
position: 'top',
gridLines: {
lineWidth:20
},
ticks : {
beginAtzero :true,
stepSize : 1
}
}],
yAxes : [{
gridLines: {
display:false,
},
ticks : {
beginAtZero :true,
max : 10,
display:false
}
}]
},
animation: {
duration: 0
},
hover: {animationDuration: 0}
}
});
You can find axes config options currently here: Axes - Chart.js Documentation
Axes config options has a global field display with the following description:
If set to false the axis is hidden from view. Overrides gridLines.display, scaleLabel.display, and ticks.display.
Here is how I have implemented it:
public chartOptions = {
scales: {
xAxes: [{
display: false,
}],
yAxes: [{
display: false,
}]
}
};
Just change border to false.
const config =
{
type: 'line',
data,
options: {
scales:{
y: {
beginAtZero: false,
border:{
display:false
}
},
x: {
beginAtZero: false,
border:{
display:false
}
}
}
}
}
}

Categories

Resources