stories/chart.map.stories.js (661 lines of code) (raw):

import React, { useState, useEffect, useRef } from 'react'; import { storiesOf } from '@storybook/react'; import { action } from '@storybook/addon-actions'; import { Wcontainer, Wmap, Wplaceholder } from '@alicloud/cloud-charts'; import adcodeMap from './data/adcode.json'; const areaData = [ { name: '一', data: [ { name: '北京', value: 10, }, { name: '天津', value: 18, }, { name: '上海', value: 22, }, { name: '重庆', value: 39, }, { name: '内蒙古', value: 22, }, { name: '广西', value: 43, }, ], }, { name: '二', data: [ { name: '西藏', value: 56, }, { name: '宁夏', value: 65, }, { name: '新疆', value: 69, }, { name: '香港', value: 22, }, { name: '澳门', value: 36, }, { name: '江西', value: 95, }, ], }, { name: '三', data: [ { name: '河南', value: 23, }, { name: '四川', value: 105, }, { name: '贵州', value: 141, }, { name: '辽宁', value: 33, }, { name: '山东', value: 135, }, { name: '山西', value: 115, }, ], }, { name: '四', data: [ { name: '浙江', value: 160, }, { name: '海南', value: 49, }, { name: '陕西', value: 140, }, { name: '福建', value: 134, }, { name: '青海', value: 197, }, { name: '湖北', value: 202, }, ], }, { name: '五', data: [ { name: '甘肃', value: 31, }, { name: '安徽', value: 224, }, { name: '台湾', value: 126, }, { name: '云南', value: 235, }, { name: '黑龙江', value: 72, }, { name: '广东', value: 91, }, ], }, { name: '六', data: [ { name: '湖南', value: 212, }, { name: '河北', value: 27, }, { name: '吉林', value: 22, }, { name: '江苏', value: 295, }, ], }, ]; const pointData = [ { name: '正常', data: [ { name: '北京', lng: 116.4551, lat: 40.2539, value: 20 }, { name: '杭州', lng: 119.5313, lat: 29.8773, value: 10 }, ], }, { name: '异常', data: [ { name: '上海', lng: 121.4648, lat: 31.2891, value: 40 }, { name: '广州', lng: 113.5107, lat: 23.2196, value: 30 }, ], }, ]; const customPointData = [ { name: '北京', lng: 116.4551, lat: 40.2539, value: 20 }, { name: '杭州', lng: 119.5313, lat: 29.8773, value: 10 }, { name: '上海', lng: 121.4648, lat: 31.2891, value: 40 }, { name: '广州', lng: 113.5107, lat: 23.2196, value: 30 }, { name: '哈尔滨', lng: 127.9688, lat: 45.368, value: 50 }, { name: '三亚', lng: 109.3716, lat: 18.3698, value: 60 }, { name: '喀什', lng: 77.168, lat: 37.8534, value: 36 }, { name: '自定义点', x: 20, y: 20, value: 36 }, ]; const stories = storiesOf('Wmap', module); stories.add('基础地图', () => ( <Wcontainer className="demos" height={400}> <Wmap config={{}} /> </Wcontainer> )); stories.add('带标签基础地图', () => ( <Wcontainer className="demos" height={400}> <Wmap config={{ label: true, background: { fill: 'rgba(200,200,200,0.2)', }, }} /> </Wcontainer> )); stories.add('区块地图', () => ( <Wcontainer className="demos" height={400}> <Wmap config={{ tooltip: { nameFormatter(n, ...args) { console.log(args); return n; }, }, }} > <Wmap.Area data={areaData} /> </Wmap> </Wcontainer> )); const baseAreaData = [ { name: '一', data: [ { name: '浙江', value: 43, }, { name: '陕西', value: 43, }, { name: '青海', value: 43, }, ], }, ]; const outAreaData = [ { name: '二', data: [ { name: '浙江', value: 43, }, { name: '陕西', value: 43, }, { name: '青海', value: 43, }, ], }, ]; stories.add('区块凸起地图', () => { const ref = useRef(); useEffect(() => { console.log(ref.current); ref.current.bgMapView.interaction('brush'); ref.current.chart.on('pan', (ev) => { // const { points } = ev; console.log('pan', ev); }); }, []); return ( <Wcontainer className="demos" height={400}> <Wmap config={{ tooltip: false, legend: false, }} ref={ref} > <Wmap.Area data={baseAreaData} /> <Wmap.Area config={{ // 45ffff - 109eff padding: [0, 0, 8, 0], areaColors() { return 'l(90) 0:#45ffff 1:#109eff'; }, }} data={outAreaData} /> </Wmap> </Wcontainer> ); }); stories.add('散点地图', () => ( <Wcontainer className="demos" height={400}> <Wmap config={{}}> <Wmap.Point data={pointData} /> </Wmap> </Wcontainer> )); function Resize() { const [width, useWidth] = useState(800); return ( <Wcontainer className="demos" width={width} height={600} title="动态改变大小" operation={ <button onClick={() => { const w = width > 700 ? 600 : 800; useWidth(w); action('resize')(w); window.dispatchEvent(new Event('resize')); }} > resize </button> } > <Wmap config={ { // labels: true, } } > <Wmap.Area data={areaData} /> <Wmap.Point data={pointData} /> <Wmap.Custom data={customPointData} render={(point, index) => ( <span> {index} : {point.name} </span> )} /> </Wmap> </Wcontainer> ); } stories.add('动态改变大小', () => <Resize />); stories.add('混合使用', () => ( <Wcontainer className="demos" height={600}> <Wmap config={ { // labels: true, } } > <Wmap.Area data={areaData} /> <Wmap.Point data={pointData} /> <Wmap.Custom data={customPointData} render={(point, index) => ( <span> {index} : {point.name} </span> )} /> </Wmap> </Wcontainer> )); class Dynamic extends React.Component { state = { data: pointData, }; componentDidMount() { setTimeout(() => { action('setData')([ { name: '正常', data: [ { name: '北京', lng: 116.4551, lat: 40.2539, value: 20 }, { name: '杭州', lng: 119.5313, lat: 29.8773, value: 10 }, { name: '上海', lng: 121.4648, lat: 31.2891, value: 40 }, ], }, ]); this.setState({ data: [ { name: '正常', data: [ { name: '北京', lng: 116.4551, lat: 40.2539, value: 20 }, { name: '杭州', lng: 119.5313, lat: 29.8773, value: 10 }, { name: '上海', lng: 121.4648, lat: 31.2891, value: 40 }, ], }, // { // name: '异常', // data: [ // , // { name: '广州', lng: 113.5107, lat: 23.2196, value: 30 }, // ] // }, ], }); }, 2000); } render() { return ( <Wcontainer className="demos" height={400}> <Wmap config={{}}> <Wmap.Point data={this.state.data} /> </Wmap> </Wcontainer> ); } } stories.add('动态数据', () => <Dynamic />); const shootData = [ { name: '北京', lng: 116.4551, lat: 40.2539 }, { name: '杭州', lng: 119.5313, lat: 29.8773 }, { name: '上海', lng: 121.4648, lat: 31.2891 }, { name: '广州', lng: 113.5107, lat: 23.2196 }, { name: '四川省' }, { name: '西安' }, { name: '哈尔滨', lng: 127.9688, lat: 45.368 }, { name: '三亚', lng: 109.3716, lat: 18.3698 }, { name: '喀什', lng: 77.168, lat: 37.8534 }, { name: '自定义点1', x: -120, y: -120 }, // { name: '自定义点2', x: 140, y: -120 }, // { name: '自定义点3', x: 140, y: 120 }, // { name: '自定义点4', x: -120, y: 120 }, ]; function ShootDemo() { const log = action('setData'); const [width, useWidth] = useState(800); const [data, setData] = useState([]); useEffect(() => { const dataLen = shootData.length; const changeData = () => { const newData = []; const len = Math.round(Math.random() * 10) + 10; for (let i = 0; i < len; i++) { let fIndex = Math.round(Math.random() * (dataLen - 1)); let tIndex = (fIndex + Math.round(Math.random() * (dataLen / 2)) + 1) % dataLen; if (fIndex === tIndex) { tIndex = (fIndex + 1) % dataLen; } newData.push({ from: Object.assign({}, shootData[fIndex]), to: Object.assign({}, shootData[tIndex]), }); } log(newData); setData(newData); }; changeData(); const timer = setInterval(() => { changeData(); }, 8000); return () => clearInterval(timer); }, []); return ( <Wcontainer className="demos" width={width} height={600} title="点击右侧测试改变大小" operation={ <button onClick={() => { const w = width > 700 ? 600 : 800; useWidth(w); action('resize')(w); window.dispatchEvent(new Event('resize')); }} > resize </button> } > <Wmap> <Wmap.Shoot data={data} /> <Wmap.Custom data={shootData} render={(point, index) => ( <span> {index} : {point.name} </span> )} /> </Wmap> </Wcontainer> ); } stories.add('飞线地图', () => <ShootDemo />); function DoubleShootDemo() { const log = action('setData'); const log2 = action('setDoubleData'); const shootConfig = { maxFps: 30, }; const [data, setData] = useState([]); const [doubleData, setDoubleData] = useState([]); useEffect(() => { const dataLen = shootData.length; const changeData = () => { const newData = []; const newDoubleData = []; const len = Math.round(Math.random() * 10) + 10; for (let i = 0; i < len; i++) { let fIndex = Math.round(Math.random() * (dataLen - 1)); let tIndex = (fIndex + Math.round(Math.random() * (dataLen / 2)) + 1) % dataLen; if (fIndex === tIndex) { tIndex = fIndex + 1; } newData.push({ from: Object.assign({}, shootData[fIndex]), to: Object.assign({}, shootData[tIndex]), }); newDoubleData.push({ from: Object.assign({}, shootData[fIndex]), to: Object.assign({}, shootData[tIndex]), }); } log(newData); setData(newData); setTimeout(() => { setDoubleData(newDoubleData); log2(newDoubleData); }, 4000); }; changeData(); const timer = setInterval(() => { changeData(); }, 8000); return () => clearInterval(timer); }, []); return ( <Wcontainer className="demos" height={600}> <Wmap> <Wmap.Shoot data={data} config={shootConfig} debug={1} /> <Wmap.Shoot data={doubleData} config={shootConfig} debug={2} /> <Wmap.Custom data={shootData} render={(point, index) => ( <span> {index} : {point.name} </span> )} /> </Wmap> </Wcontainer> ); } stories.add('双层飞线地图', () => <DoubleShootDemo />); // let maxDepth = 0; // function getTreeDepth(data, depth) { // if (depth > maxDepth) { // maxDepth = depth; // } // data.forEach((d) => { // if (Array.isArray(d)) { // getTreeDepth(d, depth + 1); // } // }); // } // getTreeDepth(taiwanData60.features[0].geometry.coordinates, 0); // taiwanData60.features[0].geometry.coordinates.forEach((polygon) => { // polygon[0].reverse(); // }); // console.log(maxDepth); stories.add('自定义地图数据', () => { const [loading, setLoading] = React.useState(false); const [geoData, setGeoData] = React.useState(undefined); React.useEffect(() => { setLoading(true); // 示例中使用 DataV.GeoAtlas 工具作为数据源:https://datav.aliyun.com/tools/atlas/ // 实际使用请使用静态化数据保证稳定性。 fetch('https://geo.datav.aliyun.com/areas_v2/bound/330000_full.json') .then((res) => res.json()) .then((res) => { setGeoData(res); setLoading(false); }) .catch((e) => { setGeoData(undefined); setLoading(false); }); }, []); return ( <Wcontainer> {loading ? ( <Wplaceholder loading /> ) : ( <Wmap height={500} geoData={geoData} config={{ label: true, showSouthChinaSea: false, }} /> )} </Wcontainer> ); }); stories.add('地图数据选择器', () => { const [code, setCode] = React.useState(''); const [loading, setLoading] = React.useState(false); const [geoData, setGeoData] = React.useState(undefined); const historyRef = React.useRef([]); React.useEffect(() => { if (code) { setLoading(true); // 示例中使用 DataV.GeoAtlas 工具作为数据源:https://datav.aliyun.com/tools/atlas/ // 实际使用请使用静态化数据保证稳定性。 fetch(`https://geo.datav.aliyun.com/areas_v2/bound/${code}_full.json`) .then((res) => res.json()) .then((res) => { setGeoData(res); setLoading(false); }) .catch((e) => { setCode(''); setGeoData(undefined); setLoading(false); }); } else { setLoading(true); setGeoData(undefined); requestAnimationFrame(() => { setLoading(false); }); } }, [code]); function handleGetChart(chart) { if (chart) { chart.interaction('element-highlight'); chart.on('polygon:click', function (e) { const name = e && e.data && e.data.data && e.data.data.name; if (name && adcodeMap[name]) { historyRef.current.push({ name, adcode: adcodeMap[name], }); setCode(adcodeMap[name]); } }); } } return ( <Wcontainer> {loading ? ( <Wplaceholder loading /> ) : ( <Wmap height={500} geoData={geoData} config={{ label: true, showSouthChinaSea: false, background: { cursor: 'pointer', }, }} getChartInstance={handleGetChart} /> )} {code && ( <div> 当前区域:{historyRef.current[historyRef.current.length - 1].name} <button onClick={() => { historyRef.current.pop(); if (historyRef.current.length === 0) { setCode(''); } else { setCode(historyRef.current[historyRef.current.length - 1].adcode); } }} > 返回上一级 </button> <a href={`https://geo.datav.aliyun.com/areas_v2/bound/${code}_full.json`} target="_blank"> 下载数据 </a> </div> )} </Wcontainer> ); });