Hey I'm having a lot of trouble trying to implement this example into my React project. The example is different to how I've set mine up and I can't convert it from their way to my way. I have a graph but I really would like the gradient colors to be included. This is as far as I got....
import React from 'react'
import { Chart } from 'react-charts'
class GraphClub extends React.Component {
constructor(props) {
super(props)
this.state = {
chartData: [
{
label: 'Won',
data: [
[0, 0],
],
},
],
}
}
componentDidMount() {
//Get chartData
}
render() {
return (
<>
<Chart
data={this.state.chartData}
axes={[
{
primary: true,
type: 'linear',
position: 'bottom',
show: this.props.axis,
},
{
type: 'linear',
position: 'left',
show: this.props.axis,
},
]}
series={{ type: 'line', showPoints: false }}
tooltip
/>
</>
)
}
}
export default GraphClub
The graph works but when I try and add the colors I can't get very far without getting errors. Would love some help.
Thanks
My first error is
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
Which is obvious seeing as it's a class component and not a functional on this line const [{ activeSeriesIndex, activeDatumIndex }, setState] = React.useState({
A HOC Utility tool built for react-query, through this you can use react-query hooks to fetch and pass data in your React class based components.
If we want to convert a function component to a class component then we need to make the following major changes. Step 1: Create a React application using the following command: Step 2: After creating your project folder i.e. foldername, move to it using the following command: Project Structure: It will look like the following.
If you need to extend a component In Javascript, classes can extend other classes, thus inheriting the parent's prototype. In fact, if you're creating a class component, you have to extend the base component from React. This is more or less not possible with function components, so I wouldn't bother trying
Function components are far less verbose, and require less boilerplate. They're (in my opinion) a bit more flexible with hooks and custom hooks, and they are (usually) a bit more performant. Note: in the examples below, I've shown how to import `React` and `Component`.
They both do exactly the same thing. Both components take a prop (name) and render `Hello, {name} `. It's an extremely simple example but already we can see some of the differences. The class component needs to extend the React Component class, and must specify a render method.
A couple of notes:
First, start from the example code in the repo, not the snippet on that page, which already fails to compile.
Next, convert the Function Components one by one and verify each step of the way before you add your own code. I've uploaded my changes to a branch here.
The two custom hooks useLagRadar()
and useDemoConfig()
used by the example proved to be far too much effort to convert into Class Components, so I simply added them to a Higher-Order Component. To do this, I renamed the MyChart class to MyChartInner and made a new Function Component HOC called MyChart which uses the hooks mentioned above.
import React from "react";
import ReactDOM from "react-dom";
import { Chart } from "react-charts";
import useDemoConfig from "./useDemoConfig";
import useLagRadar from "./useLagRadar";
import ResizableBox from "./ResizableBox";
import "./styles.css";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
activeSeriesIndex: -1,
activeDatumIndex: -1,
};
}
render() {
const {
activeSeriesIndex,
activeDatumIndex,
} = this.state;
const setState = newState => this.setState(newState);
return (
<div>
{JSON.stringify({ activeSeriesIndex, activeDatumIndex }, null, 2)}
<MyChart
elementType="line"
setState={setState}
activeDatumIndex={activeDatumIndex}
activeSeriesIndex={activeSeriesIndex}
/>
<MyChart
elementType="area"
setState={setState}
activeDatumIndex={activeDatumIndex}
activeSeriesIndex={activeSeriesIndex}
/>
<MyChart
elementType="bar"
setState={setState}
activeDatumIndex={activeDatumIndex}
activeSeriesIndex={activeSeriesIndex}
/>
</div>
);
}
}
const MyChart = props => {
useLagRadar();
// const { data, grouping, randomizeData } = useDemoConfig({
const demoConfig = useDemoConfig({
series: 4,
height: 200,
grouping: "primary",
dataType: "ordinal",
show: ["elementType", "grouping"]
});
return (
<MyChartInner
{...demoConfig}
{...props}
/>
);
}
class MyChartInner extends React.Component {
constructor(props) {
super(props);
}
render() {
const {
elementType,
activeDatumIndex,
activeSeriesIndex,
setState
} = this.props;
//useLagRadar();
const { data, grouping, randomizeData } = this.props;
const series = {
type: elementType
};
const axes = [
{
primary: true,
type: "ordinal",
position: "bottom"
},
{
type: "linear",
position: "left",
stacked: true
}
];
const getSeriesStyle =
series => ({
color: `url(#${series.index % 4})`,
opacity:
activeSeriesIndex > -1
? series.index === activeSeriesIndex
? 1
: 0.3
: 1
});
const getDatumStyle =
datum => ({
r:
activeDatumIndex === datum.index &&
activeSeriesIndex === datum.seriesIndex
? 7
: activeDatumIndex === datum.index
? 5
: datum.series.index === activeSeriesIndex
? 3
: datum.otherHovered
? 2
: 2
});
const onFocus =
focused =>
setState({
activeSeriesIndex: focused ? focused.series.id : -1,
activeDatumIndex: focused ? focused.index : -1
});
return (
<>
<button onClick={randomizeData}>Randomize Data</button>
<br />
<br />
<ResizableBox>
<Chart
data={data}
grouping={grouping}
series={series}
axes={axes}
getSeriesStyle={getSeriesStyle}
getDatumStyle={getDatumStyle}
onFocus={onFocus}
tooltip
renderSVG={() => (
<defs>
<linearGradient id="0" x1="0" x2="0" y1="1" y2="0">
<stop offset="0%" stopColor="#17EAD9" />
<stop offset="100%" stopColor="#6078EA" />
</linearGradient>
<linearGradient id="1" x1="0" x2="0" y1="1" y2="0">
<stop offset="0%" stopColor="#FCE38A" />
<stop offset="100%" stopColor="#F38181" />
</linearGradient>
<linearGradient id="2" x1="0" x2="0" y1="1" y2="0">
<stop offset="0%" stopColor="#42E695" />
<stop offset="100%" stopColor="#3BB2B8" />
</linearGradient>
<linearGradient id="3" x1="0" x2="0" y1="1" y2="0">
<stop offset="0%" stopColor="#F4Ea0A" />
<stop offset="100%" stopColor="#df4081" />
</linearGradient>
</defs>
)}
/>
</ResizableBox>
</>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
To run:
# Clone the repo and checkout the branch
git clone --branch stackoverflow-q68091135 https://github.com/codebling/react-charts.git
# Switch to the "custom-styles" example directory
cd react-charts/examples/custom-styles/
# Install the dependencies
npm i
# Run the demo
npm start
Hope this is what you were looking for. This is taken from here, as by first glance same as a first comment, but simplifying their version and taking only a few things that are needed for drawing gradient lines.
Here is example in codesandbox
import React from "react";
import ReactDOM from "react-dom";
import { Chart } from "react-charts";
import jsonData from "./data.json";
class GraphClub extends React.Component {
constructor(props) {
super(props);
this.state = {
data: jsonData,
axes: [
{
primary: true,
type: "ordinal",
position: "bottom"
},
{
type: "linear",
position: "left",
stacked: true
}
]
};
}
getSeriesStyle(series) {
return {
color: `url(#${series.index % 4})`,
opacity: 1
};
}
render() {
const { data, axes } = this.state;
return (
<div style={{ width: "500px", height: "300px" }}>
<Chart
data={data}
axes={axes}
getSeriesStyle={this.getSeriesStyle}
tooltip
renderSVG={() => (
<defs>
<linearGradient id="0" x1="0" x2="0" y1="1" y2="0">
<stop offset="0%" stopColor="#df4081" />
<stop offset="100%" stopColor="#42E695" />
</linearGradient>
<linearGradient id="1" x1="0" x2="0" y1="1" y2="0">
<stop offset="0%" stopColor="#df4081" />
<stop offset="100%" stopColor="#42E695" />
</linearGradient>
<linearGradient id="2" x1="0" x2="0" y1="1" y2="0">
<stop offset="0%" stopColor="#df4081" />
<stop offset="100%" stopColor="#42E695" />
</linearGradient>
<linearGradient id="3" x1="0" x2="0" y1="1" y2="0">
<stop offset="0%" stopColor="#df4081" />
<stop offset="100%" stopColor="#42E695" />
</linearGradient>
</defs>
)}
/>
</div>
);
}
}
export default function App() {
return <GraphClub />;
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
You can find data.json
in codesandbox
Let me know if this works for you.
Edit: Convert it to class component and in a sandbox, I do not get any error
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With