이윤영

Add HistoryGraph component

......@@ -10,12 +10,16 @@
"lint": "eslint ."
},
"dependencies": {
"d3": "^5.14.2",
"express": "^4.17.1",
"react": "16.9.0",
"react-native": "0.61.4",
"react-native-gesture-handler": "^1.5.0",
"react-native-reanimated": "^1.4.0",
"react-native-screens": "^2.0.0-alpha.8",
"react-native-segmented-control-tab": "^3.4.1",
"react-native-svg": "^9.13.6",
"react-native-svg-charts": "^5.3.0",
"react-native-table-component": "^1.2.1",
"react-native-vector-icons": "^6.6.0",
"react-navigation": "^4.0.10",
......
import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { View, Text, StyleSheet,ScrollView, RefreshControl } from 'react-native';
import { BarChart, Grid } from 'react-native-svg-charts'
import HistoryGraph from '../component/HistoryGraph'
import SegmentedControlTab from "react-native-segmented-control-tab";
const data1 = [
{ label: 'MON', value: 1.8 },
{ label: 'TUE', value: 4.2 },
{ label: 'WEN', value: 1.6 },
{ label: 'THU', value: 0 },
{ label: 'FRI', value: 2.0 },
{ label: 'SAT', value: 3.3 },
{ label: 'SUN', value: 1.3 }
]
const data2 = [
{ label: '1', value: 4.6 },
{ label: '8', value: 3.7 },
{ label: '15', value: 3.0 },
{ label: '22', value: 5.2 },
{ label: '29', value: 3.1 }
]
const data3 = [
{ label: 'Jan', value: 500 },
{ label: 'Feb', value: 312 },
{ label: 'Mar', value: 424 },
{ label: 'Apr', value: 745 },
{ label: 'May', value: 89 },
{ label: 'Jun', value: 434 },
{ label: 'Jul', value: 650 },
{ label: 'Aug', value: 980 },
{ label: 'Sep', value: 123 },
{ label: 'Oct', value: 186 },
{ label: 'Nov', value: 689 },
{ label: 'Dec', value: 643 }
]
const data4 = [
{ label: 'C', value: 500 },
{ label: 'H', value: 312 },
{ label: 'A', value: 424 },
{ label: 'N', value: 745 },
{ label: 'G', value: 89 },
{ label: 'E', value: 434 }
]
const kg1 = "총 3.5kg"
const kg2 = "총 9,6kg"
const kg3 = "총 21.3kg"
export default class HomeTab extends Component {
constructor(){
super();
this.state = {
selectedIndex: 0,
data: data1,
title: "총 3.5kg",
spane: "",
refreshing: false
}
}
_onRefresh = () => {
this.setState({refresing: true});
this.setState({data: data4})
this.setState({refreshing: false});
}
handleIndexChange = index => {
this.setState({selectedIndex: index});
switch(index){
case 0:
this.setState({data: data1, title: kg1});
break;
case 1:
this.setState({data: data2, title: kg2});
break;
case 2:
this.setState({data: data3, title: kg3});
break;
}
};
render() {
return (
<View style={style.container}>
<Text>HistoryTab</Text>
</View>
);
// const fill = 'rgb(134, 65, 244)'
// const data = [50, 10, 40, 95, -4, -24, null, 85, undefined, 0, 35, 53, -53, 24, 50, -20, -80]
// return (
// <BarChart style={{ height: 200 }} data={data} svg={{ fill }} contentInset={{ top: 30, bottom: 30 }}>
// <Grid />
// </BarChart>
// );
return(
<ScrollView
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this._onRefresh}
tintColor="#ff0000"
title="Loading..."
titleColor="#00ff00"
colors={["#ff0000",'#00ff00','#0000ff']}
progressBackgroundColor="#ffff00"
/>
}
>
<Text>{this.state.title}</Text>
<SegmentedControlTab
values={["Week", "Month", "Year"]}
selectedIndex={this.state.selectedIndex}
onTabPress={this.handleIndexChange}
/>
<HistoryGraph data={this.state.data} round={100} unit="kg"/>
</ScrollView>
)
}
}
......@@ -17,4 +122,4 @@ const style = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center',
}
});
})
\ No newline at end of file
......
import React, { PureComponent } from 'react'
import { View, Text, StyleSheet } from 'react-native';
import { Svg, G, Line, Rect } from 'react-native-svg'
import { Text as SvgText } from 'react-native-svg'
import * as d3 from 'd3'
// import Showkg from './ShowKg'
const GRAPH_MARGIN = 20
const GRAPH_BAR_WIDTH = 5
const colors = {
axis: '#E4E4E4',
bars: '#15AD13',
bardefult: '#CED4DA'
}
export default class HistoryGraph extends PureComponent {
constructor(props){
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
kg: this.props.data[this.props.data.length - 1].label,
index: this.props.data.length-1
}
}
handleClick = inkg => {
this.setState({kg: inkg});
}
componentDidUpdate(prevProps, prevState){
if (this.props.data !== prevProps.data) {
this.setState({
...this.state,
kg : this.props.data[this.props.data.length - 1].label,
index: this.props.data.length-1
})
} }
render() {
// Dimensions
const SVGHeight = 300
const SVGWidth = 300
const graphHeight = SVGHeight - 2 * GRAPH_MARGIN
const graphWidth = SVGWidth - 2 * GRAPH_MARGIN
const data = this.props.data
// X scale point
const xDomain = data.map(item => item.label)
const xRange = [0, graphWidth]
const x = d3.scalePoint()
.domain(xDomain)
.range(xRange)
.padding(1)
// Y scale linear
const maxValue = d3.max(data, d => d.value)
const topValue = Math.ceil(maxValue / this.props.round) * this.props.round
const yDomain = [0, topValue]
const yRange = [0, graphHeight]
const y = d3.scaleLinear()
.domain(yDomain)
.range(yRange)
// top axis and middle axis
const middleValue = topValue / 2
return (
<View>
<Svg width={SVGWidth} height={SVGHeight}>
<G y={graphHeight + GRAPH_MARGIN}>
{/* Top value label */}
<SvgText
x={graphWidth}
textAnchor="end"
y={y(topValue) * -1 - 5}
fontSize={12}
fill="black"
fillOpacity={0.4}>
{topValue + ' ' + this.props.unit}
</SvgText>
{/* top axis */}
<Line
x1="0"
y1={y(topValue) * -1}
x2={graphWidth}
y2={y(topValue) * -1}
stroke={colors.axis}
strokeDasharray={[3, 3]}
strokeWidth="0.5"
/>
{/* middle axis */}
<Line
x1="0"
y1={y(middleValue) * -1}
x2={graphWidth}
y2={y(middleValue) * -1}
stroke={colors.axis}
strokeDasharray={[3, 3]}
strokeWidth="0.5"
/>
{/* bottom axis */}
<Line
x1="0"
y1="2"
x2={graphWidth}
y2="2"
stroke={colors.axis}
strokeWidth="0.5"
/>
{/* bars */}
{data.map(item => (
<Rect
key={'bar' + item.label}
x={x(item.label) - (GRAPH_BAR_WIDTH / 2)}
y={y(item.value) * -1}
rx={2.5}
width={GRAPH_BAR_WIDTH}
height={y(item.value)}
fill = {this.state.kg == item.label ? colors.bars : colors.bardefult}
onPress={()=>this.handleClick(item.label)}
/>
))}
{/* labels */}
{data.map(item => (
<SvgText
key={'label' + item.label}
fontSize="8"
x={x(item.label)}
y="10"
textAnchor="middle">{item.label}</SvgText>
))}
</G>
</Svg>
<Text>{this.state.kg}</Text>
</View>
)
}
}
\ No newline at end of file
This diff is collapsed. Click to expand it.