How to do custom x-axis ticks in a Recharts graph - reactjs

I'd like to put more than one line in the x-axis ticks in a bar chart, something like this:
But all the props I have to control what renders there, underneath each group of bars, is the dataKey, so all I can get with Recharts is:
This is just rendering one value from my data.
Ideally I'd like to be able to pass XAxis a prop to render this such as:
<XAxis dataKey="name" render={(value, dataPoint) => (
<CustomXAxisName>
<p>{value}</p>
<p>{dataPoint.total} Principals</p>
</CustomXAxisName>
)} />
but I can find no affordances for this. There is a more flexible prop to configure label, but that refers to one label for the whole axis.
Is there anyway to get this? I'm quite surprised that I can't find a natural way to do this, since Rechart since so flexible in other regards and I don't think this is such a weird idea.

Have you looked at https://recharts.org/en-US/examples/CustomizedLabelLineChart?
It shows how to put something diagonally in the x-axis, surely it can be used to put multiple lines.
It uses the tick={<CustomTick/>} prop to the XAxis component.

You can do it like:
const customizedGroupTick = (props: any) => {
const { index, x, y, payload } = props;
return (
<g>
<g>
<text x={x} y={y}>
data
</text>
<text x={x} y={y }>
data
</text>
</g>
</g>
);
};
and then
<XAxis
dataKey="Date"
axisLine={false}
tickLine={false}
scale="band"
tick={customizedGroupTick}
interval={0}
/>

Related

Recharts composed chart with different data

I need a help with recharts library. I need to build the chart below:
As you can see, there is only 15 bars but the line chart is made out of thousands points. Is there a way to use composed chart, were one Bar component is not connected with Line component?
This is the closest i could make:
Found the solution: Apparently, you can use have multiple x-axis. I have provided the bar chart data for ComposedChart component, made 2 XAxis components and gave them xAxisId. One of the XAxis (the one for line chart) is hidden with property hide={true}.
Line component has data property, where I passed the line chart data. Please find the code below:
<ComposedChart data={barData}>
<XAxis xAxisId={1} />
<XAsis xAxisId={2} hide={true} />
<Tooltip />
<Legend />
<Bar xAxisId={1} dataKey="pv" barSize={20} />
<Line xAxisId={2} data={lineData} dataKey="uv" dot={false} stroke="#000000" />
</ComposedChart>
Here is the result:

Reacharts: I need help getting data from json object

I am using React Recharts for my visualization, however, I am having a challenge displaying a line chart with different corresponding object contents. I have JSON object, I would like to have the months of subcriptions as my XAxis and total of annual_payment moves as my YAxs. Ideally, the image below is representation of how I want to display my data. Instead of week, I need to display months. Thank you
Ciao, at first you have to manipulate your subscriptions array:
lets say you want to show month of date_purchased in your XAxis. So you can do:
subscriptions_manipulated = subscriptions.map(el => {
el.date_purchased = new Date(el.date_purchased).getMonth() + 1 // + 1 because for January getMonth returns 0...
return el;
});
Then you can make your graph:
<LineChart data={subscriptions_manipulated}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="date_purchased" interval="preserveStartEnd" />
<YAxis />
<Tooltip/>
<Legend />
<Line name="annual_payment" type='monotone' dataKey='annual_payment' />
</LineChart>

Custom label on Recharts radar chart

I'm Having a hell of a time trying to get custom labels on a recharts radar chart working. I've tried doing multiple things according to the docs so I figured I'd throw it to the wolves. Hopefully one of you can point me in the right direction.
<ResponsiveContainer>
<RadarChart outerRadius={125} cy={175} data={ucRadarData}>
<Legend verticalAlign='top' height={36} />
<PolarGrid />
<PolarAngleAxis dataKey='value'>
<Label content={({ value }) => <Typography>{value}</Typography>} /> // When I remove this component, the labels get removed as well so I assume this is the component I want to target.
</PolarAngleAxis>
<PolarRadiusAxis domain={[lowestRangeStart, highestRangeEnd]} tickCount={tickArray.length} />
<Radar label={({ label }) => <Typography>{label}</Typography>} name='Self Assessment' dataKey='Self' stroke='#8884d8' fill='#8884d8' fillOpacity={0.6} /> // Also tried adding custom label here.
</RadarChart>
</ResponsiveContainer>
Do this:
Make a render function for custom tick and add that as tick prop to your PolarAngleAxis component
function customTick({ payload, x, y, textAnchor, stroke, radius }) {
return (
<g
className="recharts-layer recharts-polar-angle-axis-tick"
>
<text
radius={radius}
stroke={stroke}
x={x}
y={y}
className="recharts-text recharts-polar-angle-axis-tick-value"
text-anchor={textAnchor}
>
<tspan x={x} dy="0em">
{payload.value}
</tspan>
</text>
</g>
);
}
<PolarAngleAxis dataKey='value' tick={customTick}/>

Recharts Event not working when bar chart bar value is 0

I am using Recharts BarChart components to visualize my data. In the Bar component, it supports a few events handler (onClick, onMouseDown, etc).
My question: I have an onClick event handler so users are able to click on the bar chart and redirect to other pages based on the result ID.
My problem: If the bar chart's value is at 0, users are unable to click on the link since onClick event handler is implemented on the bar itself.
Source code:
<BarChart
width={500}
height={500}
layout="vertical"
data={data}
>
<XAxis type="number" />
<YAxis dataKey="title" type="category" />
<Bar
dataKey="score"
fill={Color}
label={<CustomLabel />}
onClick={(data, index) => {
// some logic here
return history.push(`/${data.x.y.id}`);
}}
/>
</BarChart>
Screenshot:
My attempt:
I tried to look at a possible solution and observe the examples on the API in recharts website, I don't see anything that is able to solve my problem. I also tried to have onClick on the title on axis or bar, but the component does not support the feature. Please advise.
You can add an onClick attribute on the BarChart component and check data.activePayload[0] to see which bar chart has been clicked.
<BarChart
width={500}
height={500}
layout="vertical"
data={data}
onClick={(data) => {
// do your history.push based on data.activePayload[0]
if (data && data.activePayload && data.activePayload.length > 0) {
return history.push(`/${data.activePayload[0].x.y.id}`);
}
}}
>
<XAxis type="number" />
<YAxis dataKey="title" type="category" />
<Bar
dataKey="score"
fill={Color}
label={<CustomLabel />}
/>
</BarChart>

Accepting an SVG as a prop to a React component

I am working on a React component that needs to accept an SVG as a prop.
I have a default svg in case the prop is not provided, but if it is provided then the default svg can be replaced out with the one accepted from prop.
So the component is like.
<MySvg src={path to svg or the svg itself} height={20} width={20} fillColor={'red'} />
All that the component should do is display this SVG with the provided props. I expect the DOM to be something like this.
<svg fill={this.props.fillColor} height={this.props.height} width={this.props.width}>
<g>
<rect />
</g>
</svg>
Since each SVG is different, meaning it might have a polygon, rect, g, etc., what is the best way to achieve this?
2 things I am looking for?
Loading an svg from a path and applying the props (color, height, width)?
If src prop has the SVG itself, how do we display that and apply the props (color, height, width)
Update: I tried out one of the approach in the answers below, but it does not seem to work. Here is a link to a CodeSandbox I have in place - codesandbox.io/s/n0yzv9yyvp
I worked with SVG in react.js a lot, the best solution I found is to use embed svg:
<MySvg src={'/path/to/svg'} height={20} width={20} fillColor={'red'} />
And inside your component
<svg fill={this.props.fillColor} height={this.props.height} width={this.props.width}>
<g>
<image
x="10"
y="197"
width="159"
height="113"
xlinkHref={this.props.src}
/>
</g>
</svg>
x, y, width and height are usual parameters of the image svg tag, you can omit or rewrite them as you want
Your best bet will be to use data URIs.
Example:
<img src='data:image/svg+xml;utf8,<svg ... > ... </svg>'>
Read more here:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
you can pass props to svg components just like any other components
for example
function App() {
return <Svg height={20} width={20} fill={black} />;
}
const Svg = ({ height, width, color }) => (
<svg
height={height}
width={width}
fill={color}
xmlns="http://www.w3.org/2000/svg"
></svg>
);

Resources