-
-
Save V-Tom/5e441cba9d3a8ef1366997fff6a64606 to your computer and use it in GitHub Desktop.
Demo code for simple React-Native ART Curve Chart
This file contains 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, { 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