How to use Real time chart in react? - javascript

I'm currently building a realtime chart to test it out. I wrote something to receive data as an example, but it doesn't work. Below is my code.
import { StreamingPlugin, ChartStreaming } from 'chartjs-plugin-streaming'
import {
Chart as ChartJS,
LinearScale,
CategoryScale,
RadialLinearScale,
BarElement,
PointElement,
LineElement,
ArcElement,
Legend,
Tooltip
} from 'chart.js'
import {
Chart,
Line,
Pie,
Doughnut,
Radar,
getDatasetAtEvent,
getElementAtEvent,
getElementsAtEvent,
} from 'react-chartjs-2'
ChartJS.register(
LinearScale,
RadialLinearScale,
CategoryScale,
BarElement,
PointElement,
LineElement,
ArcElement,
StreamingPlugin,
Legend,
Tooltip
)
const data =
{
datasets :
[
{
label : "real",
backgroundColor : "rgb(255, 99, 132)",
borderColor: "rgb(255, 99, 132)",
fill : false,
lineTension : 0,
borderDash: [8,4],
data : [],
showLine: true,
}
]
}
console.log(data.datasets[0].data)
const RealTime_ChartTest_options =
{
elements :
{
line :
{
tesion: 0.5
}
},
scales :
{
xAxes: [
{
type: "realtime",
realtime: {
onRefresh: function () {
data.datasets[0].data.push({
x: Date.now(),
y: Math.random() * 100
}
);
},
delay: 300,
refresh: 300
}
}
],
yAxes: [
{
scaleLabel: {
display: true,
fontFamily: "Arial",
labelString: "Moment",
fontSize: 20,
fontColor: "#6c757d"
},
ticks: {
max: 100,
min: 0
}
}
]
}
}
const App = ()=>
{
retrun(
<Line data={data} options={RealTime_ChartTest_options} />
)
}
As a result, the Y-axis and labels are displayed correctly, but the values are not stored in the data in real time and the graph is not drawn.
What am I doing wrong in the code?

This is because your scale config is wrong, you are using V2 syntax while using V3, changing it to this should resolve the issue:
scales: {
x: {
type: "realtime",
realtime: {
onRefresh: function() {
data.datasets[0].data.push({
x: Date.now(),
y: Math.random() * 100
});
},
delay: 300,
refresh: 300
}
},
y: {
max: 100,
min: 0
}
}
For all changes please read the migration guide

Related

Double labels on x axis in chart.js

I am using chart.js with react-chart-2 in react , but i got double labels below x axis how can i prevent it .
import 'chartjs-adapter-moment';
import moment from 'moment';
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
PointElement,enter image description here
LineElement,
Title,
Tooltip,
Legend,
TimeScale,
} from 'chart.js';
import type { ChartData, ChartOptions } from 'chart.js';
import { Line } from 'react-chartjs-2';
import zoomPlugin from 'chartjs-plugin-zoom';
import { useRef } from 'react';
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
TimeScale,
LineElement,
Title,
Tooltip,
Legend,
zoomPlugin
);
const dump = [
{
time: 1675056240000,
soc: 62,
},
{
time: 1675056270000,
soc: 62,
},
{
time: 1675056300000,
soc: 62,
},
{
time: 1675056330000,
soc: 62,
},
{
time: 1675056360000,
soc: 62,
},
];
let lables: number[] = [];
let values: number[] = [];
dump.map((x, i) => {
lables.push(x.time);
values.push(x.soc);
});
const data: ChartData<'line'> = {
labels: lables,
datasets: [
{
label: 'Soc',
data: values,
backgroundColor: '#03c782',
borderColor: '#03c782',
borderWidth: 1,
},
],
};
export default function Main() {
const lineGraphRef = useRef<ChartJS<'line', number[], string>>(null);
const options: ChartOptions<'line'> = {
responsive: true,
animation: false,
scales: {
y: {
ticks: {
color: 'white',
},
type: 'linear',
display: true,
position: 'left',
},
xAxis: {
type: 'time',
ticks: {
major: {
enabled: true, // <-- This is the key line
},
maxRotation: 45,
minRotation: 45,
maxTicksLimit: 12,
color: 'white',
},
display: true,
},
},
datasets: {
line: {
pointRadius: 0, // disable for all `'line'` datasets,
showLine: true,
},
},
hover: {
mode: 'x',
// intersect:false,
},
onHover: (e: any) => {
if (lineGraphRef !== null && lineGraphRef.current !== null) {
lineGraphRef.current.clear();
lineGraphRef.current.draw();
const y = e.y;
const topY = lineGraphRef.current.scales.y.top;
const bottomY = lineGraphRef.current.scales.y.bottom;
// console.log(
// moment(
// lineGraphRef.current.scales.xAxis.getValueForPixel(e.x)
// ).format('MMM Do YYYY, h:mm:ss a')
// );
let ctx = e.chart.ctx;
ctx.save();
ctx.beginPath();
ctx.moveTo(e.x, 0);
ctx.lineTo(e.x, bottomY);
ctx.lineWidth = 1;
ctx.strokeStyle = '#FFAB50';
ctx.stroke();
ctx.restore();
}
},
plugins: {
legend: {
labels: {
color: 'white',
boxWidth: 13,
},
},
tooltip: {
enabled: false,
//intersect: false,
external: (context) => {
// console.log("context", context);
},
},
zoom: {
zoom: {
// wheel: {
// enabled: true
// },
drag: {
enabled: true,
threshold: 10,
},
mode: 'x',
},
},
},
};
return (
<Line
options={options}
data={data}
ref={lineGraphRef}
/>
);
}
I have tried the display false in the xAxis but it hide upper labels that i need . I want to remove lower labels . I have tries many things but not able to remove them. Can anyone explain why there are two rows for labels.
Here I am providing code sandbox link for the same
https://codesandbox.io/s/gifted-cache-6i3lqv?file=/src/styles.css
I got the answer , in documentation it says we can use any variable for axis but it start from x for X-axis and from y for Y-axis. But it gives unexpected results when only one parameter chart. If there is single axis chart than we have to use x and only.
scales: {
y: {
ticks: {
color: 'white',
},
type: 'linear',
display: true,
position: 'left',
},
x: { /// change xAxix to only x
type: 'time',
ticks: {
major: {
enabled: true, // <-- This is the key line
},
maxRotation: 45,
minRotation: 45,
maxTicksLimit: 12,
color: 'white',
},
display: true,
},
},

Chartjs-adapter-luxon doesn't give the right labels

I'm making a line chart in sveltekit, using the svelte-chartjs package. The data for this chart is a set of timestamps, so I have to use a date adapter for chart.js.
The adapter I'm using is chartjs-adapter-luxon, and it seems to work, it spaces everything out correctly, except it has the wrong labels.
The labels are all showing one specific day: Jan 20, 1970, but my data has timestamps from several weeks in it, and none of them are from 1970. It's also suspicious that they're so close to the Unix epoch.
I can't figure it out, please help
My relevant code:
<script>
export let data
import { Line } from 'svelte-chartjs';
import 'luxon'
import 'chartjs-adapter-luxon'
import {
Chart,
Tooltip,
Legend,
BarElement,
CategoryScale,
LinearScale,
LineElement,
PointElement,
TimeScale,
} from 'chart.js';
Chart.register(
Tooltip,
Legend,
BarElement,
CategoryScale,
LineElement,
PointElement,
LinearScale,
TimeScale,
);
let graphdata = graph()
let graphoptions = {
scales: {
x: {
type: 'time',
time: {
unit: 'day',
displayFormats: {
second: 'MMM d, yyyy'
}
},
adapters: {
date: {
zone: 'UTC+6'
}
},
}
},
responsive: true,
maintainAspectRatio: false,
}
function graph() {
if (data.graph) {
let labels = []
for (let i = 0; i < data.graph.timestamp.length; i++) {
let timestamp = data.graph.timestamp[i]
const myDateTime = new Date(timestamp * 1000)
const myDateTimeISO = myDateTime.toISOString()
labels.push(new Date(myDateTimeISO))
}
let graphdata = {
labels: data.graph.timestamp,
datasets: [
{
label: 'Followers',
data: data.graph.followers,
backgroundColor: ["rgb(30 58 138 / 1)"],
borderWidth: 2,
borderColor: "#e5e7eb",
hoverBackgroundColor: ["rgb(30 58 138 / 1)"],
hoverBorderColor: "#e5e7eb",
},
{
label: 'Following',
data: data.graph.following,
backgroundColor: ["#818cf8"],
borderWidth: 2,
borderColor: "#e5e7eb",
hoverBackgroundColor: ["#818cf8"],
hoverBorderColor: "#e5e7eb",
},
{
label: 'Posts',
data: data.graph.posts,
backgroundColor: ["rgb(253 224 71 / 1)"],
borderWidth: 2,
borderColor: "#e5e7eb",
hoverBackgroundColor: ["rgb(253 224 71 / 1)"],
hoverBorderColor: "#e5e7eb",
},
],
};
return graphdata
} else {
return null
}
}
</script>
<Line data={graphdata} options={graphoptions} />

'chartjs-adapter-date-fns' unable to configure time

I want to implement a simple Gantt Chart using 'react-chartjs-2'.
I want Courses on Y axis, and Time-slots(HH:mm) in X axis. I also want to set Duration of each entry. I did This -
import React from 'react'
import UniNavbar from './UniNavbar';
import {UserData} from '../components/Chart/Data';
import { Bar } from 'react-chartjs-2';
import 'chartjs-adapter-date-fns';
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
TimeScale,
BarElement,
Title,
Tooltip,
Legend,
} from 'chart.js';
ChartJS.register(
TimeScale,
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend
);
export const options = {
indexAxis: 'y',
elements: {
bar: {
},
},
scales: {
x:{
min: '00:00',
type: 'time',
time:{
unit:'hour',
displayFormats: {
hour: 'HH:mm'
},
},
},
},
responsive: true,
plugins: {
legend: {
position: 'right',
},
title: {
display: true,
text: 'Chart.js Horizontal Bar Chart',
},
},
};
const labels = ['CSE150', 'CSE331', 'IPE120D', 'CSE333', 'PHY203D', 'BUS201D', 'EEE303D'];
export const data = {
labels,
datasets: [
{
label: 'Dataset 1',
data: [
['02:00','00:40'],
['02:00','00:40'],
['02:00','00:40'],
['02:00','00:40'],
['02:00','00:40'],
['02:00','00:40'],
],
backgroundColor: [
'rgba(255, 26, 104, 0.2)',
],
borderColor: [
'rgba(255, 26, 104, 1)',
],
barPercentage: 0.2,
},
],
};
const Schedules = () => {
return (
<div>
<UniNavbar/>
Schedules
<Bar options={options} data={data} />
</div>
)
}
In each data, I want to enter starttime and endtime, according to that, I want entries on the chart.
Is my data definition wrong here?
There was no output in the chart of each data entry(HH: mm). What am I doing wrong here?

How to add shadow effect on bar chart using ChartJs?

I'm using chartjs 3.9 to build a bar chart. I'm trying to get a shadow effect on the bars like this:
I couldn't find how to do this on the documentation. Can someone help me, please?
This are my datasets:
datasets: [
{
label: 'SLP',
data: [23000, 46000, 40000, 41000, 39000, 25000, 45000, 40500, 41000],
backgroundColor: gradientBg21,
borderRadius: 9,
categoryPercentage: 0.8,
barPercentage: 0.8
},
{
label: 'AXS',
data: [19000, 22000, 19000, 42000, 39500, 18000, 22000, 18000, 42000],
backgroundColor: gradientBg31,
borderRadius: 9,
categoryPercentage: 0.8,
barPercentage: 0.8
}
]
Here's my chart: JsFiddle
import { Bar } from 'react-chartjs-2';
import {
BarElement,
CategoryScale,
Chart as ChartJS,
Legend,
LinearScale,
Title,
Tooltip,
TooltipItem,
} from 'chart.js';
ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend);
const shadowPlugin = [{
id: 'shadow',
beforeDraw: (chart: ChartJS<'bar', number[], unknown>) => {
const { ctx } = chart;
const _fill = ctx.fill;
ctx.fill = function () {
ctx.save();
ctx.shadowColor = 'red';
//ctx.shadowColor = 'rgba(12,77, 229, 0.2)';
ctx.shadowBlur = 8;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 2;
_fill.apply(this, arguments as any);
ctx.restore();
};
},
}];
<Bar
height={(BAR_THICKNESS + 28) * data.length + TICKS_PADDING}
width={chartRefContainer?.current?.offsetWidth || undefined}
ref={chartRef}
options={options}
data={dataWithGradient}
plugins={shadowPlugin}
/>
result

React chartsJS streaming live data

I am trying to build a React ChartsJS live data streaming using Chartjs i managed to render the canvas on the page but for some reason, I still can't make move like a live line chart data I am not sure if I need to embed anything to the HTML page. i install those packages: chart.js "chartjs-adapter-luxon": "^1.1.0 "chartjs-plugin-streaming": "^2.0.0"
I hope someone could help me!
import React from "react";
import { Line } from "react-chartjs-2";
import Chart from "chart.js/auto";
import { StreamingPlugin, RealTimeScale } from "chartjs-plugin-streaming";
Chart.register(StreamingPlugin, RealTimeScale);
export const IotChart = () => {
const data = {
datasets: [
{
label: "Dataset 1",
fill: false,
lineTension: 0.4,
backgroundColor: "#f44336",
borderColor: "#f44336",
borderJoinStyle: "miter",
pointRadius: 0,
showLine: true,
data: [] as any,
},
],
};
const options = {
scales: {
xAxes: [
{
type: "realtime",
realtime: {
onRefresh: function () {
data.datasets[0].data.push({
x: Date.now(),
y: Math.random() * 100,
});
},
delay: 300,
refresh: 300,
},
},
],
yAxes: [
{
scaleLabel: {
display: true,
fontFamily: "Arial",
labelString: "Moment",
fontSize: 20,
fontColor: "#6c757d",
},
ticks: {
max: 100,
min: 0,
},
},
],
},
} as any;
return (
<div>
<div>
<Line data={data} options={options} width={400} height={200} />
</div>
</div>
);
};
This is because you define your scales as arrays instead of objects. This is changed in V3, for all the changes please read the migration guide because there are a lot more breaking changes, for example your Y axis scale label font declaration.
If you check the streaming documentation/examples you would also see that its defined as objects.
So changing to this will fix your issue:
scales: {
x: {
type: "realtime",
realtime: {
onRefresh: function() {
data.datasets[0].data.push({
x: Date.now(),
y: Math.random() * 100,
});
},
delay: 300,
refresh: 300,
},
},
}

Categories

Resources