Error in the values of the Rechart Stacked chart - javascript

I'm trying to build a Stacked Bar Chart using the Pchart library. I attach the code below.
function StackedBarChart({...props}){
const {dataChart:{data,keys}} = props;
const renderBars = () =>{
return keys.map((item,index)=>(
<Bar
key={index}
dataKey={item}
stackId='a'
fill={index%2?'blue':'red'}
label
/>
))
}
return(
<ResponsiveContainer width='100%' height={400}>
<BarChart
data={data}
stackOffset='expand'
>
<XAxis dataKey="name" />
<YAxis />
{renderBars()}
</BarChart>
</ResponsiveContainer>
)
}
When I output a value to each Bar I get incorrect signatures. . Why is 2 Bar subscribed with the value 1 and not the remaining percentage. What is my mistake ?
my data
const dataChart = {
data: [{
name: 'Page A',
count: 4000,
price: 2400,
},
{
name: 'Page B',
count: 3000,
price: 1398,
},
{
name: 'Page C',
count: 2000,
price: 9800,
},
],
keys: ['price', 'count']
};

The reason of this behavior, is that upper bar shown his top value, which is 1, so this is the sum of all bars stacked.
To avoid this situation I used valueAccessor and some formatting to get value of bar and count its percentage.
Here is a link to working codesandbox where you can see final result

Related

Dynamic Bar Labeling on Ant Design Charts

I'm trying to create an ant design chart with some custom labels on the bars based on what data they contain. Is it possible to do this dynamically? I want the labels to say "Water" and "Land", which is the type of each respective data. Here is my code which I'm playing around in the Ant Design Charts Sandbox
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
import { Bar } from '#ant-design/plots';
const DemoBar = () => {
const data = [
{
year: '1991',
value: 3,
type: 'Water',
},
{
year: '1991',
value: 4,
type: 'Land',
},
];
const config = {
data: data.reverse(),
isStack: true,
xField: 'value',
yField: 'year',
seriesField: 'type',
legend: false,
label: {content: data[0].type}, // How can the content link to the data?
interactions: [{ type: 'tooltip', enable: false }]
};
return <Bar {...config} />;
};
ReactDOM.render(<DemoBar />, document.getElementById('container'));
I figured it out: Javascript lets you create a function here. Replacing the label line with this line solved it:
label: {content: ({ type }) => { return type },},
For typescript the line is:
label: { content: ({ type }: any) => { return type }, },

Check if value is undefined before render React Native

I am using (Drop Down Picker library) to display categories of my data which I get from api call. I am waiting for api to fetch the data and then plan to display the categories. The problem is that I need to reformat data first and use hooks before render, but I can't get it right.
how does the data for picker looks like:
items={[
{label: 'USA', value: 'usa'},
{label: 'UK', value: 'uk'},
{label: 'France', value: 'france'/>},
]}
my hooks:
const [country, setCountry] = useState("0");
const [categoryData, setCategoryData] = useState();
const [testingCategories, setTestingCategories] = useState({
label: null,
value: null,
});
my effect hooks and reformatting the data:
//this hook calls api and sets the data to categories data of my type
useEffect(() => {
getData(api.API_GET_DEPS, setIsLoading, setCategoryData);
}, []);
//this hooks reformats the data into acceptable format for picker
useEffect(() => {
setTestingCategories(
categoryData
? categoryData.map((item) => ({
label: item.DEPNAME, //label
value: item.DEPID, //value
}))
: [{ label: null, value: null }]
);
}, [categoryData]);
my render of drop down:
<View style={styles.container}>
{testingCategories ? (
<DropDownPicker
dropDownMaxHeight={300}
placeholder="All"
defaultValue={country}
items={testingCategories}
containerStyle={{ height: 50 }}
style={{ backgroundColor: "#fafafa" }}
itemStyle={{
justifyContent: "flex-start",
}}
dropDownStyle={{ backgroundColor: "#fafafa" }}
onChangeItem={(item) => {
console.log("changed");
}}
onOpen={() => setContainerOpacity(0.1)}
onClose={() => setContainerOpacity(1)}
labelStyle={{
fontSize: 16,
color: colors.dark,
fontWeight: "600",
}}
arrowSize={25}
arrowColor={colors.dark}
/>
) : (
<></>
)}
I get an error that drop down picker can't match the defaultValue with any label in testingCategories because it is null and haven't loaded yet. I suppose I am using setter wrong because I can't check whether testingCategories's first element was loaded. What am I doing wrong?
You have a typing mismatch between your useState definition and where you use setTestingCategories later.
In your useState, you define the initial value as a singular object:
useState({
label: null,
value: null,
});
However, what you probably want is an empty array:
useState([]);
I would also change your current line [{ label: null, value: null }] to just be an empty array [].
Then, your testingCategories flag will work, because testingCategories will initially be an array of length 0, which will fail the truthiness test.

How do i change React Google Charts background color?

I am trying to change the background color of the charts to match my body background color.
I have tried to do the two following backgroundColor styles below but it doesn't seem to work. Any ideas on how i can get around this?
<Chart
height={'300px'}
width={'370px'}
chartType='Bar'
loader={<div>Loading Chart..</div>}
data={[
['', 'UPLIFT'],
...topSpend.map(d => [d.PRODUCT, d.UPLIFT]),
]}
options={{
chart: {
title: 'Spend Uplift',
-----> backgroundColor: 'red'
},
colors: ['#FB7A21']
}}
/>
<Chart
height={'300px'}
width={'370px'}
chartType='Bar'
loader={<div>Loading Chart..</div>}
data={[
['', 'UPLIFT'],
...topSpend.map(d => [d.PRODUCT, d.UPLIFT]),
]}
options={{
chart: {
title: 'Spend Uplift',
},
colors: ['#FB7A21'],
-----> backgroundColor: 'red'
}}
/>
You need to use chartType as BarChart. For some reason, Bar seems to cause issues. In case you want the chart bars to be vertical, change it to ColumnChart.
You can see the working fiddle here
'Bar' is considered a Material chart.
vs. 'BarChart', which is a Classic chart.
with Material charts, an options conversion method needs to be used...
google.charts.Bar.convertOptions
which means you would need to access the google.charts namespace.
options={google.charts.Bar.convertOptions({
chart: {
title: 'Spend Uplift',
},
colors: ['#FB7A21'],
backgroundColor: 'red'
})}

Recharts Tooltip displays same value

I have an issue where the tooltip is displaying the same value for different series. So whenever I hover on the popover, I get the following:
Here's my implementation:
<LineChart margin={{ top: 15, right: 5, bottom: 5, left: 10 }}>
<XAxis
type='number'
dataKey='timestamp'
padding={{ left: 30, right: 30 }}
domain={['dataMin', 'dataMax']}
height={90}
tickFormatter={(unixTime) => dayjs(unixTime).format('MM/DD h:mm A')}
tickMargin={30}
/>
<YAxis
dataKey='Demand'
tickFormatter={(val, _axis) => numeral(val).format('0,0') + ' kW'}
/>
{chartData && this.renderLines(chartData, theme)}
<CartesianGrid strokeDasharray='3 3' />
<Legend />
<Tooltip
content={<LiveDailyDemandTooltip
format={{
Demand: '0.0'
}} />}
/>
</LineChart>
Where the data looks like:
{
"dataID-1": [
{Demand: 4237, timestamp: 1564977600000}
...
],
"dataID-2": [
{Demand: 112, timestamp: 1564977600000}
...
]
}
As mentioned here: https://github.com/recharts/recharts/issues/1625
You should set allowDuplicatedCategory to false in XAxis:
<XAxis allowDuplicatedCategory={false}/>
This will resolve the problem of duplicate value in tooltip.
I was able to resolve this by providing the data in a different format. It seems that Recharts needs to have data grouped by their X-Axis value:
[
{ timestamp: 1564977600000, Demand1: 4237, Demand2: 112 },
...
]

React Native Js - TypeError: l.map is not function

i m new on Js and React,for my semester 2, I have to make an application of Macronutrient.
The problem is that I would like to use a Piechart with the values of my state.
for pie chart a isued react-native-chart-kit
u can see on this link : https://www.npmjs.com/package/react-native-chart-kit
I tried
Piechart
<PieChart
width={screenWidth}
data={{
datasets: [{
data: [
{ name: 'Glucide', nb:this.state.glucide, color: '#F00', legendFontColor: '#F00', legendFontSize: 15 },
{ name: 'Proteine', nb: this.state.protaine, color: '#4250f4', legendFontColor: '#4250f4', legendFontSize: 15 },
{ name: 'Lipide', nb: this.state.lipide, color: '#04e578', legendFontColor: '#04e578', legendFontSize: 15 },
]
}]
}}
height={220}
accessor="nb"
chartConfig={chartConfig}
backgroundColor="transparent"
absolute/>
and i get TypeError: l.map is not a function. (In'l.map(c)','l.map' is undefined
l.map is not function, this error typically cause by the variable call .map() is not an array.
In this case, you should pass data array direct to data
const data = [
{ name: 'Glucide', nb:this.state.glucide, color: '#F00', legendFontColor: '#F00', legendFontSize: 15 },
{ name: 'Proteine', nb: this.state.protaine, color: '#4250f4', legendFontColor: '#4250f4', legendFontSize: 15 },
{ name: 'Lipide', nb: this.state.lipide, color: '#04e578', legendFontColor: '#04e578', legendFontSize: 15 }
]
<PieChart
width={screenWidth}
data={data}
height={220}
accessor="nb"
chartConfig={chartConfig}
backgroundColor="transparent"
absolute
/>

Categories

Resources