Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-simple-maps

Package Overview
Dependencies
Maintainers
1
Versions
54
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-simple-maps - npm Package Compare versions

Comparing version 0.9.0 to 0.10.0

topojson-maps/world-10m.json

11

lib/ComposableMap.js

@@ -60,5 +60,7 @@ "use strict";

style = _props2.style,
className = _props2.className,
showCenter = _props2.showCenter,
children = _props2.children,
aspectRatio = _props2.aspectRatio;
aspectRatio = _props2.aspectRatio,
viewBox = _props2.viewBox;

@@ -70,4 +72,4 @@

height: height,
viewBox: "0 0 " + width + " " + height,
className: "rsm-svg",
viewBox: viewBox ? viewBox : "0 0 " + width + " " + height,
className: "rsm-svg " + (className || ''),
style: style,

@@ -98,5 +100,6 @@ preserveAspectRatio: aspectRatio },

projectionConfig: _projectionConfig2.default,
aspectRatio: "xMidYMid"
aspectRatio: "xMidYMid",
viewBox: null
};
exports.default = ComposableMap;

@@ -32,3 +32,3 @@ "use strict";

_this.state = {
geographyPaths: props.geographyPaths
geographyPaths: ""
};

@@ -42,3 +42,3 @@

key: "fetchGeographies",
value: function fetchGeographies(geographyUrl) {
value: function fetchGeographies(geography) {
var _this2 = this;

@@ -51,25 +51,31 @@

if (!geographyUrl) return;
if (!geography) return;else if (Object.prototype.toString.call(geography) === '[object Object]') {
this.setState({
geographyPaths: (0, _topojsonClient.feature)(geographyPaths, geographyPaths.objects[Object.keys(geographyPaths.objects)[0]]).features
});
} else if (Array.isArray(geography)) {
this.setState({ geographyPaths: geography });
} else {
var request = new XMLHttpRequest();
request.open("GET", geography, true);
var request = new XMLHttpRequest();
request.open("GET", geographyUrl, true);
request.onload = function () {
if (request.status >= 200 && request.status < 400) {
var geographyPaths = JSON.parse(request.responseText);
_this2.setState({
geographyPaths: (0, _topojsonClient.feature)(geographyPaths, geographyPaths.objects[Object.keys(geographyPaths.objects)[0]]).features
}, function () {
request.onload = function () {
if (request.status >= 200 && request.status < 400) {
var _geographyPaths = JSON.parse(request.responseText);
_this2.setState({
geographyPaths: (0, _topojsonClient.feature)(_geographyPaths, _geographyPaths.objects[Object.keys(_geographyPaths.objects)[0]]).features
}, function () {
if (!_this2.props.onGeographiesLoaded) return;
_this2.props.onGeographyPathsLoaded(String(request.status));
});
} else {
if (!_this2.props.onGeographiesLoaded) return;
_this2.props.onGeographyPathsLoaded(String(request.status));
});
} else {
if (!_this2.props.onGeographiesLoaded) return;
_this2.props.onGeographyPathsLoaded(String(request.status));
}
};
request.onerror = function () {
console.log("There was a connection error...");
};
request.send();
}
};
request.onerror = function () {
console.log("There was a connection error...");
};
request.send();
}
}

@@ -79,12 +85,5 @@ }, {

value: function componentWillReceiveProps(nextProps) {
;
if (!nextProps.geographyUrl && !nextProps.geographyPaths.length !== this.props.geographyPaths.length) {
this.setState({
geographyPaths: nextProps.geographyPaths
});
return;
if (nextProps.geography !== this.props.geography) {
this.fetchGeographies(nextProps.geography);
}
if (nextProps.geographyUrl !== this.props.geographyUrl) {
this.fetchGeographies(nextProps.geographyUrl);
}
}

@@ -95,4 +94,3 @@ }, {

var geoPathsChanged = nextState.geographyPaths.length !== this.state.geographyPaths.length;
var choroplethChanged = JSON.stringify(nextProps.choropleth) !== JSON.stringify(this.props.choropleth);
return geoPathsChanged || choroplethChanged || nextProps.disableOptimization;
return geoPathsChanged || nextProps.disableOptimization;
}

@@ -102,3 +100,6 @@ }, {

value: function componentDidMount() {
this.fetchGeographies(this.props.geographyUrl);
if (this.props.geographyUrl || this.props.geographyPaths) {
console.warn("You are using the deprecated geographyUrl or geographyPaths props. Use the new geography prop instead. Check out the new docs here: https://github.com/zcreativelabs/react-simple-maps#Geographies-component");
}
this.fetchGeographies(this.props.geography);
}

@@ -113,7 +114,6 @@ }, {

return _react2.default.createElement(
"g",
{ className: "rsm-geographies", style: style },
children(this.state.geographyPaths, projection)
children(this.state.geographyPaths || [], projection)
);

@@ -129,6 +129,5 @@ }

disableOptimization: false,
geographyUrl: "",
geographyPaths: []
geography: ""
};
exports.default = Geographies;

@@ -166,3 +166,5 @@ "use strict";

tabable = _props9.tabable,
children = _props9.children;
zoom = _props9.zoom,
children = _props9.children,
preserveMarkerAspect = _props9.preserveMarkerAspect;
var _state = this.state,

@@ -173,6 +175,8 @@ pressed = _state.pressed,

var scale = preserveMarkerAspect ? " scale(" + 1 / zoom + ")" : "";
return _react2.default.createElement(
"g",
{ className: "rsm-marker" + (pressed ? " rsm-marker--pressed" : "") + (hover ? " rsm-marker--hover" : ""),
transform: "translate(\n " + projection()(marker.coordinates)[0] + "\n " + projection()(marker.coordinates)[1] + "\n )",
transform: "translate(\n " + projection()(marker.coordinates)[0] + "\n " + projection()(marker.coordinates)[1] + "\n ) " + scale,
style: style[pressed || hover ? pressed ? "pressed" : "hover" : "default"],

@@ -206,5 +210,6 @@ onMouseEnter: this.handleMouseEnter,

},
tabable: true
tabable: true,
preserveMarkerAspect: true
};
exports.default = Marker;

@@ -36,5 +36,5 @@ "use strict";

projection = _props.projection,
style = _props.style;
style = _props.style,
zoom = _props.zoom;
return _react2.default.createElement(

@@ -44,7 +44,9 @@ "g",

!children ? null : children.length === undefined ? _react2.default.cloneElement(children, {
projection: projection
projection: projection,
zoom: zoom
}) : children.map(function (child, i) {
return !child ? null : _react2.default.cloneElement(child, {
key: child.key || "marker-" + i,
projection: projection
projection: projection,
zoom: zoom
});

@@ -51,0 +53,0 @@ })

@@ -6,4 +6,2 @@ "use strict";

});
exports.replaceStrokeWidth = replaceStrokeWidth;
exports.createChoroplethStyles = createChoroplethStyles;
exports.calculateResizeFactor = calculateResizeFactor;

@@ -23,22 +21,2 @@ exports.calculateMousePosition = calculateMousePosition;

function replaceStrokeWidth(styles) {
var newStyles = {};
Object.keys(styles).map(function (key, i) {
if (key === "strokeWidth") newStyles[key] = "inherit";else newStyles[key] = styles[key];
});
return newStyles;
}
function createChoroplethStyles(styles, choroplethValue) {
if (choroplethValue) {
var newStyles = {};
Object.keys(styles).map(function (key, i) {
if (key === "fill") newStyles[key] = choroplethValue.value;else newStyles[key] = styles[key];
});
return newStyles;
} else {
return styles;
}
}
function calculateResizeFactor(actualDimension, baseDimension) {

@@ -45,0 +23,0 @@ return 1 / 100 * (100 / actualDimension * baseDimension);

@@ -148,5 +148,18 @@ "use strict";

}, {
key: "handleTouchStart",
value: function handleTouchStart(_ref5) {
var touches = _ref5.touches;
if (touches.length > 1) {
this.handleMouseDown(touches[0]);
} else {
this.handleMouseUp();
}
}
}, {
key: "preventTouchScroll",
value: function preventTouchScroll(evt) {
evt.preventDefault();
if (evt.touches.length > 1) {
evt.preventDefault();
}
}

@@ -248,3 +261,2 @@ }, {

return _react2.default.createElement(

@@ -251,0 +263,0 @@ "g",

{
"name": "react-simple-maps",
"version": "0.9.0",
"version": "0.10.0",
"description": "An svg map component built with and for React",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -10,5 +10,5 @@ # react-simple-maps

### API changes from 0.4 to 0.5
### API changes from 0.9 to 0.10
`React-simple-maps` has been rewritten to allow more creative freedom and low-level access for developers. The `<ReactSimpleMap />` component has been replaced with a `<ComposableMap />` component and a set of smaller components that define each part of the interactive map.
In version `0.10` the method of passing geography data to `react-simple-maps` has changed. Where previously `geographyUrl` and `geographyPaths` were separate, they are now handled together through the `geography` prop. If you are upgrading from version `0.9`, simply change `geographyUrl` or `geographyPaths` to `geography` and you should be good to go.

@@ -31,2 +31,3 @@ ### Installation

import {
ComposableMap,

@@ -44,6 +45,6 @@ ZoomableGroup,

<ZoomableGroup>
<Geographies geographyUrl={ "/path/to/your/topojson-map-file.json" }>
{(geographies, projection) => geographies.map((geography, i) => (
<Geographies geography={ "/path/to/your/topojson-map-file.json or geography object" }>
{(geographies, projection) => geographies.map(geography => (
<Geography
key={ `geography-${i}` }
key={ geography.id }
geography={ geography }

@@ -71,5 +72,5 @@ projection={ projection }

<ZoomableGroup>
<Geographies geographyUrl={ "/path/to/your/topojson-map-file.json" }>
{(geographies, projection) => geographies.map((geography, i) => (
<Geography key={ i } geography={ geography } projection={ projection } />
<Geographies geography={ "/path/to/your/topojson-map-file.json or geography object" }>
{(geographies, projection) => geographies.map(geography => (
<Geography key={ geography.id } geography={ geography } projection={ projection } />
))}

@@ -173,2 +174,4 @@ </Geographies>

| style | Object | {} |
| onMoveStart | Function | |
| onMoveEnd | Function | |

@@ -218,6 +221,6 @@ ##### Zooming

<ZoomableGroup zoom={ this.state.zoom }>
<Geographies geographyUrl={ "/path/to/your/topojson-map-file.json" }>
{(geographies, projection) => geographies.map((geography, i) => (
<Geographies geography={ "/path/to/your/topojson-map-file.json or geography object" }>
{(geographies, projection) => geographies.map(geography => (
<Geography
key={ `geography-${i}` }
key={ geography.id }
geography={ geography }

@@ -240,5 +243,32 @@ projection={ projection }

##### Move events
The `ZoomableGroup` component allows you to hook into the `onMoveStart` and `onMoveEnd` event, and exposes the new center of the map in the callback.
```js
handleMoveStart(currentCenter) {
console.log("New center: ", currentCenter)
}
handleMoveEnd(newCenter) {
console.log("New center: ", newCenter)
}
...
<ZoomableGroup
onMoveStart={this.handleMoveStart}
onMoveEnd={this.handleMoveEnd}
>
<Geographies>
...
</Geographies>
</ZoomableGroup>
...
```
#### <a name="Geographies-component"></a> `<Geographies />`
`<Geographies />` is a group wrapper around the geographies paths. It returns a function that contains the geographies extracted from the geographiesUrl passed in.
`<Geographies />` is a group wrapper around the geographies paths. It returns a function that contains the geographies extracted from the data passed ot the `geography` prop.

@@ -249,17 +279,16 @@ React-simple-maps offers a couple of ways to optimise the performance of the map:

2. A second way in which react-simple-maps can optimise maps is by setting a `cacheId` on the individual geographies. See the [`<Geography />`](#ComposableMap-component) component for more info. The unique cacheIds help to cache the paths and significantly accelerate rerenders. This second method is the recommended way of optimising maps with react-simple-maps.
2. A second way in which react-simple-maps can optimise maps is by setting a `cacheId` on the individual geographies. See the [`<Geography />`](#ComposableMap-component) component for more info. The unique cacheIds help to cache the paths and significantly accelerate rerenders. **This second method is the recommended way of optimising maps with react-simple-maps.**
If you do not want `react-simple-maps` to load your topojson and pass it down automatically, you can also pass your topojson converted `features` directly into the `Geographies` component.
If you do not want `react-simple-maps` to load your topojson and pass it down automatically, you can also pass your topojson converted `features` directly into the `Geographies` component, or an object containing the topojson data.
##### Props
| Property | Type | Default |
| ------------------- |:--------------- | :----------------------------- |
| disableOptimization | Boolean | false |
| geographyUrl | String | "" |
| geographyPaths | Array | [] |
| Property | Type | Default |
| ------------------- |:---------------------------| :----------------------------- |
| disableOptimization | Boolean | false |
| geography | String or Object, or Array | "" |
##### Choropleth map
The below example uses the [world-50m-with-data.json](https://github.com/zcreativelabs/react-simple-maps/tree/master/topojson-maps) TopoJSON file.
The below example uses the [world-50m.json](https://github.com/zcreativelabs/react-simple-maps/tree/master/topojson-maps) TopoJSON file.

@@ -269,2 +298,4 @@ ```js

import { scaleLinear } from "d3-scale"
// If you want to use an object instead of requesting a file:
import geographyObject from "/path/to/world-50m.json"

@@ -281,6 +312,7 @@ const colorScale = scaleLinear()

<ZoomableGroup>
<Geographies geographyUrl={ "/path/to/world-50m-with-data.json" }>
<Geographies geography={ "/path/to/world-50m.json or geography object" } disableOptimization> // if you are using the object, then geography={geographyObject}
{(geographies, projection) => geographies.map((geography, i) => (
<Geography
key={ `geography-${i}` }
cacheId={ `geography-${i}` }
geography={ geography }

@@ -309,2 +341,47 @@ projection={ projection }

##### Custom TopoJSON via geography
If you want to transform your own TopoJSON maps with `topojson-client`, you can use `geography` prop to inject your own array of paths into `react-simple-maps`.
```js
import React, { Component } from "react"
import { get } from "axios"
import { feature } from "topojson-client"
class CustomMap extends Component {
contructor() {
super()
this.state = {
geographyPaths: [],
}
this.loadPaths = this.loadPaths.bind(this)
}
componentDidMount() {
this.loadPaths()
}
loadPaths() {
get("/path/to/world-topojson.json")
.then(res => {
if (res.status !== 200) return
const world = res.data
const geographyPaths = feature(
world,
world.objects[Object.keys(world.objects)[0]]
).features
this.setState({ geographyPaths })
})
}
render() {
return (
...
<Geographies geography={this.state.geographyPaths} disableOptimization>
...
</Geographies>
...
)
}
```
Check out the [custom-json-geographyPaths example](https://github.com/zcreativelabs/react-simple-maps/tree/master/examples/custom-json-geographyPaths) to see how to do this.
#### <a name="Geography-component"></a> `<Geography />`

@@ -347,5 +424,10 @@

...
<Geographies geographyUrl={ "/path/to/your/topojson-map-file.json" }>
<Geographies geography={ "/path/to/your/topojson-map-file.json" }>
{(geographies, projection) => geographies.map((geography, i) => (
<Geography key={ i } geography={ geography } projection={ projection } />
<Geography
key={ i }
geography={ geography }
projection={ projection }
onClick={this.handleClick}
/>
))}

@@ -365,11 +447,12 @@ </Geographies>

The `<Marker />` component represents each marker and uses coordinates to position the marker on the map. It does not make any assumptions about what your marker looks like, so you have to specify yourself what shape it should have. See the example below for how to make the recommended circular marker. The component can be used to assign events to individual markers on the map, and to specify the hover, focus and click behavior.
The `<Marker />` component represents each marker and uses coordinates to position the marker on the map. It does not make any assumptions about what your marker looks like, so you have to specify yourself what shape it should have. See the example below for how to make the recommended circular marker. The component can be used to assign events to individual markers on the map, and to specify the hover, focus and click behavior. You can also choose to preserve the markers aspect/size when in a `<ZoomableGroup />` via the `preserveMarkerAspect` prop.
##### Props
| Property | Type | Default |
| ------------------- |:--------------- | :----------------------------- |
| marker | Object | *see below examples |
| tabable | Boolean | true |
| style | Object | *see below examples |
| Property | Type | Default |
| -------------------- |:--------------- | :----------------------------- |
| marker | Object | *see below examples |
| tabable | Boolean | true |
| style | Object | *see below examples |
| preserveMarkerAspect | Boolean | true |

@@ -376,0 +459,0 @@ ##### Marker location

@@ -30,5 +30,7 @@

style,
className,
showCenter,
children,
aspectRatio
aspectRatio,
viewBox
} = this.props

@@ -39,4 +41,4 @@

height={ height }
viewBox={ `0 0 ${width} ${height}` }
className="rsm-svg"
viewBox={ viewBox ? viewBox : `0 0 ${width} ${height}` }
className={ `rsm-svg ${className || ''}` }
style={ style }

@@ -69,5 +71,6 @@ preserveAspectRatio={ aspectRatio }>

projectionConfig: defaultProjectionConfig,
aspectRatio: "xMidYMid"
aspectRatio: "xMidYMid",
viewBox: null
}
export default ComposableMap

@@ -10,3 +10,3 @@

this.state = {
geographyPaths: props.geographyPaths,
geographyPaths: "",
}

@@ -16,50 +16,57 @@

}
fetchGeographies(geographyUrl) {
fetchGeographies(geography) {
const { width, height } = this.props
if(!geographyUrl) return
if(!geography) return
const request = new XMLHttpRequest()
request.open("GET", geographyUrl, true)
else if (Object.prototype.toString.call(geography) === '[object Object]') {
this.setState({
geographyPaths: feature(geographyPaths, geographyPaths.objects[Object.keys(geographyPaths.objects)[0]]).features
})
}
request.onload = () => {
if (request.status >= 200 && request.status < 400) {
const geographyPaths = JSON.parse(request.responseText)
this.setState({
geographyPaths: feature(geographyPaths, geographyPaths.objects[Object.keys(geographyPaths.objects)[0]]).features,
}, () => {
else if (Array.isArray(geography)) {
this.setState({ geographyPaths: geography })
}
else {
const request = new XMLHttpRequest()
request.open("GET", geography, true)
request.onload = () => {
if (request.status >= 200 && request.status < 400) {
const geographyPaths = JSON.parse(request.responseText)
this.setState({
geographyPaths: feature(geographyPaths, geographyPaths.objects[Object.keys(geographyPaths.objects)[0]]).features,
}, () => {
if (!this.props.onGeographiesLoaded) return
this.props.onGeographyPathsLoaded(String(request.status))
})
} else {
if (!this.props.onGeographiesLoaded) return
this.props.onGeographyPathsLoaded(String(request.status))
})
} else {
if (!this.props.onGeographiesLoaded) return
this.props.onGeographyPathsLoaded(String(request.status))
}
}
request.onerror = () => {
console.log("There was a connection error...")
}
request.send()
}
request.onerror = () => {
console.log("There was a connection error...")
}
request.send()
}
componentWillReceiveProps(nextProps) {;
if (!nextProps.geographyUrl && !nextProps.geographyPaths.length !== this.props.geographyPaths.length) {
this.setState({
geographyPaths: nextProps.geographyPaths,
})
return
componentWillReceiveProps(nextProps) {
if (nextProps.geography !== this.props.geography) {
this.fetchGeographies(nextProps.geography)
}
if (nextProps.geographyUrl !== this.props.geographyUrl) {
this.fetchGeographies(nextProps.geographyUrl)
}
}
shouldComponentUpdate(nextProps, nextState) {
const geoPathsChanged = nextState.geographyPaths.length !== this.state.geographyPaths.length
const choroplethChanged = JSON.stringify(nextProps.choropleth) !== JSON.stringify(this.props.choropleth)
return geoPathsChanged || choroplethChanged || nextProps.disableOptimization
return geoPathsChanged || nextProps.disableOptimization
}
componentDidMount() {
this.fetchGeographies(this.props.geographyUrl)
if (this.props.geographyUrl || this.props.geographyPaths) {
console.warn("You are using the deprecated geographyUrl or geographyPaths props. Use the new geography prop instead. Check out the new docs here: https://github.com/zcreativelabs/react-simple-maps#Geographies-component")
}
this.fetchGeographies(this.props.geography)
}
render() {
const {

@@ -70,6 +77,5 @@ projection,

} = this.props
return (
<g className="rsm-geographies" style={ style }>
{ children(this.state.geographyPaths, projection) }
{ children(this.state.geographyPaths || [], projection) }
</g>

@@ -83,6 +89,5 @@ )

disableOptimization: false,
geographyUrl: "",
geographyPaths: [],
geography: "",
}
export default Geographies

@@ -89,3 +89,5 @@

tabable,
zoom,
children,
preserveMarkerAspect,
} = this.props

@@ -98,2 +100,4 @@

const scale = preserveMarkerAspect ? ` scale(${1/zoom})` : ""
return (

@@ -104,3 +108,3 @@ <g className={ `rsm-marker${ pressed ? " rsm-marker--pressed" : "" }${ hover ? " rsm-marker--hover" : "" }` }

${ projection()(marker.coordinates)[1] }
)`}
) ${scale}`}
style={ style[pressed || hover ? (pressed ? "pressed" : "hover") : "default"] }

@@ -133,4 +137,5 @@ onMouseEnter={ this.handleMouseEnter }

tabable: true,
preserveMarkerAspect: true,
}
export default Marker

@@ -11,4 +11,4 @@

style,
zoom,
} = this.props
return (

@@ -22,2 +22,3 @@ <g className="rsm-markers" style={ style }>

projection,
zoom,
}) :

@@ -30,2 +31,3 @@ children.map((child, i) =>

projection,
zoom,
})

@@ -32,0 +34,0 @@ )

import React from "react"
export function replaceStrokeWidth(styles) {
let newStyles = {}
Object.keys(styles).map((key, i) => {
if(key === "strokeWidth") newStyles[key] = "inherit"
else newStyles[key] = styles[key]
})
return newStyles
}
export function createChoroplethStyles(styles, choroplethValue) {
if(choroplethValue) {
let newStyles = {}
Object.keys(styles).map((key, i) => {
if(key === "fill") newStyles[key] = choroplethValue.value
else newStyles[key] = styles[key]
})
return newStyles
}
else {
return styles
}
}
export function calculateResizeFactor(actualDimension, baseDimension) {

@@ -28,0 +5,0 @@ return 1 / 100 * (100 / actualDimension * baseDimension)

@@ -88,4 +88,14 @@

}
handleTouchStart({ touches }) {
if (touches.length > 1) {
this.handleMouseDown(touches[0])
}
else {
this.handleMouseUp()
}
}
preventTouchScroll(evt) {
evt.preventDefault()
if (evt.touches.length > 1) {
evt.preventDefault()
}
}

@@ -159,3 +169,2 @@ componentWillReceiveProps(nextProps) {

} = this.state
return (

@@ -162,0 +171,0 @@ <g className="rsm-zoomable-group"

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc