mirror of https://gitee.com/antv-l7/antv-l7
fix: 修改demo
This commit is contained in:
parent
9de2360085
commit
86c5f97534
|
@ -63,42 +63,12 @@ module.exports = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: {
|
name: {
|
||||||
zh: '地理可视分开发框架',
|
zh: 'Dipper 地理可视分开发框架',
|
||||||
en: 'Dipper',
|
en: 'Dipper',
|
||||||
},
|
},
|
||||||
url: 'http://antv.vision/Dipper',
|
url: 'http://antv.vision/Dipper',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
Dipper: [
|
|
||||||
{
|
|
||||||
name: {
|
|
||||||
zh: 'L7 React组件',
|
|
||||||
en: 'L7React L7 For React',
|
|
||||||
},
|
|
||||||
url: 'http://antv.vision/L7-react/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: {
|
|
||||||
zh: 'L7Draw 地理围栏绘制组件库',
|
|
||||||
en: 'L7Draw',
|
|
||||||
},
|
|
||||||
url: 'http://antv.vision/L7-draw/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: {
|
|
||||||
zh: 'L7Plot',
|
|
||||||
en: 'L7Plot',
|
|
||||||
},
|
|
||||||
url: 'http://antv.vision/L7-draw/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: {
|
|
||||||
zh: 'L7Boundary 行政区划可视化库',
|
|
||||||
en: 'L7Boundary',
|
|
||||||
},
|
|
||||||
url: 'http://antv.vision/L7-boundary/',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
docs: [
|
docs: [
|
||||||
{
|
{
|
||||||
slug: 'api/l7',
|
slug: 'api/l7',
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
|
||||||
import { Bar } from '@antv/g2plot';
|
|
||||||
|
|
||||||
export interface ChatData {
|
|
||||||
data: object[];
|
|
||||||
legend?: boolean;
|
|
||||||
loading?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function BarCahrt({ data }: ChatData) {
|
|
||||||
const id = useRef();
|
|
||||||
const [barplot, setBarplot] = useState<Bar>();
|
|
||||||
useEffect(() => {
|
|
||||||
if (!barplot && id.current) {
|
|
||||||
const bar = new Bar(id.current, {
|
|
||||||
// @ts-ignore
|
|
||||||
data: data.sort((a, b) => b.xField - a.xField),
|
|
||||||
autoFit: true,
|
|
||||||
xField: 'yField',
|
|
||||||
yField: 'xField',
|
|
||||||
xAxis: false,
|
|
||||||
label: {
|
|
||||||
position: 'left',
|
|
||||||
style: {
|
|
||||||
fill: '#fff',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
position: 'top-left',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
bar.render();
|
|
||||||
setBarplot(bar);
|
|
||||||
} else {
|
|
||||||
barplot.update({
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [id.current, data]);
|
|
||||||
|
|
||||||
return <div ref={id} style={{ height: 300 }} />;
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
|
||||||
import { Line } from '@antv/g2plot';
|
|
||||||
import { ChatData } from '../Bar';
|
|
||||||
import { Spin } from 'antd';
|
|
||||||
|
|
||||||
export function LineCahrt({ data, loading }: ChatData) {
|
|
||||||
const id = useRef();
|
|
||||||
const [lineplot, setLinePlot] = useState<Line>();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!lineplot && id.current && data) {
|
|
||||||
const lineplot = new Line(id.current, {
|
|
||||||
data,
|
|
||||||
autoFit: true,
|
|
||||||
xField: 'xField',
|
|
||||||
yField: 'yField',
|
|
||||||
seriesField: 'series',
|
|
||||||
legend: {
|
|
||||||
position: 'top-left',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
lineplot.render();
|
|
||||||
setLinePlot(lineplot);
|
|
||||||
} else {
|
|
||||||
lineplot.update({
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [id.current, data]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Spin spinning={loading}>
|
|
||||||
<div ref={id} style={{ height: 300 }} />
|
|
||||||
</Spin>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
|
||||||
import { Pie } from '@antv/g2plot';
|
|
||||||
import { ChatData } from '../Bar';
|
|
||||||
import { Spin } from 'antd';
|
|
||||||
|
|
||||||
export function PieChart({ data, legend, loading }: ChatData) {
|
|
||||||
const id = useRef();
|
|
||||||
const [pieplot, setPiePlot] = useState<Pie>();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!pieplot && id.current && data) {
|
|
||||||
const pie = new Pie(id.current, {
|
|
||||||
data,
|
|
||||||
autoFit: true,
|
|
||||||
angleField: 'xField',
|
|
||||||
colorField: 'yField',
|
|
||||||
radius: 0.7,
|
|
||||||
label: {
|
|
||||||
type: 'spider',
|
|
||||||
labelHeight: 28,
|
|
||||||
content: '{name}\n{percentage}',
|
|
||||||
},
|
|
||||||
legend: legend
|
|
||||||
? {
|
|
||||||
position: 'top-left',
|
|
||||||
}
|
|
||||||
: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
pie.render();
|
|
||||||
setPiePlot(pie);
|
|
||||||
} else {
|
|
||||||
pieplot.update({
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [id.current, data]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Spin spinning={loading}>
|
|
||||||
<div ref={id} style={{ height: 300 }} />
|
|
||||||
</Spin>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
|
||||||
import { Line } from '@antv/g2plot';
|
|
||||||
import { ChatData } from '../Bar';
|
|
||||||
|
|
||||||
export function SingleLineCahrt({ data }: ChatData) {
|
|
||||||
const id = useRef();
|
|
||||||
const [lineplot, setLinePlot] = useState<Line>();
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!lineplot && id.current && data) {
|
|
||||||
const area = new Line(id.current, {
|
|
||||||
data,
|
|
||||||
autoFit: true,
|
|
||||||
xField: 'xField',
|
|
||||||
yField: 'yField',
|
|
||||||
});
|
|
||||||
area.render();
|
|
||||||
setLinePlot(area);
|
|
||||||
}else{
|
|
||||||
lineplot.update({
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, [id.current,data]);
|
|
||||||
|
|
||||||
return <div ref={id} style={{height:300}}/>;
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
|
||||||
import { Area } from '@antv/g2plot';
|
|
||||||
import { ChatData } from '../Bar';
|
|
||||||
|
|
||||||
export function StackAreaCahrt({ data }: ChatData) {
|
|
||||||
const id = useRef();
|
|
||||||
const [pieplot, setAreaPlot] = useState<Area>();
|
|
||||||
const [list,setData] = useState([])
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
fetch('https://gw.alipayobjects.com/os/bmw-prod/b21e7336-0b3e-486c-9070-612ede49284e.json')
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((data) => {
|
|
||||||
setData(data);
|
|
||||||
});
|
|
||||||
},[])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!pieplot && id.current && list) {
|
|
||||||
const area = new Area(id.current, {
|
|
||||||
data:list,
|
|
||||||
autoFit: true,
|
|
||||||
xField: 'date',
|
|
||||||
yField: 'value',
|
|
||||||
seriesField: 'country',
|
|
||||||
legend:{
|
|
||||||
position:'top-left'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
area.render();
|
|
||||||
setAreaPlot(area);
|
|
||||||
}else{
|
|
||||||
pieplot.update({
|
|
||||||
data:list
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, [id.current,data]);
|
|
||||||
|
|
||||||
return <div ref={id} style={{height:300}}/>;
|
|
||||||
}
|
|
|
@ -1,154 +0,0 @@
|
||||||
import { IConfig, SingleSequentialColorScale } from '@antv/dipper';
|
|
||||||
import { CityList } from './mock';
|
|
||||||
export const config: Partial<IConfig> = {
|
|
||||||
viewData: {
|
|
||||||
global: {
|
|
||||||
filterData: [],
|
|
||||||
areaCode: '330100',
|
|
||||||
view: 'task',
|
|
||||||
},
|
|
||||||
widgets: {
|
|
||||||
citySelect: {
|
|
||||||
options: CityList,
|
|
||||||
value: ['330000', '330100'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
headerbar: {
|
|
||||||
display: true,
|
|
||||||
title: {
|
|
||||||
value: '数据分析',
|
|
||||||
display: true,
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'left',
|
|
||||||
title: '选择城市',
|
|
||||||
type: 'citySelect',
|
|
||||||
event: {
|
|
||||||
actionType: 'map',
|
|
||||||
action: 'queryArea',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: false,
|
|
||||||
position: 'right',
|
|
||||||
type: 'publishbar',
|
|
||||||
event: {
|
|
||||||
actionType: 'map',
|
|
||||||
action: 'publish',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
panel: {
|
|
||||||
display: true,
|
|
||||||
options: {
|
|
||||||
enableToggle: true,
|
|
||||||
defaultTitle: '所有网格',
|
|
||||||
opened: true,
|
|
||||||
width: 426,
|
|
||||||
},
|
|
||||||
position: 'right',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
type: 'meshName',
|
|
||||||
title: '网格名称',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
type: 'meshchart',
|
|
||||||
title: '所有网格数据',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: false,
|
|
||||||
type: 'panelTabContent',
|
|
||||||
title: '所有网格',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
type: 'mesh_indicator',
|
|
||||||
title: '业务数据',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'total_data_panel',
|
|
||||||
title: '人员数据',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
toolbar: {
|
|
||||||
display: false,
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
map: {
|
|
||||||
zoom: 10,
|
|
||||||
center: [120.153576, 30.287459],
|
|
||||||
pitch: 0,
|
|
||||||
style: 'normal',
|
|
||||||
},
|
|
||||||
controls: [
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'topleft',
|
|
||||||
type: 'filter',
|
|
||||||
title: '筛选',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'bottomright',
|
|
||||||
type: 'location',
|
|
||||||
title: '定位',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'bottomright',
|
|
||||||
type: 'mapStyle',
|
|
||||||
title: '地图样式',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'topleft',
|
|
||||||
type: 'searchPlaces',
|
|
||||||
title: '地区搜索',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
defaultcontrols: [
|
|
||||||
{
|
|
||||||
type: 'zoom',
|
|
||||||
position: 'bottomright',
|
|
||||||
display: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'scale',
|
|
||||||
position: 'bottomleft',
|
|
||||||
display: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
popup: {
|
|
||||||
enable: false,
|
|
||||||
},
|
|
||||||
layers: [
|
|
||||||
{
|
|
||||||
type: 'gridLayer',
|
|
||||||
options: {
|
|
||||||
label: {
|
|
||||||
field: 'name',
|
|
||||||
size: 12,
|
|
||||||
color: '#000',
|
|
||||||
},
|
|
||||||
fill: {
|
|
||||||
field: 'unit_price',
|
|
||||||
color: ['#A9D3FF', '#82B1FF', '#6294FF', '#457BFF', '#2962FF'],
|
|
||||||
bandNum: 5,
|
|
||||||
scale: 'quantile',
|
|
||||||
unknownName: '无类型',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
legends: [],
|
|
||||||
};
|
|
|
@ -1,267 +0,0 @@
|
||||||
import Mock from 'mockjs';
|
|
||||||
|
|
||||||
// 单折线图
|
|
||||||
export const singleLineChart = () => {
|
|
||||||
const data = Mock.mock({
|
|
||||||
'list|9': [
|
|
||||||
{
|
|
||||||
// 生成长度在 100~1000 之间的小写字母
|
|
||||||
yField: '@integer(0,5000)',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
return data.list
|
|
||||||
.sort((a, b) => a.yField - b.yField)
|
|
||||||
.map((item, index) => {
|
|
||||||
return {
|
|
||||||
xField: `${index + 1}月`,
|
|
||||||
...item,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 条形图
|
|
||||||
export const barChart = () => {
|
|
||||||
let xField = ['餐饮', '影院', '百货购物中心', '国内旅游', '医疗'];
|
|
||||||
const data = Mock.mock({
|
|
||||||
'list|5': [
|
|
||||||
{
|
|
||||||
// 生成长度在 100~1000 之间的小写字母
|
|
||||||
yField: '@integer(0,5000)',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
return data.list
|
|
||||||
.sort((a, b) => b.yField - a.yField)
|
|
||||||
.map((item, index) => {
|
|
||||||
return {
|
|
||||||
xField: xField[index],
|
|
||||||
...item,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 多维折线图
|
|
||||||
export const multidimensionalChart = () => {
|
|
||||||
const series = ['铺设失败', '铺设中', '铺设成功', '虚假铺设'];
|
|
||||||
const xField = new Array(12).fill('').map((item, index) => {
|
|
||||||
return `${2 * index + 2}:00`;
|
|
||||||
});
|
|
||||||
|
|
||||||
return series
|
|
||||||
.map((a, k) => {
|
|
||||||
return xField.map((b, index) => {
|
|
||||||
return {
|
|
||||||
xField: b,
|
|
||||||
series: a,
|
|
||||||
yField: Number(
|
|
||||||
((index + 1) * 10 + 20 * Math.random() + k * 20).toFixed(),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.flat();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 作业单数
|
|
||||||
export const operation = () => {
|
|
||||||
const data = Mock.mock({
|
|
||||||
'list|15': [
|
|
||||||
{
|
|
||||||
name: '@cname',
|
|
||||||
order_count: '@integer(0,100)',
|
|
||||||
staff_no: '@integer(100000,1000000)',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
return data.list;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 行业市场份额
|
|
||||||
export const marketShare = () => {
|
|
||||||
const data = Mock.mock({
|
|
||||||
'list|3': [
|
|
||||||
{
|
|
||||||
// 生成长度在 100~1000 之间的小写字母
|
|
||||||
xField: '@integer(0,100)',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
const yField = ['街电', '怪兽', '小电'];
|
|
||||||
return data.list
|
|
||||||
.sort((a, b) => a.yField - b.yField)
|
|
||||||
.map((item, index) => {
|
|
||||||
return {
|
|
||||||
yField: yField[index],
|
|
||||||
...item,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 各品牌营收
|
|
||||||
export const brandRevenue = () => {
|
|
||||||
const series = ['街电', '来电', '怪兽', '美团', '小电'];
|
|
||||||
const xField = new Array(11).fill('').map((item, index) => {
|
|
||||||
return `${2009 + index}`;
|
|
||||||
});
|
|
||||||
|
|
||||||
return series
|
|
||||||
.map((a, k) => {
|
|
||||||
return xField.map((b, index) => {
|
|
||||||
return {
|
|
||||||
xField: b,
|
|
||||||
series: a,
|
|
||||||
yField: Number(
|
|
||||||
((index + 1) * 10 + 30 * Math.random() + k * 20).toFixed(),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.flat();
|
|
||||||
};
|
|
||||||
|
|
||||||
export function randomData<T>(data: T): Promise<T> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve(data);
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成范围内的随机数
|
|
||||||
export const randomNumBoth = (min: number, max: number) => {
|
|
||||||
const Range = max - min;
|
|
||||||
const Rand = Math.random();
|
|
||||||
const num = min + Math.round(Rand * Range);
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const brandOption = [
|
|
||||||
{ label: '全部类型', value: '1' },
|
|
||||||
{ label: '街电', value: '2' },
|
|
||||||
{ label: '怪兽', value: '3' },
|
|
||||||
{ label: '小电', value: '4' },
|
|
||||||
];
|
|
||||||
|
|
||||||
export const CityList = [
|
|
||||||
{
|
|
||||||
value: '330000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '浙江省',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
value: '330100',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '杭州市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '110000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '北京市',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
value: '110000',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '北京市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '120000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '天津市',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
value: '120000',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '天津市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '310000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '上海市',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
value: '310000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '上海市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '440000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '广东省',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
value: '440100',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '广州市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '440300',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '深圳市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '440400',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '珠海市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '440600',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '佛山市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '441300',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '惠州市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '441900',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '东莞市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '442000',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '中山市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '130000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '河北省',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
value: '130100',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '石家庄市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '131000',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '廊坊市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
|
@ -1,27 +0,0 @@
|
||||||
import { initWidgets } from './widgets';
|
|
||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import { config } from './configs/config';
|
|
||||||
import { DipperContainer, IConfig } from '@antv/dipper';
|
|
||||||
import 'antd/dist/antd.css'
|
|
||||||
interface IInitData {
|
|
||||||
areaVOList: any[];
|
|
||||||
sceneCode: string;
|
|
||||||
areaCode: string;
|
|
||||||
filterData: any[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function RumbMap() {
|
|
||||||
const [mapConfig, setMapConfig] = useState<IConfig<IInitData>>();
|
|
||||||
// 初始化相关数据
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
initWidgets();
|
|
||||||
setMapConfig(config);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ height: '100%',width:'100%',position:'absolute' }}>
|
|
||||||
<DipperContainer<IInitData> cfg={mapConfig!} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
import { Select } from 'antd';
|
|
||||||
import React from 'react';
|
|
||||||
import { useConfigService } from '@antv/dipper';
|
|
||||||
import { brandOption } from '../configs/mock';
|
|
||||||
|
|
||||||
const { Option } = Select;
|
|
||||||
|
|
||||||
export const Filter = () => {
|
|
||||||
const { setWidgetsValue } = useConfigService();
|
|
||||||
|
|
||||||
const onBrandChange = (e: any) => {
|
|
||||||
setWidgetsValue('brand', e);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ background: '#fff', borderRadius: 3 }}>
|
|
||||||
<Select
|
|
||||||
defaultValue="全部地区"
|
|
||||||
style={{ width: 100, color: 'rgba(0,0,0,0.65)' }}
|
|
||||||
bordered={false}
|
|
||||||
>
|
|
||||||
<Option value="全部地区">全部地区</Option>
|
|
||||||
<Option value="示例地区1">示例地区1</Option>
|
|
||||||
<Option value="示例地区2">示例地区2</Option>
|
|
||||||
</Select>
|
|
||||||
<Select
|
|
||||||
defaultValue="1"
|
|
||||||
style={{ width: 100, color: 'rgba(0,0,0,0.65)' }}
|
|
||||||
bordered={false}
|
|
||||||
onChange={(e) => onBrandChange(e)}
|
|
||||||
>
|
|
||||||
{brandOption.map((item) => {
|
|
||||||
return (
|
|
||||||
<Option key={item.label} value={item.value}>
|
|
||||||
{item.label}
|
|
||||||
</Option>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -1,140 +0,0 @@
|
||||||
import {
|
|
||||||
useSceneService,
|
|
||||||
useConfigService,
|
|
||||||
LayerGroupEventEnum,
|
|
||||||
useLayerService,
|
|
||||||
} from '@antv/dipper';
|
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
|
||||||
import { GridLayerGroup } from '@antv/dipper';
|
|
||||||
import { randomNumBoth } from '../configs/mock';
|
|
||||||
const formatLegend = (data: any[]) => {
|
|
||||||
return data.map((item) => {
|
|
||||||
if (Array.isArray(item.value)) {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
value: item.value.map((v) => v.toFixed(2)),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
value: item.value.toFixed(2),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
export function GridLayer() {
|
|
||||||
const { layerService } = useLayerService();
|
|
||||||
const { sceneService } = useSceneService();
|
|
||||||
const { globalConfig, updateLegend, getWidgetsValue } = useConfigService();
|
|
||||||
const { layers } = globalConfig;
|
|
||||||
const [gridLayer, setGridLayer] = useState<GridLayerGroup>();
|
|
||||||
const cityValue = getWidgetsValue('citySelect');
|
|
||||||
const brandValue = getWidgetsValue('brand');
|
|
||||||
const [geoData, setGeoData] = useState();
|
|
||||||
|
|
||||||
const layerProps = useMemo(() => {
|
|
||||||
return layers.find((item: any) => item.type === 'gridLayer');
|
|
||||||
}, [layers]);
|
|
||||||
|
|
||||||
const updateLayerLegend = (items: any[]) => {
|
|
||||||
updateLegend('gridLayerLegend', {
|
|
||||||
type: 'classifyColor',
|
|
||||||
display: true,
|
|
||||||
position: 'bottomleft',
|
|
||||||
options: {
|
|
||||||
title: '充电宝投放数量',
|
|
||||||
unkownName: layerProps.options.unkownName,
|
|
||||||
items: items.map((item) => {
|
|
||||||
return {
|
|
||||||
color: item.color,
|
|
||||||
value: item.value.map((v) => {
|
|
||||||
return (v / 10000).toFixed(2);
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 根据筛选器条件请求数据
|
|
||||||
useEffect(() => {
|
|
||||||
// 可以根据业务需求配置接口
|
|
||||||
fetch(
|
|
||||||
`https://gw.alipayobjects.com/os/antvdemo/assets/dipper-city/${cityValue[1]}.json`,
|
|
||||||
)
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((data) => {
|
|
||||||
const geoDataList =
|
|
||||||
data &&
|
|
||||||
data.features?.map((item) => {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
properties: {
|
|
||||||
...item.properties,
|
|
||||||
brand_type: randomNumBoth(1, 4).toString(), // 充电宝品牌
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// 品牌 过滤
|
|
||||||
if (brandValue && geoDataList) {
|
|
||||||
// @ts-ignore
|
|
||||||
const data =
|
|
||||||
brandValue === '1'
|
|
||||||
? geoDataList
|
|
||||||
: geoDataList.filter(
|
|
||||||
(item) => item.properties.brand_type === brandValue,
|
|
||||||
);
|
|
||||||
if (data.length) {
|
|
||||||
// @ts-ignore
|
|
||||||
setGeoData({ type: 'FeatureCollection', features: data });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// @ts-ignore
|
|
||||||
setGeoData({ type: 'FeatureCollection', features: geoDataList });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 切换城市 高德地图方法
|
|
||||||
sceneService.getScene().map?.setCity(cityValue[1]);
|
|
||||||
}, [JSON.stringify(cityValue), brandValue]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!geoData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (gridLayer) {
|
|
||||||
gridLayer.setData(geoData);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const layer = new GridLayerGroup({
|
|
||||||
name: 'grid',
|
|
||||||
data: geoData,
|
|
||||||
options: layerProps.options,
|
|
||||||
});
|
|
||||||
layerService.addLayer(layer);
|
|
||||||
|
|
||||||
layer.on(LayerGroupEventEnum.DATAUPDATE, () => {
|
|
||||||
layer.getLegendItem().map((item) => {
|
|
||||||
if (Array.isArray(item.value)) {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
value: item.value.map((v) => v.toFixed(2)),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
value: item.value.toFixed(2),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
updateLayerLegend(formatLegend(layer.getLegendItem()));
|
|
||||||
});
|
|
||||||
|
|
||||||
// 更新图例
|
|
||||||
updateLayerLegend(formatLegend(layer.getLegendItem()));
|
|
||||||
|
|
||||||
setGridLayer(layer);
|
|
||||||
}, [geoData]);
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import { useLayerGroup } from '@antv/dipper';
|
|
||||||
import { brandRevenue, marketShare } from '../../configs/mock';
|
|
||||||
import { PieChart } from '../../components/Pie';
|
|
||||||
import { LineCahrt } from '../../components/Line';
|
|
||||||
|
|
||||||
export function MeshChart() {
|
|
||||||
const { selectFeatures } = useLayerGroup('grid');
|
|
||||||
const [pieData, setPieData] = useState([]);
|
|
||||||
const [lineData, setLineData] = useState([]);
|
|
||||||
const [loding, setLoding] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setLoding(true);
|
|
||||||
setTimeout(() => {
|
|
||||||
setLoding(false);
|
|
||||||
setPieData(marketShare());
|
|
||||||
setLineData(brandRevenue());
|
|
||||||
}, 300);
|
|
||||||
}, [JSON.stringify(selectFeatures)]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ padding: '0 15px' }}>
|
|
||||||
<div>
|
|
||||||
<h4>行业市场份额</h4>
|
|
||||||
<PieChart data={pieData || []} legend={false} loading={loding} />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h4>各品牌营收</h4>
|
|
||||||
<LineCahrt data={lineData} loading={loding} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
|
||||||
import { useLayerGroup } from '@antv/dipper';
|
|
||||||
import { SingleLineCahrt } from '../components/SingleLine';
|
|
||||||
import { singleLineChart, barChart } from '../configs/mock';
|
|
||||||
import { BarCahrt } from '../components/Bar';
|
|
||||||
|
|
||||||
export function MeshIndicator() {
|
|
||||||
const { selectFeatures } = useLayerGroup('grid');
|
|
||||||
|
|
||||||
// lineChart
|
|
||||||
const [lineData, setLineData] = useState([]);
|
|
||||||
|
|
||||||
const [barData, setBarData] = useState([]);
|
|
||||||
|
|
||||||
// lineChart
|
|
||||||
useEffect(() => {
|
|
||||||
setLineData(singleLineChart());
|
|
||||||
setBarData(barChart());
|
|
||||||
}, [JSON.stringify(selectFeatures)]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ overflow: 'auto', height:'630px'}}>
|
|
||||||
<div>
|
|
||||||
<div style={{ margin: '10px 0' }}>交易笔数</div>
|
|
||||||
<SingleLineCahrt data={lineData} />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div style={{ margin: '20px 0' }}>各场景覆盖数</div>
|
|
||||||
<BarCahrt data={barData} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
.meahname {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
.closeicon {
|
|
||||||
padding: 0 8px;
|
|
||||||
}
|
|
||||||
.edit {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.edit span:hover {
|
|
||||||
color: #1890ff;
|
|
||||||
}
|
|
|
@ -1,106 +0,0 @@
|
||||||
import React, {
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
useMemo,
|
|
||||||
useCallback,
|
|
||||||
useEffect,
|
|
||||||
} from 'react';
|
|
||||||
import { CheckOutlined, CloseOutlined, EditOutlined } from '@ant-design/icons';
|
|
||||||
import styles from './index.module.css'
|
|
||||||
import { Input } from 'antd';
|
|
||||||
import { useLayerGroup, useConfigService } from '@antv/dipper';
|
|
||||||
import _ from 'loadsh';
|
|
||||||
|
|
||||||
export function MeshName() {
|
|
||||||
const { selectFeatures, updateProperties } = useLayerGroup('grid');
|
|
||||||
const [edit, setEdit] = useState(false);
|
|
||||||
const ref = useRef();
|
|
||||||
const { setConfig } = useConfigService();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get meshname
|
|
||||||
* type []string
|
|
||||||
*/
|
|
||||||
const meshName = useMemo(() => {
|
|
||||||
if (!selectFeatures.length) return [];
|
|
||||||
return selectFeatures.map((item) => {
|
|
||||||
// @ts-ignore
|
|
||||||
return item.feature.properties.name;
|
|
||||||
});
|
|
||||||
}, [JSON.stringify(selectFeatures)]);
|
|
||||||
|
|
||||||
// 修改 网格名称
|
|
||||||
const editMeshName = useCallback(() => {
|
|
||||||
// @ts-ignore
|
|
||||||
const value = ref.current.state.value;
|
|
||||||
selectFeatures.forEach((item) => {
|
|
||||||
const properties = {
|
|
||||||
...item.feature.properties,
|
|
||||||
name: value,
|
|
||||||
};
|
|
||||||
updateProperties(item.feature, properties);
|
|
||||||
});
|
|
||||||
setEdit(false);
|
|
||||||
}, [JSON.stringify(selectFeatures)]);
|
|
||||||
|
|
||||||
// select more meshname 编辑 网格名称
|
|
||||||
const EditMeshName = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{!edit ? (
|
|
||||||
<div onClick={() => setEdit(!edit)}>
|
|
||||||
<span>{meshName}</span>
|
|
||||||
<EditOutlined style={{ paddingLeft: 12 }} />
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className={styles.edit}>
|
|
||||||
<Input defaultValue={meshName} ref={ref} />
|
|
||||||
<CheckOutlined
|
|
||||||
onClick={editMeshName}
|
|
||||||
className={styles.closeicon}
|
|
||||||
/>
|
|
||||||
<CloseOutlined onClick={() => setEdit(false)} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// show 多个网格名称
|
|
||||||
const ShowMeshNames = () => {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: 15 }}>
|
|
||||||
{meshName.length >= 2 &&
|
|
||||||
meshName.map((s) => {
|
|
||||||
return <span key={s}>
|
|
||||||
{s}、
|
|
||||||
</span>;
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (selectFeatures.length) {
|
|
||||||
// TODO 报错
|
|
||||||
setConfig(`panel.children.1.display`, false);
|
|
||||||
setConfig(`panel.children.2.display`, true);
|
|
||||||
// setConfig(`panel.children.${findIdMeshchart}.display`, false)
|
|
||||||
} else {
|
|
||||||
setConfig(`panel.children.1.display`, true);
|
|
||||||
setConfig(`panel.children.2.display`, false);
|
|
||||||
}
|
|
||||||
}, [JSON.stringify(selectFeatures)]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{meshName && meshName.length ? (
|
|
||||||
<div className={styles.meahname}>
|
|
||||||
{meshName.length === 1 ? <EditMeshName /> : <ShowMeshNames />}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<h4 style={{ padding: 15 }}>所有网格数据概览</h4>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
.teamcontainer {
|
|
||||||
margin: 10px 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
.orderlist {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
height: 48px;
|
|
||||||
width: 378px;
|
|
||||||
background: #fafafa;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 0 5px;
|
|
||||||
}
|
|
||||||
.orderlist .leftpart {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.orderlist .leftpart > div {
|
|
||||||
padding-right: 15px;
|
|
||||||
}
|
|
||||||
.orderlist .leftpart .ordericon {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
.sort:hover {
|
|
||||||
color: #1e73f8;
|
|
||||||
}
|
|
||||||
.orderCon :global .ant-list-split .ant-list-item {
|
|
||||||
border: none !important;
|
|
||||||
}
|
|
||||||
.orderCon :global .ant-list-item {
|
|
||||||
padding: 5px 0 !important;
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
|
||||||
import { useLayerGroup } from '@antv/dipper'
|
|
||||||
import { Button, List } from 'antd';
|
|
||||||
import { multidimensionalChart, operation } from '../../configs/mock';
|
|
||||||
import styles from './index.module.css'
|
|
||||||
import { LineCahrt } from '../../components/Line';
|
|
||||||
|
|
||||||
enum Sort {
|
|
||||||
Up,
|
|
||||||
Dowm,
|
|
||||||
}
|
|
||||||
|
|
||||||
const No1 =
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_58ab56/afts/img/A*grCBQ4izMjcAAAAAAAAAAAAAARQnAQ';
|
|
||||||
const No2 =
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_58ab56/afts/img/A*r0DyQIluJ8QAAAAAAAAAAAAAARQnAQ';
|
|
||||||
const No3 =
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_58ab56/afts/img/A*5R92QrzHW7YAAAAAAAAAAAAAARQnAQ';
|
|
||||||
|
|
||||||
export function TotalPanel() {
|
|
||||||
const { selectFeatures = [] } = useLayerGroup('grid');
|
|
||||||
|
|
||||||
const [lineData, setLineData] = useState([]);
|
|
||||||
const [orderData, setOrderData] = useState([]);
|
|
||||||
const [ordersort, setOrderSort] = useState<Sort>(1);
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
|
|
||||||
// lineChart
|
|
||||||
useEffect(() => {
|
|
||||||
setLoading(true)
|
|
||||||
setTimeout(()=>{
|
|
||||||
setLoading(false)
|
|
||||||
setLineData(multidimensionalChart());
|
|
||||||
},300)
|
|
||||||
}, [JSON.stringify(selectFeatures)]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (ordersort === undefined) {
|
|
||||||
return setOrderData(operation());
|
|
||||||
}
|
|
||||||
const sortData = operation();
|
|
||||||
if (ordersort === 0) {
|
|
||||||
return setOrderData(
|
|
||||||
sortData.sort((a, b) => a.order_count - b.order_count),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (ordersort === 1) {
|
|
||||||
return setOrderData(
|
|
||||||
sortData.sort((a, b) => b.order_count - a.order_count),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [selectFeatures, ordersort]);
|
|
||||||
|
|
||||||
// 排序
|
|
||||||
const sorts = (type: Sort) => {
|
|
||||||
setOrderSort(type);
|
|
||||||
};
|
|
||||||
|
|
||||||
// orderData index 与 icon 映射
|
|
||||||
const iconOrder = { 1: No1, 2: No2, 3: No3 };
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ overflow: 'auto', height:'560px'}}>
|
|
||||||
<div>
|
|
||||||
<h4>铺设进程</h4>
|
|
||||||
<LineCahrt data={lineData} loading={loading}/>
|
|
||||||
</div>
|
|
||||||
<div className={styles.orderCon}>
|
|
||||||
<div className={styles.teamcontainer}>
|
|
||||||
<div>团队榜单</div>
|
|
||||||
<div>
|
|
||||||
<Button
|
|
||||||
type={ordersort === 1 ? 'link' : 'text'}
|
|
||||||
className={styles.sort}
|
|
||||||
onClick={() => sorts(1)}
|
|
||||||
>
|
|
||||||
正序
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type={ordersort === 0 ? 'link' : 'text'}
|
|
||||||
className={styles.sort}
|
|
||||||
onClick={() => sorts(0)}
|
|
||||||
>
|
|
||||||
倒叙
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{orderData && (
|
|
||||||
<List
|
|
||||||
dataSource={orderData}
|
|
||||||
renderItem={(item, index) => (
|
|
||||||
<List.Item>
|
|
||||||
<div className={styles.orderlist}>
|
|
||||||
<div className={styles.leftpart}>
|
|
||||||
{index <= 2 ? (
|
|
||||||
<img
|
|
||||||
src={iconOrder[index + 1]}
|
|
||||||
className={styles.ordericon}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<div>{index + 1}</div>
|
|
||||||
)}
|
|
||||||
<span>
|
|
||||||
{item.name}({item.staff_no})
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div>作业成功{item.order_count}单</div>
|
|
||||||
</div>
|
|
||||||
</List.Item>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
import { registerWidget } from '@antv/dipper-core';
|
|
||||||
import {
|
|
||||||
CitySelect,
|
|
||||||
NavBar,
|
|
||||||
ClassifyColor,
|
|
||||||
DiscreteColor,
|
|
||||||
Draw,
|
|
||||||
MapStyle,
|
|
||||||
SearchPlace,
|
|
||||||
Location,
|
|
||||||
} from '@antv/dipper-widgets';
|
|
||||||
import { GridLayer } from './GridLayer';
|
|
||||||
import { MeshIndicator } from './MeshIndicator';
|
|
||||||
import { MeshName } from './MeshName';
|
|
||||||
import { Filter } from './Filter';
|
|
||||||
import { TotalPanel } from './TotalPanel/index';
|
|
||||||
import { MeshChart } from './MeshChart';
|
|
||||||
|
|
||||||
export function initWidgets() {
|
|
||||||
registerWidget('citySelect', CitySelect);
|
|
||||||
registerWidget('navibar', NavBar);
|
|
||||||
registerWidget('gridLayer', GridLayer);
|
|
||||||
registerWidget('classifyColor', ClassifyColor);
|
|
||||||
registerWidget('discreteColor', DiscreteColor);
|
|
||||||
registerWidget('mapStyle', MapStyle);
|
|
||||||
registerWidget('searchPlaces', SearchPlace);
|
|
||||||
registerWidget('location', Location);
|
|
||||||
registerWidget('filter', Filter);
|
|
||||||
registerWidget('mesh_indicator', MeshIndicator);
|
|
||||||
registerWidget('total_data_panel', TotalPanel);
|
|
||||||
registerWidget('meshchart', MeshChart);
|
|
||||||
registerWidget('draw', Draw);
|
|
||||||
registerWidget('meshName',MeshName)
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
|
||||||
import { Bar } from '@antv/g2plot';
|
|
||||||
|
|
||||||
export interface ChatData {
|
|
||||||
data: object[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function BarChart({ data }: ChatData) {
|
|
||||||
const id = useRef();
|
|
||||||
const [barplot, setBarplot] = useState<Bar>();
|
|
||||||
useEffect(() => {
|
|
||||||
if (!barplot && id.current) {
|
|
||||||
const bar = new Bar(id.current, {
|
|
||||||
// @ts-ignore
|
|
||||||
data: data.sort((a, b) => b.xField - a.xField),
|
|
||||||
autoFit: true,
|
|
||||||
xField: 'xField',
|
|
||||||
yField: 'yField',
|
|
||||||
xAxis: false,
|
|
||||||
label: {
|
|
||||||
position: 'left',
|
|
||||||
style: {
|
|
||||||
fill: '#fff',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
position: 'top-left',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
bar.render();
|
|
||||||
setBarplot(bar);
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return <div ref={id} style={{ height: 300 }} />;
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
|
||||||
import { Line } from '@antv/g2plot';
|
|
||||||
import { ChatData } from '../Bar';
|
|
||||||
|
|
||||||
export function LineChart({ data }: ChatData) {
|
|
||||||
const id = useRef();
|
|
||||||
const [lineplot, setLinePlot] = useState<Line>();
|
|
||||||
const [list, setData] = useState([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetch(
|
|
||||||
'https://gw.alipayobjects.com/os/bmw-prod/b21e7336-0b3e-486c-9070-612ede49284e.json',
|
|
||||||
)
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((data) => {
|
|
||||||
setData(data);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!lineplot && id.current && list) {
|
|
||||||
const area = new Line(id.current, {
|
|
||||||
data: list,
|
|
||||||
autoFit: true,
|
|
||||||
xField: 'date',
|
|
||||||
yField: 'value',
|
|
||||||
seriesField: 'country',
|
|
||||||
legend: {
|
|
||||||
position: 'top-left',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
area.render();
|
|
||||||
setLinePlot(area);
|
|
||||||
} else {
|
|
||||||
lineplot.update({
|
|
||||||
data: list,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [id.current, list]);
|
|
||||||
|
|
||||||
return <div ref={id} style={{ height: 300 }} />;
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
|
||||||
import { Pie } from '@antv/g2plot';
|
|
||||||
import { ChatData } from '../Bar';
|
|
||||||
|
|
||||||
export function PieChart({ data }: ChatData) {
|
|
||||||
const id = useRef();
|
|
||||||
const [pieplot, setPiePlot] = useState<Pie>();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!pieplot && id.current && data) {
|
|
||||||
const bar = new Pie(id.current, {
|
|
||||||
data,
|
|
||||||
autoFit: true,
|
|
||||||
angleField: 'xField',
|
|
||||||
colorField: 'yField',
|
|
||||||
radius: 0.7,
|
|
||||||
label: {
|
|
||||||
type: 'spider',
|
|
||||||
labelHeight: 28,
|
|
||||||
content: '{name}\n{percentage}',
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
position: 'top-left',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
bar.render();
|
|
||||||
setPiePlot(bar);
|
|
||||||
}
|
|
||||||
}, [id.current, data]);
|
|
||||||
|
|
||||||
return <div ref={id} style={{ height: 300 }} />;
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
|
||||||
import { Area } from '@antv/g2plot';
|
|
||||||
import { ChatData } from '../Bar';
|
|
||||||
|
|
||||||
export function StackAreaChart({ data }: ChatData) {
|
|
||||||
const id = useRef();
|
|
||||||
const [pieplot, setAreaPlot] = useState<Area>();
|
|
||||||
const [list, setData] = useState([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetch(
|
|
||||||
'https://gw.alipayobjects.com/os/bmw-prod/b21e7336-0b3e-486c-9070-612ede49284e.json',
|
|
||||||
)
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((data) => {
|
|
||||||
setData(data);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!pieplot && id.current && list) {
|
|
||||||
const area = new Area(id.current, {
|
|
||||||
data: list,
|
|
||||||
autoFit: true,
|
|
||||||
xField: 'date',
|
|
||||||
yField: 'value',
|
|
||||||
seriesField: 'country',
|
|
||||||
legend: {
|
|
||||||
position: 'top-left',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
area.render();
|
|
||||||
setAreaPlot(area);
|
|
||||||
} else {
|
|
||||||
pieplot.update({
|
|
||||||
data: list,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [id.current, data]);
|
|
||||||
|
|
||||||
return <div ref={id} style={{ height: 300 }} />;
|
|
||||||
}
|
|
|
@ -1,168 +0,0 @@
|
||||||
import { IConfig, SingleSequentialColorScale } from '@antv/dipper';
|
|
||||||
import { CityList } from './mock';
|
|
||||||
export const config: Partial<IConfig> = {
|
|
||||||
viewData: {
|
|
||||||
global: {
|
|
||||||
filterData: [],
|
|
||||||
areaCode: '110000',
|
|
||||||
view: 'task',
|
|
||||||
},
|
|
||||||
widgets: {
|
|
||||||
citySelect: {
|
|
||||||
options: CityList,
|
|
||||||
value: ['110000', '110000'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
headerbar: {
|
|
||||||
display: true,
|
|
||||||
title: {
|
|
||||||
value: 'XX 管理地图地图',
|
|
||||||
display: true,
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'left',
|
|
||||||
title: '选择城市',
|
|
||||||
type: 'citySelect',
|
|
||||||
event: {
|
|
||||||
actionType: 'map',
|
|
||||||
action: 'queryArea',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
panel: {
|
|
||||||
display: true,
|
|
||||||
|
|
||||||
position: 'right',
|
|
||||||
options: {
|
|
||||||
enableToggle: true,
|
|
||||||
defaultTitle: '所有网格',
|
|
||||||
opened: true,
|
|
||||||
width: 426,
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
type: 'meshName',
|
|
||||||
title: '网格名称',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
type: 'activityTask',
|
|
||||||
title: '活动任务',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
toolbar: {
|
|
||||||
display: true,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'left',
|
|
||||||
title: '全部活动',
|
|
||||||
type: 'activity',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'left',
|
|
||||||
title: '全部状态',
|
|
||||||
type: 'status',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'left',
|
|
||||||
title: '地图展示',
|
|
||||||
type: 'mapExhibit',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'left',
|
|
||||||
title: '人员搜索',
|
|
||||||
type: 'searchPerson',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'right',
|
|
||||||
title: '保存',
|
|
||||||
type: 'save',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'right',
|
|
||||||
type: 'publishbar',
|
|
||||||
title: '发布',
|
|
||||||
event: {
|
|
||||||
actionType: 'map',
|
|
||||||
action: 'publish',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
map: {
|
|
||||||
zoom: 10,
|
|
||||||
center: [120.153576, 30.287459],
|
|
||||||
pitch: 0,
|
|
||||||
style: 'normal',
|
|
||||||
},
|
|
||||||
controls: [
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'bottomright',
|
|
||||||
type: 'mapStyle',
|
|
||||||
title: '地图样式',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'rightcenter',
|
|
||||||
type: 'meshTools',
|
|
||||||
title: '网格工具',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
display: true,
|
|
||||||
position: 'bottomright',
|
|
||||||
type: 'location',
|
|
||||||
title: '定位',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
defaultcontrols: [
|
|
||||||
{
|
|
||||||
type: 'zoom',
|
|
||||||
position: 'bottomright',
|
|
||||||
display: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'scale',
|
|
||||||
position: 'bottomleft',
|
|
||||||
display: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
popup: {
|
|
||||||
enable: false,
|
|
||||||
},
|
|
||||||
layers: [
|
|
||||||
{
|
|
||||||
type: 'gridLayer',
|
|
||||||
options: {
|
|
||||||
label: {
|
|
||||||
field: 'name',
|
|
||||||
size: 12,
|
|
||||||
color: '#000',
|
|
||||||
},
|
|
||||||
|
|
||||||
fill: {
|
|
||||||
field: 'unit_price',
|
|
||||||
color: ['#CFE1B9', '#B0C298', '#90A276', '#718355'],
|
|
||||||
unknownName: '无类型',
|
|
||||||
scale: {
|
|
||||||
type: 'cat',
|
|
||||||
domain: ['C', 'B', 'A'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
legends: [],
|
|
||||||
};
|
|
|
@ -1,199 +0,0 @@
|
||||||
import Mock from 'mockjs';
|
|
||||||
|
|
||||||
export const chartList = Mock.mock({
|
|
||||||
// 生成长度在 0~32 之间的小写字母
|
|
||||||
success: '@string("lower", 0, 32)',
|
|
||||||
// 生成长度在 0~32 之间的小写字母
|
|
||||||
errorMessage: '@string("lower", 0, 32)',
|
|
||||||
data: {
|
|
||||||
'list|4-7': [
|
|
||||||
{
|
|
||||||
// 生成长度在 100~1000 之间的小写字母
|
|
||||||
xField: '@integer(100,1000)',
|
|
||||||
// 生成长度在 3~5 之间的中文
|
|
||||||
yField: '@ctitle(3, 5)',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const personOption = () => {
|
|
||||||
const data = Mock.mock({
|
|
||||||
'list|10': [
|
|
||||||
{
|
|
||||||
label: '@cname',
|
|
||||||
staffNo: '@integer(100000,1000000)',
|
|
||||||
value: '@integer(100000,1000000)'
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
return data.list
|
|
||||||
}
|
|
||||||
|
|
||||||
export const selectActivityItem = [
|
|
||||||
{
|
|
||||||
label: '双十一赢金币',
|
|
||||||
value: '双十一赢金币',
|
|
||||||
icon: 'https://gw.alipayobjects.com/mdn/rms_58ab56/afts/img/A*JYNuSaNAga8AAAAAAAAAAAAAARQnAQ'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '充电桩铺设',
|
|
||||||
value: '充电桩铺设',
|
|
||||||
icon: 'https://gw.alipayobjects.com/mdn/rms_58ab56/afts/img/A*eay2Q7nXeG4AAAAAAAAAAAAAARQnAQ'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '1块钱升级月卡',
|
|
||||||
value: '1块钱升级月卡',
|
|
||||||
icon: 'https://gw.alipayobjects.com/mdn/rms_58ab56/afts/img/A*nA0vQbl_hGMAAAAAAAAAAAAAARQnAQ'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '免费充电1小时',
|
|
||||||
value: '免费充电1小时',
|
|
||||||
icon: 'https://gw.alipayobjects.com/mdn/rms_58ab56/afts/img/A*snkKRYonMgEAAAAAAAAAAAAAARQnAQ'
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export function randomData<T>(data: T): Promise<T> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve(data);
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ActivityOption = [
|
|
||||||
{ label: '全部活动', value: '全部活动' },
|
|
||||||
{ label: '双十一赢金币', value: '双十一赢金币' },
|
|
||||||
{ label: '充电桩铺设', value: '充电桩铺设' },
|
|
||||||
{ label: '1块钱升级月卡', value: '1块钱升级月卡' },
|
|
||||||
{ label: '免费充电1小时', value: '免费充电1小时' }
|
|
||||||
]
|
|
||||||
|
|
||||||
export const StatusOption = [
|
|
||||||
{ label: '全部状态', value: '全部状态' },
|
|
||||||
{ label: '未拓展', value: '未拓展' },
|
|
||||||
{ label: '已拓展', value: '已拓展' },
|
|
||||||
]
|
|
||||||
|
|
||||||
export const CityList = [
|
|
||||||
{
|
|
||||||
value: '330000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '浙江省',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
value: '330100',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '杭州市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '110000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '北京市',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
value: '110000',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '北京市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '120000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '天津市',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
value: '120000',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '天津市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '310000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '上海市',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
value: '310000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '上海市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '440000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '广东省',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
value: '440100',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '广州市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '440300',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '深圳市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '440400',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '珠海市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '440600',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '佛山市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '441300',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '惠州市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '441900',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '东莞市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '442000',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '中山市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '130000',
|
|
||||||
areaLevel: 'province',
|
|
||||||
label: '河北省',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
value: '130100',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '石家庄市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '131000',
|
|
||||||
areaLevel: 'city',
|
|
||||||
label: '廊坊市',
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
|
@ -1,30 +0,0 @@
|
||||||
import { initWidgets } from './widgets';
|
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
|
||||||
import { config } from './configs/config';
|
|
||||||
import { DipperContainer, IConfig } from '@antv/dipper';
|
|
||||||
import 'antd/dist/antd.css'
|
|
||||||
|
|
||||||
interface IInitData {
|
|
||||||
areaVOList: any[];
|
|
||||||
sceneCode: string;
|
|
||||||
areaCode: string;
|
|
||||||
filterData: any[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function RumbMap() {
|
|
||||||
|
|
||||||
const [mapConfig, setMapConfig] = useState<IConfig<IInitData>>();
|
|
||||||
// 初始化相关数据
|
|
||||||
useEffect(() => {
|
|
||||||
|
|
||||||
initWidgets();
|
|
||||||
setMapConfig(config);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ height: '100%',width:'100%',position:'absolute'}}>
|
|
||||||
<DipperContainer<IInitData> cfg={mapConfig!} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
// return <h1>测试</h1>
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { Select } from 'antd';
|
|
||||||
import React, { useState,useEffect } from 'react';
|
|
||||||
import { ActivityOption } from '../configs/mock';
|
|
||||||
|
|
||||||
const { Option } = Select
|
|
||||||
|
|
||||||
export function Activity() {
|
|
||||||
|
|
||||||
const [active,setActive] = useState<string>()
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
setActive(ActivityOption[0].value)
|
|
||||||
},[])
|
|
||||||
|
|
||||||
return(
|
|
||||||
<Select value={active} bordered={false}
|
|
||||||
onChange={(e)=> setActive(e)}>
|
|
||||||
{ ActivityOption.map((item)=>{
|
|
||||||
return(
|
|
||||||
<Option value={item.value} key={item.label}>{item.label}</Option>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Select>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
.selectactivity {
|
|
||||||
padding: 0 0 20px 20px ;
|
|
||||||
}
|
|
||||||
.selectactivity .select {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
.selectactivity .select .selectitem {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 183px;
|
|
||||||
height: 64px;
|
|
||||||
margin: 0 15px 15px 0;
|
|
||||||
position: relative;
|
|
||||||
padding-left: 15px;
|
|
||||||
}
|
|
||||||
.selectactivity .select .selectitem .icon {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
.selectactivity .select .selectitem .selecticon {
|
|
||||||
width: 21px;
|
|
||||||
height: 21px;
|
|
||||||
position: absolute;
|
|
||||||
right: 6px;
|
|
||||||
top: 6px;
|
|
||||||
}
|
|
||||||
.empty {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
height: calc(674px - 80px);
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.empty img {
|
|
||||||
width: 216px;
|
|
||||||
height: 132px;
|
|
||||||
margin-left: 100px;
|
|
||||||
}
|
|
||||||
.empty span {
|
|
||||||
color: rgba(0, 0, 0, 0.55);
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
.submit {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
.task {
|
|
||||||
height: calc(674px - 130px);
|
|
||||||
position: relative;
|
|
||||||
}
|
|
|
@ -1,91 +0,0 @@
|
||||||
import React, { useState, useMemo } from 'react'
|
|
||||||
import { useLayerGroup } from '@antv/dipper'
|
|
||||||
import { Alert, Button, Select } from 'antd'
|
|
||||||
import { personOption, selectActivityItem } from '../../configs/mock'
|
|
||||||
import style from './index.module.css'
|
|
||||||
|
|
||||||
const { Option } = Select
|
|
||||||
|
|
||||||
export function ActivityTask() {
|
|
||||||
const selecticon = 'https://gw.alipayobjects.com/mdn/rms_58ab56/afts/img/A*kyI9T7Lrej4AAAAAAAAAAAAAARQnAQ'
|
|
||||||
const emptyicon = 'https://gw.alipayobjects.com/mdn/rms_58ab56/afts/img/A*H9dxSp69pi0AAAAAAAAAAAAAARQnAQ'
|
|
||||||
const { selectFeatures = [] } = useLayerGroup('grid')
|
|
||||||
const [current, setCurrent] = useState(selectActivityItem[0]?.value)
|
|
||||||
|
|
||||||
const selectItem = (item) => {
|
|
||||||
setCurrent(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
const alertMsg = useMemo(() => {
|
|
||||||
if (selectFeatures.length === 2) {
|
|
||||||
return '勾选多个网格中,批量分配后将一起更新数据'
|
|
||||||
}
|
|
||||||
if (selectFeatures.length >= 3) {
|
|
||||||
return '你当前多选网格中包含已分配网格,无法批量分配,建议选择单个网格、或选择多个未分配网格的批量操作'
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}, [JSON.stringify(selectFeatures)]);
|
|
||||||
|
|
||||||
const HasSelectFeature = () => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div style={{ margin: '0 20px 20px' }}>
|
|
||||||
{selectFeatures.length >= 2 && <Alert
|
|
||||||
style={{ display:'flex', alignItems:'baseline' }}
|
|
||||||
message={alertMsg}
|
|
||||||
type="warning" showIcon
|
|
||||||
/>}
|
|
||||||
</div>
|
|
||||||
<div className={style.selectactivity}>
|
|
||||||
<h4>选择活动</h4>
|
|
||||||
<div className={style.select}>
|
|
||||||
{selectActivityItem && selectActivityItem.map((item) => {
|
|
||||||
return (
|
|
||||||
<div key={item.label}
|
|
||||||
onClick={() => selectItem(item.value)}
|
|
||||||
style={{
|
|
||||||
border: current === item.value ? '1px solid #1E73F8' : '1px solid rgba(0,0,0,0.15)',
|
|
||||||
}}
|
|
||||||
className={style.selectitem}>
|
|
||||||
<img className={style.icon} src={item.icon} />
|
|
||||||
<span>{item.label}</span>
|
|
||||||
{current === item.value && <img className={style.selecticon} src={selecticon} />}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{ margin: '0 20px' }}>
|
|
||||||
<h4>分配人员</h4>
|
|
||||||
<Select mode="multiple" style={{ width: '100%' }}
|
|
||||||
showArrow defaultValue={['吴家豪', '周星星']}>
|
|
||||||
{personOption().map((item) => {
|
|
||||||
return (
|
|
||||||
<Option key={item.label} value={item.value}>{item.label}</Option>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
<div className={style.submit}>
|
|
||||||
<Button style={{ marginRight: 8 }}>取消</Button>
|
|
||||||
<Button type='primary'>确定</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const Empty = () => {
|
|
||||||
return (
|
|
||||||
<div className={style.empty}>
|
|
||||||
<img src={emptyicon} />
|
|
||||||
<span>暂无数据</span>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={style.task}>
|
|
||||||
{!selectFeatures.length ? <Empty /> : <HasSelectFeature />}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,140 +0,0 @@
|
||||||
import {
|
|
||||||
useSceneService,
|
|
||||||
useConfigService,
|
|
||||||
LayerGroupEventEnum,
|
|
||||||
useLayerService,
|
|
||||||
} from '@antv/dipper';
|
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
|
||||||
import { GridLayerGroup } from '@antv/dipper';
|
|
||||||
const formatLegend = (data: any[]) => {
|
|
||||||
return data.map((item) => {
|
|
||||||
if (Array.isArray(item.value)) {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
value: item.value.map((v) => v.toFixed(2)),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
value: item.value.toFixed(2),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
export function GridLayer() {
|
|
||||||
const { layerService } = useLayerService();
|
|
||||||
const { sceneService } = useSceneService();
|
|
||||||
const { globalConfig, updateLegend, getWidgetsValue } = useConfigService();
|
|
||||||
const { layers } = globalConfig;
|
|
||||||
const [gridLayer, setGridLayer] = useState<GridLayerGroup>();
|
|
||||||
const cityValue = getWidgetsValue('citySelect');
|
|
||||||
const [geoData, setGeoData] = useState();
|
|
||||||
|
|
||||||
const layerProps = useMemo(() => {
|
|
||||||
return layers.find((item: any) => item.type === 'gridLayer');
|
|
||||||
}, [layers]);
|
|
||||||
|
|
||||||
const testData = {
|
|
||||||
title: '图例',
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
colors: ['#fef0d9', '#fdcc8a', '#fc8d59', '#e34a33', '#b30000'],
|
|
||||||
title: '已分配',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
colors: ['#f1eef6', '#bdc9e1', '#74a9cf', '#2b8cbe', '#045a8d'],
|
|
||||||
title: '未分配',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateLayerLegend = (items: any[]) => {
|
|
||||||
updateLegend('gridLayerLegend', {
|
|
||||||
type: 'multiClassifyColor',
|
|
||||||
display: true,
|
|
||||||
position: 'bottomleft',
|
|
||||||
options: {
|
|
||||||
title: '网格',
|
|
||||||
unkownName: layerProps.options.unkownName,
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
colors: ['#BEC3BD', '#A1A6A0', '#828681', '#646763'],
|
|
||||||
title: '已分配',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
colors: ['#CFE1B9', '#B0C298', '#90A276', '#718355'],
|
|
||||||
title: '未分配',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
values: items.map((item) => {
|
|
||||||
return item.value.map((v) => {
|
|
||||||
return (v / 10000).toFixed(2);
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 根据筛选器条件请求数据
|
|
||||||
useEffect(() => {
|
|
||||||
// 可以根据业务需求配置接口
|
|
||||||
fetch(
|
|
||||||
`https://gw.alipayobjects.com/os/antvdemo/assets/dipper-city/${cityValue[1]}.json`,
|
|
||||||
)
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((data) => {
|
|
||||||
setGeoData(data);
|
|
||||||
});
|
|
||||||
// 切换城市 高德地图方法
|
|
||||||
sceneService.getScene().map?.setCity(cityValue[1]);
|
|
||||||
}, [JSON.stringify(cityValue)]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!geoData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (gridLayer) {
|
|
||||||
gridLayer.setData(geoData);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const color = ['#CFE1B9','#B0C298','#90A276','#718355']
|
|
||||||
|
|
||||||
const layer = new GridLayerGroup({
|
|
||||||
name: 'grid',
|
|
||||||
data: geoData,
|
|
||||||
options: {
|
|
||||||
...layerProps.options,
|
|
||||||
fill:{
|
|
||||||
...layerProps.options.fill,
|
|
||||||
color
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
layerService.addLayer(layer);
|
|
||||||
|
|
||||||
layer.on(LayerGroupEventEnum.DATAUPDATE, () => {
|
|
||||||
layer.getLegendItem().map((item) => {
|
|
||||||
if (Array.isArray(item.value)) {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
value: item.value.map((v) => v.toFixed(2)),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
value: item.value.toFixed(2),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
updateLayerLegend(formatLegend(layer.getLegendItem()));
|
|
||||||
});
|
|
||||||
|
|
||||||
// 更新图例
|
|
||||||
updateLayerLegend(formatLegend(layer.getLegendItem()));
|
|
||||||
|
|
||||||
setGridLayer(layer);
|
|
||||||
}, [geoData]);
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
.exhibititem {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
.exhibititem :global .ant-switch-checked {
|
|
||||||
background-color: #1E73F8;
|
|
||||||
}
|
|
||||||
.dropdown {
|
|
||||||
border-left: 1px solid #f3f3f3;
|
|
||||||
border-right: 1px solid #f3f3f3;
|
|
||||||
padding: 0 10px;
|
|
||||||
height: 32px;
|
|
||||||
line-height: 32px;
|
|
||||||
}
|
|
||||||
.dropicon {
|
|
||||||
padding-left: 8px;
|
|
||||||
color: rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
import { DownOutlined } from "@ant-design/icons";
|
|
||||||
import { Dropdown, Menu, Switch } from "antd";
|
|
||||||
import React from "react";
|
|
||||||
import style from './index.module.css'
|
|
||||||
|
|
||||||
export function MapExhibit() {
|
|
||||||
const onChange = (e) => {
|
|
||||||
// TODO 根据业务实现
|
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
const menu = (
|
|
||||||
<Menu>
|
|
||||||
<Menu.Item key="1">
|
|
||||||
<div className={style.exhibititem}>
|
|
||||||
<div style={{ marginRight: 50 }}>地图放大展示分配人员</div>
|
|
||||||
<Switch defaultChecked size='small' onChange={onChange} />
|
|
||||||
</div>
|
|
||||||
</Menu.Item>
|
|
||||||
</Menu>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dropdown overlay={menu}>
|
|
||||||
<div className={style.dropdown} >
|
|
||||||
地图展示<DownOutlined className={style.dropicon} />
|
|
||||||
</div>
|
|
||||||
</Dropdown>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
.meahname {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
.closeicon {
|
|
||||||
padding: 0 8px;
|
|
||||||
}
|
|
||||||
.edit {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.edit span:hover {
|
|
||||||
color: #1890ff;
|
|
||||||
}
|
|
|
@ -1,83 +0,0 @@
|
||||||
import React, { useRef, useState, useMemo, useCallback } from 'react';
|
|
||||||
import { CheckOutlined, CloseOutlined, EditOutlined } from '@ant-design/icons';
|
|
||||||
import styles from './index.module.css'
|
|
||||||
import { Input } from 'antd';
|
|
||||||
import { useLayerGroup } from '@antv/dipper';
|
|
||||||
|
|
||||||
export function MeshName() {
|
|
||||||
const { selectFeatures, updateProperties } = useLayerGroup('grid');
|
|
||||||
const [edit, setEdit] = useState(false);
|
|
||||||
const ref = useRef();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get meshname
|
|
||||||
* type []string
|
|
||||||
*/
|
|
||||||
const meshName = useMemo(() => {
|
|
||||||
if (!selectFeatures.length) return [];
|
|
||||||
return selectFeatures.map((item) => {
|
|
||||||
// @ts-ignore
|
|
||||||
return item.feature.properties.name;
|
|
||||||
});
|
|
||||||
}, [JSON.stringify(selectFeatures)]);
|
|
||||||
|
|
||||||
// 修改 网格名称
|
|
||||||
const editMeshName = useCallback(() => {
|
|
||||||
// @ts-ignore
|
|
||||||
const value = ref.current.state.value;
|
|
||||||
selectFeatures.forEach((item) => {
|
|
||||||
const properties = {
|
|
||||||
...item.feature.properties,
|
|
||||||
name: value,
|
|
||||||
};
|
|
||||||
updateProperties(item.feature, properties);
|
|
||||||
});
|
|
||||||
setEdit(false);
|
|
||||||
}, [JSON.stringify(selectFeatures)]);
|
|
||||||
|
|
||||||
// select more meshname 编辑 网格名称
|
|
||||||
const EditMeshName = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{!edit ? (
|
|
||||||
<div onClick={() => setEdit(!edit)}>
|
|
||||||
<span>{meshName}</span>
|
|
||||||
<EditOutlined style={{ paddingLeft: 12 }}/>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className={styles.edit}>
|
|
||||||
<Input defaultValue={meshName} ref={ref} />
|
|
||||||
<CheckOutlined
|
|
||||||
onClick={editMeshName}
|
|
||||||
className={styles.closeicon}
|
|
||||||
/>
|
|
||||||
<CloseOutlined onClick={() => setEdit(false)} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// show 多个网格名称
|
|
||||||
const ShowMeshNames = () => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{meshName.length >= 2 && meshName.map((s) => {
|
|
||||||
return (
|
|
||||||
<span key={s}>{s},</span>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{meshName && meshName.length ? (
|
|
||||||
<div className={styles.meahname}>
|
|
||||||
{meshName.length === 1 ? <EditMeshName /> : <ShowMeshNames />}
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
export function MeshSplitSvg() {
|
|
||||||
return (
|
|
||||||
<div style={{ marginLeft: 4 }}>
|
|
||||||
<svg
|
|
||||||
width="16px"
|
|
||||||
height="20px"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
version="1.1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M7.74074074,2.02 C8.01688312,2.02 8.24074074,2.24385763 8.24074074,2.52 L8.24,7.797 L13.5185185,7.79777778 C13.7946609,7.79777778 14.0185185,8.0216354 14.0185185,8.29777778 L14.0185185,14.0385185 C14.0185185,14.3146609 13.7946609,14.5385185 13.5185185,14.5385185 L2,14.5385185 C1.72385763,14.5385185 1.5,14.3146609 1.5,14.0385185 L1.5,2.52 C1.5,2.24385763 1.72385763,2.02 2,2.02 L7.74074074,2.02 Z M7.26727273,3.06 L2.54,3.06 L2.54,13.46 L12.94,13.46 L12.94,8.73272727 L7.267,8.732 L7.26727273,3.06 Z M14,1.5 C14.2761424,1.5 14.5,1.72385763 14.5,2 L14.5,6.2962963 C14.5,6.57243867 14.2761424,6.7962963 14,6.7962963 L9.7037037,6.7962963 C9.42756133,6.7962963 9.2037037,6.57243867 9.2037037,6.2962963 L9.2037037,2 C9.2037037,1.72385763 9.42756133,1.5 9.7037037,1.5 L14,1.5 Z M13.617284,2.38271605 L10.0864198,2.38271605 L10.0864198,5.91358025 L13.617284,5.91358025 L13.617284,2.38271605 Z"
|
|
||||||
id="形状结合"
|
|
||||||
fill="#333333"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function MeshMergeSvg() {
|
|
||||||
return (
|
|
||||||
<div style={{ marginLeft: 4 }}>
|
|
||||||
<svg
|
|
||||||
width="14px"
|
|
||||||
height="14px"
|
|
||||||
viewBox="0 0 14 14"
|
|
||||||
version="1.1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<title>自动合并</title>
|
|
||||||
<g
|
|
||||||
id="设计方案"
|
|
||||||
stroke="none"
|
|
||||||
strokeWidth="1"
|
|
||||||
fill="none"
|
|
||||||
fillRule="evenodd"
|
|
||||||
>
|
|
||||||
<g
|
|
||||||
id="兼容性播报中心"
|
|
||||||
transform="translate(-968.000000, -207.000000)"
|
|
||||||
>
|
|
||||||
<g id="自动合并" transform="translate(967.000000, 206.000000)">
|
|
||||||
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
|
|
||||||
<path
|
|
||||||
d="M10.3121824,7.30025029 L10.3121824,13.8 C10.3121824,13.9104569 10.2226393,14 10.1121824,14 L2.2,14 C2.08954305,14 2,13.9104569 2,13.8 L2,5.64440342 C2,5.53394647 2.08954305,5.44440342 2.2,5.44440342 L8.27622473,5.44440342 L8.27622473,5.44440342 L8.27622473,2.2 C8.27622473,2.08954305 8.36576778,2 8.47622473,2 L13.8,2 C13.9104569,2 14,2.08954305 14,2.2 L14,7.10025029 C14,7.21070724 13.9104569,7.30025029 13.8,7.30025029 L10.3121824,7.30025029 L10.3121824,7.30025029 Z"
|
|
||||||
id="路径-3"
|
|
||||||
stroke="#333333"
|
|
||||||
></path>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
.meshTools{
|
|
||||||
width: 32px;
|
|
||||||
height: 160px;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 2px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding:15px 5px;
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
import React, { useMemo, useState, useRef } from 'react';
|
|
||||||
import styles from './index.module.css'
|
|
||||||
import { MeshSplitSvg, MeshMergeSvg } from './SvgElement';
|
|
||||||
import { useLayerGroup } from '@antv/dipper'
|
|
||||||
import { Input, message, Modal, Popconfirm, Tooltip } from 'antd';
|
|
||||||
|
|
||||||
|
|
||||||
export function MeshTools() {
|
|
||||||
const { selectFeatures = [] } = useLayerGroup('grid')
|
|
||||||
const [visible, setVisible] = useState(false)
|
|
||||||
const refs = useRef()
|
|
||||||
|
|
||||||
const disable = { cursor: 'pointer', opacity: 1 }
|
|
||||||
const noDisable = { cursor: 'not-allowed', opacity: 0.25 }
|
|
||||||
|
|
||||||
const cssPropsSplit = useMemo(() => {
|
|
||||||
if (selectFeatures.length === 1) return disable;
|
|
||||||
return noDisable;
|
|
||||||
}, [JSON.stringify(selectFeatures)]);
|
|
||||||
|
|
||||||
const cssPropsMerge = useMemo(() => {
|
|
||||||
if (selectFeatures.length >= 2) {
|
|
||||||
return disable
|
|
||||||
}
|
|
||||||
return noDisable;
|
|
||||||
}, [JSON.stringify(selectFeatures)]);
|
|
||||||
|
|
||||||
const splitMesh = () => {
|
|
||||||
// TODO 根据业务实现
|
|
||||||
}
|
|
||||||
|
|
||||||
const mergrMesh = () => {
|
|
||||||
// @ts-ignore
|
|
||||||
const value = refs.current.state.value
|
|
||||||
if (!value) {
|
|
||||||
return message.error('请输入要合并后的名称')
|
|
||||||
}
|
|
||||||
// TODO 根据业务实现
|
|
||||||
setVisible(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={styles.meshTools}>
|
|
||||||
<Tooltip placement="left"
|
|
||||||
title={selectFeatures.length === 1 ? '选择单个网格,可以拆分' : null}>
|
|
||||||
<Popconfirm
|
|
||||||
disabled={selectFeatures.length !== 1}
|
|
||||||
placement='left'
|
|
||||||
title='该网格将被拆分成xx个基础网格,你确定要拆分吗?'
|
|
||||||
onConfirm={splitMesh}
|
|
||||||
okText='确定'
|
|
||||||
trigger='click'
|
|
||||||
cancelText='取消'
|
|
||||||
>
|
|
||||||
<div style={{ ...cssPropsSplit }}>
|
|
||||||
<MeshSplitSvg />
|
|
||||||
<div style={{ width: 32 }}>网格拆分</div>
|
|
||||||
</div>
|
|
||||||
</Popconfirm>
|
|
||||||
|
|
||||||
</Tooltip>
|
|
||||||
|
|
||||||
<Tooltip placement='left'
|
|
||||||
title={selectFeatures.length >= 2 ? '选择多个网格,可以合并' : null}>
|
|
||||||
<div style={{ ...cssPropsMerge }} onClick={() => setVisible(true)}>
|
|
||||||
<MeshMergeSvg />
|
|
||||||
<div style={{ width: 32 }}>网格合并</div>
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
|
|
||||||
<Modal title='网格合并'
|
|
||||||
okText='确认' cancelText='取消'
|
|
||||||
visible={visible} onOk={mergrMesh}
|
|
||||||
onCancel={() => setVisible(false)}
|
|
||||||
>
|
|
||||||
<h4>合并后的新网格名称</h4>
|
|
||||||
<Input ref={refs} placeholder='请输入名称' />
|
|
||||||
</Modal>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
import { SaveOutlined } from '@ant-design/icons';
|
|
||||||
import { Button } from 'antd';
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
export function Save() {
|
|
||||||
return (
|
|
||||||
<Button type="text" icon={<SaveOutlined />}>
|
|
||||||
保存
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
import React, { useState, useEffect } from "react";
|
|
||||||
import { Dropdown, Input, Menu, Select } from 'antd';
|
|
||||||
import { SearchOutlined } from "@ant-design/icons";
|
|
||||||
import { personOption } from "../configs/mock";
|
|
||||||
|
|
||||||
const { Search } = Input
|
|
||||||
const { Option } = Select
|
|
||||||
|
|
||||||
// 此功能 仅做展示,以实际业务为准
|
|
||||||
export function SearchPerson() {
|
|
||||||
|
|
||||||
const [persons, setPersons] = useState([])
|
|
||||||
const [visible, setVisible] = useState(false)
|
|
||||||
|
|
||||||
const onSearch = (e) => {
|
|
||||||
const value = e.target.value
|
|
||||||
setTimeout(() => {
|
|
||||||
if (value) {
|
|
||||||
setPersons(personOption())
|
|
||||||
setVisible(true)
|
|
||||||
} else {
|
|
||||||
setPersons([])
|
|
||||||
setVisible(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
}, 300)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 人员搜索
|
|
||||||
const onSelect = (value) =>{
|
|
||||||
// TODO 根据业务实现
|
|
||||||
}
|
|
||||||
|
|
||||||
const menu = (
|
|
||||||
<Menu>
|
|
||||||
<Menu.Item key="1">
|
|
||||||
{persons && persons.map((item) => {
|
|
||||||
return (
|
|
||||||
<div key={item.label}
|
|
||||||
onClick={()=>onSelect(item.value)}
|
|
||||||
style={{ paddingBottom: '5px' }}
|
|
||||||
>{item.label}</div>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Menu.Item>
|
|
||||||
</Menu>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ background:'#fff'}}>
|
|
||||||
<Dropdown overlay={menu} visible={visible}>
|
|
||||||
<Input bordered={false}
|
|
||||||
placeholder="搜索网格名称/人员名称"
|
|
||||||
prefix={<SearchOutlined />}
|
|
||||||
onChange={onSearch}
|
|
||||||
/>
|
|
||||||
</Dropdown>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
import { SendOutlined } from '@ant-design/icons';
|
|
||||||
import { Button } from 'antd';
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
export function Send() {
|
|
||||||
return(
|
|
||||||
<Button type='primary' icon={<SendOutlined rotate={-60} style={{color:'#fff'}}/>}>发布</Button>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { Select } from 'antd';
|
|
||||||
import React,{ useState,useEffect } from 'react';
|
|
||||||
import { StatusOption } from '../configs/mock';
|
|
||||||
|
|
||||||
const { Option } = Select
|
|
||||||
|
|
||||||
export function Status() {
|
|
||||||
|
|
||||||
const [status,setStatus] = useState<string>()
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
setStatus(StatusOption[0].value)
|
|
||||||
},[])
|
|
||||||
|
|
||||||
return(
|
|
||||||
<Select value={status} bordered={false}
|
|
||||||
onChange={(e)=> setStatus(e)}>
|
|
||||||
{ StatusOption.map((item)=>{
|
|
||||||
return(
|
|
||||||
<Option value={item.value} key={item.label}>{item.label}</Option>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Select>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
import { registerWidget } from '@antv/dipper-core';
|
|
||||||
import {
|
|
||||||
CitySelect,
|
|
||||||
ClassifyColor,
|
|
||||||
DiscreteColor,
|
|
||||||
} from '@antv/dipper-widgets';
|
|
||||||
import { Activity } from './Activity';
|
|
||||||
import { ActivityTask } from './ActivityTask';
|
|
||||||
import { GridLayer } from './GridLayer';
|
|
||||||
import { MeshName } from './MeshName/index';
|
|
||||||
import { Save } from './Save';
|
|
||||||
import { SearchPerson } from './SearchPerson';
|
|
||||||
import { Send } from './Send';
|
|
||||||
import { Status } from './Status';
|
|
||||||
import { MeshTools } from './MeshTools';
|
|
||||||
import { MapExhibit } from './MapExhibit/index';
|
|
||||||
|
|
||||||
export function initWidgets() {
|
|
||||||
registerWidget('citySelect', CitySelect);
|
|
||||||
registerWidget('gridLayer', GridLayer);
|
|
||||||
registerWidget('classifyColor', ClassifyColor);
|
|
||||||
registerWidget('discreteColor', DiscreteColor);
|
|
||||||
registerWidget('meshName', MeshName);
|
|
||||||
registerWidget('meshTools',MeshTools)
|
|
||||||
|
|
||||||
registerWidget('save', Save);
|
|
||||||
registerWidget('publishbar', Send);
|
|
||||||
registerWidget('activity', Activity);
|
|
||||||
registerWidget('status',Status);
|
|
||||||
registerWidget('mapExhibit', MapExhibit);
|
|
||||||
registerWidget('searchPerson',SearchPerson)
|
|
||||||
registerWidget('activityTask',ActivityTask)
|
|
||||||
}
|
|
|
@ -1,5 +1,4 @@
|
||||||
import Banner from '@antv/gatsby-theme-antv/site/components/Banner';
|
import Banner from '@antv/gatsby-theme-antv/site/components/Banner';
|
||||||
import BannerSVG from '@antv/gatsby-theme-antv/site/components/BannerSVG';
|
|
||||||
import Cases from '@antv/gatsby-theme-antv/site/components/Cases';
|
import Cases from '@antv/gatsby-theme-antv/site/components/Cases';
|
||||||
import Companies from '@antv/gatsby-theme-antv/site/components/Companies';
|
import Companies from '@antv/gatsby-theme-antv/site/components/Companies';
|
||||||
import Features from '@antv/gatsby-theme-antv/site/components/Features';
|
import Features from '@antv/gatsby-theme-antv/site/components/Features';
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import Loadable from "@loadable/component"
|
|
||||||
const Map = Loadable(() => import("../components/analysis"))
|
|
||||||
const Page: React.FC & { noLayout: boolean } = () => <Map/>;
|
|
||||||
|
|
||||||
Page.noLayout = true;
|
|
||||||
|
|
||||||
export default Page;
|
|
|
@ -1,8 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import Loadable from "@loadable/component"
|
|
||||||
const Map = Loadable(() => import("../components/task"))
|
|
||||||
const Page: React.FC & { noLayout: boolean } = () => <Map/>;
|
|
||||||
|
|
||||||
Page.noLayout = true;
|
|
||||||
|
|
||||||
export default Page;
|
|
|
@ -1,2 +0,0 @@
|
||||||
import Index from './task.en';
|
|
||||||
export default Index;
|
|
|
@ -1,159 +0,0 @@
|
||||||
import { useMemo } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
export const useConfig = () => {
|
|
||||||
const { t, i18n } = useTranslation();
|
|
||||||
|
|
||||||
// 通知
|
|
||||||
const notifications = useMemo(() => {
|
|
||||||
return [{
|
|
||||||
type: t('推荐'),
|
|
||||||
title: t('如何制作不一样的疫情世界地图-酷炫、动感的地理可视化'),
|
|
||||||
date: '2020.03.12',
|
|
||||||
link: 'https://www.yuque.com/antv/blog/wigku2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: t('新版发布'),
|
|
||||||
title: t('L7 2.1 正式版'),
|
|
||||||
date: '2020.03.12',
|
|
||||||
link: ' https://www.yuque.com/antv/blog/ows55v',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// L7 特性
|
|
||||||
const L7Features = useMemo(() => {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
icon:
|
|
||||||
'https://gw.alipayobjects.com/zos/basement_prod/ca2168d1-ae50-4929-8738-c6df62231de3.svg',
|
|
||||||
title: t('架构灵活且自由'),
|
|
||||||
description: t('支持地图底图,渲染引擎,图层自由定制、扩展,组合'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon:
|
|
||||||
'https://gw.alipayobjects.com/zos/basement_prod/0ccf4dcb-1bac-4f4e-8d8d-f1031c77c9c8.svg',
|
|
||||||
title: t('业务专业且通用'),
|
|
||||||
description: t(
|
|
||||||
'以图形符号学地理设计体系理论基础,易用、易理解、专业、专注',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon:
|
|
||||||
'https://gw.alipayobjects.com/zos/basement_prod/fd232581-14b3-45ec-a85c-fb349c51b376.svg',
|
|
||||||
title: t('视觉酷炫且动感'),
|
|
||||||
description: t('支持海量数据,2D、3D,动态,可交互,高性能渲染'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
|
|
||||||
const L7Case = useMemo(() => {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
logo:
|
|
||||||
'https://antv-2018.alipay.com/assets/image/icon/l7.svg',
|
|
||||||
title: t('指挥分配场景'),
|
|
||||||
description: t(
|
|
||||||
'区域化网格化数据管理指挥分配场景',
|
|
||||||
),
|
|
||||||
link: `/${i18n.language}/task`,
|
|
||||||
image:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_08cc33/afts/img/A*CLJESKDO1g4AAAAAAAAAAAAAARQnAQ',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
logo:
|
|
||||||
'https://antv-2018.alipay.com/assets/image/icon/l7.svg',
|
|
||||||
title: t('地图数据分析'),
|
|
||||||
description: t(
|
|
||||||
'区域化网格化数据分析场景',
|
|
||||||
),
|
|
||||||
link: `/${i18n.language}/view`,
|
|
||||||
image:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_08cc33/afts/img/A*jb4tS7BiNo4AAAAAAAAAAAAAARQnAQ',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
logo:
|
|
||||||
'https://gw.alipayobjects.com/zos/bmw-prod/222865fc-15e9-44b9-b726-444e1512d937.ico',
|
|
||||||
title: t('地理分析工具'),
|
|
||||||
description: t(
|
|
||||||
'地图可视化配置分析类场景',
|
|
||||||
),
|
|
||||||
link: `/${i18n.language}/examples/gallery/basic`,
|
|
||||||
image:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_e7e1c6/afts/img/A*MPWKQqh54vwAAAAAAAAAAAAAARQnAQ',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
}, [])
|
|
||||||
const companies = useMemo(() => [{
|
|
||||||
name: '阿里云',
|
|
||||||
img:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*V_xMRIvw2iwAAAAAAAAAAABkARQnAQ',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '支付宝',
|
|
||||||
img:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*lYDrRZvcvD4AAAAAAAAAAABkARQnAQ',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '天猫',
|
|
||||||
img:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*BQrxRK6oemMAAAAAAAAAAABkARQnAQ',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '淘宝网',
|
|
||||||
img:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*1l8-TqUr7UcAAAAAAAAAAABkARQnAQ',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '网商银行',
|
|
||||||
img:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*ZAKFQJ5Bz4MAAAAAAAAAAABkARQnAQ',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '盒马',
|
|
||||||
img:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*ePJMQZCb8vkAAAAAAAAAAABkARQnAQ',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'yunos',
|
|
||||||
img:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*_js7SaNosUwAAAAAAAAAAABkARQnAQ',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '菜鸟',
|
|
||||||
img:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*TgV-RZDODJIAAAAAAAAAAABkARQnAQ',
|
|
||||||
}
|
|
||||||
], []);
|
|
||||||
|
|
||||||
const ecosystems = useMemo(() => [{
|
|
||||||
name: '阿里云',
|
|
||||||
img:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*V_xMRIvw2iwAAAAAAAAAAABkARQnAQ',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '支付宝',
|
|
||||||
img:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*lYDrRZvcvD4AAAAAAAAAAABkARQnAQ',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '天猫',
|
|
||||||
img:
|
|
||||||
'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*BQrxRK6oemMAAAAAAAAAAABkARQnAQ',
|
|
||||||
}
|
|
||||||
], []);
|
|
||||||
|
|
||||||
return {
|
|
||||||
ecosystems,
|
|
||||||
L7Features,
|
|
||||||
notifications,
|
|
||||||
companies,
|
|
||||||
L7Case,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
import Index from './view.zh';
|
|
||||||
export default Index;
|
|
|
@ -1,8 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import Loadable from "@loadable/component"
|
|
||||||
const Map = Loadable(() => import("../components/analysis"))
|
|
||||||
const Page: React.FC & { noLayout: boolean } = () => <Map/>;
|
|
||||||
|
|
||||||
Page.noLayout = true;
|
|
||||||
|
|
||||||
export default Page;
|
|
Loading…
Reference in New Issue