이윤영

Add HistoryGraph component

...@@ -10,12 +10,16 @@ ...@@ -10,12 +10,16 @@
10 "lint": "eslint ." 10 "lint": "eslint ."
11 }, 11 },
12 "dependencies": { 12 "dependencies": {
13 + "d3": "^5.14.2",
13 "express": "^4.17.1", 14 "express": "^4.17.1",
14 "react": "16.9.0", 15 "react": "16.9.0",
15 "react-native": "0.61.4", 16 "react-native": "0.61.4",
16 "react-native-gesture-handler": "^1.5.0", 17 "react-native-gesture-handler": "^1.5.0",
17 "react-native-reanimated": "^1.4.0", 18 "react-native-reanimated": "^1.4.0",
18 "react-native-screens": "^2.0.0-alpha.8", 19 "react-native-screens": "^2.0.0-alpha.8",
20 + "react-native-segmented-control-tab": "^3.4.1",
21 + "react-native-svg": "^9.13.6",
22 + "react-native-svg-charts": "^5.3.0",
19 "react-native-table-component": "^1.2.1", 23 "react-native-table-component": "^1.2.1",
20 "react-native-vector-icons": "^6.6.0", 24 "react-native-vector-icons": "^6.6.0",
21 "react-navigation": "^4.0.10", 25 "react-navigation": "^4.0.10",
......
1 import React, { Component } from 'react'; 1 import React, { Component } from 'react';
2 -import { View, Text, StyleSheet } from 'react-native'; 2 +import { View, Text, StyleSheet,ScrollView, RefreshControl } from 'react-native';
3 +import { BarChart, Grid } from 'react-native-svg-charts'
4 +import HistoryGraph from '../component/HistoryGraph'
5 +import SegmentedControlTab from "react-native-segmented-control-tab";
6 +const data1 = [
7 + { label: 'MON', value: 1.8 },
8 + { label: 'TUE', value: 4.2 },
9 + { label: 'WEN', value: 1.6 },
10 + { label: 'THU', value: 0 },
11 + { label: 'FRI', value: 2.0 },
12 + { label: 'SAT', value: 3.3 },
13 + { label: 'SUN', value: 1.3 }
14 +]
15 +const data2 = [
16 + { label: '1', value: 4.6 },
17 + { label: '8', value: 3.7 },
18 + { label: '15', value: 3.0 },
19 + { label: '22', value: 5.2 },
20 + { label: '29', value: 3.1 }
21 +]
22 +const data3 = [
23 + { label: 'Jan', value: 500 },
24 + { label: 'Feb', value: 312 },
25 + { label: 'Mar', value: 424 },
26 + { label: 'Apr', value: 745 },
27 + { label: 'May', value: 89 },
28 + { label: 'Jun', value: 434 },
29 + { label: 'Jul', value: 650 },
30 + { label: 'Aug', value: 980 },
31 + { label: 'Sep', value: 123 },
32 + { label: 'Oct', value: 186 },
33 + { label: 'Nov', value: 689 },
34 + { label: 'Dec', value: 643 }
35 +]
36 +
37 +const data4 = [
38 + { label: 'C', value: 500 },
39 + { label: 'H', value: 312 },
40 + { label: 'A', value: 424 },
41 + { label: 'N', value: 745 },
42 + { label: 'G', value: 89 },
43 + { label: 'E', value: 434 }
44 +]
45 +
46 +const kg1 = "총 3.5kg"
47 +const kg2 = "총 9,6kg"
48 +const kg3 = "총 21.3kg"
3 49
4 export default class HomeTab extends Component { 50 export default class HomeTab extends Component {
51 + constructor(){
52 + super();
53 + this.state = {
54 + selectedIndex: 0,
55 + data: data1,
56 + title: "총 3.5kg",
57 + spane: "",
58 + refreshing: false
59 + }
60 + }
61 +
62 + _onRefresh = () => {
63 + this.setState({refresing: true});
64 + this.setState({data: data4})
65 + this.setState({refreshing: false});
66 + }
67 +
68 + handleIndexChange = index => {
69 + this.setState({selectedIndex: index});
70 + switch(index){
71 + case 0:
72 + this.setState({data: data1, title: kg1});
73 + break;
74 + case 1:
75 + this.setState({data: data2, title: kg2});
76 + break;
77 + case 2:
78 + this.setState({data: data3, title: kg3});
79 + break;
80 + }
81 + };
82 +
5 render() { 83 render() {
6 - return ( 84 + // const fill = 'rgb(134, 65, 244)'
7 - <View style={style.container}> 85 + // const data = [50, 10, 40, 95, -4, -24, null, 85, undefined, 0, 35, 53, -53, 24, 50, -20, -80]
8 - <Text>HistoryTab</Text> 86 +
9 - </View> 87 + // return (
10 - ); 88 + // <BarChart style={{ height: 200 }} data={data} svg={{ fill }} contentInset={{ top: 30, bottom: 30 }}>
89 + // <Grid />
90 + // </BarChart>
91 + // );
92 +
93 + return(
94 + <ScrollView
95 + refreshControl={
96 + <RefreshControl
97 + refreshing={this.state.refreshing}
98 + onRefresh={this._onRefresh}
99 + tintColor="#ff0000"
100 + title="Loading..."
101 + titleColor="#00ff00"
102 + colors={["#ff0000",'#00ff00','#0000ff']}
103 + progressBackgroundColor="#ffff00"
104 + />
105 + }
106 + >
107 + <Text>{this.state.title}</Text>
108 + <SegmentedControlTab
109 + values={["Week", "Month", "Year"]}
110 + selectedIndex={this.state.selectedIndex}
111 + onTabPress={this.handleIndexChange}
112 + />
113 + <HistoryGraph data={this.state.data} round={100} unit="kg"/>
114 + </ScrollView>
115 + )
11 } 116 }
12 } 117 }
13 118
...@@ -17,4 +122,4 @@ const style = StyleSheet.create({ ...@@ -17,4 +122,4 @@ const style = StyleSheet.create({
17 alignItems: 'center', 122 alignItems: 'center',
18 justifyContent: 'center', 123 justifyContent: 'center',
19 } 124 }
20 -}); 125 +})
...\ No newline at end of file ...\ No newline at end of file
......
1 +import React, { PureComponent } from 'react'
2 +import { View, Text, StyleSheet } from 'react-native';
3 +import { Svg, G, Line, Rect } from 'react-native-svg'
4 +import { Text as SvgText } from 'react-native-svg'
5 +import * as d3 from 'd3'
6 +// import Showkg from './ShowKg'
7 +
8 +const GRAPH_MARGIN = 20
9 +const GRAPH_BAR_WIDTH = 5
10 +const colors = {
11 + axis: '#E4E4E4',
12 + bars: '#15AD13',
13 + bardefult: '#CED4DA'
14 +}
15 +
16 +export default class HistoryGraph extends PureComponent {
17 +
18 + constructor(props){
19 + super(props);
20 + this.handleClick = this.handleClick.bind(this);
21 + this.state = {
22 + kg: this.props.data[this.props.data.length - 1].label,
23 + index: this.props.data.length-1
24 + }
25 + }
26 +
27 + handleClick = inkg => {
28 + this.setState({kg: inkg});
29 + }
30 +
31 + componentDidUpdate(prevProps, prevState){
32 + if (this.props.data !== prevProps.data) {
33 + this.setState({
34 + ...this.state,
35 + kg : this.props.data[this.props.data.length - 1].label,
36 + index: this.props.data.length-1
37 + })
38 + } }
39 +
40 + render() {
41 + // Dimensions
42 + const SVGHeight = 300
43 + const SVGWidth = 300
44 + const graphHeight = SVGHeight - 2 * GRAPH_MARGIN
45 + const graphWidth = SVGWidth - 2 * GRAPH_MARGIN
46 + const data = this.props.data
47 +
48 + // X scale point
49 + const xDomain = data.map(item => item.label)
50 + const xRange = [0, graphWidth]
51 + const x = d3.scalePoint()
52 + .domain(xDomain)
53 + .range(xRange)
54 + .padding(1)
55 +
56 + // Y scale linear
57 + const maxValue = d3.max(data, d => d.value)
58 + const topValue = Math.ceil(maxValue / this.props.round) * this.props.round
59 + const yDomain = [0, topValue]
60 + const yRange = [0, graphHeight]
61 + const y = d3.scaleLinear()
62 + .domain(yDomain)
63 + .range(yRange)
64 +
65 + // top axis and middle axis
66 + const middleValue = topValue / 2
67 +
68 + return (
69 + <View>
70 + <Svg width={SVGWidth} height={SVGHeight}>
71 + <G y={graphHeight + GRAPH_MARGIN}>
72 + {/* Top value label */}
73 + <SvgText
74 + x={graphWidth}
75 + textAnchor="end"
76 + y={y(topValue) * -1 - 5}
77 + fontSize={12}
78 + fill="black"
79 + fillOpacity={0.4}>
80 + {topValue + ' ' + this.props.unit}
81 + </SvgText>
82 +
83 + {/* top axis */}
84 + <Line
85 + x1="0"
86 + y1={y(topValue) * -1}
87 + x2={graphWidth}
88 + y2={y(topValue) * -1}
89 + stroke={colors.axis}
90 + strokeDasharray={[3, 3]}
91 + strokeWidth="0.5"
92 + />
93 +
94 + {/* middle axis */}
95 + <Line
96 + x1="0"
97 + y1={y(middleValue) * -1}
98 + x2={graphWidth}
99 + y2={y(middleValue) * -1}
100 + stroke={colors.axis}
101 + strokeDasharray={[3, 3]}
102 + strokeWidth="0.5"
103 + />
104 +
105 + {/* bottom axis */}
106 + <Line
107 + x1="0"
108 + y1="2"
109 + x2={graphWidth}
110 + y2="2"
111 + stroke={colors.axis}
112 + strokeWidth="0.5"
113 + />
114 +
115 + {/* bars */}
116 + {data.map(item => (
117 + <Rect
118 + key={'bar' + item.label}
119 + x={x(item.label) - (GRAPH_BAR_WIDTH / 2)}
120 + y={y(item.value) * -1}
121 + rx={2.5}
122 + width={GRAPH_BAR_WIDTH}
123 + height={y(item.value)}
124 + fill = {this.state.kg == item.label ? colors.bars : colors.bardefult}
125 + onPress={()=>this.handleClick(item.label)}
126 + />
127 + ))}
128 +
129 + {/* labels */}
130 + {data.map(item => (
131 + <SvgText
132 + key={'label' + item.label}
133 + fontSize="8"
134 + x={x(item.label)}
135 + y="10"
136 + textAnchor="middle">{item.label}</SvgText>
137 + ))}
138 + </G>
139 + </Svg>
140 + <Text>{this.state.kg}</Text>
141 + </View>
142 + )
143 + }
144 +}
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.