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} />
Related
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?
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
I am using chart.js in reaction to create line chart. I want to show the day and month data like Aug 25, Jul 16. I don't know how to change the format of this data downloaded from the API. Please help. Here is my code
thank you for the hints
Is there a proper way to format dates for data labels in Chart.JS?
import axios from 'axios';
import { useParams } from 'react-router-dom';
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
} from 'chart.js';
import { Line } from 'react-chartjs-2';
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend
);
const rate = axios.create({
baseURL: 'http://api.nbp.pl/api/exchangerates/rates/a/',
});
const Chart = () => {
const [post, setPost] = useState();
const { id } = useParams();
useEffect(() => {
async function getPost() {
const response = await rate.get(`/${id}/last/10/?format=json`);
setPost(response.data);
}
getPost();
}, [id]);
const data = {
type: 'line',
labels: post?.rates?.map((x) => x.effectiveDate),
datasets: [
{
label: `Ostatnie 10 odczytów`,
data: post?.rates?.map((y) => y.mid),
lineTension: 0.1,
backgroundColor: 'rgba(15, 174, 150)',
borderColor: 'rgba(15, 174, 150)',
gridLines: 'false',
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: 'rgba(15, 174, 150)',
pointBackgroundColor: '#fff',
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: 'rgba(15, 174, 150)',
pointHoverBorderColor: 'rgba(220,220,220,1)',
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
},
],
options: {
responsive: true,
},
};
return (
<div
style={{
width: '800px',
height: '800px',
margin: '0px auto',
paddingTop: '500px',
}}
>
<Line data={data} />
</div>
);
};
export default Chart;
Welcome, Veronica! If you don't want to use a third-party package, I would advise working with the Date type along with the Intl.DateTimeFormat object. Once you've cast to Date, you can build the desired string.
post?.rates?.map(x => {
date = new Date(x.effectiveDate);
return new Intl.DateTimeFormat('en-US', {
month: 'short',
day: 'numeric',
}).format(date);
});
Hi I think you can use moment or dayjs(same stuff and moment since its depricated suggested dayjs) for this like
post?.rates?.map((x) => moment(x.effectiveDate).format('the format you want))
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
I am collecting the data of temperature and relative humidity everyday. I wanted to display these data with Chart.js and currently it is possible to show all my data. But I wonder how to display specific time label in x-axis by Chart.js?
As you can see, the x-axis is too "crowded" with the time label. I searched Chart.js documentation and tried to add autoskip and autoskippadding but it failed to show the targeted time label.
xAxes: [{
ticks: {
autoSkip: true,
autoSkipPadding: 60
}
}]
Hence, as these data were collected every minute and the size of data is so huge, how can I to display specific time label in x-axis only (00:00, 01:00, 02:00... and so on) so that to prevent too "crowded"? Any suggestions are highly appreciated, thank you!
You can define the x-axis as a time cartesian axis as follows:
scales: {
x: {
type: 'time',
time: {
parser: 'HH:mm:ss',
unit: 'hour',
displayFormats: {
hour: 'HH:mm'
},
tooltipFormat: 'D MMM YYYY - HH:mm:ss'
}
}
}
Please take a look at your amended code below and see how it works. This code now uses the chartjs-adapter-moment together with moment. Feel free to use a different adapter.
$(function() {
getXlsxData();
});
function getXlsxData() {
var xlsxUrl =
"https://script.google.com/macros/s/AKfycbw9PQRojIml3x5gnMMiKihnTh9aLODd86ankhoz0ETIu0a8tcVh1ZIc4R08hlw8nHF8pA/exec?id=1Bvzqyu_NvPdL-zsOShbKF5me2bjtVVWQCK9MDA2KW58&sheet=Today"
var xlsxData = $.getJSON(xlsxUrl, function(data) {
$.each(data.Today, function(i, el) {
labels.push(el.Time);
TodayTemperature.push(el.CurrentTemp);
TodayRH.push(el.CurrentRH);
});
load_chart();
});
}
var labels = [],
TodayTemperature = [],
TodayRH = []
function load_chart() {
var myChart = new Chart('alldata', {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Temperature(°C)',
fill: false,
data: TodayTemperature,
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132, 0.8)',
borderWidth: 1,
radius: 0,
}, {
label: 'Relative Humidity (%)',
fill: false,
data: TodayRH,
backgroundColor: 'rgb(255, 159, 64)',
borderColor: 'rgb(255, 159, 64, 0.8)',
hidden: true,
borderWidth: 1,
radius: 0,
}, ]
},
options: {
responsive: true,
maintainAspectRatio: false,
legend: {
position: 'bottom',
},
layout: {
padding: {
top: 35,
right: 15,
}
},
scales: {
x: {
type: 'time',
time: {
parser: 'HH:mm:ss',
unit: 'hour',
displayFormats: {
hour: 'HH:mm'
},
tooltipFormat: 'D MMM YYYY - HH:mm:ss'
}
}
}
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment-with-locales.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment#1.0.0"></script>
<canvas id="alldata" height="200"></canvas>