I am building a covid-19 tracker using react charts but when my data is displayed on the screen it does not come out be as expected.
This is my chart code
<div >
{data?.length > 0 && (
<Line
data={{
datasets: [
{
backgroundColor: "rgba(204, 16, 52, 0.5)",
borderColor: "#CC1034",
data: data,
},
],
}}
options={options}
/>
)}
</div>
[enter image description here][1]
These are my option parameters
const options = {
legend: {
display: false,
},
elements: {
point: {
radius: 0,
},
},
maintainAspectRatio: false,
tooltips: {
mode: "index",
intersect: false,
callbacks: {
label: function (tooltipItem, data) {
return numeral(tooltipItem.value).format("+0,0");
},
},
},
scales: {
xAxes: [
{
type: "time",
time: {
format: "MM/DD/YY",
tooltipFormat: "ll",
},
},
],
yAxes: [
{
gridLines: {
display: false,
},
ticks: {
// Include a dollar sign in the ticks
callback: function (value, index, values) {
return numeral(value).format("0a");
},
},
},
],
},
};
My graph is coming out to be stretched and its height is increasing.
Related
i want to show the percentage at the chart, i tried to use tooltips but it's not working.
i'm using vue 2
polar chart
the code:
Codesandbox
polarChart: { options: { responsive: true, maintainAspectRatio: false, responsiveAnimationDuration: 500, yaxis: { show: true,
},
legend: { position: 'right', labels: { padding: 25, boxWidth: 10, showActualPercentages: true, fontSize: 15,
},
}, tooltips: { callbacks: { shadowOffsetX: 1, shadowOffsetY: 1, shadowBlur: 8,
},
}, scale: { scaleShowLine: true, scaleLineWidth: 1, ticks: { display: false,
}, reverse: false, gridLines: { display: false,
},
}, animation: { animateRotate: false,
},
},
chartData: { labels: ['Africa', 'Asia', 'Europe'],
The data -----
datasets: [
{ label: 'Population (millions)', ba
ckgroundColor: [
'#836AF9',
'#ffe800',
'#28dac6',
'#ffe802',
'#FDAC34',
'#299AFF',
'#4F5D70',
'#2c9aff',
'#84D0FF',
'#EDF1F4',
], data: [3141, 3132, 2112],
borderWidth: 0,
},
],
},
i tried to use tooltips but it does not working.
i want that the chart show the percentage and the value.
I use ChatJS and i want to add an € Symbol after every number in the Tooltip.
On my most charts it works perfectly but the Stacked Bar Chart makes me problems.
Here is an example Code like mine (Just a basic Example)
var barChart = new Chart(ctx_barChart, {
type: 'bar',
data: {
labels: ["Fruits"],
datasets: [{
label: [
["Apple"]
],
data: [12],
backgroundColor: 'blue',
barThickness: 80,
},
{
label: ["Banana"],
data: [15],
backgroundColor: 'red',
barThickness: 80,
},
]
},
options: {
maintainAspectRatio: false,
indexAxis: 'y',
responsive: true,
scales: {
x: {
stacked: true,
display: false,
},
y: {
stacked: true,
display: false,
mirror: true,
}
},
plugins: {
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'EUR'
}).format(context.parsed.y);
}
return label;
}
}
},
legend: {
display: false
},
title: {
display: false,
},
},
},
});
The tooltips both show 0,00$, but not my Values 12 and 15. Anyone have an suggestiont?
You should use context.parsed.x instead of context.parsed.y since it's a horizontal bar chart.
Please take a look at your amended code and see how it works.
new Chart('barChart', {
type: 'bar',
data: {
labels: ["Fruits"],
datasets: [{
label: "Apple",
data: [12],
backgroundColor: 'blue',
barThickness: 80,
},
{
label: "Banana",
data: [15],
backgroundColor: 'red',
barThickness: 80,
},
]
},
options: {
maintainAspectRatio: false,
indexAxis: 'y',
responsive: true,
scales: {
x: {
stacked: true,
display: false,
},
y: {
stacked: true,
display: false,
mirror: true,
}
},
plugins: {
tooltip: {
callbacks: {
label: ctx => ctx.dataset.label + ': ' + new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(ctx.parsed.x)
}
},
legend: {
display: false
},
title: {
display: false,
},
},
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<canvas id="barChart" height="100"></canvas>
I'm using chartjs-plugin-datalabels to show values on chart, but the labels are not centered.
The main part is in the datasets.datalabels where I can override default settings, which sets to center anyway, but wanted to show where its done.
I have tried positione it to the right, but as the value getting bigger, the datalabel is less centered.
Chart.register(ChartDataLabels);
const data_tafkidim_cat_count = {
labels: window.TafkidimCatCount.map((el) => el.TafkidCat.split(' ')).slice(0, pagination['tafkidim_cat_count'].show),
datasets: [
{
data: window.TafkidimCatCount.map((el) => el.Total),
backgroundColor: Setcolors(),
borderColor: Setcolors(1),
borderWidth: 1,
datalabels: {
anchor: 'center',
align: 'center',
},
},
],
};
const config_tafkidim_cat_count = {
type: 'bar',
data: data_tafkidim_cat_count,
options: {
scales: {
x: {
grid: {
borderColor: '#829AB1',
},
ticks: {
color: '#627D98',
},
reverse: true,
},
y: {
grid: {
borderColor: '#829AB1',
},
beginAtZero: true,
ticks: {
color: '#627D98',
},
},
},
plugins: {
title: {
text: TL['tafkidim_cat_count'],
padding: {
bottom: 20,
},
},
legend: {
display: false,
},
tooltip: {
callbacks: {
title: (context) => {
return context[0].label.replaceAll(',', ' ');
},
},
},
},
},
};
const tafkidim_cat_count = new Chart('#tafkidim-cat-count'.Element().getContext('2d'), config_tafkidim_cat_count);
solved it with
textAlign = "center"
apparently the default is "start".
I have a React project that utilizes Chart JS to plot charts based on data.
I have a drop down list selector to select which dataset to draw from. However, after I switch to another dataset and then switch back to the initial rendered dataset, it does not appear to work anymore. Here is my code:
import React from 'react';
import { Line } from 'react-chartjs-2';
import { chartData } from './Search.js';
import { xLabels } from './Search.js';
import { allEpsData } from './Search.js';
let chartDataSeason = [];
let xLabelsSeason = [];
export class Graph extends React.Component {
constructor(props) {
super(props);
this.state = {
selectValue: '',
seasonSelected: false,
chartIt: {
labels: xLabels,
datasets: [
{
label: 'Rating',
data: chartData,
fill: false,
borderColor: '#00B4CC',
},
],
},
chartItSeason: {
labels: xLabelsSeason,
datasets: [
{
label: 'Rating',
data: chartDataSeason,
fill: false,
borderColor: '#00B4CC',
},
],
},
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
if (e.target.value === 'All Seasons') {
this.setState({
seasonSelected: false,
chartIt: {
labels: xLabels,
datasets: [
{
label: 'Rating',
data: chartData,
fill: false,
borderColor: '#00B4CC',
},
],
},
});
console.log(chartData);
} else {
chartDataSeason = [];
xLabelsSeason = [];
let seasonNum = e.target.value.slice(6);
for (let i = 0; i < allEpsData[seasonNum - 1].length; i++) {
chartDataSeason.push(allEpsData[seasonNum - 1][i].imdbRating);
xLabelsSeason.push(
`s${seasonNum}e${allEpsData[seasonNum - 1][i].Episode} "${
allEpsData[seasonNum - 1][i].Title
}"`
);
}
this.setState({
selectValue: e.target.value,
seasonSelected: true,
chartItSeason: {
labels: xLabelsSeason,
datasets: [
{
label: 'Rating',
data: chartDataSeason,
fill: false,
borderColor: '#00B4CC',
},
],
},
});
}
// console.log(chartDataSeason)
}
render() {
let seasons = [];
for (let i = 0; i < allEpsData.length; i++) {
seasons.push(i);
}
if (this.state.seasonSelected === false) {
return (
<div>
<select // selector
className="select"
value={this.state.selectValue}
onChange={this.handleChange}
>
<option>All Seasons</option>
{seasons.map((el) => {
return <option key={el}>season {el + 1}</option>;
})}
</select>
<div className="line-container">
<Line
data={this.state.chartIt}
width={600}
height={400}
options={{
maintainAspectRatio: false,
scales: {
xAxes: [
{
ticks: {
display: true, //this will remove only the label
},
gridLines: {
show: false,
display: false,
},
},
],
yAxes: [
{
gridLines: {
show: false,
drawBorder: false,
},
},
],
},
animation: {
duration: 200,
easing: 'easeInOutQuart',
},
tooltips: {
enabled: true,
},
}}
/>
</div>
<div className="seasons-graph-container"></div>
</div>
);
} else {
return (
<div>
<select
className="select"
value={this.state.selectValue}
onChange={this.handleChange}
>
<option>All Seasons</option>
{seasons.map((el) => {
return <option key={el}>season {el + 1}</option>;
})}
</select>
<div className="line-container">
<Line
data={this.state.chartItSeason}
width={600}
height={400}
options={{
maintainAspectRatio: false,
scales: {
xAxes: [
{
ticks: {
display: false, //this will remove only the label
},
gridLines: {
show: false,
display: false,
},
},
],
yAxes: [
{
gridLines: {
show: false,
drawBorder: false,
},
},
],
},
animation: {
duration: 200,
easing: 'easeInOutQuart',
},
tooltips: {
enabled: true,
},
}}
/>
</div>
<div className="seasons-graph-container"></div>
</div>
);
}
}
}
the problem lies with chartData, it is not getting re-rendered correctly -- all the data associated with it has been replaced with the data of the last menu item. However oddly enough, xLabels does get rendered properly. Nothing is changing the value of chartData or xLabels but only xLabels gets correctly updated. Is there anything that I'm missing here? Apologies in advance for the spaghetti code, I am still learning React!
I'm currently working with ChartJS.
It works fine on Firefox and Chrome.
On Safari there is horizontal lines which appear. (here there is one good on orange and two others unwanted )
I have a lot of datapoint (2 lines of 1600 data point). I don't know if it could be a cause.
My code is here.
In some other part, I update time uni and time min.
_displayChart: function(label1, label2){
var timeFormat = 'DD/MM/YYYY HH:mm';
var ctx = document.getElementById(this.heading).getContext('2d');
const data = {
// Labels should be Date objects
//labels:this._stats[1],
datasets: [{
fill: false,
label: label1,
data: this._stats[2],
borderColor: '#fe8b36',
pointRadius: 0,
backgroundColor: [
'#fe8b36'
]
},{
label: label2,
fill: false,
data: this._stats[3],
borderWidth: 1,
pointRadius: 0,
borderColor: 'rgba(99, 100, 200, 1)',
backgroundColor: [
'rgba(99, 100, 200, 0.2)'
]
}]
}
const options = {
type: 'line',
data: data,
options: {
responsive: false,
fill: false,
responsive: true,
maintainAspectRatio:!this._isMobile(),
max: this.max,
hover: {
// Overrides the global setting
mode: 'index'
},
annotation: {
drawTime: 'beforeDatasetsDraw',
events: ['click'],
annotations: []
},
legend: {
labels: {
filter: function(legendItem, chartData) {
if(legendItem.datasetIndex == 2 || legendItem.datasetIndex == 3 ){
return false;
}
return true;
}
}
},
tooltips: {
mode:'index',
intersect : false,
callbacks: {
title: function(tooltipItems, data) {
return tooltipItems[0].xLabel.format(timeFormat);
},
label: function(tooltipItems, data) {
return tooltipItems.yLabel+'%';
}
}
},
scales: {
xAxes: [{
type: 'time',
display: true,
time:{
unit:'day',
min:moment(Date.now()-this.monthTs),
max:this._stats[1][this._stats[1].length]
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
},
display: true
}]
}
}
}
this._chart = new Chart(ctx, options);
},
When I'm applying this, I have no problem:
this._chart.options.scales.xAxes[0].time.unit = 'month';
this._chart.options.scales.xAxes[0].time.stepSize = 1;
this._chart.options.scales.xAxes[0].time.min = this._stats[1][0];
this._chart.options.scales.xAxes[0].time.max = this._stats[1][this._stats[1].length-1];
Thanks