${geography.properties.name}\nElectoral Votes: ${data.electoralVotes}`,
+ highlightBorderWidth: 3
+ }}
+ fills={{
+ 'Republican': '#cc4731',
+ 'Democrat': '#306596',
+ 'Heavy Democrat': '#667faf',
+ 'Light Democrat': '#a9c0de',
+ 'Heavy Republican': '#ca5e5b',
+ 'Light Republican': '#eaa9a8',
+ 'defaultFill': '#eddc4e'
+ }}
+ data={{
+ AZ: {
+ fillKey: 'Republican',
+ electoralVotes: 5
+ },
+ CO: {
+ fillKey: 'Light Democrat',
+ electoralVotes: 5
+ },
+ DE: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ FL: {
+ fillKey: 'UNDECIDED',
+ electoralVotes: 29
+ },
+ GA: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ HI: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ ID: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ IL: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ IN: {
+ fillKey: 'Republican',
+ electoralVotes: 11
+ },
+ IA: {
+ fillKey: 'Light Democrat',
+ electoralVotes: 11
+ },
+ KS: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ KY: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ LA: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ MD: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ ME: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ MA: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ MN: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ MI: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ MS: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ MO: {
+ fillKey: 'Republican',
+ electoralVotes: 13
+ },
+ MT: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ NC: {
+ fillKey: 'Light Republican',
+ electoralVotes: 32
+ },
+ NE: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ NV: {
+ fillKey: 'Heavy Democrat',
+ electoralVotes: 32
+ },
+ NH: {
+ fillKey: 'Light Democrat',
+ electoralVotes: 32
+ },
+ NJ: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ NY: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ ND: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ NM: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ OH: {
+ fillKey: 'UNDECIDED',
+ electoralVotes: 32
+ },
+ OK: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ OR: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ PA: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ RI: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ SC: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ SD: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ TN: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ TX: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ UT: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ WI: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ VA: {
+ fillKey: 'Light Democrat',
+ electoralVotes: 32
+ },
+ VT: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ WA: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ WV: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ WY: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ CA: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ CT: {
+ fillKey: 'Democrat',
+ electoralVotes: 32
+ },
+ AK: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ AR: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ },
+ AL: {
+ fillKey: 'Republican',
+ electoralVotes: 32
+ }
+ }}
+ labels
+ />
+
+ );
+ }
+
+}
diff --git a/examples/zoom-example.jsx b/examples/zoom-example.jsx
new file mode 100644
index 0000000..06e65d2
--- /dev/null
+++ b/examples/zoom-example.jsx
@@ -0,0 +1,95 @@
+/* global d3 */
+
+import React from 'react';
+
+import Datamap from '../src';
+import Example from './example';
+
+const colors = d3.scale.category10();
+
+export default class ZoomExample extends React.Component {
+
+ setProjection(element) {
+ const projection = d3.geo.equirectangular()
+ .center([23, -3])
+ .rotate([4.4, 0])
+ .scale(400)
+ .translate([element.offsetWidth / 2, element.offsetHeight / 2]);
+ const path = d3.geo.path()
+ .projection(projection);
+
+ return { path, projection };
+ }
+
+ render() {
+ return (
+
+
+ `Bubble for ${data.name}`
+ }}
+ />
+
+ );
+ }
+
+}
diff --git a/package.json b/package.json
index 3fd54aa..4c3eb56 100644
--- a/package.json
+++ b/package.json
@@ -35,12 +35,14 @@
"datamaps": "^0.4.2"
},
"devDependencies": {
- "@btmills/eslint-config-btmills": "^0.1.3",
+ "@btmills/eslint-config-btmills": "^1.0.0-beta.6",
"babel-cli": "^6.4.5",
+ "babel-eslint": "^6.1.0",
+ "babel-plugin-transform-class-properties": "^6.10.2",
"babel-plugin-transform-object-rest-spread": "^6.3.13",
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
- "eslint": "^1.10.3",
- "eslint-plugin-react": "^3.16.1"
+ "eslint": "^2.13.1",
+ "eslint-plugin-react": "^5.2.2"
}
}
diff --git a/src/datamap.jsx b/src/datamap.jsx
index 506d6b9..a71b2f3 100644
--- a/src/datamap.jsx
+++ b/src/datamap.jsx
@@ -1,71 +1,104 @@
import React from 'react';
-import Datamap from 'datamaps';
+import Datamaps from 'datamaps';
-export default React.createClass({
+export default class Datamap extends React.Component {
- displayName: 'Datamap',
-
- propTypes: {
+ static propTypes = {
arc: React.PropTypes.array,
arcOptions: React.PropTypes.object,
bubbleOptions: React.PropTypes.object,
bubbles: React.PropTypes.array,
+ data: React.PropTypes.object,
graticule: React.PropTypes.bool,
- labels: React.PropTypes.bool
- },
+ height: React.PropTypes.any,
+ labels: React.PropTypes.bool,
+ style: React.PropTypes.object,
+ updateChoroplethOptions: React.PropTypes.object,
+ width: React.PropTypes.any
+ };
componentDidMount() {
this.drawMap();
- },
+ }
- componentWillReceiveProps() {
- this.clear();
- },
+ componentWillReceiveProps(newProps) {
+ if (
+ this.props.height !== newProps.height
+ || this.props.width !== newProps.width
+ ) {
+ this.clear();
+ }
+ }
componentDidUpdate() {
this.drawMap();
- },
+ }
componentWillUnmount() {
this.clear();
- },
+ }
clear() {
- const container = this.refs.container;
+ const { container } = this.refs;
for (const child of Array.from(container.childNodes)) {
container.removeChild(child);
}
- },
+
+ delete this.map;
+ }
drawMap() {
- const map = new Datamap(Object.assign({}, { ...this.props }, {
- element: this.refs.container
- }));
+ const {
+ arc,
+ arcOptions,
+ bubbles,
+ bubbleOptions,
+ data,
+ graticule,
+ labels,
+ updateChoroplethOptions,
+ ...props
+ } = this.props;
+
+ let map = this.map;
+
+ if (!map) {
+ map = this.map = new Datamaps({
+ ...props,
+ data,
+ element: this.refs.container
+ });
+ } else {
+ map.updateChoropleth(data, updateChoroplethOptions);
+ }
- if (this.props.arc) {
- map.arc(this.props.arc, this.props.arcOptions);
+ if (arc) {
+ map.arc(arc, arcOptions);
}
- if (this.props.bubbles) {
- map.bubbles(this.props.bubbles, this.props.bubbleOptions);
+ if (bubbles) {
+ map.bubbles(bubbles, bubbleOptions);
}
- if (this.props.graticule) {
+ if (graticule) {
map.graticule();
}
- if (this.props.labels) {
+ if (labels) {
map.labels();
}
- },
+ }
render() {
const style = {
- position: 'relative'
+ height: '100%',
+ position: 'relative',
+ width: '100%',
+ ...this.props.style
};
- return
;
+ return
;
}
-});
+}