Skip to content

Instantly share code, notes, and snippets.

@V-Tom
Created January 26, 2018 05:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save V-Tom/5e441cba9d3a8ef1366997fff6a64606 to your computer and use it in GitHub Desktop.
Save V-Tom/5e441cba9d3a8ef1366997fff6a64606 to your computer and use it in GitHub Desktop.
Demo code for simple React-Native ART Curve Chart
import React, { Component } from 'react'
import * as d3 from 'd3-shape'
import {
ART,
View,
ScrollView,
Dimensions,
Text
} from 'react-native';
const {
Surface,
Group,
Shape,
Path,
LinearGradient
} = ART;
const data = [
{ "data": "Mon", "value": 820 },
{ "data": "Tue", "value": 932 },
{ "data": "Wed", "value": 631 },
{ "data": "Thu", "value": 934 },
{ "data": "Fri", "value": 890 },
{ "data": "Sat", "value": 1330 },
{ "data": "Sun", "value": 1320 }
]
const CHART_WIDTH = 375
const CHART_HEIGHT = 300
const MAX_Y_AXIS = 1500
const MIN_Y_AXIS = 0
const X_AXIS_WIDTH = 20
const X_AXIS_OFFSET = 50 + X_AXIS_WIDTH
const CHART_REAL_WIDTH = data.length * X_AXIS_OFFSET
export default class ReactNativeART extends Component {
renderBg() {
return <Shape
d={new Path().moveTo(0, 0)
.lineTo(0, CHART_HEIGHT)
.lineTo(CHART_REAL_WIDTH, CHART_HEIGHT)
.lineTo(CHART_REAL_WIDTH, 0)
.close()}
fill={new LinearGradient({
'0': '#A185D4',
'1': '#B19FD3'
},
0, 0, 0, CHART_HEIGHT
)}
/>
}
renderYAxis(data) {
const split = 6
return new Array(split).fill(null).map((d, i) => {
if (i === 0) return null
return <Text
key={i}
style={{
position: 'absolute',
fontSize: 12,
color: '#fff',
left: '3%',
backgroundColor: 'transparent',
top: CHART_HEIGHT - (i / split) * CHART_HEIGHT
}}
alignment={'center'}
>
{String((i / split) * MAX_Y_AXIS)}
</Text>
})
}
renderXAxis(data) {
return data.map((d, i) => {
return <ART.Text
key={i}
fill={'#fff'}
font={`normal 12px Heiti SC`}
x={i * X_AXIS_OFFSET + 12}
y={CHART_HEIGHT - 12}
alignment={'center'}
>
{d.data}
</ART.Text>
})
}
renderLine(data) {
const lineGenerator = d3.line()
.x((d, i) => i * X_AXIS_OFFSET)
.y(d => CHART_HEIGHT - CHART_HEIGHT * Math.min(1, (d.value / MAX_Y_AXIS)))
.curve(d3.curveMonotoneX);
return <Shape
d={lineGenerator(data)}
stroke="#fff"
strokeWidth={1}
/>
}
renderPath(data) {
const areaGenerator = d3.area()
.x((d, i) => i * X_AXIS_OFFSET)
.y0(CHART_HEIGHT)
.y1(d => CHART_HEIGHT - CHART_HEIGHT * Math.min(1, (d.value / MAX_Y_AXIS)))
.curve(d3.curveMonotoneX);
return <Shape
d={areaGenerator(data)}
fill={new LinearGradient({
'0': '#875CD5',
'.88': '#A084D4'
}, 0, 0, 0, CHART_HEIGHT
)}
strokeWidth={1}
/>
}
renderPoints(data) {
const pointArc = 3
return data.map((d, i) => {
if (i === 0) return null
return (
<Shape
key={i}
d={new Path()
.moveTo(X_AXIS_OFFSET * i, CHART_HEIGHT - pointArc - CHART_HEIGHT * Math.min(1, (d.value / MAX_Y_AXIS)))
.arc(0, 2 * pointArc, pointArc)
.arc(0, -2 * pointArc, pointArc)
.close()
}
strokeWidth={0}
stroke={'#9573D4'}
fill={'#f00'}
/>
)
})
}
render() {
return (
<View
style={{
position: 'relative',
width: Dimensions.get('window').width,
height: CHART_HEIGHT
}}
>
<ScrollView
bounces={false}
showsHorizontalScrollIndicator={false}
horizontal
>
<Surface
width={CHART_REAL_WIDTH}
height={CHART_HEIGHT}
>
<Group>
{this.renderBg()}
{this.renderLine(data)}
{this.renderPath(data)}
{this.renderPoints(data)}
{this.renderXAxis(data)}
</Group>
</Surface>
</ScrollView>
{this.renderYAxis(data)}
</View>
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment