Date is not displayed from props in rechart react - javascript

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 :

Related

How to display the selected items of a treeview in ReactJS?

I have no clue how to display the elements selected in my treeview. Ideas or tips ? please
The purpose of this treeview is to filter the data for export purposes.
The origin of the code comes from here (https://mui.com/material-ui/react-tree-view/#customization)
import React, {useEffect, useState} from 'react';
import ReactDOMServer from 'react-dom/server';
import TreeView from '#mui/lab/TreeView';
import TreeItem from '#mui/lab/TreeItem';
function MinusSquare(props) {
return (
<SvgIcon fontSize="inherit" style={{ width: 25, height: 25 }} {...props}>
{/* tslint:disable-next-line: max-line-length */}
<path d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z" />
</SvgIcon>
);
}
function PlusSquare(props) {
return (
<SvgIcon fontSize="inherit" style={{ width: 25, height: 25 }} {...props}>
{/* tslint:disable-next-line: max-line-length */}
<path d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 12.977h-4.923v4.896q0 .401-.281.682t-.682.281v0q-.375 0-.669-.281t-.294-.682v-4.896h-4.923q-.401 0-.682-.294t-.281-.669v0q0-.401.281-.682t.682-.281h4.923v-4.896q0-.401.294-.682t.669-.281v0q.401 0 .682.281t.281.682v4.896h4.923q.401 0 .682.281t.281.682v0q0 .375-.281.669t-.682.294z" />
</SvgIcon>
);
}
function CloseSquare(props) {
return (
<SvgIcon
className="close"
fontSize="inherit"
style={{ width: 25, height: 25 }}
{...props}
>
{/* tslint:disable-next-line: max-line-length */}
<path d="M17.485 17.512q-.281.281-.682.281t-.696-.268l-4.12-4.147-4.12 4.147q-.294.268-.696.268t-.682-.281-.281-.682.294-.669l4.12-4.147-4.12-4.147q-.294-.268-.294-.669t.281-.682.682-.281.696 .268l4.12 4.147 4.12-4.147q.294-.268.696-.268t.682.281 .281.669-.294.682l-4.12 4.147 4.12 4.147q.294.268 .294.669t-.281.682zM22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0z" />
</SvgIcon>
);
}
function TransitionComponent(props) {
const style = useSpring({
from: {
opacity: 0,
transform: 'translate3d(20px,0,0)',
},
to: {
opacity: props.in ? 1 : 0,
transform: `translate3d(${props.in ? 0 : 20}px,0,0)`,
},
});
return (
<animated.div style={style}>
<Collapse {...props} />
</animated.div>
);
}
TransitionComponent.propTypes = {
/**
* Show the component; triggers the enter or exit states
*/
in: PropTypes.bool,
};
const StyledTreeItem = styled((props) => (
<TreeItem {...props} TransitionComponent={TransitionComponent} />
))(({ theme }) => ({
[`& .${treeItemClasses.iconContainer}`]: {
'& .close': {
opacity: 0.3,
},
},
[`& .${treeItemClasses.group}`]: {
marginLeft: 15,
paddingLeft: 18,
borderLeft: `1px dashed ${alpha(theme.palette.text.primary, 0.4)}`,
},
}));
const TreeViewBuilder = ({data, ChoiceDate, ChoiceModality}) => {
return (
<>
{data.map((key, index) => {
if (ChoiceModality.includes(data[index]['modality']) && (Date.parse(ChoiceDate[0]) <= Date.parse(data[index]['startDate']) && Date.parse(data[index]['startDate']) <= Date.parse(ChoiceDate[1]))) {
return <StyledTreeItem nodeId={data[index]['series'][0] + "_" + index} label={data[index]['series'][0]}>
<StyledTreeItem nodeId={data[index]['series'][0] + "_" + data[index]['modality']} label={data[index]['modality']}/>
</StyledTreeItem>
}
})
}
</>
);
};
export default TreeViewBuilder;
Here you will find an example of the display I have.
you can get selected node/nodes of treeview from the onNodeSelect event on TreeView element like this
<TreeView
aria-label="customized"
defaultExpanded={['1']}
defaultCollapseIcon={<MinusSquare />}
defaultExpandIcon={<PlusSquare />}
defaultEndIcon={<CloseSquare />}
sx={{ height: 264, flexGrow: 1, maxWidth: 400, overflowY: 'auto' }}
onNodeSelect={handleSelectedItems}
>
The callback event will recieve nodeId/nodeIds like this
const handleSelectedItems = (event, nodeId) => {
console.log(nodeId);
}
If you are using multiSelect prop, nodeId will be an array containing the nodeIds of all selected nodes. If you are not using multiSelect it will be string with the selected node's nodeId.

I can't pass arguments to a function inside props on React Native

I'm new to React Native development and I'm struggling to understand why does the argument that I pass on a function like <TouchableHighlight onPress={props.executeFunction(props.label)}> is a SyntheticBaseEvent, instead of the props.label itself
On App.js:37 console.log, it shows SyntheticBaseEvent {_reactName: 'onClick', _targetInst: null, type: 'click', nativeEvent: PointerEvent, target:
Am I losing reference to the original functions?
App.js:
import { StyleSheet, Text, View } from 'react-native';
import React, { Component } from 'react'
import Calculator from './Calculator';
import { LinearGradient } from 'expo-linear-gradient';
const initialState = {
displayValue: '0',
clearDisplay: false,
previousOperation: null,
operation: null,
values: [null, null],
currentPositionOnValues: 0,
originalValue: 0
}
class App extends Component {
constructor(props) {
super(props);
this.state = { ...initialState }
this.clear = this.clear.bind(this);
this.addDigit = this.addDigit.bind(this);
}
clear() {
this.setState({ ...initialState });
}
addDigit(digit) {
console.log(digit)
if (digit === "." && this.state.displayValue.includes('.')) {
// Prevent double decimals
return
}
const clearDisplay = this.state.displayValue === '0' || this.state.clearDisplay
/*
Boolean value saying if it's necessary to clear the display
True if the currentValue display value is 0 or the variable this.state.clearDisplay is set to true
*/
const currentValue = clearDisplay ? '' : this.state.displayValue
/*
currentValue shows the 'cleared' value or the display value
*/
const displayValue = currentValue + digit
this.setState({ displayValue: displayValue, clearDisplay: false })
if (digit !== '.') {
const i = this.state.currentPositionOnValues
const newValue = parseFloat(displayValue)
const values = [...this.state.values]
values[i] = newValue
this.setState({ values: values })
}
}
render() {
return (
<View style={styles.container}>
<LinearGradient
colors={['#4b6cb7', '#182848']}
style={styles.background}
start={[1, 1]} end={[0, 0]}
>
</LinearGradient>
<Text style={styles.head}>Calculator</Text>
<Calculator
addDigit={() => this.addDigit}
clear={() => this.clear}
setOperation={() => this.setOperation}
displayValue = {this.state.displayValue}
/>
</View>
);
}
}
export default App;
Calculator.js
import React from 'react';
import { View } from 'react-native';
import Interface from './Interface';
const Calculator = (props) => {
return (
<View>
<Interface
addDigit={props.addDigit}
clear={props.clear}
displayValue={props.displayValue}
setOperation={props.setOperation}
/>
</View>
);
}
export default Calculator;
Interface.js
import React from 'react';
import { View, StyleSheet, FlatList, Text } from 'react-native';
import Button from './Button';
import Display from './Display';
const Interface = (props) => {
return (
<View style={style.container}>
<Display value={props.displayValue} />
<Button label="AC" executeFunction={props.clear} triple />
<Button label="/" executeFunction={props.setOperation} operation />
<Button label="7" executeFunction={props.addDigit} />
<Button label="8" executeFunction={props.addDigit} />
<Button label="9" executeFunction={props.addDigit} />
<Button label="*" executeFunction={props.setOperation} operation />
<Button label="4" executeFunction={props.addDigit} />
<Button label="5" executeFunction={props.addDigit} />
<Button label="6" executeFunction={props.addDigit} />
<Button label="-" executeFunction={props.setOperation} operation />
<Button label="1" executeFunction={props.addDigit} />
<Button label="2" executeFunction={props.addDigit} />
<Button label="3" executeFunction={props.addDigit} />
<Button label="+" executeFunction={props.setOperation} operation />
<Button label="0" executeFunction={props.addDigit} double />
<Button label="." executeFunction={props.addDigit} />
<Button label="=" executeFunction={props.setOperation} operation />
</View>
);
}
const style = StyleSheet.create({
container: {
width: 400,
borderRadius: 5,
overflow: 'hidden',
position: 'relative',
justifyContent: 'center',
flexDirection: 'row',
flexWrap: 'wrap',
}
})
export default Interface
Button.js
import React from "react";
import { View, StyleSheet, Text, TouchableHighlight } from "react-native";
const Button = (props) => {
let classes = 'button '
classes += props.operation ? 'operation' : ''
classes += props.double ? 'double' : ''
classes += props.triple ? 'triple' : ''
if (props.operation) {
return (
<TouchableHighlight onPress={props.executeFunction(props.label)}>
<View style={[style.button, style.operation]}>
<Text style={style.text}>
{props.label}
</Text>
</View>
</TouchableHighlight>
)
} else if (props.double) {
return (
<TouchableHighlight onPress={props.executeFunction(props.label)}>
<View style={[style.button, style.double]}>
<Text style={style.text}>
{props.label}
</Text>
</View>
</TouchableHighlight>
)
} else if (props.triple) {
return (
<TouchableHighlight onPress={props.executeFunction()}>
<View style={[style.button, style.triple]}>
<Text style={style.text}>
{props.label}
</Text>
</View>
</TouchableHighlight>
)
} else {
return (
<TouchableHighlight onPress={props.executeFunction(props.label)} activeOpacity={0.8}>
<View style={[style.button]}>
<Text style={style.text}>
{props.label}
</Text>
</View>
</TouchableHighlight>
)
}
}
const style = StyleSheet.create({
button: {
width: 100,
height: 100,
fontSize: 30,
backgroundColor: '#f0f0f0',
outline: 'none',
textAlign: 'center',
justifyContent: 'space-evenly',
borderColor: '#888',
borderWidth: 1,
borderStyle: 'solid',
},
double: {
width: 200,
},
triple: {
width: 300,
},
operation: {
backgroundColor: '#fa8231',
color: '#FFF',
},
text: {
fontSize: 30,
textAlign: 'center',
justifyContent: 'space-evenly',
}
})
export default Button
What is happening?
Currently your code will execute props.executeFunction(props.label) once when the component loads.
This is because the function is immediately invoked when evaluated:
// directly invokes `props.executeFunction` with `props.label` because of brackets `()`
onPress={props.executeFunction(props.label)}
Because your function returns undefined, this is what subsequently gets passed to the onPress prop.
What's the solution?
If you want to pass props.label then you can pass via an anonymous function instead:
onPress={() => props.executeFunction(props.label)}
The onPress prop will attach the anonymous function to the event. When the event is triggered, the function will be called which will in turn call props.executeFunction passing props.label as desired.
The SyntheticEvent
The onPress function passes a SyntheticEvent when calling the handler. We can see this by logging the event in an anonymous function:
onPress={(event) => console.log(event)} // SyntheticEvent
Therefore, if you pass props.executeFunction as a direct argument to the onPress prop this event is what gets passed:
onPress={props.executeFunction} // passes the event as the argument to `props.executeFunction`
Examples
Invoking inline
This executes the function when the expression is evaluated (once). undefined is returned and passed to onClick so the onClick handler is not added.
function App(props) {
function foo(bar) {
console.log(bar);
}
return (
<button onClick={foo("test")}>Test</button>
);
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Invoking via anonymous function
The onClick handler is passed the anonymous function which will execute on every click.
This is useful if you need to pass arguments to your functions.
function App(props) {
function foo(bar) {
console.log(bar);
}
return (
<button onClick={() => foo("test")}>Test</button>
);
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Passing function as an argument
The event gets passed to the function.
This is useful if you need to access the event.
function App(props) {
function foo(bar) {
console.log(bar); // this logs the event as the event is passed
}
return (
<button onClick={foo}>Test</button>
);
}
ReactDOM.render(
<App />,
document.getElementById("react-root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react-root"></div>
updated your code: https://snack.expo.dev/qw9iqqVxs
App.JS
import { StyleSheet, Text, View } from 'react-native';
import React, { Component } from 'react';
import Calculator from './Calculator';
import { LinearGradient } from 'expo-linear-gradient';
const initialState = {
displayValue: 0,
clearDisplay: false,
previousOperation: null,
operation: null,
values: [null, null],
currentPositionOnValues: 0,
originalValue: 0,
};
class App extends Component {
constructor(props) {
super(props);
this.state = { ...initialState };
this.clear = this.clear.bind(this);
this.addDigit = this.addDigit.bind(this);
}
clear() {
this.setState({ ...initialState });
};
addDigit(digit){
if (digit === '.' && this.state.displayValue.includes('.')) {
// Prevent double decimals
return;
}
const clearDisplay =
this.state.displayValue === '0' || this.state.clearDisplay;
/*
Boolean value saying if it's necessary to clear the display
True if the currentValue display value is 0 or the variable this.state.clearDisplay is set to true
*/
const currentValue = clearDisplay ? '' : this.state.displayValue;
/*
currentValue shows the 'cleared' value or the display value
*/
const displayValue = currentValue + digit;
this.setState({ displayValue: displayValue, clearDisplay: false })
if (digit !== '.') {
const i = this.state.currentPositionOnValues;
const newValue = parseFloat(displayValue)
const values = [...this.state.values];
values[i] = newValue;
this.setState({ values: values });
}
};
render() {
return (
<View style={styles.container}>
<LinearGradient
colors={['#4b6cb7', '#182848']}
style={styles.background}
start={[1, 1]}
end={[0, 0]}></LinearGradient>
<Text style={styles.head}>Calculator</Text>
<Text style={styles.head}>
{JSON.stringify(this.state.displayValue)}
</Text>
<Calculator
addDigit={(digit) => {
this.addDigit(digit);
}}
clear={(value) => {
this.clear(value)
}}
setOperation={this.setOperation}
displayValue={this.state.displayValue}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
background: {
background: 'red',
},
triple: {
width: 300,
},
operation: {
backgroundColor: '#fa8231',
color: '#FFF',
},
text: {
fontSize: 30,
textAlign: 'center',
justifyContent: 'space-evenly',
},
});
export default App;
Button.JS
import React from "react";
import { View, StyleSheet, Text, TouchableHighlight } from "react-native";
const Button = ({operation, double, triple, executeFunction, label}) => {
let classes = 'button '
classes += operation ? 'operation' : ''
classes += double ? 'double' : ''
classes += triple ? 'triple' : ''
if (operation) {
return (
<TouchableHighlight onPress={()=>executeFunction(label)}>
<View style={[style.button, style.operation]}>
<Text style={style.text}>
{label}
</Text>
</View>
</TouchableHighlight>
)
} else if (double) {
return (
<TouchableHighlight onPress={()=>executeFunction(label)}>
<View style={[style.button, style.double]}>
<Text style={style.text}>
{label}
</Text>
</View>
</TouchableHighlight>
)
} else if (triple) {
return (
<TouchableHighlight onPress={()=>executeFunction()}>
<View style={[style.button, style.triple]}>
<Text style={style.text}>
{label}
</Text>
</View>
</TouchableHighlight>
)
} else {
return (
<TouchableHighlight onPress={()=>executeFunction(label)} activeOpacity={0.8}>
<View style={[style.button]}>
<Text style={style.text}>
{label}
</Text>
</View>
</TouchableHighlight>
)
}
}
const style = StyleSheet.create({
button: {
width: 100,
height: 100,
fontSize: 30,
backgroundColor: '#f0f0f0',
outline: 'none',
textAlign: 'center',
justifyContent: 'space-evenly',
borderColor: '#888',
borderWidth: 1,
borderStyle: 'solid',
},
double: {
width: 200,
},
triple: {
width: 300,
},
operation: {
backgroundColor: '#fa8231',
color: '#FFF',
},
text: {
fontSize: 30,
textAlign: 'center',
justifyContent: 'space-evenly',
}
})
export default Button
Calculator
import React from 'react';
import { View } from 'react-native';
import Interface from './Interface';
const Calculator = ({addDigit, clear, displayValue, setOperation}) => {
return (
<View>
<Interface
addDigit={addDigit}
clear={clear}
displayValue={displayValue}
setOperation={setOperation}
/>
</View>
);
}
export default Calculator;
Interface.JS
import React from 'react';
import { View, StyleSheet, FlatList, Text } from 'react-native';
import Button from './Button';
const Interface = ({clear, addDigit, setOperation}) => {
return (
<View style={style.container}>
<Button label="AC" executeFunction={clear} triple />
<Button label="/" executeFunction={setOperation} operation />
<Button label="7" executeFunction={addDigit} />
<Button label="8" executeFunction={addDigit} />
<Button label="9" executeFunction={addDigit} />
<Button label="*" executeFunction={setOperation} operation />
<Button label="4" executeFunction={addDigit} />
<Button label="5" executeFunction={addDigit} />
<Button label="6" executeFunction={addDigit} />
<Button label="-" executeFunction={setOperation} operation />
<Button label="1" executeFunction={addDigit} />
<Button label="2" executeFunction={addDigit} />
<Button label="3" executeFunction={addDigit} />
<Button label="+" executeFunction={setOperation} operation />
<Button label="0" executeFunction={addDigit} double />
<Button label="." executeFunction={addDigit} />
<Button label="=" executeFunction={setOperation} operation />
</View>
);
}
const style = StyleSheet.create({
container: {
width: 400,
borderRadius: 5,
overflow: 'hidden',
position: 'relative',
justifyContent: 'center',
flexDirection: 'row',
flexWrap: 'wrap',
}
})
export default Interface

Customize ReChart bar chart labels and colors for each Bar

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

X-axis start and end labels are not showing

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' }}
/>

configuration with the .map() in arrays. Fetching data from firebase and outputting in a tinder-like card view in React Native

Here, I am fetching data from firebase and then trying to output it in a tinder card like format. My code is as follows -
import React from 'react';
import { View, ImageBackground, Text, Image, TouchableOpacity } from 'react-native';
import CardStack, { Card } from 'react-native-card-stack-swiper';
import City from '../components/City';
import Filters from '../components/Filters';
import CardItem from '../components/CardItem';
import styles from '../assets/styles';
import Demo from '../assets/demo';;
import {db} from '../config/config';
class Home extends React.Component {
constructor (props) {
super(props);
this.state = ({
items: [],
isReady: false,
});
}
componentWillMount() {
let items = [];
db.ref('cards').once('value', (snap) => {
snap.forEach((child) => {
let item = child.val();
item.id = child.key;
items.push({
name: child.val().pet_name,
description: child.val().pet_gender,
pet_age: child.val().pet_age,
pet_breed: child.val().pet_breed,
photoUrl: child.val().photoUrl,
});
});
//console.log(items)
this.setState({ items: items, isReady: true });
console.log(items);
});
}
componentWillUnmount() {
// fix Warning: Can't perform a React state update on an unmounted component
this.setState = (state,callback)=>{
return;
};
}
render() {
return (
<ImageBackground
source={require('../assets/images/bg.png')}
style={styles.bg}
>
<View style={styles.containerHome}>
<View style={styles.top}>
<City />
<Filters />
</View>
<CardStack
loop={true}
verticalSwipe={false}
renderNoMoreCards={() => null}
ref={swiper => {
this.swiper = swiper
}}
>
{this.state.items.map((item, index) => (
<Card key={index}>
<CardItem
//image={item.image}
name={item.name}
description={item.description}
actions
onPressLeft={() => this.swiper.swipeLeft()}
onPressRight={() => this.swiper.swipeRight()}
/>
</Card>
))}
</CardStack>
</View>
</ImageBackground>
);
}
}
export default Home;
I am fetching data and storing it in an array called items[]. Console.log(items) gives me the following result:
Array [
Object {
"description": "male",
"name": "dawn",
"pet_age": "11",
"pet_breed": "golden retriever",
"photoUrl": "picture",
},
Object {
"description": "Male",
"name": "Rambo",
"pet_age": "7",
"pet_breed": "German",
"photoUrl": "https://firebasestorage.googleapis.com/v0/b/woofmatix-50f11.appspot.com/o/pFkdnwKltNVAhC6IQMeSapN0dOp2?alt=media&token=36087dae-f50d-4f1d-9bf6-572fdaac8481",
},
]
Furthermore, I want to output my data in a card like outlook so I made a custom component called CardItem:
import React from 'react';
import styles from '../assets/styles';
import { Text, View, Image, Dimensions, TouchableOpacity } from 'react-native';
import Icon from './Icon';
const CardItem = ({
actions,
description,
image,
matches,
name,
pet_name,
pet_gender,
pet_age,
onPressLeft,
onPressRight,
status,
variant
}) => {
// Custom styling
const fullWidth = Dimensions.get('window').width;
const imageStyle = [
{
borderRadius: 8,
width: variant ? fullWidth / 2 - 30 : fullWidth - 80,
height: variant ? 170 : 350,
margin: variant ? 0 : 20
}
];
const nameStyle = [
{
paddingTop: variant ? 10 : 15,
paddingBottom: variant ? 5 : 7,
color: '#363636',
fontSize: variant ? 15 : 30
}
];
return (
<View style={styles.containerCardItem}>
{/* IMAGE */}
<Image source={image} style={imageStyle} />
{/* MATCHES */}
{matches && (
<View style={styles.matchesCardItem}>
<Text style={styles.matchesTextCardItem}>
<Icon name="heart" /> {matches}% Match!
</Text>
</View>
)}
{/* NAME */}
<Text style={nameStyle}>{name}</Text>
{/* DESCRIPTION */}
{description && (
<Text style={styles.descriptionCardItem}>{description}</Text>
)}
{/* STATUS */}
{status && (
<View style={styles.status}>
<View style={status === 'Online' ? styles.online : styles.offline} />
<Text style={styles.statusText}>{pet_age}</Text>
</View>
)}
{/* ACTIONS */}
{actions && (
<View style={styles.actionsCardItem}>
<View style={styles.buttonContainer}>
<TouchableOpacity style={[styles.button, styles.red]} onPress={() => {
this.swiper.swipeLeft();
}}>
<Image source={require('../assets/red.png')} resizeMode={'contain'} style={{ height: 62, width: 62 }} />
</TouchableOpacity>
<TouchableOpacity style={[styles.button, styles.orange]} onPress={() => {
this.swiper.goBackFromLeft();
}}>
<Image source={require('../assets/back.png')} resizeMode={'contain'} style={{ height: 32, width: 32, borderRadius: 5 }} />
</TouchableOpacity>
<TouchableOpacity style={[styles.button, styles.green]} onPress={() => {
this.swiper.swipeRight();
}}>
<Image source={require('../assets/green.png')} resizeMode={'contain'} style={{ height: 62, width: 62 }} />
</TouchableOpacity>
</View>
</View>
)}
</View>
);
};
export default CardItem;
The problem is when I try to pass the data in my items[] array, the cardItem component just doesnt work. To dry-run, I used a sample demo array and when I use the Demo array, my component works just fine. What am I doing wrong? I have been tinkering with this problem for quite a while now. Any help whatsoever would be appreciated.

Categories