mirror of https://gitee.com/antv-l7/antv-l7
Fix site map (#846)
* fix: 解决方案页面懒加载 * fix: 添加demo * 添加两个组件 * fix: 修改样式 * fix: 样式调整 * fix: 更新官网 * fix: 修改样式 Co-authored-by: wb-yzg904416@antgroup.com <wb-yzg904416@antgroup.com>
This commit is contained in:
parent
97fabe60c7
commit
975fa5777d
|
@ -532,6 +532,18 @@ layer.select(false);
|
|||
layer.setSelect(id);
|
||||
```
|
||||
|
||||
### getLegendItems
|
||||
|
||||
获取图例配置
|
||||
|
||||
#### 参数
|
||||
|
||||
- name 获取的图例类型 `color|size`
|
||||
|
||||
```ts
|
||||
layer.getLegendItems('color');
|
||||
```
|
||||
|
||||
## 鼠标事件
|
||||
|
||||
鼠标事件回调参数 target
|
||||
|
|
|
@ -39,6 +39,66 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
],
|
||||
ecosystems: [
|
||||
{
|
||||
name: {
|
||||
zh: 'L7 React组件',
|
||||
en: 'L7React L7 For React',
|
||||
},
|
||||
url: 'http://antv.vision/L7-react/',
|
||||
},
|
||||
{
|
||||
name: {
|
||||
zh: 'L7 地理围栏绘制组件库',
|
||||
en: 'L7Draw',
|
||||
},
|
||||
url: 'http://antv.vision/L7-draw/',
|
||||
},
|
||||
{
|
||||
name: {
|
||||
zh: 'L7 行政区划可视化库',
|
||||
en: 'L7Boundary',
|
||||
},
|
||||
url: 'http://antv.vision/L7-boundary/',
|
||||
},
|
||||
{
|
||||
name: {
|
||||
zh: '地理可视分开发框架',
|
||||
en: '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: [
|
||||
{
|
||||
slug: 'api/l7',
|
||||
|
|
|
@ -6,9 +6,10 @@
|
|||
"url": "https://github.com/antvis/L7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antv/dipper": "^0.0.5",
|
||||
"@antv/dipper-widgets": "^0.0.5",
|
||||
"@antv/dipper": "0.0.6",
|
||||
"@antv/dipper-widgets": "0.0.6",
|
||||
"@antv/g2": "^3.5.9",
|
||||
"@antv/g2plot": "^2.3.40",
|
||||
"@antv/gatsby-theme-antv": "^1.1.1",
|
||||
"@antv/l7-district": "^2.3.9",
|
||||
"@antv/l7-draw": "^2.3.40",
|
||||
|
@ -89,6 +90,7 @@
|
|||
"jest-styled-components": "^6.2.1",
|
||||
"lerna": "^3.16.4",
|
||||
"lint-staged": "^9.2.4",
|
||||
"mockjs": "^1.1.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"popmotion": "^9.4.2",
|
||||
"postcss": "^7.0.18",
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
// eslint-disable-next-line no-unused-vars
|
||||
import React from 'react';
|
||||
import '../../css/dipper.css';
|
||||
|
||||
interface DipperProps {
|
||||
dipper: {
|
||||
title: string;
|
||||
image: string;
|
||||
link: string
|
||||
}[]
|
||||
}
|
||||
|
||||
export function Dipper(props: DipperProps) {
|
||||
const { dipper } = props;
|
||||
|
||||
const jumoDemo = (url: string) => {
|
||||
window.open(url, '_blank');
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='dippercontainer'>
|
||||
<div className='title'>Dipper 地理分析应用开发框架</div>
|
||||
<div className='subtitle'>Dipper 是基于 L7 地理分析应用开发框架,用于快速构建和开发地理分析应用。用户通过组件化、模块化低代码的方式配置地图分析、指挥类应用。</div>
|
||||
<div className='dipperdemo'>
|
||||
{dipper.map(item => {
|
||||
return (
|
||||
<div key={item.title} className='dipperitem' >
|
||||
<img className='dipperimg' src={item.image} />
|
||||
<span style={{cursor:'pointer'}} className='dippertitle'>{item.title}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
// eslint-disable-next-line no-unused-vars
|
||||
import { Carousel } from 'antd';
|
||||
import React from 'react';
|
||||
import '../../css/dippermap.css';
|
||||
|
||||
interface DipperMapProps {
|
||||
dippermap: {
|
||||
desc: string;
|
||||
img: string;
|
||||
alt: string
|
||||
}[]
|
||||
}
|
||||
|
||||
export function DipperMap(props: DipperMapProps) {
|
||||
const { dippermap } = props;
|
||||
|
||||
const jumpDipperMap = (url: string) => {
|
||||
window.open(url, '_blank');
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='dippermapcontainer'>
|
||||
<div className='title'>Dipper Map 地理可视化分析工具</div>
|
||||
<div className='subtitle'>DipperMap 基于L7 地图可视分析工具,用户自由上传地理数据进行可视化化配置。</div>
|
||||
<div className='carousel'>
|
||||
<Carousel
|
||||
autoplay
|
||||
effect='fade'
|
||||
dotPosition='right'
|
||||
>
|
||||
{dippermap.map(item => {
|
||||
return (
|
||||
<div>
|
||||
<h3 style={{ textAlign: 'center' }}>{item.desc}</h3>
|
||||
<img key={item.alt} alt={item.alt} src={item.img} />
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</Carousel>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
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 }} />;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
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>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
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>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
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}}/>;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
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}}/>;
|
||||
}
|
|
@ -4,30 +4,20 @@ export const config: Partial<IConfig> = {
|
|||
viewData: {
|
||||
global: {
|
||||
filterData: [],
|
||||
sceneCode: 'iot_terminal_dominant',
|
||||
areaCode: '330100',
|
||||
view: 'task',
|
||||
},
|
||||
widgets: {
|
||||
citySelect: {
|
||||
options: CityList,
|
||||
value: [330000, 330100],
|
||||
value: ['330000', '330100'],
|
||||
},
|
||||
},
|
||||
},
|
||||
headerbar: {
|
||||
display: true,
|
||||
logo: {
|
||||
display: true,
|
||||
value:
|
||||
'https://gw.alipayobjects.com/mdn/rms_855bab/afts/img/A*ObVJT4IxmlkAAAAAAAAAAAAAARQnAQ',
|
||||
style: {
|
||||
height: '24px',
|
||||
width: '24px',
|
||||
},
|
||||
},
|
||||
title: {
|
||||
value: '区代指挥中心',
|
||||
value: '数据分析',
|
||||
display: true,
|
||||
},
|
||||
children: [
|
||||
|
@ -41,21 +31,6 @@ export const config: Partial<IConfig> = {
|
|||
action: 'queryArea',
|
||||
},
|
||||
},
|
||||
{
|
||||
display: true,
|
||||
options: [
|
||||
{
|
||||
label: '热区分析',
|
||||
value: 'hotspot',
|
||||
},
|
||||
{
|
||||
label: '任务管理',
|
||||
value: 'task',
|
||||
},
|
||||
],
|
||||
position: 'center',
|
||||
type: 'navibar',
|
||||
},
|
||||
{
|
||||
display: false,
|
||||
position: 'right',
|
||||
|
@ -69,24 +44,37 @@ export const config: Partial<IConfig> = {
|
|||
},
|
||||
panel: {
|
||||
display: true,
|
||||
options: {
|
||||
enableToggle: true,
|
||||
defaultTitle: '所有网格',
|
||||
opened: true,
|
||||
width: 360,
|
||||
width: 426,
|
||||
},
|
||||
position: 'right',
|
||||
children: [
|
||||
{
|
||||
type: 'siderbartabcontent',
|
||||
display: true,
|
||||
type: 'meshName',
|
||||
title: '网格名称',
|
||||
},
|
||||
{
|
||||
display: true,
|
||||
type: 'meshchart',
|
||||
title: '所有网格数据',
|
||||
},
|
||||
{
|
||||
display: false,
|
||||
type: 'panelTabContent',
|
||||
title: '所有网格',
|
||||
children: [
|
||||
{
|
||||
display: true,
|
||||
type: 'mesh_indicator',
|
||||
title: '数据查看',
|
||||
title: '业务数据',
|
||||
},
|
||||
{
|
||||
type: 'total_data_panel',
|
||||
title: '地图面板',
|
||||
title: '人员数据',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -106,9 +94,27 @@ export const config: Partial<IConfig> = {
|
|||
{
|
||||
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: [
|
||||
{
|
||||
|
@ -136,7 +142,7 @@ export const config: Partial<IConfig> = {
|
|||
},
|
||||
fill: {
|
||||
field: 'unit_price',
|
||||
color: SingleSequentialColorScale.Blue,
|
||||
color: ['#A9D3FF', '#82B1FF', '#6294FF', '#457BFF', '#2962FF'],
|
||||
bandNum: 5,
|
||||
scale: 'quantile',
|
||||
unknownName: '无类型',
|
|
@ -0,0 +1,267 @@
|
|||
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: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
|
@ -0,0 +1,27 @@
|
|||
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>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
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>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,140 @@
|
|||
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 <></>;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
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>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
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>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
.meahname {
|
||||
padding: 20px;
|
||||
}
|
||||
.closeicon {
|
||||
padding: 0 8px;
|
||||
}
|
||||
.edit {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.edit span:hover {
|
||||
color: #1890ff;
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
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>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
.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;
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
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>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
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,532 +0,0 @@
|
|||
export const geojson = [
|
||||
{
|
||||
type: 'Feature',
|
||||
properties: {
|
||||
label: 'A类区域',
|
||||
value: 'A',
|
||||
featureId: '2021102300040027',
|
||||
id: '2021102300040027',
|
||||
name: '哈哈6666',
|
||||
groupId: '2021102300073562',
|
||||
canvasId: '2021102300077947',
|
||||
creator: '285869',
|
||||
modifier: 'WB904416',
|
||||
gmtCreate: '2021-10-23T13:23:53.000+00:00',
|
||||
gmtModified: '2021-10-29T08:43:06.000+00:00',
|
||||
status: 1,
|
||||
bizId: 'ALGO13301000000030038b',
|
||||
source: 'INIT',
|
||||
extInfo: {
|
||||
area_centroid: '[120.200270,30.137812]',
|
||||
},
|
||||
},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [
|
||||
[
|
||||
[120.147844, 30.143857],
|
||||
[120.146688, 30.144529],
|
||||
[120.145292, 30.145769],
|
||||
[120.14333, 30.146841],
|
||||
[120.138229, 30.153274],
|
||||
[120.133322, 30.160392],
|
||||
[120.132625, 30.161615],
|
||||
[120.135188, 30.16281],
|
||||
[120.136067, 30.163429],
|
||||
[120.137014, 30.164436],
|
||||
[120.138875, 30.167409],
|
||||
[120.139576, 30.168271],
|
||||
[120.140893, 30.169368],
|
||||
[120.141752, 30.169944],
|
||||
[120.144082, 30.170827],
|
||||
[120.147209, 30.171816],
|
||||
[120.151231, 30.172756],
|
||||
[120.154113, 30.173337],
|
||||
[120.155476, 30.173477],
|
||||
[120.158666, 30.173408],
|
||||
[120.158813, 30.173182],
|
||||
[120.167716, 30.173249],
|
||||
[120.167809, 30.173079],
|
||||
[120.167644, 30.172555],
|
||||
[120.167663, 30.172204],
|
||||
[120.168217, 30.171148],
|
||||
[120.168583, 30.170715],
|
||||
[120.168799, 30.169991],
|
||||
[120.16937, 30.169203],
|
||||
[120.168394, 30.168113],
|
||||
[120.167832, 30.167112],
|
||||
[120.170001, 30.162286],
|
||||
[120.170393, 30.161163],
|
||||
[120.170857, 30.160363],
|
||||
[120.171268, 30.159909],
|
||||
[120.171843, 30.159472],
|
||||
[120.172585, 30.159084],
|
||||
[120.173472, 30.158806],
|
||||
[120.176516, 30.158457],
|
||||
[120.178244, 30.158018],
|
||||
[120.181234, 30.156641],
|
||||
[120.182546, 30.156143],
|
||||
[120.187335, 30.155265],
|
||||
[120.188246, 30.155308],
|
||||
[120.188949, 30.155505],
|
||||
[120.189517, 30.155768],
|
||||
[120.190041, 30.156122],
|
||||
[120.191852, 30.157747],
|
||||
[120.192457, 30.158198],
|
||||
[120.199627, 30.161976],
|
||||
[120.200393, 30.161113],
|
||||
[120.201372, 30.160261],
|
||||
[120.204072, 30.158385],
|
||||
[120.204474, 30.157992],
|
||||
[120.205018, 30.15764],
|
||||
[120.205398, 30.157546],
|
||||
[120.205887, 30.157658],
|
||||
[120.205706, 30.15851],
|
||||
[120.206192, 30.158863],
|
||||
[120.206058, 30.159513],
|
||||
[120.206121, 30.159901],
|
||||
[120.207273, 30.160486],
|
||||
[120.208006, 30.160419],
|
||||
[120.208488, 30.159493],
|
||||
[120.208835, 30.158228],
|
||||
[120.208544, 30.157534],
|
||||
[120.206494, 30.157128],
|
||||
[120.207878, 30.156136],
|
||||
[120.208276, 30.156082],
|
||||
[120.208298, 30.156518],
|
||||
[120.209071, 30.157141],
|
||||
[120.210222, 30.156577],
|
||||
[120.210388, 30.157044],
|
||||
[120.210978, 30.157462],
|
||||
[120.212571, 30.158131],
|
||||
[120.212937, 30.158078],
|
||||
[120.213941, 30.157481],
|
||||
[120.214887, 30.159206],
|
||||
[120.214888, 30.160837],
|
||||
[120.215479, 30.161676],
|
||||
[120.215645, 30.162161],
|
||||
[120.215948, 30.162305],
|
||||
[120.218933, 30.162964],
|
||||
[120.21947, 30.162984],
|
||||
[120.221036, 30.16208],
|
||||
[120.221542, 30.161941],
|
||||
[120.221799, 30.162783],
|
||||
[120.222203, 30.163521],
|
||||
[120.222931, 30.164169],
|
||||
[120.225012, 30.165453],
|
||||
[120.225443, 30.165901],
|
||||
[120.226118, 30.16827],
|
||||
[120.226124, 30.168557],
|
||||
[120.225875, 30.168755],
|
||||
[120.226207, 30.170185],
|
||||
[120.226446, 30.170469],
|
||||
[120.226639, 30.170573],
|
||||
[120.227512, 30.170626],
|
||||
[120.227522, 30.171242],
|
||||
[120.227796, 30.171909],
|
||||
[120.229737, 30.172137],
|
||||
[120.229916, 30.171461],
|
||||
[120.23, 30.170618],
|
||||
[120.230569, 30.170018],
|
||||
[120.233933, 30.169673],
|
||||
[120.23455, 30.165985],
|
||||
[120.234458, 30.164828],
|
||||
[120.234558, 30.162136],
|
||||
[120.234676, 30.16115],
|
||||
[120.235118, 30.159612],
|
||||
[120.235576, 30.158653],
|
||||
[120.235617, 30.15825],
|
||||
[120.236053, 30.157277],
|
||||
[120.235382, 30.157034],
|
||||
[120.235301, 30.156572],
|
||||
[120.23496, 30.156239],
|
||||
[120.234249, 30.155793],
|
||||
[120.233696, 30.155684],
|
||||
[120.2332, 30.15573],
|
||||
[120.232496, 30.155586],
|
||||
[120.23286, 30.154907],
|
||||
[120.233495, 30.154176],
|
||||
[120.232856, 30.153878],
|
||||
[120.232683, 30.153433],
|
||||
[120.232879, 30.153278],
|
||||
[120.232872, 30.152843],
|
||||
[120.232724, 30.152397],
|
||||
[120.23234, 30.151877],
|
||||
[120.231848, 30.151555],
|
||||
[120.231595, 30.151273],
|
||||
[120.231185, 30.150624],
|
||||
[120.230557, 30.150187],
|
||||
[120.230053, 30.149345],
|
||||
[120.229281, 30.148778],
|
||||
[120.228917, 30.148747],
|
||||
[120.228421, 30.14842],
|
||||
[120.228184, 30.147479],
|
||||
[120.226923, 30.147425],
|
||||
[120.226418, 30.147328],
|
||||
[120.225486, 30.147388],
|
||||
[120.226496, 30.146217],
|
||||
[120.225966, 30.145733],
|
||||
[120.225583, 30.145521],
|
||||
[120.225428, 30.14502],
|
||||
[120.224312, 30.14501],
|
||||
[120.223858, 30.144788],
|
||||
[120.223652, 30.144476],
|
||||
[120.223478, 30.144345],
|
||||
[120.222825, 30.14418],
|
||||
[120.222569, 30.14428],
|
||||
[120.221885, 30.144124],
|
||||
[120.221396, 30.144273],
|
||||
[120.220971, 30.1447],
|
||||
[120.220603, 30.144724],
|
||||
[120.220295, 30.144623],
|
||||
[120.220024, 30.144701],
|
||||
[120.219842, 30.144619],
|
||||
[120.219654, 30.144693],
|
||||
[120.219384, 30.144654],
|
||||
[120.218498, 30.144158],
|
||||
[120.217793, 30.143521],
|
||||
[120.217119, 30.143362],
|
||||
[120.216758, 30.14301],
|
||||
[120.216674, 30.14272],
|
||||
[120.216732, 30.142301],
|
||||
[120.217668, 30.141623],
|
||||
[120.218151, 30.141431],
|
||||
[120.220282, 30.139534],
|
||||
[120.220356, 30.140206],
|
||||
[120.220619, 30.140315],
|
||||
[120.220731, 30.140486],
|
||||
[120.221293, 30.140608],
|
||||
[120.221736, 30.140936],
|
||||
[120.221342, 30.141563],
|
||||
[120.22151, 30.141869],
|
||||
[120.220996, 30.142466],
|
||||
[120.22197, 30.142837],
|
||||
[120.223564, 30.142785],
|
||||
[120.223847, 30.142422],
|
||||
[120.223877, 30.142059],
|
||||
[120.223806, 30.141797],
|
||||
[120.221855, 30.139726],
|
||||
[120.2231, 30.140085],
|
||||
[120.223641, 30.140564],
|
||||
[120.223948, 30.141129],
|
||||
[120.223997, 30.141173],
|
||||
[120.224257, 30.141696],
|
||||
[120.224258, 30.142105],
|
||||
[120.224381, 30.142548],
|
||||
[120.224535, 30.142716],
|
||||
[120.224726, 30.143188],
|
||||
[120.2255, 30.143728],
|
||||
[120.226119, 30.144357],
|
||||
[120.226434, 30.14455],
|
||||
[120.228071, 30.144609],
|
||||
[120.229719, 30.144786],
|
||||
[120.229908, 30.14485],
|
||||
[120.23018, 30.145286],
|
||||
[120.230407, 30.145484],
|
||||
[120.231237, 30.145853],
|
||||
[120.231382, 30.146076],
|
||||
[120.231631, 30.146207],
|
||||
[120.232288, 30.146322],
|
||||
[120.233052, 30.146667],
|
||||
[120.23368, 30.14734],
|
||||
[120.233786, 30.147891],
|
||||
[120.234623, 30.14832],
|
||||
[120.234839, 30.148646],
|
||||
[120.235314, 30.149087],
|
||||
[120.23548, 30.149626],
|
||||
[120.235721, 30.149938],
|
||||
[120.236457, 30.150391],
|
||||
[120.23716, 30.150539],
|
||||
[120.237485, 30.150801],
|
||||
[120.23803, 30.151477],
|
||||
[120.239139, 30.152535],
|
||||
[120.23946, 30.153088],
|
||||
[120.240229, 30.153121],
|
||||
[120.240626, 30.152351],
|
||||
[120.241359, 30.151459],
|
||||
[120.242314, 30.150725],
|
||||
[120.245302, 30.148847],
|
||||
[120.24628, 30.147889],
|
||||
[120.247034, 30.146693],
|
||||
[120.247423, 30.145397],
|
||||
[120.247992, 30.145405],
|
||||
[120.248012, 30.143993],
|
||||
[120.247725, 30.142724],
|
||||
[120.247166, 30.142646],
|
||||
[120.242305, 30.130879],
|
||||
[120.241721, 30.130596],
|
||||
[120.240334, 30.12946],
|
||||
[120.239997, 30.129042],
|
||||
[120.238317, 30.125574],
|
||||
[120.237006, 30.123431],
|
||||
[120.236783, 30.122886],
|
||||
[120.235868, 30.122206],
|
||||
[120.236571, 30.122049],
|
||||
[120.23665, 30.121468],
|
||||
[120.235894, 30.119696],
|
||||
[120.235675, 30.118672],
|
||||
[120.235701, 30.117587],
|
||||
[120.235629, 30.11654],
|
||||
[120.235379, 30.116023],
|
||||
[120.233483, 30.116034],
|
||||
[120.233123, 30.116188],
|
||||
[120.232895, 30.116075],
|
||||
[120.231727, 30.115965],
|
||||
[120.230487, 30.116072],
|
||||
[120.230015, 30.116313],
|
||||
[120.229969, 30.115245],
|
||||
[120.229787, 30.11438],
|
||||
[120.229945, 30.113327],
|
||||
[120.232144, 30.112345],
|
||||
[120.233516, 30.111985],
|
||||
[120.235989, 30.111814],
|
||||
[120.234895, 30.107582],
|
||||
[120.234778, 30.106555],
|
||||
[120.234895, 30.104915],
|
||||
[120.230596, 30.103151],
|
||||
[120.2278, 30.101876],
|
||||
[120.226383, 30.101599],
|
||||
[120.222325, 30.1023],
|
||||
[120.2147, 30.103149],
|
||||
[120.212667, 30.103445],
|
||||
[120.21219, 30.10365],
|
||||
[120.211945, 30.103932],
|
||||
[120.210495, 30.107288],
|
||||
[120.209991, 30.108123],
|
||||
[120.209384, 30.108529],
|
||||
[120.208824, 30.10864],
|
||||
[120.208085, 30.108556],
|
||||
[120.205857, 30.107717],
|
||||
[120.205393, 30.107652],
|
||||
[120.204861, 30.107693],
|
||||
[120.201864, 30.109287],
|
||||
[120.20089, 30.109712],
|
||||
[120.199973, 30.109881],
|
||||
[120.193121, 30.109323],
|
||||
[120.191151, 30.109647],
|
||||
[120.190646, 30.109835],
|
||||
[120.190888, 30.111217],
|
||||
[120.190796, 30.111259],
|
||||
[120.190086, 30.109884],
|
||||
[120.189525, 30.109667],
|
||||
[120.18587, 30.107744],
|
||||
[120.185064, 30.109015],
|
||||
[120.183326, 30.113489],
|
||||
[120.18151, 30.11587],
|
||||
[120.180172, 30.11726],
|
||||
[120.177758, 30.119219],
|
||||
[120.174527, 30.121509],
|
||||
[120.173028, 30.122505],
|
||||
[120.172232, 30.122899],
|
||||
[120.171456, 30.123117],
|
||||
[120.170975, 30.12361],
|
||||
[120.170378, 30.12466],
|
||||
[120.166094, 30.128398],
|
||||
[120.165454, 30.129692],
|
||||
[120.164526, 30.130852],
|
||||
[120.163489, 30.131706],
|
||||
[120.162161, 30.132556],
|
||||
[120.160762, 30.133219],
|
||||
[120.158745, 30.134854],
|
||||
[120.156354, 30.137038],
|
||||
[120.154387, 30.138586],
|
||||
[120.152292, 30.139893],
|
||||
[120.150055, 30.14083],
|
||||
[120.149208, 30.142005],
|
||||
[120.148552, 30.143085],
|
||||
[120.147844, 30.143857],
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'Feature',
|
||||
properties: {
|
||||
label: 'B类区域',
|
||||
value: 'B',
|
||||
featureId: '2021102300040027',
|
||||
id: '2021102300040027',
|
||||
name: '于争光',
|
||||
groupId: '2021102300073562',
|
||||
canvasId: '2021102300077947',
|
||||
creator: '285869',
|
||||
modifier: 'WB904416',
|
||||
gmtCreate: '2021-10-23T13:23:53.000+00:00',
|
||||
gmtModified: '2021-10-29T08:43:06.000+00:00',
|
||||
status: 1,
|
||||
bizId: 'ALGO13301000000030038b',
|
||||
source: 'INIT',
|
||||
extInfo: {
|
||||
area_centroid: '[120.200270,30.137812]',
|
||||
},
|
||||
},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [
|
||||
[
|
||||
[120.1636505126953, 30.24631485403797],
|
||||
[120.17704010009766, 30.22970466206658],
|
||||
[120.19214630126953, 30.243942141326617],
|
||||
[120.1636505126953, 30.24631485403797],
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'Feature',
|
||||
properties: {
|
||||
label: 'C类区域',
|
||||
value: 'C',
|
||||
featureId: '2021102300040027',
|
||||
id: '2021102300040027',
|
||||
name: 'ecnevnevnec',
|
||||
groupId: '2021102300073562',
|
||||
canvasId: '2021102300077947',
|
||||
creator: '285869',
|
||||
modifier: 'WB904416',
|
||||
gmtCreate: '2021-10-23T13:23:53.000+00:00',
|
||||
gmtModified: '2021-10-29T08:43:06.000+00:00',
|
||||
status: 1,
|
||||
bizId: 'ALGO13301000000030038b',
|
||||
source: 'INIT',
|
||||
extInfo: {
|
||||
area_centroid: '[120.200270,30.137812]',
|
||||
},
|
||||
},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [
|
||||
[
|
||||
[120.09017944335938, 30.224958377428475],
|
||||
[120.08949279785156, 30.18994745521063],
|
||||
[120.14751434326172, 30.189353942421295],
|
||||
[120.14854431152342, 30.22466172703242],
|
||||
[120.09017944335938, 30.224958377428475],
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
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,20 +0,0 @@
|
|||
import { registerWidget } from '@antv/dipper-core';
|
||||
import {
|
||||
CitySelect,
|
||||
SiderBar,
|
||||
NavBar,
|
||||
ClassifyColor,
|
||||
DiscreteColor,
|
||||
} from '@antv/dipper-widgets';
|
||||
import { GridLayer } from './GridLayer';
|
||||
import { MapStyle } from '@antv/dipper-widgets';
|
||||
|
||||
export function initWidgets() {
|
||||
registerWidget('citySelect', CitySelect);
|
||||
registerWidget('siderbartabcontent', SiderBar);
|
||||
registerWidget('navibar', NavBar);
|
||||
registerWidget('gridLayer', GridLayer);
|
||||
registerWidget('classifyColor', ClassifyColor);
|
||||
registerWidget('discreteColor', DiscreteColor);
|
||||
registerWidget('mapStyle', MapStyle);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
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 }} />;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
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 }} />;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
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 }} />;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
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 }} />;
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
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: [],
|
||||
};
|
|
@ -0,0 +1,199 @@
|
|||
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: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
|
@ -2,6 +2,7 @@ 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[];
|
|
@ -0,0 +1,25 @@
|
|||
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>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
.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;
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
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>
|
||||
)
|
||||
}
|
|
@ -34,15 +34,43 @@ export function GridLayer() {
|
|||
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: 'discreteColor',
|
||||
type: 'multiClassifyColor',
|
||||
display: true,
|
||||
position: 'bottomleft',
|
||||
options: {
|
||||
targetName: '区域类型',
|
||||
title: '网格',
|
||||
unkownName: layerProps.options.unkownName,
|
||||
items,
|
||||
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);
|
||||
});
|
||||
}),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -70,10 +98,18 @@ export function GridLayer() {
|
|||
return;
|
||||
}
|
||||
|
||||
const color = ['#CFE1B9','#B0C298','#90A276','#718355']
|
||||
|
||||
const layer = new GridLayerGroup({
|
||||
name: 'grid',
|
||||
geodata: geoData,
|
||||
options: layerProps.options,
|
||||
data: geoData,
|
||||
options: {
|
||||
...layerProps.options,
|
||||
fill:{
|
||||
...layerProps.options.fill,
|
||||
color
|
||||
}
|
||||
},
|
||||
});
|
||||
layerService.addLayer(layer);
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
.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);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
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>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
.meahname {
|
||||
padding: 20px;
|
||||
}
|
||||
.closeicon {
|
||||
padding: 0 8px;
|
||||
}
|
||||
.edit {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.edit span:hover {
|
||||
color: #1890ff;
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
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}
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
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>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
.meshTools{
|
||||
width: 32px;
|
||||
height: 160px;
|
||||
background: #fff;
|
||||
border-radius: 2px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding:15px 5px;
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
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>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import { SaveOutlined } from '@ant-design/icons';
|
||||
import { Button } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
export function Save() {
|
||||
return (
|
||||
<Button type="text" icon={<SaveOutlined />}>
|
||||
保存
|
||||
</Button>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
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>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
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>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
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>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
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)
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
.dippercontainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
height: 538px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 30px;
|
||||
font-family: 'PingFangSC-Semibold';
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 16px;
|
||||
color: #697B8C;
|
||||
font-family: 'PingFangSC-Regular';
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.dipperdemo {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.dipperitem {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
min-width: 400px;
|
||||
max-width: 600px;
|
||||
margin:40px 20px;
|
||||
}
|
||||
|
||||
.dipperimg {
|
||||
border-radius: 50%;
|
||||
box-shadow: inset 0 0 16px 4px rgba(115, 108, 255, 0.44);
|
||||
background-color: rgba(#746CFF, 0.24);
|
||||
height: 180px;
|
||||
width: 180px;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.dipperitem:hover .dipperimg{
|
||||
padding: 32px;
|
||||
border: 8px solid rgba(115, 108, 255, 0.08);
|
||||
box-shadow: inset 0 0 16px 4px rgba(115, 108, 255, 0.44);
|
||||
}
|
||||
|
||||
.dippertitle {
|
||||
font-size: 24px;
|
||||
font-family: 'PingFangSC-Semibold';
|
||||
color: #0D1A26;
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.dipperitem:hover .dippertitle {
|
||||
color: #873BF4;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
.dippermapcontainer{
|
||||
/* height: 656px; */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-top: 68px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 30px;
|
||||
font-family: 'PingFangSC-Semibold';
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 16px;
|
||||
color: #697B8C;
|
||||
font-family: 'PingFangSC-Regular';
|
||||
padding-top: 20px;
|
||||
}
|
||||
.carousel{
|
||||
width: 80%;
|
||||
padding-top: 36px;
|
||||
}
|
||||
.carousel img{
|
||||
width: 100%;
|
||||
height: 520px;
|
||||
object-fit: cover;
|
||||
}
|
||||
.ant-carousel-vertical .slick-dots-right{
|
||||
right: -40px !important;
|
||||
top: 100px;
|
||||
}
|
|
@ -16,5 +16,8 @@
|
|||
"深版精彩案例": "Dark Theme",
|
||||
"感谢信赖":"WE ARE TRUSTED BY",
|
||||
"新版发布" : "New Version",
|
||||
"一个个真实的地理数据可视化案例,将复杂的地理数据,通过简单,易用的API接口,让用户达到开箱即用的效果。" : "We have summarized a series of story design templates from lots of real geospatial data visualization cases, so that users can use them directly."
|
||||
"一个个真实的地理数据可视化案例,将复杂的地理数据,通过简单,易用的API接口,让用户达到开箱即用的效果。" : "We have summarized a series of story design templates from lots of real geospatial data visualization cases, so that users can use them directly.",
|
||||
"指挥监控场景": "Command monitoring scene",
|
||||
"指挥分配场景": "Command distribution scenario",
|
||||
"可视化配置场景": "Visual configuration scenario"
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
const Page: React.FC & { noLayout: boolean } = () => <h1>地图</h1>;
|
||||
|
||||
Page.noLayout = true;
|
||||
|
||||
export default Page;
|
|
@ -6,75 +6,15 @@ import Features from '@antv/gatsby-theme-antv/site/components/Features';
|
|||
import SEO from '@antv/gatsby-theme-antv/site/components/Seo';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useConfig } from './useConfig';
|
||||
import { Dipper } from '../components/Dipper';
|
||||
import { DipperMap } from '../components/DipperMap';
|
||||
import '../css/home.css';
|
||||
|
||||
const IndexPage = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const { L7Case, L7Features,notifications,companies, ecosystems} = useConfig();
|
||||
|
||||
const features = [
|
||||
{
|
||||
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 companies = [
|
||||
{
|
||||
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 bannerButtons = [
|
||||
{
|
||||
text: t('图表示例'),
|
||||
|
@ -87,43 +27,55 @@ const IndexPage = () => {
|
|||
},
|
||||
];
|
||||
|
||||
const notifications = [
|
||||
|
||||
const dipper = [
|
||||
{
|
||||
type: t('推荐'),
|
||||
title: t('如何制作不一样的疫情世界地图-酷炫、动感的地理可视化'),
|
||||
date: '2020.03.12',
|
||||
link: 'https://www.yuque.com/antv/blog/wigku2',
|
||||
title: t('配置化'),
|
||||
image: 'https://gw.alipayobjects.com/zos/bmw-prod/a8d32053-ef9d-485e-ae13-2b49535e6f4f.svg',
|
||||
link: `/${i18n.language}/view`
|
||||
},
|
||||
{
|
||||
type: t('新版发布'),
|
||||
title: t('L7 2.1 正式版'),
|
||||
date: '2020.03.12',
|
||||
link: ' https://www.yuque.com/antv/blog/ows55v',
|
||||
title: t('组件化'),
|
||||
image: 'https://gw.alipayobjects.com/zos/bmw-prod/4235cc53-ef5f-4a47-a33c-1623df19e4b7.svg',
|
||||
link: `/${i18n.language}/task`
|
||||
},
|
||||
{
|
||||
title: t('自由定制'),
|
||||
image: 'https://gw.alipayobjects.com/zos/bmw-prod/29cbd68c-86ac-440c-a38d-792dbd8aea61.svg',
|
||||
link: 'https://dippermap.alipay.com'
|
||||
}
|
||||
];
|
||||
|
||||
const cases = [
|
||||
const dippermap = [
|
||||
{
|
||||
logo:
|
||||
'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*gjBmT56SDgsAAAAAAAAAAABkARQnAQ',
|
||||
title: t('浅版精彩案例'),
|
||||
description: t(
|
||||
'一个个真实的地理数据可视化案例,将复杂的地理数据,通过简单,易用的API接口,让用户达到开箱即用的效果。',
|
||||
),
|
||||
link: `/${i18n.language}/examples/gallery/basic`,
|
||||
image:
|
||||
'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*h1vhT6eSVPkAAAAAAAAAAABkARQnAQ',
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_e7e1c6/afts/img/A*6S8hQJAUB2oAAAAAAAAAAAAAARQnAQ',
|
||||
alt: 'heat',
|
||||
desc: '3D热力图',
|
||||
},
|
||||
{
|
||||
logo:
|
||||
'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*gjBmT56SDgsAAAAAAAAAAABkARQnAQ',
|
||||
title: t('深版精彩案例'),
|
||||
description: t(
|
||||
'一个个真实的地理数据可视化案例,将复杂的地理数据,通过简单,易用的API接口,让用户达到开箱即用的效果。',
|
||||
),
|
||||
link: `/${i18n.language}/examples/gallery/basic`,
|
||||
image:
|
||||
'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*-gtxQbUPoGQAAAAAAAAAAABkARQnAQ',
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_e7e1c6/afts/img/A*R8juSLJc86wAAAAAAAAAAAAAARQnAQ',
|
||||
alt: '3DARC',
|
||||
desc: '3D曲线',
|
||||
},
|
||||
{
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_e7e1c6/afts/img/A*MDmtT6lRS6EAAAAAAAAAAAAAARQnAQ',
|
||||
alt: 'trip',
|
||||
desc: '路径图',
|
||||
},
|
||||
{
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_e7e1c6/afts/img/A*lRdLQotjkKsAAAAAAAAAAAAAARQnAQ',
|
||||
alt: 'point',
|
||||
desc: '3D柱图',
|
||||
},
|
||||
{
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_e7e1c6/afts/img/A*W_DMQ5DVmIsAAAAAAAAAAAAAARQnAQ',
|
||||
alt: 'polygon',
|
||||
desc: '中国3D地图',
|
||||
},
|
||||
{
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_e7e1c6/afts/img/A*InJXT6G-l6UAAAAAAAAAAAAAARQnAQ',
|
||||
alt: 'hex',
|
||||
desc: '六边形图',
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -140,16 +92,19 @@ const IndexPage = () => {
|
|||
}
|
||||
title={t('L7 空间数据可视分析')}
|
||||
description={t(
|
||||
'蚂蚁金服 AntV 数据可视化团队推出的基于 WebGL 的开源大规模地理空间数据可视分析开发框架。',
|
||||
'蚂蚁金服 AntV 数据可视化团队推出的基于 WebGL 的开源大规模地理空间数据可视分析引擎。',
|
||||
)}
|
||||
buttons={bannerButtons}
|
||||
notifications={notifications}
|
||||
className="banner"
|
||||
githubStarLink="https://github.com/antvis/L7/stargazers"
|
||||
/>
|
||||
<Features features={features} style={{ width: '100%' }} />
|
||||
<Cases cases={cases} />
|
||||
<Features features={L7Features} style={{ width: '100%' }} />
|
||||
<Dipper dipper={dipper} />
|
||||
<Cases cases={L7Case} />
|
||||
<DipperMap dippermap={dippermap} />
|
||||
<Companies title={t('感谢信赖')} companies={companies} />
|
||||
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
import Index from './map.zh';
|
||||
export default Index;
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import Loadable from "@loadable/component"
|
||||
const Map = Loadable(() => import("../components/rumbling"))
|
||||
const Map = Loadable(() => import("../components/analysis"))
|
||||
const Page: React.FC & { noLayout: boolean } = () => <Map/>;
|
||||
|
||||
Page.noLayout = true;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
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;
|
|
@ -0,0 +1,2 @@
|
|||
import Index from './task.en';
|
||||
export default Index;
|
|
@ -0,0 +1,159 @@
|
|||
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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
import Index from './view.zh';
|
||||
export default Index;
|
|
@ -0,0 +1,8 @@
|
|||
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