I am trying to make a custom label by passing a React Component to the content props of Label component and the label doesn't show.
My goal is to display the label at the center of a pie chart. Below is my code snippet and here is a working sample.
<PieChart>
<Pie
isAnimationActive={false}
data={pieArray}
innerRadius={100}
outerRadius={150}
dataKey="value"
cy="50%"
cx="50%"
startAngle={90}
endAngle={-270}
>
{pieArray.map(({ data }, id) => (
<Cell key={data} fill={chartColors[id % 8]} />
))}
<Label
content={<CustomLabel />}
position="center"
/>
</Pie>
</PieChart>
Pie Chart
function CustomLabel(props: any) {
return (
<div>
<h1 className="custom">Custom Label</h1>
<p>Testing</p>
</div>
);
}
Custom Label
I am using React version 17.0.2 and recharts 2.1.2. Link to code sample. Thanks.
Related
I have a common grid component where I define the structure of the grid and also structure of a button bar that goes on top of the grid.
Common-grid.js
<Box height='100%' width='100%' position='absolute'>
<div className="common-grid">
<div className="button-bar">
</div>
<div className="ag-grid">
</div>
</div>
</Box>
I pass data to the grid from my other component based to fill in the grid.
MyComponent.js
{gridData.length > 0 && <Grid tableData={gridData} columnData={activeListColumnDef} {...props}/>}
Along with the data, I would also like to pass icon buttons that I would like to see in button bar.
<IconButton
icon={<AddIcon />}
onClick={onClickOpenActiveListEditor}
/>
<IconButton
icon={<EditIcon />}
/>
I do not want to define icon buttons in the common component but pass it as props. Is it possible to pass such html elements along with its event listeners as props? Please help!
Sure, it's called a render prop. Just directly pass the node like this:
// in the parent component
<Grid
tableData={gridData}
columnData={activeListColumnDef}
icon={<AddIcon onClick={onClickOpenActiveListEditor} />}
{...props}
/>
// in the Grid component
function Grid({tableData, columnData, icon}){
return (
<>
// grid stuff
{icon && icon}
</>
)
}
If you need typescript support, the node would typed as such:
interface GridProps{
// stuff
icon?: React.ReactNode;
}
You could do something like:
const renderIcon = (onClick) => {
return <Icon onClick={onClick} />
}
...
<IconButton renderIcon={renderIcon} />
Then, inside IconButton:
{renderIcon()}
I was creating React project and here is the component that I want to ensure that is put inside a string.
<InfoIcon
tooltip={`${hints.todoHint} <br/> ${hints.inProgressHint} <br/> ${hints.doneHint}`}
/>
but it is not working since br/ is literally rendered like br/
One option is to convert tooltip in to three props and add <br /> in the InfoIcon component. For example InfoIcon component can be
const InfoIcon = ({ todoHint, inProgressHint, doneHint }) => (
<div>
{todoHint}
<br />
{inProgressHint}
<br />
{doneHint}
</div>
);
// Using Info Icon
<InfoIcon todoHint={todoHint} inProgressHint={inProgressHint} doneHint={doneHint} />
Other option is to send tooltip as follows
const tooltip = (
<div>
{hints.todoHint}
<br />
{hints.inProgressHint}
<br />
{hints.doneHint}
</div>
)
<InfoIcon tooltip={tooltip} />
Well, material-ui tooltip allows you to use ANY kind of HTML content. => refer to official document customized tooltiops
This means you can use normal <div> and <Typography />, and any other styled elements to handle multi-line content.
The only thing you need to do is pass the content to props title => refer to document of tooltip api
import {
Tooltip,
Typography
} from '#material-ui/core';
<Tooltip
title={ // customized content here via props `title`
<>
<div>Seperate line</div>
<Typography>Seperate line</Typography>
</>
}
>
<IconButton aria-label="delete">
<InfoIcon /> // You can use your original icon here
</IconButton>
</Tooltip>
Watch it online: https://stackblitz.com/run
You can find related question here: How to make line break for ToolTip titles in Material-UI
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}/>
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>
I'm working on a react-vis chart that will dynamically update the data that is displayed when a user clicks on/off the legend item for that series.
If a user clicks clicks off all of the series the JSX that I render essentially looks like this:
<div>
<XYPlot
xDomain={paretoOrder}
margin={{left: 150, bottom: 150}}
width={450}
height={450}
xType="ordinal"
stackBy="y"
>
<VerticalGridLines />
<HorizontalGridLines />
<XAxis
tickLabelAngle={-45}
/>
<YAxis
tickFormat={ tick => translator.formatTime(tick, {hideZero: true})}
/>
<VerticalBarSeries
data={[]}
/>
</XYPlot>
<DiscreteColorLegend
orientation="horizontal"
width={300}
items={legendItems}
onItemClick={this.onLegendClick}
/>
</div>
I would expect that this would still render the axes, the grid lines, etc, but the entire chart is removed from the DOM instead. How do I render a chart with empty data but keep the axes, grid lines, etc in the DOM?
Add dontCheckIfEmpty prop (as true, default is false) to <XYPlot> tag.
<XYPlot
dontCheckIfEmpty
>
<XAxis/>
<YAxis/>
<VerticalBarSeries
data={data}
/>
<VerticalGridLines />
<HorizontalGridLines />
</XYPlot>