Related
(Requirement: The bar has to start from the first tick(i.e label "a" below) in x axis whereas the line has to start from third tick(label "c" below)).
I have tried the following way.
import React from "react";
import Chart from 'chart.js';
import ChartDataLabels from 'chartjs-plugin-datalabels';
class Barchart extends React.Component {
//chart= null;
componentDidMount(){
this.configureChart();
}
configureChart = ()=>{
let bardata=[7, 3, 2];
let linedata=[ 0,0,0,75, 55, 80, 65];
// xaxislabel=["a","b","c"]
// xaxislabelline=["d","e","f","g"]
const node=this.node;
new Chart(node,{
plugins: [ChartDataLabels],
type:'',
data:{
datasets:[
{
yAxisID:'A',
label: "Bar Dataset",
data: bardata ,
type: "bar",
backgroundColor: "#DE924B",
order:1
},
{
yAxisID:'B',
label: "Line Dataset 2",
data: linedata,
type: "line",
fill: false,
borderColor: 'rgb(75, 192, 192)',
order:2
},
],
labels:["a","b","c","d","e","f","g"]
},
options:{
scales:{
yAxes:[
{ id:'A',
display:true,
ticks:{
beginAtZero:true
}
},
{ id:'B',
display:true,
ticks:{
beginAtZero:true
}
}
],
xAxes:[
{ id:'C',
display: true,
barThickness: 25,
ticks: {
beginAtZero: true,
}
},
{ id:'D',
display: true,
ticks: {
beginAtZero:true,
min:'c',
}
}
},
]
}
}
})
}
render(){
return(
<div>
<canvas
style={{ width: 650, height: 165 }}
ref={node => (this.node = node)}
/>
</div>
);
}
}
export default Barchart;
Below is the attached result I got.
I am not sure how to have the line graph start from label "c" of the main label(or have single label for both graphs).
Found the solution.
changed
let linedata=[ 0,0,0,75, 55, 80, 65]-->
let linedata=[ null,null,null,75, 55, 80, 65];
I'm using react-Chartjs-2 pie chart for my dashboard. as per the requirement I have to show both label with data in the legend. the below component which I'm using in my application
import React, { Component } from "react";
import { Doughnut } from "react-chartjs-2";
class DoughnutChart extends Component {
constructor(props) {
super(props);
}
render() {
const chartdata = {
labels: ["Newly Added", "Edited", "Deleted"],
datasets: [
{
label: "Markets Monitored",
backgroundColor: [
"#83ce83",
"#959595",
"#f96a5d",
"#00A6B4",
"#6800B4",
],
data: [9, 5, 3],
},
],
};
return (
<Doughnut
data={chartdata}
options={{
legend: { display: true, position: "right" },
datalabels: {
display: true,
color: "white",
},
tooltips: {
backgroundColor: "#5a6e7f",
},
}}
/>
);
}
}
export default DoughnutChart;
now I'm getting chart like given below
my output
my requirement is adding values in legend(customizing chart legend). example image expected output
One way to do it would be to define data and labels before creating the chart. Then you can add the data to labels using .map method.
import React, { Component } from "react";
import { Doughnut } from "react-chartjs-2";
class DoughnutChart extends Component {
constructor(props) {
super(props);
}
render() {
let data = [9, 5, 3]
let labels = ["Newly Added", "Edited", "Deleted"]
let customLabels = labels.map((label,index) =>`${label}: ${data[index]}`)
const chartdata = {
labels: customLabels,
datasets: [
{
label: "Markets Monitored",
backgroundColor: [
"#83ce83",
"#959595",
"#f96a5d",
"#00A6B4",
"#6800B4",
],
data: data,
},
],
};
return (
<Doughnut
data={chartdata}
options={{
legend: { display: true, position: "right" },
datalabels: {
display: true,
color: "white",
},
tooltips: {
backgroundColor: "#5a6e7f",
},
}}
/>
);
}
}
export default DoughnutChart;
I am using chart.js in a React app to chart live data. I want the user to be able to pan and zoom on the graph, so I've also included the chart.js zoom plugin. My relevant code is below. Before I've either zoomed or panned, the chart continually shifts to show new data. However, after zooming of panning, the chart no longer automatically shifts to show new data—I need to manually zoom out or pan right to show the new data. I'd like it to be so that if the user is zoomed/panned on the far right side of the chart (i.e., where the newest data is added), the chart will automatically shift as it does before I initially zoom/pan. Is this possible? Or is there another way I can go about doing this if it does not work with chart.js? Thanks!
// graph.js
import React from "react";
import Chart from "./chart";
import * as zoom from 'chartjs-plugin-zoom';
let updateInterval = 1000;
let typeData = "Live";
class Graph extends React.Component {
constructor(props) {
super(props);
this.state = {
meta: {
ticks: props.ticks,
lab: [],
dat: []
},
lineChartData: {
labels: [],
datasets: [
{
type: "line",
label: typeData,
backgroundColor: "rgba(0, 0, 0, 0)",
borderColor: this.props.theme.palette.primary.main,
pointBackgroundColor: this.props.theme.palette.secondary.main,
pointBorderColor: this.props.theme.palette.secondary.main,
borderWidth: "2",
lineTension: 0.45,
data: []
}
]
},
lineChartOptions: {
responsive: true,
maintainAspectRatio: false,
tooltips: {
enabled: true
},
scales: {
xAxes: [
{
ticks: {
autoSkip: true,
suggestedMax: 100
}
}
]
},
plugins: {
zoom: {
pan: {
enabled: true,
mode: 'x',
speed: 100,
},
zoom: {
enabled: true,
mode: 'x',
speed: 0.75,
}
}
}
}
};
this.updateChart = this.updateChart.bind(this);
}
componentDidMount() {
setInterval( this.updateChart,
updateInterval)
}
updateChart() {
console.log(this.state.lineChartOptions.scales.xAxes.suggestedMax);
const newDat = this.state.meta.dat;
const newNum = Math.round(Math.random()*100);
newDat.push(newNum);
const newLab = [...Array(newDat.length).keys()];
const newMeta = {ticks: this.props.ticks, lab: newLab, dat: newDat}
this.setState({meta: newMeta})
const oldDataSet = this.state.lineChartData.datasets[0];
let newDataSet = { ...oldDataSet };
newDataSet.data.push(newNum);
const possLabs = this.state.meta.lab;
const newChartData = {
...this.state.lineChartData,
datasets: [newDataSet],
labels: possLabs
};
this.setState({ lineChartData: newChartData });
}
render() {
return (
<div style={{height: 400}}>
<Chart
data={this.state.lineChartData}
options={this.state.lineChartOptions}
/>
</div>
);
}
}
export default Graph;
// chart.js
import React from "react";
import { Line } from "react-chartjs-2";
const Chart = props => <Line data={props.data} options={props.options} />;
export default Chart;
// App.js
import React from "react";
import Graph from "./graph"
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
}
};
render() {
return (
<div>
<Graph/>
</div>
);
}
}
export default App;
I want to have three LineCharts below each other. They are sharing same x-axis (time). I was able to create this:
However, it is very useless to have x-axis on the top and middle chart. I would prefer not to display the x-axis for the top and middle. When I tried it, I got this:
But as you can see, the last grid for 12AM is not visible for the top and middle chart, and the grids are not aligned (it looks weird). Each chart is rendered as a separate component using React.
Here are my TimelinePlot component which is rendering each LineChart (sorry for the mess, but I did not yet refactor it):
import React from 'react';
import { Line } from 'react-chartjs-2';
import { GetColors } from '../../utils/PlotDescriptionHelper';
class TimelinePlot extends React.Component {
MapPropsToData(props) {
const colors = GetColors(props.series.length);
return props.series.map((dataset, index) => {
return {
label: dataset.name,
data: dataset.data,
borderWidth: 1,
fill: false,
borderColor: colors[index],
//pointBackgroundColor: 'rgb(255,255,255)',
};
});
}
MapPropsToOptions(props) {
return {
elements: {
point: {
radius: 0,
},
},
legend: {
// display: props.showLegend,
position: 'top',
align: 'end',
},
scales: {
yAxes: [
{
ticks: props.yAxisTicks,
scaleLabel: {
display: true,
labelString: props.yAxisName + props.yAxisUnit,
},
},
],
xAxes: [
{
type: 'time',
// position: props.xAxisPosition,
time: {
parser: 'YYYY-MM-DD HH:mm',
tooltipFormat: 'll HH:mm',
},
// scaleLabel: {
// display: true,
// //labelString: 'Date',
// },
ticks: {
min: props.xAxisStart,
max: props.xAxisEnd,
//display: true,
display: props.xAxisDisplay,
},
},
],
},
};
}
render() {
const dataset = { datasets: this.MapPropsToData(this.props) };
return (
<div className='measurement-row'>
<Line
data={dataset}
options={this.MapPropsToOptions(this.props)}
position='absolute'
height='15%'
width='80%'
/>
</div>
);
}
}
And here is the render method of the parent using TimelinePlot component:
render() {
var plots = Object.keys(this.state.timeSeries).map((key, index) => {
return (
<TimelinePlot
key={key + index}
series={this.state.timeSeries[key]}
yAxisName={FirstLetterToUpper(key)}
yAxisUnit={MapKeyToUnit(key)}
xAxisDisplay={index === Object.keys(this.state.timeSeries).length - 1}
xAxisPosition={index === 0 ? 'top' : 'bottom'}
xAxisStart={this.state.startTime}
xAxisEnd={this.state.endTime}
showLegend={index === 0}
yAxisTicks={MapYAxisTicks(key)}
/>
);
});
return (
<div className='width-90'>
<TimelineDashboardHeader />
<div className='dashboard__column'>{plots}</div>
</div>
);
}
I'm using Chart js version: 2.1.4 and I'm not able to limit the bar width. I found two options on stackoverflow
barPercentage: 0.5
or
categorySpacing: 0
but neither of one works with the mentioned version. Is there a way to solve this issue without manually modifying the chart.js core library?
thanks
You were right : The attribute you have to edit is barPercentage.
But maybe the error comes from where you edited the value.
As you can see in the bar chart options :
Name : barPercentage
- Type : Number
- Default : 0.9
- Description : Percent (0-1) of the available width each bar should be within the category percentage. 1.0 will take the whole category width and put the bars right next to each other. Read More
The attribute is actually stored in scales.xAxes ("Options for xAxes" table).
So you just have to edit your chart this way :
var options = {
scales: {
xAxes: [{
barPercentage: 0.4
}]
}
}
Here is a fully working example with a custom width (0.2) for the bar :
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: "rgba(75,192,192,0.4)",
borderColor: "rgba(75,192,192,1)",
data: [65, 59, 75, 81, 56, 55, 40],
}]
};
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: data,
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
// Change here
barPercentage: 0.2
}]
}
}
});
console.log(myChart);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.6/Chart.js"></script>
<canvas id="myChart"></canvas>
Update (Chart.js Version 2.2.0+)
As stated in the Release Version 2.2.0 - Candidate 2 :
Enhancements
Can now manually configure the thickness of a bar in a bar chart. Use a new barThickness option on the correct axis to set the thickness of a bar.
And so on ...
For version 2.8+ (and apparently as far back as 2.2), there are now some excellent controls over the bar thickness, max thickness, etc.
Per the Chart.js documentation, you would set them like so:
{
type: 'bar', // or 'horizontalBar'
data: ...,
options: {
scales: {
xAxes: [{
barThickness: 6, // number (pixels) or 'flex'
maxBarThickness: 8 // number (pixels)
}]
}
}
}
As of v2.7.2 it can be done by:
scales: {
xAxes: [{
maxBarThickness: 100,
}],
}
In case if you are using ng2-chart in an angular project then the bar chart configuration looks Alike this:
npm install ng2-charts chart.js --save
import 'ng2-charts' in your module.
import { ChartsModule } from 'ng2-charts';
Now the bar chart configurations:
barChartOptions: ChartOptions = {
responsive: true,
maintainAspectRatio: false,
legend: {
display: false
},
};
barChartLabels: Label[] = ['2006', '2007', '2008', '2009', '2010', '2011', '2012'];
barChartType: ChartType = 'bar';
barChartLegend = true;
barChartPlugins = [];
barChartData: ChartDataSets[] = [
{
barThickness: 16,
barPercentage: 0.5,
data: [65, 59, 80],
label: 'Growth'
},
{
barThickness: 16,
barPercentage: 0.5,
data: [28, 48, 40],
label: 'Net'
}
];
barChartColors: Color[] = [
{ backgroundColor: '#24d2b5' },
{ backgroundColor: '#20aee3' },
];
Now the HTML part:
<div class="bar-chart-wrapper">
<canvas baseChart [datasets]="barChartData" [colors]="barChartColors"
[labels]="barChartLabels"
[options]="barChartOptions" [plugins]="barChartPlugins" [legend]="barChartLegend"
[chartType]="barChartType">
</canvas>
</div>
You can control the height of your chart container
.bar-chart-wrapper {
height: 310px;
}
barThickness and maxBarThickness (previously in ChartOptions[]) are now a part of ChartDataSets[].
As per above answer
Here is complete Bar chart graph using react chartjs2.
import React from 'react';
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend,
} from 'chart.js';
import { Bar } from 'react-chartjs-2';
ChartJS.register(
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend
);
export const options = {
responsive: true,
plugins: {
legend: {
position: 'top', // lable position left/right/top/bottom
labels: {
boxWidth: 0, // lable box size
}
},
},
elements: {
point: {
radius: 1
}
},
scales: {
x: {
display: false, // show/ hide x-axis
grid: {
display: false // show/hide grid line in x-axis
},
},
y: {
display: false, // same as x-axis
grid: {
display: false
}
}
}
};
const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
export const data = {
labels,
datasets: [
{
label: 'datasets', // label text
data: [100, 300, 500, 700],
backgroundColor: '#7b62ff', // bar / column color
barThickness: 6, // <<<<<<<<<<<< bar / column size
},
],
};
export default function ResumesGraph() {
return (
<div>
<Bar
data={data}
options={options}
width={'500px'}
height={'180px'}
/>
</div>
);
}
Try this
import {Chart} from "chart.js"
Chart.defaults.datasets.bar.maxBarThickness = 73;
//also try barPercentage
For those who are interested, i made a quick fork based on 3.9 branch to manage dynamic width :
https://github.com/stephanebouget/Chart.js/tree/3.9
For example :
Live demo
https://codepen.io/stephanebouget/pen/PoerxPP
var data = {
datasets: [{
label: 'Dataset #1',
backgroundColor: 'rgba(255,99,132,0.2)',
borderColor: 'rgba(255,99,132,1)',
borderWidth: 1,
hoverBackgroundColor: 'rgba(255,99,132,0.4)',
hoverBorderColor: 'rgba(255,99,132,1)',
data: [65, 59, 20, 81, 56, 55, 40],
setPercentage: [10, 2, 20, 40, 4, 6, 18], // Here is the magic !!!
}],
};