Created
May 21, 2020 07:31
-
-
Save andreferi3/02e8d0aea646928c0a682c77f7f3c781 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Dimensions } from 'react-native'; | |
| import { utcParse } from 'd3'; | |
| export const { width } = Dimensions.get('screen') | |
| export const GRAPH_MARGIN = 10 | |
| export const SVGHeight = 150 | |
| export const SVGWidth = width / 100 * 80 | |
| export const graphHeight = SVGHeight - 2 * GRAPH_MARGIN | |
| export const graphWidth = SVGWidth - 5 * GRAPH_MARGIN | |
| export const parseTime = utcParse("%Y-%m-%dT%H:%M:%S.%LZ") | |
| export const xRange = [0, graphWidth - GRAPH_MARGIN] | |
| export const yRange = [graphHeight - GRAPH_MARGIN, 0] | |
| export function countGraphWidth(width) { | |
| return width - 5 * GRAPH_MARGIN | |
| } | |
| export function countGraphHeight(height) { | |
| return height - 2 * GRAPH_MARGIN | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React from 'react' | |
| import { View, ViewPropTypes } from 'react-native' | |
| import PropTypes from 'prop-types'; | |
| import { data1 } from '../example/Chart/dataScheme'; | |
| import { SVGHeight, SVGWidth, GRAPH_MARGIN, graphWidth, graphHeight, parseTime, xRange, yRange, countGraphHeight, countGraphWidth } from './helper/chartHelper'; | |
| import { utcParse, extent, min, max } from 'd3'; | |
| import * as shape from 'd3-shape'; | |
| import { scaleTime, scaleLinear } from 'd3-scale' | |
| import Svg, { Defs, LinearGradient, Stop, Path, G, Line, Text } from 'react-native-svg'; | |
| import { Colors } from '../../../../assets/themes'; | |
| import moment from 'moment'; | |
| const viewPropTypes = View.propTypes || ViewPropTypes | |
| const d3 = { shape } | |
| /** | |
| * @param {number} width | |
| */ | |
| function rangeX(width) { | |
| let range = xRange | |
| if (width) { | |
| range = [0, countGraphWidth(width) - GRAPH_MARGIN] | |
| } | |
| return range | |
| } | |
| /** | |
| * @param {number} height | |
| */ | |
| function rangeY(height) { | |
| let range = yRange | |
| if (height) { | |
| range = [countGraphHeight(height) - GRAPH_MARGIN, 0] | |
| } | |
| return range | |
| } | |
| /** | |
| * @param {string, arrayOfObject, string, string, View.Style, number, number} param0 | |
| */ | |
| const NChart = ({ chartColor, data, x, y, containerStyle, height, width }) => { | |
| const xDomain = extent(data, function (d) { return parseTime(d[x]) }) | |
| const scaleX = scaleTime().domain(xDomain).range(rangeX(width)); | |
| const yMinDomain = min(data, d => d[y]) | |
| const yMaxDomain = max(data, d => d[y]) | |
| const yBottomDomain = ((yMaxDomain - yMinDomain) < yMinDomain) ? (yMaxDomain - yMinDomain) : yMinDomain | |
| const yTopDomain = ((yBottomDomain == yMinDomain)) ? yMaxDomain + 5 : yMaxDomain | |
| const yDomain = [yMinDomain, yTopDomain] | |
| const scaleY = scaleLinear().domain(yDomain).range(rangeY(height)); | |
| const yTicks = scaleLinear().domain(yDomain).ticks(5) | |
| const line = d3.shape.line() | |
| .x(function (d) { return scaleX(parseTime(d[x])) }) | |
| .y(function (d) { return scaleY(d[y]) }) | |
| .curve(d3.shape.curveBasis)(data) | |
| /** | |
| * @variation conditionalProperty | |
| */ | |
| const WIDTH = width ? width : SVGWidth | |
| const HEIGHT = height ? height : SVGHeight | |
| const GRAPH_HEIGHT = height ? countGraphHeight(height) : graphHeight | |
| const GRAPH_WIDTH = width ? countGraphWidth(width) : graphWidth | |
| const gradientColor = chartColor == 'green' ? Colors.colorScheme.$greenDark : Colors.colorScheme.$tertiaryDark | |
| const lineColor = chartColor == 'green' ? Colors.colorScheme.$green : Colors.colorScheme.$red | |
| return ( | |
| <View style={containerStyle}> | |
| <Svg width={WIDTH} height={HEIGHT}> | |
| <G> | |
| <Defs> | |
| <LinearGradient id="gradient" x1="50%" y1="0%" x2="50%" y2="100%"> | |
| <Stop offset="0%" stopColor={gradientColor} stopOpacity="0.7" /> | |
| <Stop offset="80%" stopColor={gradientColor} stopOpacity="0.2" /> | |
| <Stop offset="100%" stopColor={gradientColor} stopOpacity="0" /> | |
| </LinearGradient> | |
| </Defs> | |
| <Path d={`${line}L ${GRAPH_WIDTH - GRAPH_MARGIN} ${GRAPH_HEIGHT} L 0 ${GRAPH_HEIGHT}`} fill="url(#gradient)" /> | |
| <Path d={line} fill="transparent" stroke={lineColor} strokeWidth={3} /> | |
| <Line | |
| x1={0} | |
| y1={GRAPH_HEIGHT} | |
| x2={GRAPH_WIDTH} | |
| y2={GRAPH_HEIGHT} | |
| stroke={Colors.colorScheme.$textSecondary} | |
| strokeWidth={1} | |
| translateY={-10} | |
| /> | |
| { | |
| data.map((item, index) => ( | |
| <Line | |
| key={index} | |
| x1={scaleX(parseTime(item[x]))} | |
| y1={GRAPH_HEIGHT - 2} | |
| x2={scaleX(parseTime(item[x]))} | |
| y2={GRAPH_HEIGHT - GRAPH_MARGIN} | |
| stroke={Colors.colorScheme.$textSecondary} | |
| strokeWidth={1} | |
| /> | |
| )) | |
| } | |
| { | |
| data.map((item, index) => { | |
| return ( | |
| <Text | |
| key={index} | |
| x={scaleX(parseTime(item[x]))} | |
| y={GRAPH_HEIGHT + GRAPH_MARGIN} | |
| textAnchor="start" | |
| fill={Colors.colorScheme.$textSecondary} | |
| fontSize={12} | |
| translateY={5} | |
| > | |
| {moment(item[x]).format('hh:mm')} | |
| </Text> | |
| ) | |
| }) | |
| } | |
| { | |
| yTicks.map((item, index) => ( | |
| <Line | |
| key={index} | |
| x1={GRAPH_WIDTH - 5} | |
| y1={scaleY(item)} | |
| x2={GRAPH_WIDTH + 7} | |
| y2={scaleY(item)} | |
| stroke={Colors.colorScheme.$textSecondary} | |
| strokeWidth={1} | |
| /> | |
| )) | |
| } | |
| { | |
| yTicks.map((item, index) => ( | |
| <Line | |
| key={index} | |
| x1={0} | |
| y1={scaleY(item)} | |
| x2={GRAPH_WIDTH - 8} | |
| y2={scaleY(item)} | |
| stroke={Colors.colorScheme.$textSecondary} | |
| strokeWidth={0.5} | |
| strokeDasharray={[5, 5]} | |
| /> | |
| )) | |
| } | |
| { | |
| yTicks.map((item, index) => { | |
| return ( | |
| <Text | |
| key={index} | |
| x={GRAPH_WIDTH + 10} | |
| y={scaleY(item)} | |
| textAnchor="start" | |
| fontSize={12} | |
| fill={Colors.colorScheme.$textSecondary} | |
| > | |
| {item + '%'} | |
| </Text> | |
| ) | |
| }) | |
| } | |
| <Line | |
| x1={GRAPH_WIDTH} | |
| y1={scaleY(yMinDomain)} | |
| x2={GRAPH_WIDTH} | |
| y2={scaleY(yMaxDomain) - 15} | |
| stroke={Colors.colorScheme.$textSecondary} | |
| strokeWidth={1} | |
| /> | |
| </G> | |
| </Svg> | |
| </View> | |
| ) | |
| } | |
| NChart.propTypes = { | |
| chartColor: PropTypes.oneOf(['red', 'green']), | |
| containerStyle: viewPropTypes.style, | |
| data: PropTypes.arrayOf(PropTypes.object).isRequired, | |
| x: PropTypes.string, | |
| y: PropTypes.string, | |
| height: PropTypes.number, | |
| width: PropTypes.number | |
| } | |
| NChart.defaultProps = { | |
| data: data1, | |
| chartColor: 'green', | |
| x: 'x', | |
| y: 'y' | |
| } | |
| export default NChart |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment