feat(react): add react lib

This commit is contained in:
thinkinggis 2020-02-11 20:31:55 +08:00
parent 48644b6414
commit e70f700486
20 changed files with 399 additions and 2 deletions

View File

@ -1,5 +1,5 @@
// tslint:disable-next-line:no-submodule-imports
import '!style-loader!css-loader!sass-loader!./iframe.scss';
// import '!style-loader!css-loader!sass-loader!./iframe.scss';
import { addParameters, configure } from '@storybook/react';
import { create } from '@storybook/theming';

View File

@ -116,7 +116,7 @@ export interface ILayer {
Partial<IModelInitializationOptions>,
): IModel;
init(): ILayer;
scale(field: string | IScaleOptions, cfg: IScale): ILayer;
scale(field: string | IScaleOptions, cfg?: IScale): ILayer;
size(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
color(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
shape(field: StyleAttrField, value?: StyleAttributeOption): ILayer;

11
packages/react/README.md Normal file
View File

@ -0,0 +1,11 @@
# `react`
> TODO: description
## Usage
```
const react = require('react');
// TODO: DEMONSTRATE API
```

View File

@ -0,0 +1,7 @@
'use strict';
const react = require('..');
describe('react', () => {
it('needs tests');
});

View File

@ -0,0 +1,36 @@
{
"name": "@antv/l7-react",
"version": "2.0.18",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
"types": "es/index.d.ts",
"sideEffects": true,
"files": [
"lib",
"es",
"README.md"
],
"scripts": {
"tsc": "tsc --project tsconfig.build.json",
"clean": "rimraf dist; rimraf es; rimraf lib;",
"build": "run-p build:*",
"build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
"lint:ts": "run-p -c lint:ts-*",
"test": "jest"
},
"author": "lzxue",
"license": "ISC",
"dependencies": {
"@antv/l7": "^2.0.18",
"@antv/l7-maps": "^2.0.18",
"react": "^16.8.6",
"@babel/runtime": "^7.7.7"
},
"gitHead": "f2bd3c6473df79d815467b1677c6f985cf68800e",
"publishConfig": {
"access": "public"
}
}

View File

@ -0,0 +1,17 @@
import * as React from 'react';
import { ILayerProps } from './LayerAttribute';
import BaseLayer from './LayerAttribute/Layer';
const PolygonLayer = React.memo(function Layer(props: ILayerProps) {
return BaseLayer('polygonLayer', props);
});
const LineLayer = React.memo(function Layer(props: ILayerProps) {
return BaseLayer('polygonLayer', props);
});
const PointLayer = React.memo(function Layer(props: ILayerProps) {
return BaseLayer('pointLayer', props);
});
export { PolygonLayer, LineLayer, PointLayer };

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;
color: Partial<IAttributeOptions>;
}
export default React.memo(function Chart(props: ILayerProps) {
const { layer, color } = props;
useEffect(() => {
color.field
? layer.color(color.field as StyleAttrField, color.values)
: layer.color(color.value as StyleAttrField);
}, [color.value, color.field, JSON.stringify(color.values)]);
return null;
});

View File

@ -0,0 +1,51 @@
import { ILayer, LineLayer, PointLayer, PolygonLayer, Scene } from '@antv/l7';
import * as React from 'react';
import { useSceneValue } from '../SceneContext';
import { Color, 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;
const mapScene = (useSceneValue() as unknown) as Scene;
const [layer, setLayer] = useState();
if (!layer) {
let l: ILayer;
switch (type) {
case 'polygonLayer':
l = new PolygonLayer(options);
break;
case 'lineLayer':
l = new LineLayer(options);
break;
case 'pointLayer':
l = new PointLayer(options);
break;
default:
l = new PolygonLayer(options);
}
setLayer(l);
}
useEffect(() => {
mapScene.addLayer(layer);
return () => {
mapScene.removeLayer(layer);
};
}, []);
useEffect(() => {
if (layer) {
mapScene.render();
}
});
return (
<>
<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} />}
</>
);
}

View File

@ -0,0 +1,21 @@
import { ILayer, IScale, IScaleOptions } from '@antv/l7';
import * as React from 'react';
import { IScaleAttributeOptions } from './';
const { useEffect } = React;
interface ILayerProps {
layer: ILayer;
scales: Partial<IScaleAttributeOptions>;
}
export default React.memo(function Chart(props: ILayerProps) {
const { layer, scales } = props;
useEffect(
() => {
scales.field
? layer.scale(scales.field as string, scales.value as IScale)
: layer.scale(scales.values as IScaleOptions);
},
Object.values(scales).map((scale) => JSON.stringify(scales)),
);
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;
shape: Partial<IAttributeOptions>;
}
export default React.memo(function Chart(props: ILayerProps) {
const { layer, shape } = props;
useEffect(() => {
shape.field
? layer.shape(shape.field, shape.values)
: layer.shape(shape.value as StyleAttrField);
}, [shape.field, shape.value, JSON.stringify(shape.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;
size: Partial<IAttributeOptions>;
}
export default React.memo(function Chart(props: ILayerProps) {
const { layer, size } = props;
useEffect(() => {
size.field
? layer.size(size.field, size.values)
: layer.size(size.value as StyleAttrField);
}, [size.field, size.value, JSON.stringify(size.values)]);
return null;
});

View File

@ -0,0 +1,19 @@
import { ILayer } from '@antv/l7';
import * as React from 'react';
import { ISourceOptions } from './';
const { useEffect } = React;
interface ISourceProps {
layer: ILayer;
source: Partial<ISourceOptions>;
}
export default React.memo(function Chart(props: ISourceProps) {
const { layer, source } = props;
const { data, ...sourceOption } = source;
useEffect(() => {
// @ts-ignore
layer.source(data, sourceOption);
}, []);
return null;
});

View File

@ -0,0 +1,16 @@
import { ILayer } from '@antv/l7';
import * as React from 'react';
import { IStyleOptions } from './';
const { useEffect } = React;
interface ILayerProps {
layer: ILayer;
style: Partial<IStyleOptions>;
}
export default React.memo(function Chart(props: ILayerProps) {
const { layer, style } = props;
useEffect(() => {
layer.style(style);
}, Object.values(style));
return null;
});

View File

@ -0,0 +1,38 @@
import { IScale, IScaleOptions, ISourceCFG } from '@antv/l7';
import Color from './Color';
import Scales from './Scales';
import Shape from './Shape';
import Size from './Size';
import Source from './Source';
import Style from './Style';
export interface IAttributeOptions {
field: string;
value: string | number;
values: string[] | number[] | string;
}
export interface IScaleAttributeOptions {
field: string;
value: IScale;
values: IScaleOptions;
}
export interface IStyleOptions {
opacity: number;
[key: string]: any;
}
export interface ISourceOptions extends ISourceCFG {
data: any;
}
export interface ILayerProps {
options?: {
[key: string]: any;
};
source: ISourceOptions;
color: Partial<IAttributeOptions>;
shape: Partial<IAttributeOptions>;
scales?: Partial<IScaleAttributeOptions>;
size?: Partial<IAttributeOptions>;
style?: Partial<IStyleOptions>;
}
export { Source, Size, Color, Shape, Style, Scales };

View File

@ -0,0 +1,42 @@
import { IMapWrapper, Scene } from '@antv/l7';
import React, { createElement, createRef, useEffect, useState } from 'react';
import SceneContext from './SceneContext';
interface IMapSceneConig {
style?: React.CSSProperties;
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 container = createRef();
const [scene, setScene] = useState();
useEffect(() => {
const sceneInstance = new Scene({
id: container.current as HTMLDivElement,
map,
});
sceneInstance.on('loaded', () => {
setScene(sceneInstance);
});
return () => {
sceneInstance.destroy();
};
}, []);
return (
<SceneContext.Provider value={scene}>
{createElement(
'div',
{
ref: container,
style,
className,
},
scene && props.children,
)}
</SceneContext.Provider>
);
});
export default MapScene;

View File

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

View File

@ -0,0 +1,3 @@
export * from './component/SceneContext';
export { default as Scene } from './component/Scene';
export * from './component/Layer';

View File

@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.build.json",
"compilerOptions": {
"declarationDir": "./es",
"rootDir": "./src",
"baseUrl": "./"
},
"include": ["./src"]
}

View File

@ -0,0 +1,6 @@
import { storiesOf } from '@storybook/react';
import * as React from 'react';
import GaodeMapScene from './components/Scene';
// @ts-ignore
storiesOf('React', module).add('高德地图', () => <GaodeMapScene />);

View File

@ -0,0 +1,60 @@
import { GaodeMap, Mapbox } from '@antv/l7-maps';
import { LineLayer, Scene } from '@antv/l7-react';
import * as React from 'react';
export default React.memo(function Map() {
// @ts-ignore
const amap = new GaodeMap({
center: [110.19382669582967, 50.258134],
pitch: 0,
style: 'dark',
zoom: 3,
});
const [data, setData] = React.useState();
React.useEffect(() => {
const fetchData = async () => {
const response = await fetch(
'https://gw.alipayobjects.com/os/basement_prod/32e1f3ab-8588-46cb-8a47-75afb692117d.json',
);
const data = await response.json();
setData(data);
};
fetchData();
}, []);
return (
<>
<Scene
map={amap}
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
>
{data && (
<LineLayer
key={'2'}
source={{
data,
}}
size={{
value: 1,
}}
color={{
value: '#fff',
}}
shape={{
value: 'line',
}}
style={{
opacity: 1,
}}
/>
)}
</Scene>
/>
</>
);
});