add world map package

This commit is contained in:
Krist Wongsuphasawat 2019-01-30 15:03:12 -08:00 committed by Yongjie Zhao
parent 1d3e3c5c27
commit b44a0b1613
10 changed files with 323 additions and 0 deletions

View File

@ -26,6 +26,7 @@ const metadata = new ChartMetadata({
description: '',
name: t('Calendar Heatmap'),
thumbnail,
useLegacyApi: true,
});
export default class ChordChartPlugin extends ChartPlugin {

View File

@ -0,0 +1,34 @@
## @superset-ui/legacy-plugin-chart-world-map
[![Version](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-world-map.svg?style=flat-square)](https://img.shields.io/npm/v/@superset-ui/legacy-plugin-chart-world-map.svg?style=flat-square)
[![David (path)](https://img.shields.io/david/apache-superset/superset-ui.svg?path=packages%2Fsuperset-ui-legacy-plugin-chart-world-map&style=flat-square)](https://david-dm.org/apache-superset/superset-ui?path=packages/superset-ui-legacy-plugin-chart-world-map)
This plugin provides World Map for Superset.
### Usage
Configure `key`, which can be any `string`, and register the plugin. This `key` will be used to lookup this chart throughout the app.
```js
import WorldmapChartPlugin from '@superset-ui/legacy-plugin-chart-world-map';
new WorldmapChartPlugin()
.configure({ key: 'world-map' })
.register();
```
Then use it via `SuperChart`. See [storybook](https://apache-superset.github.io/superset-ui-legacy/?selectedKind=plugin-chart-world-map) for more details.
```js
<SuperChart
chartType="world-map"
chartProps={{
width: 600,
height: 600,
formData: {...},
payload: {
data: {...},
},
}}
/>
```

View File

@ -0,0 +1,44 @@
{
"name": "@superset-ui/legacy-plugin-chart-world-map",
"version": "0.0.0",
"description": "Superset Legacy Chart - World Map",
"sideEffects": false,
"main": "lib/index.js",
"module": "esm/index.js",
"files": [
"esm",
"lib"
],
"repository": {
"type": "git",
"url": "git+https://github.com/apache-superset/superset-ui-legacy.git"
},
"keywords": [
"superset"
],
"author": "Superset",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/apache-superset/superset-ui-legacy/issues"
},
"homepage": "https://github.com/apache-superset/superset-ui-legacy#readme",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@superset-ui/core": "^0.9.x",
"d3": "^3.5.17",
"datamaps": "^0.5.8",
"prop-types": "^15.6.2"
},
"devDependencies": {
"@superset-ui/chart": "^0.9.x",
"@superset-ui/number-format": "^0.9.x",
"@superset-ui/translation": "^0.9.x"
},
"peerDependencies": {
"@superset-ui/chart": "^0.9.x",
"@superset-ui/number-format": "^0.9.x",
"@superset-ui/translation": "^0.9.x"
}
}

View File

@ -0,0 +1,22 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { reactify } from '@superset-ui/chart';
import WorldMap from './WorldMap';
export default reactify(WorldMap);

View File

@ -0,0 +1,25 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
.superset-legacy-chart-world-map svg {
background-color: #feffff;
}
.superset-legacy-chart-world-map {
position: relative;
}

View File

@ -0,0 +1,129 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* eslint-disable sort-keys */
import d3 from 'd3';
import PropTypes from 'prop-types';
import Datamap from 'datamaps/dist/datamaps.world.min';
import { getNumberFormatter } from '@superset-ui/number-format';
import './WorldMap.css';
const propTypes = {
data: PropTypes.arrayOf(
PropTypes.shape({
country: PropTypes.string,
latitude: PropTypes.number,
longitude: PropTypes.number,
name: PropTypes.string,
m1: PropTypes.number,
m2: PropTypes.number,
}),
),
height: PropTypes.number,
maxBubbleSize: PropTypes.number,
showBubbles: PropTypes.bool,
};
const formatter = getNumberFormatter();
function WorldMap(element, props) {
const { data, height, maxBubbleSize, showBubbles } = props;
const div = d3.select(element);
div.classed('superset-legacy-chart-world-map', true);
const container = element;
container.style.height = `${height}px`;
div.selectAll('*').remove();
// Ignore XXX's to get better normalization
const filteredData = data.filter(d => d.country && d.country !== 'XXX');
const ext = d3.extent(filteredData, d => d.m1);
const extRadius = d3.extent(filteredData, d => d.m2);
const radiusScale = d3.scale
.linear()
.domain([extRadius[0], extRadius[1]])
.range([1, maxBubbleSize]);
const colorScale = d3.scale
.linear()
.domain([ext[0], ext[1]])
.range(['#FFF', 'black']);
const processedData = filteredData.map(d => ({
...d,
radius: radiusScale(d.m2),
fillColor: colorScale(d.m1),
}));
const mapData = {};
processedData.forEach(d => {
mapData[d.country] = d;
});
const map = new Datamap({
element,
data: processedData,
fills: {
defaultFill: '#ddd',
},
geographyConfig: {
popupOnHover: true,
highlightOnHover: true,
borderWidth: 1,
borderColor: '#fff',
highlightBorderColor: '#fff',
highlightFillColor: '#005a63',
highlightBorderWidth: 1,
popupTemplate: (geo, d) =>
`<div class="hoverinfo"><strong>${d.name}</strong><br>${formatter(d.m1)}</div>`,
},
bubblesConfig: {
borderWidth: 1,
borderOpacity: 1,
borderColor: '#005a63',
popupOnHover: true,
radius: null,
popupTemplate: (geo, d) =>
`<div class="hoverinfo"><strong>${d.name}</strong><br>${formatter(d.m2)}</div>`,
fillOpacity: 0.5,
animate: true,
highlightOnHover: true,
highlightFillColor: '#005a63',
highlightBorderColor: 'black',
highlightBorderWidth: 2,
highlightBorderOpacity: 1,
highlightFillOpacity: 0.85,
exitDelay: 100,
key: JSON.stringify,
},
});
map.updateChoropleth(mapData);
if (showBubbles) {
map.bubbles(processedData);
div.selectAll('circle.datamaps-bubble').style('fill', '#005a63');
}
}
WorldMap.displayName = 'WorldMap';
WorldMap.propTypes = propTypes;
export default WorldMap;

View File

@ -0,0 +1,39 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { t } from '@superset-ui/translation';
import { ChartMetadata, ChartPlugin } from '@superset-ui/chart';
import transformProps from './transformProps';
import thumbnail from './images/thumbnail.png';
const metadata = new ChartMetadata({
credits: ['http://datamaps.github.io/'],
description: '',
name: t('World Map'),
thumbnail,
});
export default class WorldMapChartPlugin extends ChartPlugin {
constructor() {
super({
loadChart: () => import('./ReactWorldMap.js'),
metadata,
transformProps,
});
}
}

View File

@ -0,0 +1,29 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export default function transformProps(chartProps) {
const { height, formData, payload } = chartProps;
const { maxBubbleSize, showBubbles } = formData;
return {
data: payload.data,
height,
maxBubbleSize: parseInt(maxBubbleSize, 10),
showBubbles,
};
}