data-vis-ui
Version:
## [使用文档](https://temp-static-domain.jd.com/data-vis-ui)
333 lines (288 loc) • 22 kB
JavaScript
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
import React, { useMemo, useState, useRef } from 'react';
import axios from 'axios';
import * as echarts from 'echarts';
import { useEffect } from 'react';
import chinaGeoJson from './100000_full.json';
import allAreaCode from './all.json';
import tooltipBg from './img/tooltipbg.png';
import add from './img/add.svg';
import reduce from './img/reduce.svg';
import _ from 'lodash';
import { formdataNumber } from '../../utils/tools';
import "./index.css";
var mapDataUrl = 'https://storage.jd.com/iot.open/qld-map';
var getGeoJson = function getGeoJson(code) {
return new Promise(function (resolve, reject) {
axios.get("".concat(mapDataUrl, "/").concat(code, ".json")).then(function (e) {
if (e.status === 200) {
resolve(e.data);
} else {
resolve(chinaGeoJson);
}
}).catch(function () {
reject(chinaGeoJson);
});
});
};
var parkTooltipElement = function parkTooltipElement(opt, mapStatistics) {
var _a, _b;
var parkName = ((_a = opt === null || opt === void 0 ? void 0 : opt.data) === null || _a === void 0 ? void 0 : _a.parkName) || ((_b = opt === null || opt === void 0 ? void 0 : opt.data) === null || _b === void 0 ? void 0 : _b.name) || opt.name || '';
return "<div style=\"display:flex;flex-direction:column;background:url(".concat(tooltipBg, ") no-repeat;background-size:344px 211px;width:344px;height:211px;padding:10px 16px;\">\n <p style=\"font-size:14px;color:#F9F9F9;text-align: center;\">").concat(parkName, "</p>\n <div style=\"display:flex;align-items:center;margin-top:15px;margin-bottom:10px;\">\n <div style=\"flex:1;text-align: center;\">\n <div style=\"font-family: PingFangSC-Regular;font-size: 12px;color: #00B4FF;line-height: 12px;font-weight: 400;\">\u8BBE\u5907\u603B\u91CF</div>\n <div style=\"display:flex;justify-content: center;font-size:22px;font-family: DINCondensed-Bold;font-weight: 700;line-height: 22px;color: #00FAF9;margin-top:7px;\">").concat(formdataNumber(mapStatistics.deviceCount), "<span style=\"font-size:12px\">\u53F0</span></div>\n </div>\n <div style=\"flex:1;text-align: center;\">\n <p style=\"font-family: PingFangSC-Regular;font-size: 12px;color: #00B4FF;line-height: 12px;font-weight: 400;\">\u8BBE\u5907\u51C0\u6536\u5165</p>\n <div style=\"display:flex;justify-content: center;font-size:22px;font-family: DINCondensed-Bold;font-weight: 700;line-height: 22px;color: #00FAF9;margin-top:7px;\">").concat(formdataNumber(mapStatistics.totalPrice), "<span style=\"font-size:12px\">\u5143</span></div>\n </div>\n <div style=\"flex:1;text-align: center;\">\n <p style=\"font-family: PingFangSC-Regular;font-size: 12px;color: #00B4FF;line-height: 12px;font-weight: 400;\">\u7EFF\u8272\u6307\u6570</p>\n <div style=\"display:flex;justify-content: center;font-size:22px;font-family: DINCondensed-Bold;font-weight: 700;line-height: 22px;color: #00FAF9;margin-top:7px;\">100<span style=\"font-size:12px\">\u5206</span></div>\n </div>\n </div>\n\n <div style=\"display:flex;flex-direction:row;justify-content:space-between;padding-top:16px;border-top:1.2px dashed #4C63B6\">\n <p style=\"font-family: PingFangSC-Regular;font-size: 12px;color: #A8B2C1;line-height: 12px;font-weight: 400;\">\u8BBE\u5907\u72B6\u6001\u660E\u7EC6</p>\n <div style=\"width:120px\">\n <div style=\"display:flex;justify-content:space-between;font-family: PingFangSC-Regular;font-size: 12px; color: #FFFFFF;line-height: 12px;font-weight: 400;\">\n <span>\u4F7F\u7528\u4E2D</span>\n <span>").concat(formdataNumber(mapStatistics.deviceUseCount), " \u53F0</span>\n </div>\n <div style=\"display:flex;justify-content:space-between;font-family: PingFangSC-Regular;font-size: 12px; color: #FFFFFF;line-height: 12px;font-weight: 400;margin-top:8px;\">\n <span>\u7A7A\u95F2\u4E2D</span>\n <span>").concat(formdataNumber(mapStatistics.deviceFreeCount), " \u53F0</span>\n </div>\n <div style=\"display:flex;justify-content:space-between;font-family: PingFangSC-Regular;font-size: 12px; color: #FFFFFF;line-height: 12px;font-weight: 400;margin-top:8px;\">\n <span>\u6545\u969C\u4E2D</span>\n <span>").concat(formdataNumber(mapStatistics.deviceFaultCount), " \u53F0</span>\n </div>\n </div>\n </div>");
};
var tooltipElement = function tooltipElement(opt, mapStatistics) {
return "<div style=\"display:flex;flex-direction:column;background:url(".concat(tooltipBg, ") no-repeat;background-size:344px 211px;width:344px;height:211px;padding:10px 16px;\">\n <p style=\"font-size:14px;color:#F9F9F9;text-align: center;\">").concat(opt.name, "</p>\n <div style=\"display:flex;align-items:center;margin-top:15px;margin-bottom:10px;\">\n <div style=\"flex:1;text-align: center;\">\n <div style=\"font-family: PingFangSC-Regular;font-size: 12px;color: #00B4FF;line-height: 12px;font-weight: 400;\">\u56ED\u533A\u603B\u91CF</div>\n <div style=\"display:flex;justify-content: center;font-size:22px;font-family: DINCondensed-Bold;font-weight: 700;line-height: 22px;color: #00FAF9;margin-top:7px;\">").concat(formdataNumber(mapStatistics.parkCount), "<span style=\"font-size:12px\">\u4E2A</span></div>\n </div>\n <div style=\"flex:1;text-align: center;\">\n <div style=\"font-family: PingFangSC-Regular;font-size: 12px;color: #00B4FF;line-height: 12px;font-weight: 400;\">\u8BBE\u5907\u603B\u91CF</div>\n <div style=\"display:flex;justify-content: center;font-size:22px;font-family: DINCondensed-Bold;font-weight: 700;line-height: 22px;color: #00FAF9;margin-top:7px;\">").concat(formdataNumber(mapStatistics.deviceCount), "<span style=\"font-size:12px\">\u53F0</span></div>\n </div>\n <div style=\"flex:1;text-align: center;\">\n <p style=\"font-family: PingFangSC-Regular;font-size: 12px;color: #00B4FF;line-height: 12px;font-weight: 400;\">\u8BBE\u5907\u51C0\u6536\u5165</p>\n <div style=\"display:flex;justify-content: center;font-size:22px;font-family: DINCondensed-Bold;font-weight: 700;line-height: 22px;color: #00FAF9;margin-top:7px;\">").concat(formdataNumber(mapStatistics.totalPrice), "<span style=\"font-size:12px\">\u5143</span></div>\n </div>\n <div style=\"flex:1;text-align: center;\">\n <p style=\"font-family: PingFangSC-Regular;font-size: 12px;color: #00B4FF;line-height: 12px;font-weight: 400;\">\u7EFF\u8272\u6307\u6570</p>\n <div style=\"display:flex;justify-content: center;font-size:22px;font-family: DINCondensed-Bold;font-weight: 700;line-height: 22px;color: #00FAF9;margin-top:7px;\">100<span style=\"font-size:12px\">\u5206</span></div>\n </div>\n </div>\n\n <div style=\"display:flex;flex-direction:row;justify-content:space-around;padding-top:16px;border-top:1.2px dashed #4C63B6\">\n <div style=\"flex:2;text-align: center;padding:0 8px;\">\n <p style=\"font-family: PingFangSC-Regular;font-size: 12px;color: #A8B2C1;line-height: 12px;font-weight: 400;\">\u56ED\u533A\u72B6\u6001\u660E\u7EC6</p>\n <div style=\"margin-top:16px\">\n <div style=\"display:flex;justify-content:space-between;font-family: PingFangSC-Regular;font-size: 12px; color: #FFFFFF;line-height: 12px;font-weight: 400;margin-top:8px;\">\n <span>\u5B89\u88C5\u4E2D</span>\n <span>").concat(formdataNumber(mapStatistics.parkInstallingCount), " \u4E2A</span>\n </div>\n <div style=\"display:flex;justify-content:space-between;font-family: PingFangSC-Regular;font-size: 12px; color: #FFFFFF;line-height: 12px;font-weight: 400;margin-top:8px;\">\n <span>\u5EFA\u8BBE\u4E2D</span>\n <span>").concat(formdataNumber(mapStatistics.parkUnInstallCount), " \u4E2A</span>\n </div>\n <div style=\"display:flex;justify-content:space-between;font-family: PingFangSC-Regular;font-size: 12px; color: #FFFFFF;line-height: 12px;font-weight: 400;margin-top:8px;\">\n <span>\u5DF2\u5B8C\u6210</span>\n <span>").concat(formdataNumber(mapStatistics.parkInstalledCount), " \u4E2A</span>\n </div>\n </div>\n </div>\n\n <div style=\"flex:1\"></div>\n\n <div style=\"flex:2;text-align: center;padding:0 8px;\">\n <p style=\"font-family: PingFangSC-Regular;font-size: 12px;color: #A8B2C1;line-height: 12px;font-weight: 400;\">\u8BBE\u5907\u72B6\u6001\u660E\u7EC6</p>\n <div style=\"margin-top:16px\">\n <div style=\"display:flex;justify-content:space-between;font-family: PingFangSC-Regular;font-size: 12px; color: #FFFFFF;line-height: 12px;font-weight: 400;margin-top:8px;\">\n <span>\u4F7F\u7528\u4E2D</span>\n <span>").concat(formdataNumber(mapStatistics.deviceUseCount), " \u53F0</span>\n </div>\n <div style=\"display:flex;justify-content:space-between;font-family: PingFangSC-Regular;font-size: 12px; color: #FFFFFF;line-height: 12px;font-weight: 400;margin-top:8px;\">\n <span>\u7A7A\u95F2\u4E2D</span>\n <span>").concat(formdataNumber(mapStatistics.deviceFreeCount), " \u53F0</span>\n </div>\n <div style=\"display:flex;justify-content:space-between;font-family: PingFangSC-Regular;font-size: 12px; color: #FFFFFF;line-height: 12px;font-weight: 400;margin-top:8px;\">\n <span>\u6545\u969C\u4E2D</span>\n <span>").concat(formdataNumber(mapStatistics.deviceFaultCount), " \u53F0</span>\n </div>\n </div>\n </div>\n </div>");
};
var ChinaMap = function ChinaMap(_ref) {
var map = _ref.map,
park = _ref.park,
onChange = _ref.onChange,
customerMapClick = _ref.customerMapClick;
var mapEcharts = useRef(null);
var historyList = useRef([]);
var mapDataRef = useRef(map || {});
var _useState = useState({}),
_useState2 = _slicedToArray(_useState, 2),
forceRender = _useState2[1]; // 地图初始化
var initMap = function initMap(mapData, mapName, isInit) {
// 注册地图
echarts.registerMap(mapName, mapData); // 配置项
var options = {
tooltip: {},
geo: {
map: mapName,
roam: true,
animation: false,
tooltip: {
show: true,
backgroundColor: 'transport',
padding: 0,
borderWidth: 0,
formatter: function formatter(obj) {
var _a, _b;
var code = (_a = allAreaCode.find(function (fd) {
return fd.name === obj.name;
})) === null || _a === void 0 ? void 0 : _a.adcode;
if (!code) return null;
var mapStatistics = (_b = mapDataRef.current[code.toString()]) === null || _b === void 0 ? void 0 : _b.mapStatistics;
if (!mapStatistics) return null;
return tooltipElement(obj, mapStatistics);
}
},
label: {
show: true,
color: '#FFF'
},
// 地图样式
itemStyle: {
// 区域样式
areaColor: '#021863',
borderWidth: 1,
borderColor: '#426FF4',
shadowColor: '#013590',
shadowOffsetX: -2,
shadowOffsetY: 20,
shadowBlur: 30 // 文字块的背景阴影长度
},
// 选中状态下样式
emphasis: {
label: {
color: '#ffffff'
},
itemStyle: {
areaColor: '#314C9E'
}
}
},
series: [{
type: 'effectScatter',
coordinateSystem: 'geo',
data: [],
symbolSize: 5,
tooltip: {
show: true,
backgroundColor: 'transport',
padding: 0,
borderWidth: 0,
formatter: function formatter(obj) {
var _a;
if ((_a = obj === null || obj === void 0 ? void 0 : obj.data) === null || _a === void 0 ? void 0 : _a.parkName) {
return parkTooltipElement(obj, obj.data.mapStatistics);
}
return tooltipElement(obj, obj.data.mapStatistics);
}
}
}]
};
if (mapName === '中国') {
// @ts-ignore
options.geo.zoom = 1.6; // @ts-ignore
options.geo.top = 170;
}
mapEcharts.current.setOption(options, true);
!map && forceRender({});
!isInit && onChange && onChange(mapData, historyList.current); // mapEcharts.current.hideLoading();
};
useEffect(function () {
var initSetTimeout = setTimeout(function () {
var doc = document.getElementById('chinaMap');
if (doc) {
if (mapEcharts.current) {
mapEcharts.current.dispose(); // 销毁实例,实例销毁后无法再被使用。
} // 初始化图表
mapEcharts.current = echarts.init(doc);
historyList.current.push({
code: 'china',
name: '中国',
key: 'china'
});
mapEcharts.current.on('click', function (params) {
if (allAreaCode.filter(function (item) {
return item.name.indexOf(params.name) > -1;
})[0]) {
var areaCode = allAreaCode.filter(function (item) {
return item.name.indexOf(params.name) > -1;
})[0].adcode + '';
var level = allAreaCode.filter(function (item) {
return item.name.indexOf(params.name) > -1;
})[0].level;
if (customerMapClick) {
customerMapClick(Object.assign(Object.assign({}, params), {
areaCode: areaCode,
level: level
}), allAreaCode);
return;
}
if (areaCode == '100000') return;
if (historyList.current.find(function (fd) {
return fd.code === areaCode;
})) return;
getGeoJson(areaCode).then(function (data) {
initMap(data, areaCode);
}).catch(function () {
getGeoJson(areaCode).then(function (res) {
initMap(res, areaCode);
}).catch(function () {});
}); // 记录在哪一级
var key = 'china';
switch (level) {
case 'province':
key = 'provinceCode';
break;
case 'city':
key = 'cityCode';
break;
case 'district':
key = 'areaCode';
break;
}
historyList.current.push({
code: areaCode,
name: params.name,
key: key
});
var result = [];
var obj = {};
for (var i = 0; i < historyList.current.length; i++) {
if (!obj[historyList.current[i].code]) {
result.push(historyList.current[i]);
obj[historyList.current[i].code] = true;
}
}
historyList.current = result;
}
});
initMap(chinaGeoJson, '中国', true);
}
}, 0);
return function () {
clearTimeout(initSetTimeout);
};
}, []);
useMemo(function () {
var mapChangeTimeout = setTimeout(function () {
if (mapEcharts.current && mapEcharts.current.getOption && map) {
var options = mapEcharts.current.getOption();
var data = Object.values(map).map(function (item) {
var _a;
return {
value: [item.longitude, item.latitude],
itemStyle: {
color: ((_a = item === null || item === void 0 ? void 0 : item.parkName) === null || _a === void 0 ? void 0 : _a.includes('京东')) ? '#FFD649' : '#00D0D8'
},
name: item.areaName,
parkName: item.parkName,
mapStatistics: item.mapStatistics
};
});
mapDataRef.current = map;
var effectScatter = options.series.find(function (fd) {
return fd.type === 'effectScatter';
});
effectScatter.data = data;
mapEcharts.current.setOption && mapEcharts.current.setOption(options, true);
clearTimeout(mapChangeTimeout);
}
}, 0);
}, [map]);
var mapGoBack = _.debounce(function () {
// // 当双击事件发生时,清除单击事件,仅响应双击事件
if (historyList.current.length == 1) {
alert('已经到达最上一级地图了');
return;
}
historyList.current.pop();
if (historyList.current[historyList.current.length - 1].code == 'china') {
initMap(chinaGeoJson, '中国');
} else {
getGeoJson(historyList.current[historyList.current.length - 1].code).then(function (data) {
initMap(data, historyList.current[historyList.current.length - 1].code);
}).catch(function () {
getGeoJson(historyList.current[historyList.current.length - 1].code).then(function (res) {
initMap(res, historyList.current[historyList.current.length - 1].code);
}).catch(function () {});
});
}
}, 300);
var roamMap = function roamMap(flag) {
var option = mapEcharts.current.getOption();
var increaseAmplitude = 1.2; // 点击按钮每次 放大/缩小 比例
if (flag === 1) {
increaseAmplitude = 0.8;
}
option.geo[0].zoom = option.geo[0].zoom * increaseAmplitude; //下层geo的缩放等级跟着上层的geo一起改变
mapEcharts.current.setOption(option, true); //设置option
};
return /*#__PURE__*/React.createElement("div", {
className: "content-center-map"
}, historyList.current.length !== 1 ? /*#__PURE__*/React.createElement("div", {
className: "map-goback",
onClick: mapGoBack
}, "\u8FD4\u56DE") : null, /*#__PURE__*/React.createElement("div", {
className: "map-zoomBtn"
}, /*#__PURE__*/React.createElement("div", {
className: "zoom-add"
}, /*#__PURE__*/React.createElement("img", {
src: add,
onClick: function onClick() {
roamMap(0);
},
className: "btn-add"
})), /*#__PURE__*/React.createElement("div", {
className: "zoom-reduce"
}, /*#__PURE__*/React.createElement("img", {
src: reduce,
onClick: function onClick() {
roamMap(1);
},
className: "btn-reduce"
}))), /*#__PURE__*/React.createElement("div", {
id: "chinaMap"
}));
};
export default ChinaMap;