Skip to content

Commit c55c723

Browse files
authored
Enhanced pie chart multicolor support, jest tests, & updated example sync util (capitalone#36)
* Initial attempt at better pie multicolor support * Added sync-rnpc script as an alternative to prior filewatch util * Added jest snapshot tests for Pie chart * Added test kickoff for circleci config
1 parent 944e184 commit c55c723

File tree

15 files changed

+428
-64
lines changed

15 files changed

+428
-64
lines changed

.babelrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["react-native"]
3+
}

README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,12 @@ react-native run-android
5353

5454
### Developing and Testing With The Example App
5555

56-
Please see the [util/watchman-update-example-src/README.md](util/watchman-update-example-src/README.md) for information on how to setup a [Watchman](https://facebook.github.io/watchman/)-based file watch that automates source file copying between [project source](src) and the [example app](example) to make manual testing easier
56+
As you are working on changing src files in this library and testing those changes against the example app, it is necessary to copy files to example/node_modules/react-native-pathjs-charts each time a change is made. To automate this, a `sync-rnpc` script has been added that will create a background process to watch for src file changes and automatically copy them. To enable this:
5757

58+
```
59+
cd example
60+
npm run sync-rnpc
61+
```
5862

5963
## Todo
6064

circle.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ dependencies:
44

55
test:
66
override:
7-
- echo "Verifying login successful prior to npm publish..."
8-
- npm owner ls
7+
- npm test
98

109
deployment:
1110
release:

example/package.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
"version": "0.0.1",
44
"private": true,
55
"scripts": {
6-
"start": "node node_modules/react-native/local-cli/cli.js start"
6+
"start": "node node_modules/react-native/local-cli/cli.js start",
7+
"sync-rnpc": "rm -rf ./node_modules/react-native-pathjs-charts; sane '/usr/bin/rsync -v -a --exclude .git --exclude example --exclude node_modules ../ ./node_modules/react-native-pathjs-charts/' .. --glob='{**/*.json,**/*.js}'"
78
},
89
"dependencies": {
910
"react": "^15.4.1",
1011
"react-native": "^0.38.1",
1112
"react-native-pathjs-charts": "file:../",
1213
"react-native-side-menu": "^0.20.1"
14+
},
15+
"devDependencies": {
16+
"sane": "^1.4.1"
1317
}
1418
}

example/src/pie/PieChartBasic.js

+26-4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ class PieChartBasic extends Component {
3030
"population": 2584160
3131
}, {
3232
"name": "Minnesota",
33-
"population": 6590667
33+
"population": 6590667,
34+
"color": {'r':223,'g':154,'b':20}
3435
}, {
3536
"name": "Alaska",
3637
"population": 7284698
@@ -64,10 +65,31 @@ class PieChartBasic extends Component {
6465

6566
return (
6667
<View>
67-
<Pie
68-
data={data}
68+
<Pie data={data}
6969
options={options}
70-
accessorKey="population" />
70+
accessorKey="population"
71+
margin={{top: 20, left: 20, right: 20, bottom: 20}}
72+
color="#2980B9"
73+
pallete={
74+
[
75+
{'r':25,'g':99,'b':201},
76+
{'r':24,'g':175,'b':35},
77+
{'r':190,'g':31,'b':69},
78+
{'r':100,'g':36,'b':199},
79+
{'r':214,'g':207,'b':32},
80+
{'r':198,'g':84,'b':45}
81+
]
82+
}
83+
r={50}
84+
R={150}
85+
legendPosition="topLeft"
86+
label={{
87+
fontFamily: 'Arial',
88+
fontSize: 8,
89+
fontWeight: true,
90+
color: '#ECF0F1'
91+
}}
92+
/>
7193
</View>
7294
)
7395
}

package.json

+12-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"main": "src/index.js",
1010
"scripts": {
1111
"start": "node_modules/react-native/packager/packager.sh",
12-
"lint": "eslint --ext .js,.jsx src"
12+
"lint": "eslint --ext .js,.jsx src",
13+
"test": "jest"
1314
},
1415
"keywords": [
1516
"react-native",
@@ -41,7 +42,16 @@
4142
"react-native-svg": "^4.4.1"
4243
},
4344
"devDependencies": {
45+
"babel-jest": "*",
46+
"babel-preset-react-native": "^1.9.0",
47+
"diff": "^3.1.0",
48+
"jest": "^18.0.0",
49+
"jest-react-native": "*",
4450
"react": "~15.4.1",
45-
"react-native": "^0.38.1"
51+
"react-native": "^0.38.1",
52+
"react-test-renderer": "*"
53+
},
54+
"jest": {
55+
"preset": "jest-react-native"
4656
}
4757
}

src/Pie.js

+9-8
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,15 @@ export default class PieChart extends Component {
4242
bold: true,
4343
color: '#ECF0F1'
4444
}
45-
}
45+
},
4646
}
4747

4848
color(i) {
49-
let color = this.props.options.color
49+
let color = this.props.color || (this.props.options && this.props.options.color)
5050
if (color && !_.isString(color)) color = color.color
51-
let pallete = this.props.pallete || Colors.mix(color || '#9ac7f7')
52-
return Colors.string(cyclic(pallete, i)) }
51+
let pallete = this.props.pallete || (this.props.options && this.props.options.pallete) || Colors.mix(color || '#9ac7f7')
52+
return Colors.string(cyclic(pallete, i))
53+
}
5354

5455

5556
get defaultRange() {
@@ -68,17 +69,17 @@ export default class PieChart extends Component {
6869
let radius = Math.min(x, y)
6970

7071
let chart = Pie({
71-
center: this.props.options.center || [0,0],
72-
r: this.props.options.r || radius /2,
73-
R: this.props.options.R || radius,
72+
center: this.props.center || (this.props.options && this.props.options.center) || [0,0] ,
73+
r: this.props.r || (this.props.options && this.props.options.r) || radius /2,
74+
R: this.props.R || (this.props.options && this.props.options.R) || radius,
7475
data: this.props.data,
7576
accessor: this.props.accessor || identity(this.props.accessorKey)
7677
})
7778

7879
let textStyle = fontAdapt(options.label)
7980

8081
let slices = chart.curves.map( (c, i) => {
81-
let fill = this.color(i)
82+
let fill = (c.item.color && Colors.string(c.item.color)) || this.color(i)
8283
let stroke = Colors.darkenColor(fill)
8384
return (
8485
<G key={ i } x={x - options.margin.left} y={y - options.margin.top}>

src/__mocks__/react-native-svg.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React from 'react'
2+
3+
export default function({ children }) {
4+
return (
5+
<view mockedComponent="svg-component">
6+
{children}
7+
</view>
8+
)
9+
}
10+
11+
export const Rect = (props) => {
12+
return (
13+
<view mockedComponent="svg-Rect" {...props} />
14+
)
15+
}
16+
17+
export const Path = (props) => {
18+
return (
19+
<view mockedComponent="svg-Path" {...props} />
20+
)
21+
}
22+
23+
export const G = ({ children }) => {
24+
return (
25+
<view mockedComponent="svg-G">
26+
{children}
27+
</view>
28+
)
29+
}
30+
31+
export const Svg = (props) => {
32+
return (
33+
<view mockedComponent="svg-Svg" {...props} />
34+
)
35+
}
36+
37+
export const Text = (props) => {
38+
return (
39+
<view mockedComponent="svg-Text" {...props} />
40+
)
41+
}

src/__mocks__/react-native.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import React from 'react'
2+
3+
export const View = ({ children }) => {
4+
return (
5+
<div>{children}</div>
6+
)
7+
}

src/__tests__/PieBasic-test.js

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import 'react-native'
2+
import React from 'react'
3+
import Pie from '../Pie'
4+
import renderer from 'react-test-renderer'
5+
import { diffJson } from 'diff'
6+
7+
let data = [{
8+
"name": "Washington",
9+
"population": 7694980
10+
}, {
11+
"name": "Oregon",
12+
"population": 2584160
13+
}, {
14+
"name": "Minnesota",
15+
"population": 6590667,
16+
"color": {'r':223,'g':154,'b':20}
17+
}, {
18+
"name": "Alaska",
19+
"population": 7284698
20+
}]
21+
22+
let options = {
23+
margin: {
24+
top: 20,
25+
left: 20,
26+
right: 20,
27+
bottom: 20
28+
},
29+
width: 350,
30+
height: 350,
31+
color: '#2980B9',
32+
r: 50,
33+
R: 150,
34+
legendPosition: 'topLeft',
35+
animate: {
36+
type: 'oneByOne',
37+
duration: 200,
38+
fillTransition: 3
39+
},
40+
label: {
41+
fontFamily: 'Arial',
42+
fontSize: 8,
43+
fontWeight: true,
44+
color: '#ECF0F1'
45+
}
46+
}
47+
48+
it('renders using options property correctly', () => {
49+
let tree = renderer.create(
50+
<Pie data={data}
51+
options={options}/>
52+
).toJSON()
53+
expect(tree).toMatchSnapshot()
54+
})
55+
56+
it('renders using flattened properties correctly', () => {
57+
let tree = renderer.create(
58+
<Pie data={data}
59+
options={options}
60+
r={10} />
61+
).toJSON()
62+
expect(tree).toMatchSnapshot()
63+
})
64+
65+
it('contains expected diff between flattened vs non-flattened option usage', () => {
66+
let treeUsingOptionsProp = renderer.create(
67+
<Pie data={data}
68+
options={options}/>
69+
).toJSON()
70+
71+
let treeUsingFlattenedProps = renderer.create(
72+
<Pie data={data}
73+
options={options}
74+
r={10}/>
75+
).toJSON()
76+
77+
let jsonDiff = diffJson(treeUsingOptionsProp, treeUsingFlattenedProps)
78+
79+
const expectedRemoveCount = 4
80+
const expectedAddCount = 4
81+
var actualRemoveCount = 0
82+
var actualAddCount = 0
83+
84+
jsonDiff.forEach((part) => {
85+
if (part.removed && part.value.trim()
86+
=== '"d": "M NaN NaN A 150 150 0 0 1 NaN NaN L NaN NaN A 50 50 0 0 0 NaN NaN Z ",') {
87+
actualRemoveCount++
88+
}
89+
if (part.added && part.value.trim()
90+
=== '"d": "M NaN NaN A 150 150 0 0 1 NaN NaN L NaN NaN A 10 10 0 0 0 NaN NaN Z ",') {
91+
actualAddCount++
92+
}
93+
})
94+
expect(actualRemoveCount).toBe(expectedRemoveCount)
95+
expect(actualAddCount).toBe(expectedAddCount)
96+
97+
})

0 commit comments

Comments
 (0)