mirror of
https://github.com/visgl/react-map-gl.git
synced 2026-01-25 16:02:50 +00:00
Update the overlay API to use a callback and update required props in overlays.
This commit is contained in:
parent
aadd76b2d0
commit
f7741b0b07
@ -17,7 +17,6 @@
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
|
||||
var assign = require('object-assign');
|
||||
@ -57,6 +56,9 @@ var ChoroplethOverlayExample = React.createClass({
|
||||
},
|
||||
|
||||
_onChangeViewport: function _onChangeViewport(opt) {
|
||||
if (this.props.onChangeViewport) {
|
||||
return this.props.onChangeViewport(opt);
|
||||
}
|
||||
this.setState({
|
||||
latitude: opt.latitude,
|
||||
longitude: opt.longitude,
|
||||
@ -67,24 +69,18 @@ var ChoroplethOverlayExample = React.createClass({
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
return r(MapGL, assign({
|
||||
latitude: this.state.latitude,
|
||||
longitude: this.state.longitude,
|
||||
zoom: this.state.zoom,
|
||||
width: this.props.width,
|
||||
height: this.props.height,
|
||||
startDragLngLat: this.state.startDragLngLat,
|
||||
isDragging: this.state.isDragging,
|
||||
onChangeViewport: this.props.onChangeViewport || this._onChangeViewport
|
||||
}, this.props), [
|
||||
r(ChoroplethOverlay, {
|
||||
globalOpacity: 0.8,
|
||||
colorDomain: [0, 500, 1000],
|
||||
colorRange: ['#31a354', '#addd8e', '#f7fcb9'],
|
||||
renderWhileDragging: false,
|
||||
features: ZIPCODES_SF.get('features')
|
||||
})
|
||||
]);
|
||||
return r(MapGL, assign({}, this.state, this.props, {
|
||||
onChangeViewport: this._onChangeViewport,
|
||||
overlays: function overlays(viewport) {
|
||||
return r(ChoroplethOverlay, assign({}, viewport, {
|
||||
globalOpacity: 0.8,
|
||||
colorDomain: [0, 500, 1000],
|
||||
colorRange: ['#31a354', '#addd8e', '#f7fcb9'],
|
||||
renderWhileDragging: false,
|
||||
features: ZIPCODES_SF.get('features')
|
||||
}));
|
||||
}
|
||||
}, this.props));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -67,6 +67,9 @@ var OverlayExample = React.createClass({
|
||||
},
|
||||
|
||||
_onChangeViewport: function _onChangeViewport(opt) {
|
||||
if (this.props.onChangeViewport) {
|
||||
return this.props.onChangeViewport(opt);
|
||||
}
|
||||
this.setState({
|
||||
latitude: opt.latitude,
|
||||
longitude: opt.longitude,
|
||||
@ -76,40 +79,33 @@ var OverlayExample = React.createClass({
|
||||
});
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
return r(MapGL, assign({
|
||||
latitude: this.state.latitude,
|
||||
longitude: this.state.longitude,
|
||||
zoom: this.state.zoom,
|
||||
startDragLngLat: this.state.startDragLngLat,
|
||||
isDragging: this.state.isDragging,
|
||||
width: this.props.width,
|
||||
height: this.props.height,
|
||||
onChangeViewport: this.props.onChangeViewport || this._onChangeViewport
|
||||
}, this.props), [
|
||||
r(CanvasOverlay, {redraw: function _redrawCanvas(opt) {
|
||||
var p1 = opt.project([location.longitude, location.latitude]);
|
||||
opt.ctx.clearRect(0, 0, opt.width, opt.height);
|
||||
opt.ctx.strokeStyle = alphaify('#1FBAD6', 0.4);
|
||||
opt.ctx.lineWidth = 2;
|
||||
locations.forEach(function forEach(loc, index) {
|
||||
opt.ctx.beginPath();
|
||||
var p2 = opt.project(loc.toArray());
|
||||
opt.ctx.moveTo(p1[0], p1[1]);
|
||||
opt.ctx.lineTo(p2[0], p2[1]);
|
||||
opt.ctx.stroke();
|
||||
opt.ctx.beginPath();
|
||||
opt.ctx.fillStyle = alphaify('#1FBAD6', 0.4);
|
||||
opt.ctx.arc(p2[0], p2[1], 6, 0, 2 * Math.PI);
|
||||
opt.ctx.fill();
|
||||
opt.ctx.beginPath();
|
||||
opt.ctx.fillStyle = '#FFFFFF';
|
||||
opt.ctx.textAlign = 'center';
|
||||
opt.ctx.fillText(index, p2[0], p2[1] + 4);
|
||||
});
|
||||
}}),
|
||||
_renderOverlays: function _renderOverlays(viewport) {
|
||||
return [
|
||||
r(CanvasOverlay, assign({}, viewport, {
|
||||
redraw: function _redrawCanvas(opt) {
|
||||
var p1 = opt.project([location.longitude, location.latitude]);
|
||||
opt.ctx.clearRect(0, 0, opt.width, opt.height);
|
||||
opt.ctx.strokeStyle = alphaify('#1FBAD6', 0.4);
|
||||
opt.ctx.lineWidth = 2;
|
||||
locations.forEach(function forEach(loc, index) {
|
||||
opt.ctx.beginPath();
|
||||
var p2 = opt.project(loc.toArray());
|
||||
opt.ctx.moveTo(p1[0], p1[1]);
|
||||
opt.ctx.lineTo(p2[0], p2[1]);
|
||||
opt.ctx.stroke();
|
||||
opt.ctx.beginPath();
|
||||
opt.ctx.fillStyle = alphaify('#1FBAD6', 0.4);
|
||||
opt.ctx.arc(p2[0], p2[1], 6, 0, 2 * Math.PI);
|
||||
opt.ctx.fill();
|
||||
opt.ctx.beginPath();
|
||||
opt.ctx.fillStyle = '#FFFFFF';
|
||||
opt.ctx.textAlign = 'center';
|
||||
opt.ctx.fillText(index, p2[0], p2[1] + 4);
|
||||
});
|
||||
}
|
||||
})),
|
||||
// We use invisible SVG elements to support interactivity.
|
||||
r(SVGOverlay, {
|
||||
r(SVGOverlay, assign({}, viewport, {
|
||||
redraw: function _redrwaSVGOverlay(opt) {
|
||||
var p1 = opt.project([location.longitude, location.latitude]);
|
||||
var style = {
|
||||
@ -144,8 +140,15 @@ var OverlayExample = React.createClass({
|
||||
}, this))
|
||||
);
|
||||
}.bind(this)
|
||||
})
|
||||
]);
|
||||
}))
|
||||
];
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
return r(MapGL, assign({}, this.state, this.props, {
|
||||
onChangeViewport: this._onChangeViewport,
|
||||
overlays: this._renderOverlays
|
||||
}, this.props));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -68,6 +68,9 @@ var GeodataCreator = React.createClass({
|
||||
},
|
||||
|
||||
_onChangeViewport: function _onChangeViewport(opt) {
|
||||
if (this.props.onChangeViewport) {
|
||||
return this.props.onChangeViewport(opt);
|
||||
}
|
||||
this.setState({
|
||||
latitude: opt.latitude,
|
||||
longitude: opt.longitude,
|
||||
@ -95,52 +98,50 @@ var GeodataCreator = React.createClass({
|
||||
this.setState({points: points});
|
||||
},
|
||||
|
||||
_renderOverlays: function _renderOverlays(viewport) {
|
||||
return [
|
||||
r(SVGOverlay, assign({}, viewport, {redraw: function _redraw(opt) {
|
||||
if (!this.state.points.size) {
|
||||
return null;
|
||||
}
|
||||
var d = 'M' + this.state.points.map(function _map(point) {
|
||||
return opt.project(point.get('location').toArray());
|
||||
}).join('L');
|
||||
return r.path({
|
||||
style: {stroke: '#1FBAD6', strokeWidth: 2, fill: 'none'},
|
||||
d: d
|
||||
});
|
||||
}.bind(this)})),
|
||||
r(DraggableOverlay, assign({}, viewport, {
|
||||
points: this.state.points,
|
||||
onAddPoint: this._onAddPoint,
|
||||
onUpdatePoint: this._onUpdatePoint,
|
||||
renderPoint: function renderPoint(point, pixel) {
|
||||
return r.g({}, [
|
||||
r.circle({
|
||||
r: 10,
|
||||
style: {
|
||||
fill: alphaify('#1FBAD6', 0.5),
|
||||
pointerEvents: 'all'
|
||||
}
|
||||
}),
|
||||
r.text({
|
||||
style: {fill: 'white', textAnchor: 'middle'},
|
||||
y: 5
|
||||
}, point.get('id'))
|
||||
]);
|
||||
}
|
||||
}))
|
||||
];
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
return r.div([
|
||||
r(MapGL, assign({
|
||||
latitude: this.state.latitude,
|
||||
longitude: this.state.longitude,
|
||||
zoom: this.state.zoom,
|
||||
width: this.props.width,
|
||||
height: this.props.height,
|
||||
startDragLngLat: this.state.startDragLngLat,
|
||||
isDragging: this.state.isDragging,
|
||||
r(MapGL, assign({}, this.state, this.props, {
|
||||
style: {float: 'left'},
|
||||
onChangeViewport: this.props.onChangeViewport || this._onChangeViewport
|
||||
}, this.props), [
|
||||
r(SVGOverlay, {redraw: function _redraw(opt) {
|
||||
if (!this.state.points.size) {
|
||||
return null;
|
||||
}
|
||||
var d = 'M' + this.state.points.map(function _map(point) {
|
||||
return opt.project(point.get('location').toArray());
|
||||
}).join('L');
|
||||
return r.path({
|
||||
style: {stroke: '#1FBAD6', strokeWidth: 2, fill: 'none'},
|
||||
d: d
|
||||
});
|
||||
}.bind(this)}),
|
||||
r(DraggableOverlay, {
|
||||
points: this.state.points,
|
||||
onAddPoint: this._onAddPoint,
|
||||
onUpdatePoint: this._onUpdatePoint,
|
||||
renderPoint: function renderPoint(point, pixel) {
|
||||
return r.g({}, [
|
||||
r.circle({
|
||||
r: 10,
|
||||
style: {
|
||||
fill: alphaify('#1FBAD6', 0.5),
|
||||
pointerEvents: 'all'
|
||||
}
|
||||
}),
|
||||
r.text({
|
||||
style: {fill: 'white', textAnchor: 'middle'},
|
||||
y: 5
|
||||
}, point.get('id'))
|
||||
]);
|
||||
}
|
||||
})
|
||||
])
|
||||
onChangeViewport: this._onChangeViewport,
|
||||
overlays: this._renderOverlays
|
||||
}, this.props))
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
|
||||
var assign = require('object-assign');
|
||||
|
||||
@ -54,6 +54,9 @@ var RouteOverlayExample = React.createClass({
|
||||
},
|
||||
|
||||
_onChangeViewport: function _onChangeViewport(opt) {
|
||||
if (this.props.onChangeViewport) {
|
||||
return this.props.onChangeViewport(opt);
|
||||
}
|
||||
this.setState({
|
||||
latitude: opt.latitude,
|
||||
longitude: opt.longitude,
|
||||
@ -110,19 +113,16 @@ var RouteOverlayExample = React.createClass({
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
return r(MapGL, assign({
|
||||
latitude: this.state.latitude,
|
||||
longitude: this.state.longitude,
|
||||
zoom: this.state.zoom,
|
||||
width: this.props.width,
|
||||
height: this.props.height,
|
||||
startDragLngLat: this.state.startDragLngLat,
|
||||
isDragging: this.state.isDragging,
|
||||
onChangeViewport: this.props.onChangeViewport || this._onChangeViewport
|
||||
}, this.props), [
|
||||
r(SVGOverlay, {redraw: this._redrawSVGOverlay}),
|
||||
r(CanvasOverlay, {redraw: this._redrawCanvasOverlay})
|
||||
]);
|
||||
return r(MapGL, assign({}, this.state, this.props, {
|
||||
onChangeViewport: this._onChangeViewport,
|
||||
overlays: function overlays(viewport) {
|
||||
return [
|
||||
r(SVGOverlay, assign({redraw: this._redrawSVGOverlay}, viewport)),
|
||||
r(CanvasOverlay, assign({redraw: this._redrawCanvasOverlay},
|
||||
viewport))
|
||||
];
|
||||
}.bind(this)
|
||||
}, this.props));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -61,6 +61,9 @@ var ScatterplotOverlayExample = React.createClass({
|
||||
},
|
||||
|
||||
_onChangeViewport: function _onChangeViewport(opt) {
|
||||
if (this.props.onChangeViewport) {
|
||||
return this.props.onChangeViewport(opt);
|
||||
}
|
||||
this.setState({
|
||||
latitude: opt.latitude,
|
||||
longitude: opt.longitude,
|
||||
@ -71,23 +74,17 @@ var ScatterplotOverlayExample = React.createClass({
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
return r(MapGL, assign({
|
||||
latitude: this.state.latitude,
|
||||
longitude: this.state.longitude,
|
||||
zoom: this.state.zoom,
|
||||
isDragging: this.state.isDragging,
|
||||
startDragLngLat: this.state.startDragLngLat,
|
||||
width: this.props.width,
|
||||
height: this.props.height,
|
||||
onChangeViewport: this.props.onChangeViewport || this._onChangeViewport
|
||||
}, this.props), [
|
||||
r(ScatterplotOverlay, {
|
||||
locations: locations,
|
||||
dotRadius: 2,
|
||||
globalOpacity: 1,
|
||||
compositeOperation: 'screen'
|
||||
})
|
||||
]);
|
||||
return r(MapGL, assign({}, this.state, this.props, {
|
||||
onChangeViewport: this._onChangeViewport,
|
||||
overlays: function overlay(viewport) {
|
||||
return r(ScatterplotOverlay, assign({}, viewport, {
|
||||
locations: locations,
|
||||
dotRadius: 2,
|
||||
globalOpacity: 1,
|
||||
compositeOperation: 'screen'
|
||||
}));
|
||||
}
|
||||
}, this.props));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -155,7 +155,14 @@ var MapGL = React.createClass({
|
||||
* The first argument of the callback will be the array of feature the
|
||||
* mouse is over. This is the same response returned from `featuresAt`.
|
||||
*/
|
||||
onClickFeatures: React.PropTypes.func
|
||||
onClickFeatures: React.PropTypes.func,
|
||||
|
||||
/**
|
||||
* A Callback used to render data overlays. This function will be passed
|
||||
* a viewport object that includes two methods, `project` and `unproject`
|
||||
* as well as the props, latitude, longitude, zoom, width, and height.
|
||||
*/
|
||||
overlays: React.PropTypes.func
|
||||
},
|
||||
|
||||
getDefaultProps: function getDefaultProps() {
|
||||
@ -542,8 +549,9 @@ var MapGL = React.createClass({
|
||||
},
|
||||
|
||||
_renderOverlays: function _renderOverlays(transform) {
|
||||
var children = [];
|
||||
|
||||
if (!this.props.overlays) {
|
||||
return null;
|
||||
}
|
||||
var viewportConfig = {
|
||||
center: [this.props.longitude, this.props.latitude],
|
||||
zoom: this.props.zoom,
|
||||
@ -551,24 +559,24 @@ var MapGL = React.createClass({
|
||||
dimensions: [this.props.width, this.props.height]
|
||||
};
|
||||
|
||||
var viewport = ViewportMercator(viewportConfig);
|
||||
var mercator = ViewportMercator(viewportConfig);
|
||||
|
||||
// This is the `viewport` object exposed to the overlays.
|
||||
var viewport = {
|
||||
width: this.props.width,
|
||||
height: this.props.height,
|
||||
longitude: this.props.longitude,
|
||||
latitude: this.props.latitude,
|
||||
zoom: this.props.zoom,
|
||||
isDragging: this.props.isDragging,
|
||||
project: mercator.project,
|
||||
unproject: mercator.unproject
|
||||
};
|
||||
|
||||
React.Children.forEach(this.props.children, function _map(child) {
|
||||
if (!child) {
|
||||
return;
|
||||
}
|
||||
children.push(React.cloneElement(child, {
|
||||
width: this.props.width,
|
||||
height: this.props.height,
|
||||
isDragging: this.props.isDragging,
|
||||
project: viewport.project,
|
||||
unproject: viewport.unproject
|
||||
}));
|
||||
}, this);
|
||||
return r.div({
|
||||
className: 'overlays',
|
||||
style: {position: 'absolute', left: 0, top: 0}
|
||||
}, children);
|
||||
}, this.props.overlays(viewport));
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
@ -588,7 +596,8 @@ var MapGL = React.createClass({
|
||||
|
||||
var content = [
|
||||
r.div({ref: 'mapboxMap', style: style, className: props.className}),
|
||||
this._renderOverlays(transform)
|
||||
this._renderOverlays(transform),
|
||||
r.div({position: 'absolute', left: 0, top: 0}, this.props.children)
|
||||
];
|
||||
|
||||
if (this.props.onChangeViewport) {
|
||||
|
||||
@ -32,11 +32,11 @@ var CanvasOverlay = React.createClass({
|
||||
displayName: 'CanvasOverlay',
|
||||
|
||||
propTypes: {
|
||||
width: React.PropTypes.number,
|
||||
height: React.PropTypes.number,
|
||||
width: React.PropTypes.number.isRequired,
|
||||
height: React.PropTypes.number.isRequired,
|
||||
redraw: React.PropTypes.func.isRequired,
|
||||
project: React.PropTypes.func,
|
||||
isDragging: React.PropTypes.bool
|
||||
project: React.PropTypes.func.isRequired,
|
||||
isDragging: React.PropTypes.bool.isRequired
|
||||
},
|
||||
|
||||
componentDidMount: function componentDidMount() {
|
||||
|
||||
@ -30,19 +30,19 @@ var ChoroplethOverlay = React.createClass({
|
||||
displayName: 'ChoroplethOverlay',
|
||||
|
||||
propTypes: {
|
||||
width: React.PropTypes.number,
|
||||
height: React.PropTypes.number,
|
||||
project: React.PropTypes.func,
|
||||
isDragging: React.PropTypes.bool,
|
||||
renderWhileDragging: React.PropTypes.bool,
|
||||
globalOpacity: React.PropTypes.number,
|
||||
width: React.PropTypes.number.isRequired,
|
||||
height: React.PropTypes.number.isRequired,
|
||||
project: React.PropTypes.func.isRequired,
|
||||
isDragging: React.PropTypes.bool.isRequired,
|
||||
renderWhileDragging: React.PropTypes.bool.isRequired,
|
||||
globalOpacity: React.PropTypes.number.isRequired,
|
||||
/**
|
||||
* An Immutable List of feature objects.
|
||||
*/
|
||||
features: React.PropTypes.instanceOf(Immutable.List),
|
||||
colorDomain: React.PropTypes.array,
|
||||
colorRange: React.PropTypes.array,
|
||||
valueAccessor: React.PropTypes.func
|
||||
colorRange: React.PropTypes.array.isRequired,
|
||||
valueAccessor: React.PropTypes.func.isRequired
|
||||
},
|
||||
|
||||
getDefaultProps: function getDefaultProps() {
|
||||
|
||||
@ -34,17 +34,17 @@ var DraggablePointsOverlay = React.createClass({
|
||||
displayName: 'DraggablePointsOverlay',
|
||||
|
||||
propTypes: {
|
||||
width: React.PropTypes.number,
|
||||
height: React.PropTypes.number,
|
||||
points: React.PropTypes.instanceOf(Immutable.List),
|
||||
project: React.PropTypes.func,
|
||||
unproject: React.PropTypes.func,
|
||||
isDragging: React.PropTypes.bool,
|
||||
keyAccessor: React.PropTypes.func,
|
||||
lngLatAccessor: React.PropTypes.func,
|
||||
onAddPoint: React.PropTypes.func,
|
||||
onUpdatePoint: React.PropTypes.func,
|
||||
renderPoint: React.PropTypes.func
|
||||
width: React.PropTypes.number.isRequired,
|
||||
height: React.PropTypes.number.isRequired,
|
||||
points: React.PropTypes.instanceOf(Immutable.List).isRequired,
|
||||
project: React.PropTypes.func.isRequired,
|
||||
unproject: React.PropTypes.func.isRequired,
|
||||
isDragging: React.PropTypes.bool.isRequired,
|
||||
keyAccessor: React.PropTypes.func.isRequired,
|
||||
lngLatAccessor: React.PropTypes.func.isRequired,
|
||||
onAddPoint: React.PropTypes.func.isRequired,
|
||||
onUpdatePoint: React.PropTypes.func.isRequired,
|
||||
renderPoint: React.PropTypes.func.isRequired
|
||||
},
|
||||
|
||||
getDefaultProps: function getDefaultProps() {
|
||||
|
||||
@ -28,11 +28,11 @@ var HTMLOverlay = React.createClass({
|
||||
displayName: 'HTMLOverlay',
|
||||
|
||||
propTypes: {
|
||||
width: React.PropTypes.number,
|
||||
height: React.PropTypes.number,
|
||||
redraw: React.PropTypes.func,
|
||||
project: React.PropTypes.func,
|
||||
isDragging: React.PropTypes.bool
|
||||
width: React.PropTypes.number.isRequired,
|
||||
height: React.PropTypes.number.isRequired,
|
||||
redraw: React.PropTypes.func.isRequired,
|
||||
project: React.PropTypes.func.isRequired,
|
||||
isDragging: React.PropTypes.bool.isRequired
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
|
||||
@ -31,17 +31,17 @@ var ScatterplotOverlay = React.createClass({
|
||||
displayName: 'ScatterplotOverlay',
|
||||
|
||||
propTypes: {
|
||||
width: React.PropTypes.number,
|
||||
height: React.PropTypes.number,
|
||||
project: React.PropTypes.func,
|
||||
isDragging: React.PropTypes.bool,
|
||||
locations: React.PropTypes.instanceOf(Immutable.List),
|
||||
lngLatAccessor: React.PropTypes.func,
|
||||
width: React.PropTypes.number.isRequired,
|
||||
height: React.PropTypes.number.isRequired,
|
||||
project: React.PropTypes.func.isRequired,
|
||||
isDragging: React.PropTypes.bool.isRequired,
|
||||
locations: React.PropTypes.instanceOf(Immutable.List).isRequired,
|
||||
lngLatAccessor: React.PropTypes.func.isRequired,
|
||||
renderWhileDragging: React.PropTypes.bool,
|
||||
globalOpacity: React.PropTypes.number,
|
||||
dotRadius: React.PropTypes.number,
|
||||
dotFill: React.PropTypes.string,
|
||||
compositeOperation: React.PropTypes.oneOf(COMPOSITE_TYPES)
|
||||
globalOpacity: React.PropTypes.number.isRequired,
|
||||
dotRadius: React.PropTypes.number.isRequired,
|
||||
dotFill: React.PropTypes.string.isRequired,
|
||||
compositeOperation: React.PropTypes.oneOf(COMPOSITE_TYPES).isRequired
|
||||
},
|
||||
|
||||
getDefaultProps: function getDefaultProps() {
|
||||
|
||||
@ -28,11 +28,11 @@ var SVGOverlay = React.createClass({
|
||||
displayName: 'SVGOverlay',
|
||||
|
||||
propTypes: {
|
||||
width: React.PropTypes.number,
|
||||
height: React.PropTypes.number,
|
||||
redraw: React.PropTypes.func,
|
||||
project: React.PropTypes.func,
|
||||
isDragging: React.PropTypes.bool
|
||||
width: React.PropTypes.number.isRequired,
|
||||
height: React.PropTypes.number.isRequired,
|
||||
redraw: React.PropTypes.func.isRequired,
|
||||
project: React.PropTypes.func.isRequired,
|
||||
isDragging: React.PropTypes.bool.isRequired
|
||||
},
|
||||
|
||||
render: function render() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user