I am using Recharts and using labellist to add label on top of every stacked bar chart, but instead of only one label for every stacked chart it is creating a label for stack (every stack) and my custom render events looks like:
const renderCustomizedEvent = (props) => {
const { x, y, width, height, value } = props;
const radius = 20;
if (!value) return null;
return (
<g>
<rect
x={x + width / 2 - 30}
y={y - radius - 10}
width="60"
height="20"
style={{ strokeWidth: 3, fill: "#203557" }}
/>
<text
x={x + width / 2}
y={y - radius}
fill="#fff"
textAnchor="middle"
dominantBaseline="middle"
style={{ fontSize: "10px" }}
>
data
</text>
</g>
);
};
and my data looks like:
const data = [
{
Date: "2022-12",
Electricity: 220.129804,
Gas: 90,
Net_Carbon_Impact: 90,
EventType: "Event_Gas"
},
{
Date: "2022-11",
Electricity: 220.129804,
Gas: 0.023072,
Net_Carbon_Impact: 220.15287600000002
}
]
<ResponsiveContainer width={width} height={400}>
<ComposedChart
data={data}
stackOffset="sign"
margin={{ left: 20, bottom: 60 }}
barSize={40}
barCategoryGap={40}
>
<CartesianGrid color="#E1E2E1" vertical={false} />
<XAxis
dataKey="Date"
axisLine={false}
tickLine={false}
scale="band"
tick={customizedGroupTick}
interval={0}
/>
<YAxis
tickLine={false}
color="#E1E2E1"
tickSize={1}
tickCount={uniquelabels.length + 1}
label={{ value: "tCO2-e", angle: -90, position: "insideLeft" }}
tickFormatter={(e) => {
return Math.abs(e) >= 1000000000
? `${e / 1000000000}b`
: Math.abs(e) >= 1000000
? `${e / 1000000}m`
: Math.abs(e) >= 1000
? `${e / 1000}k`
: e;
}}
/>
<Tooltip content={customizedTooltip} cursor={false} />
<Legend
layout="horizontal"
verticalAlign="top"
content={renderLegend}
align="left"
/>
{uniquelabels.map((item: string) => (
<Bar
key={item}
dataKey={item}
stackId="a"
fill={renderColor(item)}
width="30px"
>
<LabelList
position="top"
dataKey="EventType"
content={renderCustomizedEvent}
/>
</Bar>
))}
<Line
strokeWidth={3}
type="monotone"
dataKey="Net_Carbon_Impact"
stroke="#FFE81C"
dot={{ strokeWidth: 8, fill: "#FFE81C" }}
/>
</ComposedChart>
</ResponsiveContainer>
how it looks like now is like the picture attached, and as it is shown in the picture also Jan2023 has two events (Gas and Electricity(is is hidden behind the bar chart)) but i only want one of them which is gas. any help will be appreciate. Thank you in advance
Related
I'm using rechart line chart to display the date, I have the dates as props from the Api and when I try to format it shows no value but the values are shown in the custom tooltip.
I tried to console log the value and it shows no value,I'm not sure why !!
My component is
import React from 'react'
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
import moment from 'moment';
import CustomTooltip from './tooltip/CustomTooltip';
const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042'];
const CustomLineChart = (props) => {
const formatXAxis = tickItem => {
return moment.unix(Number(tickItem.toString())).format('D MMM');
}
console.log('line', props.data)
const data = props.data
return (
<div style={{ width: '100%', height: 500 }}>
<ResponsiveContainer >
<LineChart
width={700}
height={400}
data={data}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis padding={{ left: 20 }}
dataKey='time' name='time' tickFormatter={formatXAxis}
onClick={(item) => console.log('insidex', item)}
/>
{/* <YAxis label={{ value: 'Number of Users', angle: -90, position: 'insideLeft' }} /> */}
<YAxis />
<Tooltip wrapperStyle={{ border: 'none', outline: 'none' }} content={<CustomTooltip header={props.datakey[0]} content={props.datakey} />} />
<Legend />
{props.datakey.map((key, index) => {
if (index !== 0) {
return <Line type="monotone" dataKey={key} stroke={COLORS[index]} activeDot={{ r: 8 }} />
}
})}
</LineChart>
</ResponsiveContainer>
</div>
)
}
export default CustomLineChart
my data is something like this :
Hi I am creating a barchart using the Recharts library. I am wanting to draw a trend line on top of the barchart like so:
I am using the following to draw the barchart:
<BarChart data={transformedDataByCategory}>
<CartesianGrid strokeDasharray="3 3" vertical={false} />
<XAxis
dataKey="category"
interval={0}
tickLine={false}
tick={(e) => {
const { payload: { value } } = e;
e.fill = theme.colors.onfCategory[value].base;
e.fontSize = '11px';
e.fontWeight = 'bold';
return <ChartText {...e}>{value}</ChartText>;
}}
/>
<YAxis />
<Legend />
<Tooltip cursor={{ fill: '#f1f1f1' }} />
{years.map((year, i) => <>
<Bar key={`year_${i}`} dataKey={year} fill={yearColours[i]}/>
</>)}
</BarChart>
I have tried using the ReferenceLine component to draw on top of the graph but have had no luck. Any help would be great thanks!
I have a rechart bar chart that I would like to have the Labels like this...
And I want the colors to be like this...
The problem is that I can't seem to get them both at the same time. The second image is the closest I can get but it is bringing in the value instead of the name hence the int(85) instead of string(85%) and it is also not angles.
Here is my code. I commented out the part that allows for angled labels because it wont work when is there..
import { BarChart, Bar, LabelList, Cell } from "recharts";
import { colors } from "../../Colors/colors";
const data = [
{
name: `${85}%`,
uv: 85,
},
{
name: `${95}%`,
uv: 95,
},
{
name: `${80}%`,
uv: 80,
},
];
export default function MyBarChart(): JSX.Element {
return (
<BarChart width={150} height={400} data={data}>
<Bar
dataKey="uv"
fill={colors.blueTheme[0]}
radius={8}
label={{ position: "insideBottom", fill: "black" }}
name="name"
>
{/* <LabelList
dataKey="name"
position="insideBottom"
angle={270}
offset={25}
/> */}
{colors.blueTheme.map((entry, index) => (
<Cell key={`cell-${index}`} fill={colors.blueTheme[index % 20]} />
))}
</Bar>
</BarChart>
);
}
The colors.tsx
export const colors = {
blueTheme: ["#85A5FF", "#ADC6FF", "#D6E4FF"],
};
How can I get the angled labels with the color differences simultaneously?
I figured it out...
<BarChart width={150} height={400} data={data}>
<Bar dataKey="uv" radius={8}>
<LabelList
dataKey="name"
position="insideBottom"
angle={270}
offset={25}
fill="black"
/>
{colors.blueTheme.map((entry, index) => (
<Cell key={`cell-${index}`} fill={colors.blueTheme[index % 20]} />
))}
</Bar>
</BarChart>
If you update the data and add the color each bar needs to have, as follows:
const data = [
{
name: `${85}%`,
uv: 85,
color: "#85A5FF" // you may pass a value directly as string
},
{
name: `${95}%`,
uv: 95,
color: colors.blueTheme[1] // or colors.blueTheme by index
},
{
name: `${80}%`,
uv: 80,
color: colors.blueTheme[getIndex()] // or some custom logic to evaluate index
},
];
You can update the code as follows and it will work:
export default function MyBarChart(): JSX.Element {
return (
<BarChart width={300} height={400} data={data}>
<Bar
dataKey="uv"
fill="#85A5FF"
radius={8}
label={{
position: "insideBottom",
angle: -60,
fill: "black",
offset: 25
}}
>
<LabelList dataKey="name" />
{data.map((entry, index) => (
<Cell fill={entry.color} key={`cell-${index}`} />
))}
</Bar>
</BarChart>
);
}
Working example:
https://codesandbox.io/embed/bar-chart-with-customized-event-forked-4ygf7i?fontsize=14&hidenavigation=1&theme=dark
I have to create this graph in React. I am using the rechart npm package to do so. But I am not able to get the corner radiuses and the linear gradient. I am open to use any other library if needed.
Image
What I have tried?
I have used rechart Pie component to achieve this. Here is the code
import React from 'react';
import { PieChart, Pie, Sector } from 'recharts';
import getDevice from '../../styles/devices';
const renderActiveShape = (props) => {
const { cx, cy, startAngle, endAngle, payload, innerRadius, outerRadius, z, cornerRadius } = props;
console.log(startAngle, endAngle)
return (
<g>
<text x={cx} y={cy - 20} dy={8} fontSize={z ? '16px' : "24px"} textAnchor="middle" fill="#001233" fontWeight="bold">
{/* {parseFloat(payload.value / 1000).toFixed(1)}K */}
{payload.value < 1000 ? payload.value : `${parseFloat(payload.value / 1000).toFixed(1)}K`}
</text>
<text x={cx} y={cy + 5} dy={8} fontSize="12px" textAnchor="middle" fill="#5C677D">
{payload.name}
</text>
<Sector
cx={cx}
cy={cy}
innerRadius={innerRadius}
outerRadius={outerRadius + 20}
startAngle={startAngle}
endAngle={endAngle}
fill={"#12A4ED"}
cornerRadius={payload.name === 'Deposit' ? cornerRadius : 0}
/>
<Sector
cx={cx}
cy={cy}
innerRadius={innerRadius - 18}
outerRadius={innerRadius - 10}
startAngle={startAngle}
endAngle={endAngle}
fill={"#7674740f"}
/>
{/* <path d={`M${sx},${sy}L${mx},${my}L${ex},${ey}`} stroke={fill} fill="none" />
<circle cx={ex} cy={ey} r={2} fill={fill} stroke="none" /> */}
{/* <text x={ex + (cos >= 0 ? 1 : -1) * 12} y={ey} textAnchor={textAnchor} fill="#333">{`${value}%`}</text> */}
</g>
);
};
export default function Chart({ data }) {
// const [activeIndex, setActiveIndex] = useState(1)
// const onPieEnter = (_, index) => {
// setActiveIndex(index)
// };
const { isMobile } = getDevice()
return (
<PieChart width={400} height={350}>
<Pie
activeIndex={1}
activeShape={renderActiveShape}
data={data}
cx={200}
innerRadius={isMobile ? 60 : 80}
outerRadius={isMobile ? 100 : 120}
cornerRadius={isMobile ? 5 : 10}
fill="#7DC762"
dataKey="value"
z={isMobile}
>
</Pie>
</PieChart>
);
}
But what I get by using this is
Can anyone help how to achieve this? Any help is appreciated.
To add gradient color to your chart, you can do the following:
This is just an example:
<PieChart width={400} height={350}>
{/* This will allow to add color based on your need, so update it accordingly */}
<defs>
<linearGradient id="colorUv" x1="1" y1="1" x2="0" y2="0">
<stop offset="30%" stopColor="#6584FF" stopOpacity={0.5} />
<stop offset="95%" stopColor="#FFFFFF" stopOpacity={0.5} />
</linearGradient>
</defs>
<Pie
activeIndex={1}
activeShape={renderActiveShape}
data={data}
cx={200}
innerRadius={isMobile ? 60 : 80}
outerRadius={isMobile ? 100 : 120}
cornerRadius={isMobile ? 5 : 10}
fill="url(#colorUv)"//Add the id 'colorUv' which is used in linearGradient
dataKey="value"
z={isMobile}
></Pie>
</PieChart>
I have tried formatting the X-axis to display dates in order, but some of the points are still not showing. Here's a link for viewing the chart and editing - https://snack.expo.io/#anushkas/4cfb05
The very first label is suppose to be '09-10-2020' , it shows as '10-2020'. I am using react-native-svg-charts library.
import React from 'react';
import {LineChart, XAxis, YAxis} from 'react-native-svg-charts';
import {View, Text} from 'react-native';
import {Svg, Line, Circle, G, Rect} from 'react-native-svg';
export default class CustomLineChartOne extends React.PureComponent {
handleFill = (value) => {
if (value > 100) {
return 'rgba(190, 30, 45, 0.5)';
} else if (value > 80 && value <= 100) {
return 'yellow';
} else {
return '#CCE6D0';
}
};
render() {
const xAxisLabels = [
'09-10-2020',
'10-10-2020',
'11-10-2020',
'12-10-2020',
];
const data = [50, 10, 40, 95];
const Decorator = ({x, y, data}) => {
return data.map((value, index) => (
<View>
<Rect
x={x(index) - 1.75}
y={y(value + 8)}
width="4"
height="40"
rx="2"
fill={this.handleFill(value)}
/>
<Circle
key={index}
cx={x(index)}
cy={y(value)}
r={2}
stroke={'#639123'}
fill={'#606060'}
/>
</View>
));
};
return (
<View
style={{
height: 200,
flexDirection: 'row',
}}>
<YAxis
data={data}
contentInset={{top: 20, bottom: 20}}
svg={{
fill: 'black',
fontSize: 10,
}}
/>
<View style={{flex: 1}}>
<LineChart
style={{flex: 1}}
data={data}
svg={{stroke: 'rgb(134, 65, 244)'}}
contentInset={{top: 10, bottom: 10, left: 10, right: 10}}>
<Decorator />
</LineChart>
<XAxis
data={data}
formatLabel={(value, index) => xAxisLabels[index]}
contentInset={{ left: 10, right: 10 }}
svg={{ fontSize: 8, fill: '#3A8F98' }}
/>
</View>
</View>
);
}
}
To XAxis component, give contentInset value of 15 to left and right, 10 seems bit low, if it's still hiding then increase it a bit more:
<XAxis
data={data}
formatLabel={(value, index) => xAxisLabels[index]}
contentInset={{ left:15, right: 15 }}
svg={{ fontSize: 8, fill: '#3A8F98' }}
/>