diff options
| author | Andrew <saintruler@gmail.com> | 2019-03-11 21:00:02 +0400 |
|---|---|---|
| committer | Andrew <saintruler@gmail.com> | 2019-03-11 21:00:02 +0400 |
| commit | 7e7dd5244e8d26485ad7950a89c04c98c4fef83f (patch) | |
| tree | 810730c4650392080fb87a78d3b527201e89fe4b /frontend/app/components/charts | |
Initial commit/
Diffstat (limited to 'frontend/app/components/charts')
| -rw-r--r-- | frontend/app/components/charts/areaChart.js | 120 | ||||
| -rw-r--r-- | frontend/app/components/charts/areaSmoothedChart.js | 118 | ||||
| -rw-r--r-- | frontend/app/components/charts/doughnutChart.js | 125 | ||||
| -rw-r--r-- | frontend/app/components/charts/index.js | 4 | ||||
| -rw-r--r-- | frontend/app/components/charts/progessChart.js | 96 |
5 files changed, 463 insertions, 0 deletions
diff --git a/frontend/app/components/charts/areaChart.js b/frontend/app/components/charts/areaChart.js new file mode 100644 index 0000000..be40960 --- /dev/null +++ b/frontend/app/components/charts/areaChart.js @@ -0,0 +1,120 @@ +import React from 'react'; +import { + View, + Dimensions, +} from 'react-native'; +import { + RkComponent, + RkTheme, + RkText, +} from 'react-native-ui-kitten'; + +import { + VictoryChart, + VictoryAxis, + VictoryArea, + VictoryScatter, + VictoryGroup, +} from 'victory-native'; + + +export class AreaChart extends RkComponent { + state = { + data: [ + { x: 1, y: 1 }, + { x: 2, y: 2 }, + { x: 3, y: 1 }, + { x: 4, y: 2 }, + { x: 5, y: 3 }, + { x: 6, y: 3 }, + { x: 7, y: 4 }, + { x: 8, y: 3 }, + { x: 9, y: 2 }, + { x: 10, y: 4 }, + ], + }; + + componentWillMount() { + this.size = Dimensions.get('window').width; + } + + componentDidMount() { + this.setStateInterval = setInterval(() => { + let positive = Math.random() > 0.5; + let newValue = this.state.data[this.state.data.length - 1].y; + if (newValue > 3) { + positive = false; + } else if (newValue < 2) { + positive = true; + } + newValue = positive ? newValue + 1 : newValue - 1; + const newData = this.state.data.map((d, i) => ({ + x: d.x, + y: i === this.state.data.length - 1 ? newValue : this.state.data[i + 1].y, + })); + this.setState({ + data: newData, + }); + }, 3000); + } + + componentWillUnmount() { + clearInterval(this.setStateInterval); + } + + render = () => ( + <View> + <RkText rkType='header4'>REAL TIME VISITORS</RkText> + <VictoryChart + padding={{ + top: 20, left: 40, right: 5, bottom: 5, + }} + width={this.size - 60}> + <VictoryAxis + tickValues={[]} + style={{ + axis: { stroke: 'transparent' }, + }} + /> + <VictoryAxis + dependentAxis + tickValues={['50', '100', '150', '200']} + style={{ + axis: { stroke: 'transparent' }, + grid: { stroke: RkTheme.current.colors.disabled, strokeWidth: 0.5 }, + tickLabels: { + fontSize: 14, + stroke: RkTheme.current.colors.text.secondary, + fill: RkTheme.current.colors.text.secondary, + fontFamily: RkTheme.current.fonts.family.regular, + strokeWidth: 0.5, + }, + }} + /> + <VictoryGroup data={this.state.data}> + <VictoryArea + style={{ + data: { + fill: RkTheme.current.colors.charts.area.fill, + fillOpacity: 0.5, + stroke: RkTheme.current.colors.charts.area.stroke, + strokeOpacity: 0.8, + strokeWidth: 1.5, + }, + }} + /> + <VictoryScatter + style={{ + data: { + fill: 'white', + stroke: RkTheme.current.colors.charts.area.stroke, + strokeOpacity: 0.8, + strokeWidth: 1.5, + }, + }} + /> + </VictoryGroup> + </VictoryChart> + </View> + ); +} diff --git a/frontend/app/components/charts/areaSmoothedChart.js b/frontend/app/components/charts/areaSmoothedChart.js new file mode 100644 index 0000000..54ca435 --- /dev/null +++ b/frontend/app/components/charts/areaSmoothedChart.js @@ -0,0 +1,118 @@ +import React from 'react'; +import { + View, + Dimensions, +} from 'react-native'; +import { + RkComponent, + RkText, + RkTheme, +} from 'react-native-ui-kitten'; +import { + VictoryChart, + VictoryAxis, + VictoryArea, +} from 'victory-native'; + +export class AreaSmoothedChart extends RkComponent { + state = { + data: [ + [ + { x: 1, y: 1.0, key: 0 }, + { x: 2, y: 1.5, key: 1 }, + { x: 3, y: 1.0, key: 2 }, + { x: 4, y: 0.5, key: 3 }, + { x: 5, y: 1.0, key: 4 }, + { x: 6, y: 2.0, key: 5 }, + { x: 7, y: 2.5, key: 6 }, + ], + [ + { x: 1, y: 1.5, key: 0 }, + { x: 2, y: 2.0, key: 1 }, + { x: 3, y: 1.5, key: 2 }, + { x: 4, y: 0.8, key: 3 }, + { x: 5, y: 1.5, key: 4 }, + { x: 6, y: 2.6, key: 5 }, + { x: 7, y: 3.3, key: 6 }, + ], + [ + { x: 1, y: 2.0, key: 0 }, + { x: 2, y: 2.5, key: 1 }, + { x: 3, y: 2.0, key: 2 }, + { x: 4, y: 1.1, key: 3 }, + { x: 5, y: 2.0, key: 4 }, + { x: 6, y: 3.2, key: 5 }, + { x: 7, y: 4.0, key: 6 }, + ], + [ + { x: 1, y: 2.5, key: 0 }, + { x: 2, y: 3.0, key: 1 }, + { x: 3, y: 2.5, key: 2 }, + { x: 4, y: 1.4, key: 3 }, + { x: 5, y: 2.5, key: 4 }, + { x: 6, y: 3.7, key: 5 }, + { x: 7, y: 4.7, key: 6 }, + ], + ], + }; + colors = RkTheme.current.colors.charts.followersArea; + + componentWillMount() { + this.size = Dimensions.get('window').width; + } + + renderChartAreas = () => this.state.data.reverse().map((area, index) => ( + <VictoryArea + key={`${area.length * index}`} + interpolation="natural" + style={{ + data: { + fill: this.colors[index], + stroke: this.colors[index], + }, + }} + data={area} + /> + )); + + render = () => ( + <View> + <RkText rkType='header4'>NEW FOLLOWERS</RkText> + <VictoryChart + padding={{ + top: 20, left: 40, right: 15, bottom: 40, + }} + width={this.size - 60}> + <VictoryAxis + tickValues={['Sun', 'Mon', 'Tue', ' Wed', 'Thu', 'Fri', 'Sat']} + style={{ + axis: { stroke: 'transparent' }, + tickLabels: { + fontSize: 14, + stroke: RkTheme.current.colors.text.secondary, + fill: RkTheme.current.colors.text.secondary, + fontFamily: RkTheme.current.fonts.family.regular, + strokeWidth: 0.5, + }, + }} + /> + <VictoryAxis + dependentAxis + tickValues={['10k', '20k', '30k', '40k']} + style={{ + axis: { stroke: 'transparent' }, + grid: { stroke: RkTheme.current.colors.disabled, strokeWidth: 0.5 }, + tickLabels: { + fontSize: 14, + stroke: RkTheme.current.colors.text.secondary, + fill: RkTheme.current.colors.text.secondary, + fontFamily: RkTheme.current.fonts.family.regular, + strokeWidth: 0.5, + }, + }} + /> + {this.renderChartAreas()} + </VictoryChart> + </View> + ) +} diff --git a/frontend/app/components/charts/doughnutChart.js b/frontend/app/components/charts/doughnutChart.js new file mode 100644 index 0000000..5b67ba7 --- /dev/null +++ b/frontend/app/components/charts/doughnutChart.js @@ -0,0 +1,125 @@ +import React from 'react'; +import { View } from 'react-native'; +import { + RkComponent, + RkText, + RkTheme, + RkStyleSheet, +} from 'react-native-ui-kitten'; +import { VictoryPie } from 'victory-native'; +import { Svg, Text as SvgText } from 'react-native-svg'; +import { scale } from '../../utils/scale'; + +export class DoughnutChart extends RkComponent { + state = { + selected: 0, + data: [ + { + x: 1, + y: 240, + title: '24%', + name: 'Likes', + color: RkTheme.current.colors.charts.doughnut[0], + }, + { + x: 2, + y: 270, + title: '27%', + name: 'Comments', + color: RkTheme.current.colors.charts.doughnut[1], + }, + { + x: 3, + y: 170, + title: '17%', + name: 'Shares', + color: RkTheme.current.colors.charts.doughnut[2], + }, + { + x: 4, + y: 320, + title: '32%', + name: 'People', + color: RkTheme.current.colors.charts.doughnut[3], + }, + ], + }; + size = 300; + fontSize = 40; + + computeColors = () => this.state.data.map(i => i.color); + + onPeopleChartPressed = (event, props) => { + this.setState({ + selected: props.index, + }); + }; + + renderMarkdown = () => this.state.data.map(this.renderMarkdownItem); + + renderMarkdownItem = (item) => ( + <View key={item.name} style={styles.legendItem}> + <View style={[styles.itemBadge, { backgroundColor: item.color }]} /> + <RkText rkType="primary3">{item.name}</RkText> + </View> + ); + + render = () => ( + <View> + <RkText rkType='header4'>AUDIENCE OVERVIEW</RkText> + <View style={{ alignSelf: 'center' }}> + <Svg width={scale(this.size)} height={scale(this.size)}> + <VictoryPie + labels={[]} + width={scale(this.size)} + height={scale(this.size)} + colorScale={this.computeColors()} + data={this.state.data} + standalone={false} + padding={scale(25)} + innerRadius={scale(70)} + events={[{ + target: 'data', + eventHandlers: { + onPressIn: this.onPeopleChartPressed, + }, + }]} + /> + <SvgText + textAnchor="middle" + verticalAnchor="middle" + x={scale(this.size / 2)} + y={scale(this.size / 2)} + height={scale(this.fontSize)} + fontSize={scale(this.fontSize)} + fontFamily={RkTheme.current.fonts.family.regular} + stroke={RkTheme.current.colors.text.base} + fill={RkTheme.current.colors.text.base}> + {this.state.data[this.state.selected].title} + </SvgText> + </Svg> + </View> + <View style={styles.legendContainer}> + {this.renderMarkdown()} + </View> + </View> + ); +} + +const styles = RkStyleSheet.create(() => ({ + legendContainer: { + flexDirection: 'row', + flexWrap: 'wrap', + justifyContent: 'space-around', + }, + legendItem: { + flexDirection: 'row', + alignItems: 'center', + }, + itemBadge: { + width: 10, + height: 10, + borderRadius: 5, + marginRight: 5, + }, +})); diff --git a/frontend/app/components/charts/index.js b/frontend/app/components/charts/index.js new file mode 100644 index 0000000..c4438e8 --- /dev/null +++ b/frontend/app/components/charts/index.js @@ -0,0 +1,4 @@ +export * from './progessChart'; +export * from './doughnutChart'; +export * from './areaChart'; +export * from './areaSmoothedChart'; diff --git a/frontend/app/components/charts/progessChart.js b/frontend/app/components/charts/progessChart.js new file mode 100644 index 0000000..bd70dcf --- /dev/null +++ b/frontend/app/components/charts/progessChart.js @@ -0,0 +1,96 @@ +import React from 'react'; +import { View } from 'react-native'; +import { + RkComponent, + RkText, + RkTheme, + RkStyleSheet, +} from 'react-native-ui-kitten'; +import { VictoryPie } from 'victory-native'; +import { Svg, Text as SvgText } from 'react-native-svg'; +import { scale } from '../../utils/scale'; + +export class ProgressChart extends RkComponent { + state = { + percents: 72, + }; + size = 120; + fontSize = 25; + + componentDidMount() { + this.setStateInterval = setInterval(this.updatePercent, 1500); + } + + componentWillUnmount() { + clearInterval(this.setStateInterval); + } + + updatePercent = () => { + let positive = Math.random() > 0.5; + if (this.state.percents > 95) { + positive = false; + } else if (this.state.percents < 60) { + positive = true; + } + this.setState({ + percents: positive ? this.state.percents + 1 : this.state.percents - 1, + }); + }; + + getChartData = () => [ + { x: 1, y: this.state.percents }, + { x: 2, y: 100 - this.state.percents }, + ]; + + onChartFill = (data) => { + const themeColor = RkTheme.current.colors.charts.followersProgress; + return data.x === 1 ? themeColor : 'transparent'; + }; + + render = () => ( + <View> + <RkText rkType='header4'>FOLLOWERS</RkText> + <View style={styles.chartContainer}> + <Svg width={scale(this.size)} height={scale(this.size)}> + <VictoryPie + labels={[]} + padding={0} + standalone={false} + width={scale(this.size)} + height={scale(this.size)} + style={{ data: { fill: this.onChartFill } }} + data={this.getChartData()} + cornerRadius={scale(25)} + innerRadius={scale(40)} + /> + <SvgText + textAnchor="middle" + verticalAnchor="middle" + x={scale(this.size / 2)} + y={scale(this.size / 2)} + height={scale(this.fontSize)} + fontSize={scale(this.fontSize)} + fontFamily={RkTheme.current.fonts.family.regular} + stroke={RkTheme.current.colors.text.base} + fill={RkTheme.current.colors.text.base}> + {`${this.state.percents}%`} + </SvgText> + </Svg> + <View> + <RkText rkType='header4'>REACH</RkText> + <RkText rkType='header2'>1 500 356</RkText> + <RkText rkType='secondary2'>+6 per day in average</RkText> + </View> + </View> + </View> + ); +} + +const styles = RkStyleSheet.create(() => ({ + chartContainer: { + flexDirection: 'row', + justifyContent: 'space-around', + alignItems: 'center', + marginTop: 10, + }, +})); |