Merge pull request #213 from wufenfen/master

优化React封装,新增组件
This commit is contained in:
@thinkinggis 2020-02-19 09:32:27 +08:00 committed by GitHub
commit ba2fbaa942
14 changed files with 152 additions and 25 deletions

View File

@ -2,7 +2,9 @@ import * as React from 'react';
import { ILayerProps } from './LayerAttribute';
import BaseLayer from './LayerAttribute/Layer';
const PolygonLayer = React.memo(function Layer(props: ILayerProps) {
const PolygonLayer = React.memo(function Layer(
props: ILayerProps & { children?: any },
) {
return BaseLayer('polygonLayer', props);
});
@ -10,7 +12,9 @@ const LineLayer = React.memo(function Layer(props: ILayerProps) {
return BaseLayer('polygonLayer', props);
});
const PointLayer = React.memo(function Layer(props: ILayerProps) {
const PointLayer = React.memo(function Layer(
props: ILayerProps & { children?: any },
) {
return BaseLayer('pointLayer', props);
});

View File

@ -0,0 +1,17 @@
import { IActiveOption, ILayer } from '@antv/l7';
import * as React from 'react';
const { useEffect } = React;
interface ILayerProps {
layer: ILayer;
active: {
option: IActiveOption | boolean;
};
}
export default React.memo(function Chart(props: ILayerProps) {
const { layer, active } = props;
useEffect(() => {
layer.active(active.option);
}, [active, layer]);
return null;
});

View File

@ -13,6 +13,6 @@ export default React.memo(function Chart(props: ILayerProps) {
color.field
? layer.color(color.field as StyleAttrField, color.values)
: layer.color(color.value as StyleAttrField);
}, [color.value, color.field, JSON.stringify(color.values)]);
}, [color.value, color.field, JSON.stringify(color.values), color.values]);
return null;
});

View File

@ -0,0 +1,18 @@
import { ILayer, StyleAttrField } from '@antv/l7';
import * as React from 'react';
import { IAttributeOptions } from './';
const { useEffect } = React;
interface ILayerProps {
layer: ILayer;
filter: Partial<IAttributeOptions>;
}
export default React.memo(function Chart(props: ILayerProps) {
const { layer, filter } = props;
useEffect(() => {
if (filter.field) {
layer.filter(filter.field as string, filter.values as StyleAttrField);
}
}, [filter.field, JSON.stringify(filter.values), filter.values]);
return null;
});

View File

@ -1,12 +1,37 @@
import { ILayer, LineLayer, PointLayer, PolygonLayer, Scene } from '@antv/l7';
import * as React from 'react';
import { LayerContext } from '../LayerContext';
import { useSceneValue } from '../SceneContext';
import { Color, ILayerProps, Scales, Shape, Size, Source, Style } from './';
import {
Active,
Color,
Filter,
ILayerProps,
Scales,
Shape,
Size,
Source,
Style,
} from './';
const { useEffect, useState } = React;
export default function BaseLayer(type: string, props: ILayerProps) {
const { source, color, shape, style, size, scales, options } = props;
export default function BaseLayer(
type: string,
props: ILayerProps & { children?: any },
) {
const {
source,
color,
shape,
style,
size,
scales,
active,
filter,
options,
} = props;
const mapScene = (useSceneValue() as unknown) as Scene;
const [layer, setLayer] = useState();
if (!layer) {
@ -39,13 +64,17 @@ export default function BaseLayer(type: string, props: ILayerProps) {
}
});
return (
<>
<LayerContext.Provider value={layer}>
<Source layer={layer} source={source} />
{scales && <Scales layer={layer} scales={scales} />}
<Color layer={layer} color={color} />
{size && <Size layer={layer} size={size} />}
<Shape layer={layer} shape={shape} />
{style && <Style layer={layer} style={style} />}
</>
{active && <Active layer={layer} active={active} />}
{filter && <Filter layer={layer} filter={filter} />}
{/* LayerContext主要传入LayerEvent组件 */}
{props.children}
</LayerContext.Provider>
);
}

View File

@ -13,6 +13,6 @@ export default React.memo(function Chart(props: ILayerProps) {
shape.field
? layer.shape(shape.field, shape.values)
: layer.shape(shape.value as StyleAttrField);
}, [shape.field, shape.value, JSON.stringify(shape.values)]);
}, [shape.field, shape.value, JSON.stringify(shape.values), shape.values]);
return null;
});

View File

@ -13,6 +13,6 @@ export default React.memo(function Chart(props: ILayerProps) {
size.field
? layer.size(size.field, size.values)
: layer.size(size.value as StyleAttrField);
}, [size.field, size.value, JSON.stringify(size.values)]);
}, [size.field, size.value, JSON.stringify(size.values), size.values]);
return null;
});

View File

@ -12,8 +12,15 @@ export default React.memo(function Chart(props: ISourceProps) {
const { data, ...sourceOption } = source;
useEffect(() => {
// @ts-ignore
layer.source(data, sourceOption);
}, []);
if (!layer.inited) {
layer.source(data, sourceOption);
} else {
layer.setData(data, sourceOption);
if (layer.type === 'PolygonLayer') {
// 重新设置data之后自适应处理
layer.fitBounds();
}
}
}, [data]);
return null;
});

View File

@ -1,14 +1,19 @@
import { IScale, IScaleOptions, ISourceCFG } from '@antv/l7';
import { IActiveOption, IScale, IScaleOptions, ISourceCFG } from '@antv/l7';
import Active from './Active';
import Color from './Color';
import Filter from './Filter';
import Scales from './Scales';
import Shape from './Shape';
import Size from './Size';
import Source from './Source';
import Style from './Style';
type CallBack = (...args: any[]) => any;
export interface IAttributeOptions {
field: string;
value: string | number;
values: string[] | number[] | string;
value: string | number | CallBack;
values: string[] | number[] | string | CallBack;
}
export interface IScaleAttributeOptions {
@ -20,9 +25,14 @@ export interface IStyleOptions {
opacity: number;
[key: string]: any;
}
export interface ISourceOptions extends ISourceCFG {
data: any;
}
export interface IActiveOptions {
option: IActiveOption | boolean;
}
export interface ILayerProps {
options?: {
[key: string]: any;
@ -33,6 +43,8 @@ export interface ILayerProps {
scales?: Partial<IScaleAttributeOptions>;
size?: Partial<IAttributeOptions>;
style?: Partial<IStyleOptions>;
active?: IActiveOptions;
filter?: Partial<IAttributeOptions>;
}
export { Source, Size, Color, Shape, Style, Scales };
export { Active, Color, Filter, Source, Size, Shape, Style, Scales };

View File

@ -0,0 +1,7 @@
import { Layers } from '@antv/l7';
import { createContext, useContext } from 'react';
export const LayerContext = createContext(null);
export function useLayerValue(): Layers {
return (useContext(LayerContext) as unknown) as Layers;
}

View File

@ -0,0 +1,18 @@
import { ILayer } from '@antv/l7';
import * as React from 'react';
import { useLayerValue } from './LayerContext';
const { useEffect } = React;
interface ILayerProps {
type: string;
handler: (...args: any[]) => void;
}
export const LayerEvent = React.memo((props: ILayerProps) => {
const { type, handler } = props;
const layer = (useLayerValue() as unknown) as ILayer;
useEffect(() => {
layer.on(type, handler);
}, [type]);
return null;
});

View File

@ -1,14 +1,19 @@
import { IMapWrapper, Scene } from '@antv/l7';
import React, { createElement, createRef, useEffect, useState } from 'react';
import SceneContext from './SceneContext';
import { SceneContext } from './SceneContext';
interface IMapSceneConig {
style?: React.CSSProperties;
// 配置项,比如是否禁止鼠标缩放地图
options?: {
[key: string]: any;
};
className?: string;
map: IMapWrapper;
children?: JSX.Element | JSX.Element[] | Array<JSX.Element | undefined>;
}
const MapScene = React.memo((props: IMapSceneConig) => {
const { style, className, map } = props;
const { style, className, map, options } = props;
const container = createRef();
const [scene, setScene] = useState();
useEffect(() => {
@ -18,6 +23,14 @@ const MapScene = React.memo((props: IMapSceneConig) => {
});
sceneInstance.on('loaded', () => {
setScene(sceneInstance);
// 禁止鼠标滚轮缩放地图
if (options && !options.enableMouseZoom) {
const mapsService = sceneInstance.getMapService();
if (mapsService && mapsService.getType() === 'mapbox') {
(mapsService.map as any).scrollZoom.disable();
}
// TODO高德地图的禁止待补充
}
});
return () => {
sceneInstance.destroy();
@ -39,4 +52,4 @@ const MapScene = React.memo((props: IMapSceneConig) => {
);
});
export default MapScene;
export { MapScene };

View File

@ -1,7 +1,7 @@
import { Scene } from '@antv/l7';
import { createContext, useContext } from 'react';
const SceneContext = createContext(null);
export const SceneContext = createContext(null);
export function useSceneValue(): Scene {
return (useContext(SceneContext) as unknown) as Scene;
}
export default SceneContext;

View File

@ -1,3 +1,5 @@
export * from './component/SceneContext';
export { default as Scene } from './component/Scene';
export * from './component/Layer';
export { MapScene } from './component/Scene';
export { PolygonLayer, LineLayer, PointLayer } from './component/Layer';
export { LayerEvent } from './component/LayerEvent';
export { useSceneValue, SceneContext } from './component/SceneContext';
export { useLayerValue, LayerContext } from './component/LayerContext';