Skip to content

Commit 6e32667

Browse files
authored
Rc 2.5.0 (#163)
* Add legend support to charts * added polyfill for find
1 parent 3a3323f commit 6e32667

File tree

7 files changed

+197
-6
lines changed

7 files changed

+197
-6
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import React from 'react';
2+
import {Pie} from 'react-chartjs-2';
3+
4+
const data = {
5+
labels: [
6+
'Red',
7+
'Green',
8+
'Yellow'
9+
],
10+
datasets: [{
11+
data: [300, 50, 100],
12+
backgroundColor: [
13+
'#FF6384',
14+
'#36A2EB',
15+
'#FFCE56'
16+
],
17+
hoverBackgroundColor: [
18+
'#FF6384',
19+
'#36A2EB',
20+
'#FFCE56'
21+
]
22+
}]
23+
};
24+
25+
const legendOpts = {
26+
onClick: (e, item) => alert(`Item with text ${item.text} and index ${item.index} clicked`),
27+
onHover: (e, item) => alert(`Item with text ${item.text} and index ${item.index} hovered`),
28+
};
29+
30+
export default React.createClass({
31+
displayName: 'LegendExample',
32+
33+
getInitialState() {
34+
return {
35+
legend: legendOpts
36+
}
37+
},
38+
39+
applyLegendSettings() {
40+
const { value } = this.legendOptsInput;
41+
42+
try {
43+
const opts = JSON.parse(value);
44+
this.setState({
45+
legend: opts
46+
});
47+
} catch(e) {
48+
alert(e.message);
49+
throw Error(e);
50+
}
51+
},
52+
53+
render() {
54+
return (
55+
<div>
56+
<h2>Legend Handlers Example</h2>
57+
<p>Hover over label and click</p>
58+
<Pie data={data} legend={this.state.legend} />
59+
</div>
60+
);
61+
}
62+
})
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import React from 'react';
2+
import {Pie} from 'react-chartjs-2';
3+
4+
const data = {
5+
labels: [
6+
'Red',
7+
'Green',
8+
'Yellow'
9+
],
10+
datasets: [{
11+
data: [300, 50, 100],
12+
backgroundColor: [
13+
'#FF6384',
14+
'#36A2EB',
15+
'#FFCE56'
16+
],
17+
hoverBackgroundColor: [
18+
'#FF6384',
19+
'#36A2EB',
20+
'#FFCE56'
21+
]
22+
}]
23+
};
24+
25+
const legendOpts = {
26+
display: true,
27+
position: 'top',
28+
fullWidth: true,
29+
reverse: false,
30+
labels: {
31+
fontColor: 'rgb(255, 99, 132)'
32+
}
33+
};
34+
35+
export default React.createClass({
36+
displayName: 'LegendExample',
37+
38+
getInitialState() {
39+
return {
40+
legend: legendOpts
41+
}
42+
},
43+
44+
applyLegendSettings() {
45+
const { value } = this.legendOptsInput;
46+
47+
try {
48+
const opts = JSON.parse(value);
49+
this.setState({
50+
legend: opts
51+
});
52+
} catch(e) {
53+
alert(e.message);
54+
throw Error(e);
55+
}
56+
},
57+
58+
render() {
59+
return (
60+
<div>
61+
<h2>Legend Options Example</h2>
62+
<textarea
63+
cols="40"
64+
rows="15"
65+
ref={input => { this.legendOptsInput = input; }}
66+
defaultValue={JSON.stringify(this.state.legend, null, 2)}></textarea>
67+
<div>
68+
<button onClick={this.applyLegendSettings}>Apply legend settings</button>
69+
</div>
70+
<Pie data={data} legend={this.state.legend} redraw />
71+
</div>
72+
);
73+
}
74+
})

example/src/example.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import ScatterExample from './components/scatter';
1414
import MixedDataExample from './components/mix';
1515
import RandomizedDataLineExample from './components/randomizedLine';
1616
import CrazyDataLineExample from './components/crazyLine';
17+
import LegendOptionsExample from './components/legend-options'
18+
import LegendHandlersExample from './components/legend-handlers'
1719

1820
class App extends React.Component {
1921
render() {
@@ -45,6 +47,10 @@ class App extends React.Component {
4547
<RandomizedDataLineExample />
4648
<hr />
4749
<CrazyDataLineExample />
50+
<hr />
51+
<LegendOptionsExample />
52+
<hr />
53+
<LegendHandlersExample />
4854
</div>
4955
);
5056
}

example/src/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
<body>
77
<div class="container">
88
<h1>react-chartjs-2</h1>
9-
<h2><a href="https://github.com/gor181/react-chartjs-2">View project on GitHub</a></h2>
9+
<h2><a href="https://github.com/jerairrest/react-chartjs-2">View project on GitHub</a></h2>
1010
<!-- the example app is rendered into this div -->
1111
<div id="app"></div>
1212
<div class="hint">
1313
<!-- put any hints about your component example here -->
1414
</div>
1515
<div class="footer">
16-
Copyright &copy; 2016 Goran Udosic.
16+
Copyright &copy; 2017 Jeremy Ayerst.
1717
</div>
1818
</div>
1919
<script src="common.js"></script>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-chartjs-2",
3-
"version": "2.4.1",
3+
"version": "2.5.0",
44
"description": "react-chartjs-2",
55
"main": "lib/index.js",
66
"author": "Goran Udosic",

src/index.js

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,55 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3-
import ReactDOM from 'react-dom';
43
import Chart from 'chart.js';
54
import isEqual from 'lodash.isequal';
65

6+
7+
//Taken from MDN
8+
if (!Array.prototype.find) {
9+
Object.defineProperty(Array.prototype, 'find', {
10+
value: function(predicate) {
11+
// 1. Let O be ? ToObject(this value).
12+
if (this == null) {
13+
throw new TypeError('"this" is null or not defined');
14+
}
15+
16+
var o = Object(this);
17+
18+
// 2. Let len be ? ToLength(? Get(O, "length")).
19+
var len = o.length >>> 0;
20+
21+
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
22+
if (typeof predicate !== 'function') {
23+
throw new TypeError('predicate must be a function');
24+
}
25+
26+
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
27+
var thisArg = arguments[1];
28+
29+
// 5. Let k be 0.
30+
var k = 0;
31+
32+
// 6. Repeat, while k < len
33+
while (k < len) {
34+
// a. Let Pk be ! ToString(k).
35+
// b. Let kValue be ? Get(O, Pk).
36+
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
37+
// d. If testResult is true, return kValue.
38+
var kValue = o[k];
39+
if (predicate.call(thisArg, kValue, k, o)) {
40+
return kValue;
41+
}
42+
// e. Increase k by 1.
43+
k++;
44+
}
45+
46+
// 7. Return undefined.
47+
return undefined;
48+
}
49+
});
50+
}
51+
52+
753
class ChartComponent extends React.Component {
854
static getLabelAsKey = d => d.label;
955

@@ -22,6 +68,7 @@ class ChartComponent extends React.Component {
2268
plugins: PropTypes.arrayOf(PropTypes.object),
2369
redraw: PropTypes.bool,
2470
type: function(props, propName, componentName) {
71+
2572
if(!Object.keys(Chart.controllers).find((chartType) => chartType === props[propName])){
2673
return new Error(
2774
'Invalid chart type `' + props[propName] + '` supplied to' +
@@ -203,6 +250,7 @@ class ChartComponent extends React.Component {
203250
const {options, legend, type, redraw, plugins} = this.props;
204251
const node = this.element;
205252
const data = this.memoizeDataProps();
253+
options.legend = legend;
206254

207255
this.chart_instance = new Chart(node, {
208256
type,

test/__tests__/Chart_spec.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,15 @@ describe('<Chart />', () => {
122122
it('renders on props.options change', () => {
123123
const spy = sinon.spy(Chart.prototype, 'render');
124124
const wrapper = mountComponent({ options: {} });
125+
const defaultLegendOpts = wrapper.prop('legend');
125126

126127
expect(spy.callCount).to.equal(1);
127128

128-
wrapper.setProps({ options: {} });
129+
wrapper.setProps({ options: { legend: defaultLegendOpts } });
129130

130131
expect(spy.callCount).to.equal(1);
131132

132-
wrapper.setProps({ options: { a: 1 } });
133+
wrapper.setProps({ options: { legend: defaultLegendOpts, a: 1 } });
133134

134135
expect(spy.callCount).to.equal(2);
135136

0 commit comments

Comments
 (0)