React Recharts, difference between chromium and firefox - reactjs

I have a stacked area chart with a time series. I'm normalizing the data to always add up to 100%.
With some specific data, the chart breaks, and used to break in the same way in firefox until I added scale="time" to XAxis.
Right now this is what I have:
<AreaChart data={percentData.sort((a, b) => a.name >= b.name)}>
<defs>
{colors.map((c, i) => (
<linearGradient id={`graphColor${i}`} x1="0" y1="0" x2="0" y2="1" key={c}>
<stop offset="5%" stopColor={c} stopOpacity={1} />
<stop offset="95%" stopColor={c} stopOpacity={0.5} />
</linearGradient>
))}
{customGradients()}
</defs>
<XAxis
dataKey="name"
type="number"
domain={[MIN, MAX]}
scale="time"
tickFormatter={dateFormatter}
ticks={tickArray}
tickCount={5}
>
<Label value="Date" position="bottom" style={{ textAnchor: 'middle' }} />
</XAxis>
<YAxis ticks={[0, 25, 50, 75, 100]} domain={[0, 100]} unit="%" type="number">
<Label angle={-90} value="Percentage" position="insideLeft" style={{ textAnchor: 'middle' }} />
</YAxis>
<Tooltip content={<CustomTooltip tickFormatter={dateFormatter} />} />
<CartesianGrid strokeDasharray="3 3" />
{tab
&& tab.keys
.sort()
.map((k, i) => (
<Area
type="monotone"
dataKey={k}
stroke={tab.data[`${k}color`] || getColorForCurrentIndex(i)}
fillOpacity={1}
fill={
tab.data[`${k}color`]
? `url(#graphColor${k}color)`
: `url(#graphColor${getColorIndex(i)})`
}
key={k}
stackId="1"
/>
))}
</AreaChart>
The console in chromium outputs the following:
Error: <rect> attribute x: Expected length, "NaN".
Error: <rect> attribute width: Expected length, "NaN".
I'm using unix timestamps for the x coordinates, they are proper number instances.
And this is the result in firefox:
Firefox stacked time series area chart
The first render on chromium:
Chromium stacked time series area chart first render
After re-render on chromium:
Chromium stacked time series area chart second render
Any help is appreciated, struggling with figuring this out. Thanks!
I've tried the example for Percent area chart provided in recharts docs, same result.

Turns out I wasn't sorting my data properly, even though they were numbers passed to a numeric axis, sorting the data array fixed this issue:
sort((a, b) => a.name >= b.name) => sort((a, b) => a.name - b.name)

Related

How to plot events based on beginning and end of day in rechart

Hello I want to plot a graph on rechart library based on the data I have however I want it to be such that on the start of the x axis it labelled 12am (start of date) and end it is 11:59pm then using this I can plot a graph based on the events of the day
here is how my data looks like
const data=[{moneyIn: 100, time: '9:07 AM'}
{moneyIn: 140, time: '9:07 AM'}
{moneyIn: 250, time: '9:08 AM'}]
here is how I have plotted my current graph
<ResponsiveContainer width="99%" aspect={aspect}>
<AreaChart
width={730}
height={300}
data={data}
style
margin={{ top: 10, right: 0, left: 0, bottom: 0 }}
>
<defs>
<linearGradient id="total" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={color} stopOpacity={0.8} />
<stop offset="95%" stopColor={color} stopOpacity={0.3} />
</linearGradient>
</defs>
<XAxis dataKey={time} stroke="gray" />
<YAxis />
<CartesianGrid strokeDasharray="3 3" className="chartGrid" />
<Tooltip />
<Area
type="monotone"
dataKey={moneyIn}
stroke={color}
fillOpacity={1}
fill="url(#total)"
/>
</AreaChart>
<ResponsiveContainer/>
this produces the folowing result
However i want the time to begin from 12am to 11:59pm then plot those points according to time, how do i do it? What other library can these be achieved in?
You can set the axes to a given value by providing the ticks attribute:
This thread on the Recharts Git discusses how.
<XAxis ticks={[1.2, 2.8, 4.4, 6]} />
You may want to have a few more ticks in your example, like 12-noon.
But you may have to format your x-axis values into a number or date value in order to make it work how you expect.
The XAxis Docs from Recharts give some good pointers on how certain props change the behaviour of the XAxis.

recharts line chart 'Y' axis range issue

I have a line chart that displays several lines of data, everything works as expected, the only issue is that when the chart is displayed there is huge blank space inside the chart itself, I have been checking the data range I am sending but seems fine, all values appear, have been also checking for some styling issue but I dont seem to see anything strange, sadly the docs are very limited for the styling regard that I am not able yet to find a solution.
<ResponsiveContainer aspect={10.0 / 3.0}>
<LineChart margin={{left: 30, top: 30}} width={730} height={300}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis
dataKey="month"
type="category"
allowDuplicatedCategory={false}
allowDecimals={false}
/>
<YAxis
padding={{top: 28}}
interval={0}
ticks={range}
tickSize={2}
tickFormatter={val => getLocaleString(val)}
label={{
value: 'EUR',
position: {x: 40, y: 0},
className: 'chart__label',
}}
/>
<Tooltip />
<Legend
onMouseOver={mouseOverLegend}
onMouseLeave={mouseLeaveLegend}
/>
{data.map((data, index) => {
const namePostfix = `EUR ${yearsDataChart[index]}`
const stroke =
hoverIndex === index || !legendHover
? colorsChart[index]
: COLOR_HOVER
const costName = `${translate('cost')} ${namePostfix}`
const revenueName = `${translate('revenue')} ${namePostfix}`
return [
<>
<Line
dataKey="revenue"
data={data}
name={revenueName}
stroke={stroke}
/>
<Line
dataKey="cost"
data={data}
name={costName}
stroke={
hoverIndex === index || !legendHover
? colorsChartProvider[index]
: stroke
}
/>
</>,
]
})}
</LineChart>
</ResponsiveContainer>
the result is :
hope someone has an idea of what could be the issue here

React ReCharts - Tooltip does not work on Safari (but works fine on Firefox)

I've created a simple ReCharts - Line Chart with one data element (Date & Value). Chart is working fine but the tooltip only works when I run this on Firefox. The chart is unresponsive (or static) on Safari (v14.1.1) on a Mac.
<div className="card">
<LineChart width={950} height={300} data={this.props.inputdata} margin={{ top: 5, right: 20, bottom: 5, left: 20 }}>
<Line type="monotone" dataKey="Total_Returns_Index" stroke="#8884d8" />
<CartesianGrid stroke="#ccc" strokeDasharray="5 5" />
<XAxis dataKey="Date" />
<YAxis domain={[500, 2000]} />
<Tooltip />
<Legend />
</LineChart>
</div>

Recharts - How to force chart to start at x=0?

I'm using Recharts to draw some charts. Depending on the length of the data array, the chart doesn't start at x = 0 (not at the intersection of x and y) and doesn't finish at the max value of x:
How can I force it to always begin at x = 0 and occupy all the x axis?
This is how I'm implementing it:
<ResponsiveContainer width="100%" height={400}>
<ComposedChart
data={chartContent.content.chart}
//data={data}
margin={{ top: 5, bottom: 5, left: 5 }}
>
<defs>
<linearGradient
id="colorBtc"
x1="0"
y1="0"
x2="0"
y2="1"
>
<stop
offset="5%"
stopColor="#ff9500"
stopOpacity={0.8}
/>
<stop
offset="95%"
stopColor="#ff9500"
stopOpacity={0}
/>
</linearGradient>
<linearGradient
id="colorStock"
x1="0"
y1="0"
x2="0"
y2="1"
>
<stop
offset="5%"
stopColor="#00a1e4"
stopOpacity={0.8}
/>
<stop
offset="95%"
stopColor="#00a1e4"
stopOpacity={0}
/>
</linearGradient>
</defs>
<XAxis
dataKey="date"
tickFormatter={formatDate}
/>
<YAxis tickFormatter={formatYAxis} />
<CartesianGrid strokeDasharray="3 3" />
<Tooltip
formatter={formatTooltip}
labelFormatter={formatDate}
/>
<Legend />
<Area
name={t("Total amount in BTC")}
type="monotone"
dataKey="investment_total_btc"
stroke="#ff9500"
fillOpacity={1}
fill="url(#colorBtc)"
/>
<Area
name={`${t("Total amount in")} ${
chartContent.content.symbol
}`}
type="monotone"
dataKey="investment_total_stock"
stroke="#00a1e4"
fillOpacity={1}
fill="url(#colorStock)"
/>
<Line
name={t("Total invested in $")}
dataKey="invested"
type="monotone"
stroke="#ff0000"
dot={false}
/>
</ComposedChart>
</ResponsiveContainer>
Unfortunately the API documentation is not so clear and I couldn't find a solution.
Thanks in advance
What helped in my scenario was to add dataMax + 1 to the domain parameter of the XAxis component.
Based on what the documentation says I would have assumed that adding 'dataMin' for the first element of the domain array would help. However, it was dataMax + 1 that resolved it for me
Full snippet
<XAxis
dataKey="date"
name="Time"
type="number"
domain={["dataMin", "dataMax + 1"]}
tickFormatter={(tickItem) => moment(tickItem).format("MMM Do YY")}
/>
Adding domain={["dataMin", "dataMax + 1"]} doesn't work, since the XAxis type in my case is category(the default value).
According to the library API document, in order to set domain, the XAxis type should be "number"reference
For category type XAxis, I found that Priyank Kachhela pointed out an alternative solution. You can specify the scale of XAxis to be point( the default scale is band ). It resolved my issue.
<XAxis
dataKey="date"
tickFormatter={formatDate}
scale="point"
/>

How to add a custom svg as the line/tooltip for recharts

I have a line chart with two lines.
For one of the lines, I want to use a custom svg to represent it in the chart. See screenshot.
How can I do this?
Here's my code:
<LineChart
// width={800}
onClick={() => {}}
height={300}
data={this.state.data}
// margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
>
<XAxis dataKey="to_char" />
<YAxis
tickFormatter={value => {
let val = value / 1000000;
return `$${new Intl.NumberFormat("en").format(val)}m`;
}}
/>
<CartesianGrid strokeDasharray="3" vertical={false} />
<Tooltip />
<Legend />
<Line
dot={false}
type="monotone"
dataKey="predictedprice"
stroke="#1C85E8"
activeDot={{ r: 8 }}
name="True Home Estimateā„¢"
strokeWidth={3}
/>
<Line
type="monotone"
name="Sold Price"
dataKey="soldprice"
stroke="#82ca9d"
shape="star"
/>
</LineChart>
You should be able to add the shape property to ReferenceDot or ReferenceArea - I'm not sure if the shape properly can be used on regular properties, but here's a link I found to a GitHub conversation that talks more about this:
https://github.com/recharts/recharts/issues/922

Resources