Passing an array of objects through props in React - reactjs

(Solved): Solution was compatibility issues between chart.js and the react version. The recent update to the react version solved it.
I was having trouble finding the solution to this, maybe someone will know why this error is happening:
I am passing an object array via props, but I'm getting an error when it comes to using the prop:
Object array sample (The data for score is fed in through an API and is working):
var teamData = [
{
teamName: "Cowboys",
score: 0,
color: "rgba(0, 34, 68, 0.9)",
},
{
teamName: "Cardinals",
score: 0,
color: "rgba(135, 0, 39, 0.9)",
},
{
teamName: "Patriots",
score: 0,
color: "rgba(0, 21, 50, 0.9)",
},
{
teamName: "49ers",
score: 0,
color: "rgba(170, 0, 0.9)",
},
App.js example
const App = () => {
getData();
return (
<div>
<Header />
<BarChart teamData={teamData} />
<Calculator teamData={teamData} />
<Footer />
</div>
);
};
export default App;
And here is where I pass the props to insert one by one into a chart.js component({props[0].score} is where the error is, it says: SyntaxError C:\Users\name\Documents\Websites\React Based\madden-ranker\src\components\BarChart.js: Unexpected token, expected "," (14:37):
import React from "react";
import { Bar, HorizontalBar } from "react-chartjs-2";
const BarChart = (props) => {
return (
<HorizontalBar
// prettier-ignore
data={{
labels: ['Team1' ],
datasets: [
{
label: 'Cumulative Score',
data: [{props[0].score}, 19, 3, 5, 2, 3, 100, 19, 3, 5, 2, 3, 5, 2, 3, 100, 19, 3, 5, 2, 3, 100, 19, 3, 5, 2, 3, 5, 2, 3, 10, 20],
backgroundColor: []
},
],
}}
height={500}
width={600}
options={{
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
},
},
}}
/>
);
};
export default BarChart;
Interestingly, I tried console logging it inside the teamData component and got this:
line5: console.log(props);
line6: console.log(props.teamData[0].score);
.

Just add a condition to check if props[0] exists before rendering, cause the first time the props is empty, and when you setstate after getting data from API the component rerenders. Hopefully this helps.

I think you had a few commas in places that they shouldn't be
Try this
const BarChart = (props) => {
return (
<HorizontalBar
// prettier-ignore
data={{
labels: ['Team1' ],
datasets: [
{
label: 'Cumulative Score',
data: [{props[0].score}, 19, 3, 5, 2, 3, 100, 19, 3, 5, 2, 3, 5, 2, 3, 100, 19, 3, 5, 2, 3, 100, 19, 3, 5, 2, 3, 5, 2, 3, 10, 20],
backgroundColor: []
}
]
}}
height={500}
width={600}
options={{
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
}
}
}}
/>
);
};

Related

How do I create a stacked horizontal bar chart with Chart.js in React?

I'm really struggling to find a clear answer to this question - especially in React. I'd like to create a stacked horizontal bar chart component for my React application. This is the type of chart I'm trying to create: https://codepen.io/pen. The code pasted below is what I've tried to use so far but it isn't rendering currently.
import React, { Component } from 'react';
import Chart from 'chart.js/auto';
export default class LineChart extends Component {
chartRef = React.createRef();
componentDidMount() {
const ctx = this.chartRef.current.getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
],
},
options: {
scales: {
yAxes: [
{
stacked: true,
},
],
},
},
datasets: [
{
data: [86, 114, 106, 106, 107, 111, 133],
label: 'Total',
borderColor: '#3e95cd',
backgroundColor: '#7bb6dd',
// fill: False,
},
{
data: [70, 90, 44, 60, 83, 90, 100],
label: 'Accepted',
borderColor: '#3cba9f',
backgroundColor: '#71d1bd',
// fill: False,
},
{
data: [10, 21, 60, 44, 17, 21, 17],
label: 'Pending',
borderColor: '#ffa500',
backgroundColor: '#ffc04d',
// fill: False,
},
{
data: [6, 3, 2, 2, 7, 0, 16],
label: 'Rejected',
borderColor: '#c45850',
backgroundColor: '#d78f89',
// fill: False,
},
],
});
}
render() {
return (
<div>
<canvas id="myChart" ref={this.chartRef} />
</div>
);
}
}
You are using V2 syntax of Chart.js while using V3. V3 has major breaking changis inclusing all scales are their own object. For all changes please read the migration guide.
When using objects for scales you get what you want:
const options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'orange'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
backgroundColor: 'pink'
}
]
},
options: {
scales: {
y: {
stacked: true
},
x: {
stacked: true
}
}
}
}
const 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/3.7.1/chart.js"></script>
</body>

Chart js bar with the highest value is a different color among the rest - React

I'm trying to make a chart for Peak Hours and I want the hour with the highest value to be of a different color, how do I do that? For example, in the data array, ideally the one that should have a different bar color would be the one with the value "12". Currently I've only set one color in the data.datasets.backgroundColor and I'm not sure how to add a backgroundColor conditionally. I'm using React so I've installed chartjs in my project. Ideally it should look something like
render() {
return (
<div
style={{ padding: "0 15px" }}
className="chart"
>
<div>
<span>1 PM usually busy</span>
</div>
<Bar
height={145}
responsive={false}
data={{
labels: [
"00",
"",
"",
"03",
"",
"",
"06",
" ",
"",
"09",
"",
"",
"12",
"",
"",
"15",
"",
"",
"18",
" ",
"",
"21",
" ",
"",
"24",
],
fontSize: 1,
datasets: [
{
label: "Time",
data: [
2,
0,
3,
4,
5,
8,
7,
8,
9,
10,
11,
12,
11,
10,
9,
6,
7,
8,
7,
5,
4,
3,
2,
8,
],
backgroundColor: ["#33AF4F"],
borderWidth: 0,
},
],
}}
options={{
barThickness: 10,
borderRadius: 10,
plugins: {
legend: {
display: false,
labels: {
fontSize: 9,
boxWidth: 5,
usePointStyle: true,
},
},
},
scales: {
x: {
ticks: {
font: {
size: 10,
},
},
stacked: true,
grid: {
display: false,
},
},
y: {
ticks: {
display: false,
},
stacked: true,
grid: {
borderDash: [2, 3],
color: "#bdbdbd",
},
},
},
}}
/>
</div>
);
}
You have to call function giving conditional array of colors for in the place of backgroundColor: ["#33AF4F"]
taking into consideration that you want highest value with different color create this function before rendering component.
function getBgColors() {
var array = [2,0,3,4,5,8,7,8,9,10,11,12,11,10,9,6,7,8,7,5,4,3,2,8];
var maxValue = Math.max.apply(this, array);
var bg = array.map(a => a === maxValue ? "#0f7d28" : "#33AF4F");
return bg;
}
and call this function at backgroundColor: getBgColors()

How to show Modal when we click on it using reactjs?

I'm new to react and wanted to create a Calendar and wanted to add event to the respective date in the Calendar, when we click on the field it should show the modal popup but modal is not getting displayed. Here i'm using only semantic-ui-react for designing the every component. Can anyone help me to resolve this issue?
first Component:
import React, { Component } from "react";
import { render } from "react-dom";
import { Calendar, momentLocalizer } from "react-big-calendar";
import moment from "moment";
import "react-big-calendar/lib/css/react-big-calendar.css";
import CreateEvent from "./CreteEvent";
const localizer = momentLocalizer(moment);
class ShowCalendar extends Component {
constructor() {
super();
const now = new Date();
const events = [
{
id: 0,
title: "All Day Event very long title",
allDay: true,
start: new Date(2015, 3, 0),
end: new Date(2015, 3, 1)
},
{
id: 1,
title: "Long Event",
start: new Date(2015, 3, 7),
end: new Date(2015, 3, 10)
},
{
id: 2,
title: "DTS STARTS",
start: new Date(2016, 2, 13, 0, 0, 0),
end: new Date(2016, 2, 20, 0, 0, 0)
},
{
id: 3,
title: "DTS ENDS",
start: new Date(2016, 10, 6, 0, 0, 0),
end: new Date(2016, 10, 13, 0, 0, 0)
},
{
id: 4,
title: "Some Event",
start: new Date(2015, 3, 9, 0, 0, 0),
end: new Date(2015, 3, 10, 0, 0, 0)
},
{
id: 5,
title: "Conference",
start: new Date(2015, 3, 11),
end: new Date(2015, 3, 13),
desc: "Big conference for important people"
},
{
id: 6,
title: "Meeting",
start: new Date(2015, 3, 12, 10, 30, 0, 0),
end: new Date(2015, 3, 12, 12, 30, 0, 0),
desc: "Pre-meeting meeting, to prepare for the meeting"
},
{
id: 7,
title: "Lunch",
start: new Date(2015, 3, 12, 12, 0, 0, 0),
end: new Date(2015, 3, 12, 13, 0, 0, 0),
desc: "Power lunch"
},
{
id: 8,
title: "Meeting",
start: new Date(2015, 3, 12, 14, 0, 0, 0),
end: new Date(2015, 3, 12, 15, 0, 0, 0)
},
{
id: 9,
title: "Happy Hour",
start: new Date(2015, 3, 12, 17, 0, 0, 0),
end: new Date(2015, 3, 12, 17, 30, 0, 0),
desc: "Most important meal of the day"
},
{
id: 10,
title: "Dinner",
start: new Date(2015, 3, 12, 20, 0, 0, 0),
end: new Date(2015, 3, 12, 21, 0, 0, 0)
},
{
id: 11,
title: "Birthday Party",
start: new Date(2015, 3, 13, 7, 0, 0),
end: new Date(2015, 3, 13, 10, 30, 0)
},
{
id: 12,
title: "Late Night Event",
start: new Date(2015, 3, 17, 19, 30, 0),
end: new Date(2015, 3, 18, 2, 0, 0)
},
{
id: 12.5,
title: "Late Same Night Event",
start: new Date(2015, 3, 17, 19, 30, 0),
end: new Date(2015, 3, 17, 23, 30, 0)
},
{
id: 13,
title: "Multi-day Event",
start: new Date(2015, 3, 20, 19, 30, 0),
end: new Date(2015, 3, 22, 2, 0, 0)
},
{
id: 14,
title: "Today",
start: new Date(new Date().setHours(new Date().getHours() - 3)),
end: new Date(new Date().setHours(new Date().getHours() + 3))
},
{
id: 15,
title: "Point in Time Event",
start: now,
end: now
}
];
this.state = {
name: "React",
showModal: false,
events
};
this.openModal = this.openModal.bind(this);
this.handleCloseModal = this.handleCloseModal.bind(this);
}
handleCloseModal() {
this.setState({ showModal: false });
}
openModal() {
this.setState({ showModal: true });
}
render() {
return (
<div>
<div style={{ height: "500pt" }}>
<Calendar
events={this.state.events}
startAccessor="start"
endAccessor="end"
defaultDate={moment().toDate()}
localizer={localizer}
onDrillDown={this.openModal}
/>
</div>
{this.state.showModal ? (
<CreateEvent
isOpen={this.state.showModal}
onClose={this.handleCloseModal}
/>
) : (
""
)}
</div>
);
}
}
export default ShowCalendar;
2nd Component: Modal.jsx
import React, { Component } from "react";
import { Modal, Button, Header, Icon } from "semantic-ui-react";
export default class CreteEvent extends Component {
render() {
return (
<div>
<Modal isOpen={this.props.isOpen}>
<Modal.Header>Create Event</Modal.Header>
<Modal.Content>
<Modal.Description>Hi Everyone</Modal.Description>
</Modal.Content>
<Modal.Actions>
<Button primary onClick={this.props.onClose}>
Close <Icon name="right chevron" />
</Button>
</Modal.Actions>
</Modal>
</div>
);
}
}
Here is the entire code "Code: "https://codesandbox.io/s/strange-bhaskara-1n1jc""
So I have got in to the office and could have look, you never include the semantic UI css: https://react.semantic-ui.com/usage/#theme
In index.js https://react.semantic-ui.com/usage/#theme and add semantic-ui-css as a dependency, and as #PompolutZ mentioned the modal needs open vs isOpen
There is probably some other issues, but changing the default state to true now shows the modal - might just need to fix up how the modal gets displayed, i.e. when does openModal get called. (Ah clicking the date is the driver (never used the calendar component before: had to look at the docs)
https://codesandbox.io/s/morning-darkness-hz06m?fontsize=14&hidenavigation=1&theme=dark
Add dependency to semantic-ui-css
Import css in your main index.js file:
import 'semantic-ui-css/semantic.min.css';
You need to change isOpen to just open in Modal:
import React, { Component } from "react";
import { Modal, Button, Header, Icon } from "semantic-ui-react";
export default class CreteEvent extends Component {
render() {
return (
<div>
<Modal open={this.props.isOpen}>
<Modal.Header>Create Event</Modal.Header>
<Modal.Content>
<Modal.Description>Hi Everyone</Modal.Description>
</Modal.Content>
<Modal.Actions>
<Button primary onClick={this.props.onClose}>
Close <Icon name="right chevron" />
</Button>
</Modal.Actions>
</Modal>
</div>
);
}
}
Here is fixed codesandbox: https://codesandbox.io/s/sad-lamport-y6jqg (with aforementioned import)

update charjs dataset using react library

I created pretty easy curves with the library chartjs.
I have created a simple input field or I can select a number. I would like to be able to update this data line: [5, 7, 4, 2, 1, 8, 7, 2, 5].
For example, if we put the number 3, it replaces 5 by 3. I stuck on this problem.
Any help will be very helpful, thank you very much!
I attach my code below.
this.state = {
value: '',
data: {
labels: ["1", "2", "3", "4", "5", "6", "7", "8", "9"], // nb jours
datasets: [
{
type: 'line',
label: "Hour of sleep",
backgroundColor: 'transparent',
borderColor: 'green',
pointRadius: 3,
data: [6, 8, 7, 8, 7, 7, 7, 8, 9, 6] // pour l instant on part du principe que dormir 10 heure c est le meilleur.
},
{
type: 'line',
backgroundColor: 'transparent',
borderColor: 'orange',
label: "Fruits and legume",
pointRadius: 3,
data: [5, 7, 4, 2, 1, 8, 7, 2, 5] // faire un select qui selon le jour remplis le tableaux data.
},
]
}
}
render() {
return(
<div style={{ position: "relative", width: "80%", height: "50%"}}>
<form onSubmit={this.handleSubmit}>
<input type="number" value={this.state.value} onChange={this.handleChange} /><input type="submit" value="ok" />
</form>
<Line
options={{
responsive: true
}}
data = {this.state.data}
/>
</div>
)
}
handleChange = (e) => {
let value = e.target.value;
this.setState({
value: value
});
}
Have you tried to add redraw={true} to Line component?
<Line
options={{
responsive: true
}}
data = {this.state.data}
redraw={true}
/>
If it doesn't work, can you please provide also handleChange and handleSubmit functions

Adding labels to both ends of axis google charts

I've built a bubble chart on quadrant graph using google-charts in reactjs but I can only had two labels on my axis and I need four.
I've tried fiddling with the code but unsuccessfully. I don't want to append dummy data and additional series elements. Is overlay the only option to add axis?
<Chart
width={"800px"}
height={"600px"}
chartType="BubbleChart"
loader={<div>Loading Chart</div>}
data={[
["Age", "Weight", "4", "Group", "Size"],
["Name", -12, 34, 1, 7],
["Name", -5.5, 6, 1, 8],
["Name", 22, 35, 1, 4],
["Name", 14, 4, 2, 5],
["Name", -5, -5, 2, 6],
["Name", 15, 34, 3, 1],
["Name4", 7, -21, 4, 22]
]}
options={{
bubble: {},
chartArea: { left: 20, top: 0, width: "90%", height: "95%" },
colors: ["red", "green", "yellow", "blue"],
hAxis: {
title: "Low Importance",
ticks: "none",
baseline: 0,
ticks: ["none"],
minValue: -50,
gridlines: { count: 0 },
maxValue: 50
},
vAxis: {
title: "Low Urgency",
baseline: 0,
ticks: ["none"],
minValue: -50,
gridlines: { count: 0 },
maxValue: 50
},
legend: "none"
}}
/>;
As you can see in the graph below, I can only get left and bottom labels but not top and right. Any ideas how I could achieve that using google-chart library for reactjs?

Resources