mirror of https://gitee.com/antv-l7/antv-l7
fix(layer): fix sum statistic
This commit is contained in:
parent
064917c37b
commit
4dc0cfac3c
|
@ -0,0 +1,40 @@
|
|||
import { Scene, HeatmapLayer } from '@antv/l7';
|
||||
import { Mapbox } from '@antv/l7-maps';
|
||||
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
style: 'blank',
|
||||
pitch: 0,
|
||||
center: [ 110.097892, 33.853662 ],
|
||||
zoom: 4.056
|
||||
})
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
fetch(
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/3dadb1f5-8f54-4449-8206-72db6e142c40.json'
|
||||
)
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
const layer = new HeatmapLayer({
|
||||
autoFit: true
|
||||
})
|
||||
.source(data, {
|
||||
transforms: [
|
||||
{
|
||||
type: 'hexagon',
|
||||
size: 5 * 100000
|
||||
}
|
||||
]
|
||||
})
|
||||
.shape('circle')
|
||||
.active(false)
|
||||
.color('#aaa')
|
||||
.style({
|
||||
coverage: 0.7,
|
||||
angle: 0,
|
||||
opacity: 1.0
|
||||
});
|
||||
scene.addLayer(layer);
|
||||
});
|
||||
});
|
|
@ -4,6 +4,11 @@
|
|||
"en": "heatmap"
|
||||
},
|
||||
"demos": [
|
||||
{
|
||||
"filename": "grid_world.js",
|
||||
"title": "网格世界地图",
|
||||
"screenshot":"https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*1PeGSboLGUUAAAAAAAAAAABkARQnAQ"
|
||||
},
|
||||
{
|
||||
"filename": "china.js",
|
||||
"title": "网格热力图",
|
||||
|
|
|
@ -26,7 +26,7 @@ scene.on('loaded', () => {
|
|||
transforms: [
|
||||
{
|
||||
type: 'hexagon',
|
||||
size: 17000,
|
||||
size: 200000,
|
||||
field: 'v',
|
||||
method: 'sum'
|
||||
}
|
||||
|
|
|
@ -1,6 +1,128 @@
|
|||
// tslint:disable-next-line:no-submodule-imports
|
||||
import merge from 'lodash/merge';
|
||||
let DataConfig: { [key: string]: any } = {
|
||||
|
||||
let DataLevel = 1;
|
||||
const dataLevel1: { [key: string]: any } = {
|
||||
world: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/d666a08d-fce1-48e2-913a-87d81772bcc9.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/62f61f5f-cca7-4137-845d-13c8f9969664.bin',
|
||||
},
|
||||
label: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/90c51eb3-04d7-402f-bd05-95e4bd27dd62.bin',
|
||||
parser: {
|
||||
type: 'geojson',
|
||||
},
|
||||
},
|
||||
nationalBoundaries: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/ee493a41-0558-4c0e-bee6-520276c4f1a8.json',
|
||||
},
|
||||
},
|
||||
country: {
|
||||
CHN: {
|
||||
1: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/25228941-b2ac-4591-b07d-8261ac08d06f.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/70ec087e-c48a-4b76-8825-6452f17bae7a.bin',
|
||||
},
|
||||
provinceLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/0024caaf-86b2-4e75-a3d1-6d2146490b67.bin',
|
||||
},
|
||||
label: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/36832a45-68f8-4b51-b006-9dec71f92a23.json',
|
||||
},
|
||||
},
|
||||
2: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/522c6496-c711-4581-88db-c3741cd39abd.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/f6a4e2b1-359b-43a6-921c-39d2088d1dab.bin',
|
||||
},
|
||||
cityLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/f6a4e2b1-359b-43a6-921c-39d2088d1dab.bin',
|
||||
},
|
||||
provinceLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/0024caaf-86b2-4e75-a3d1-6d2146490b67.bin',
|
||||
},
|
||||
},
|
||||
3: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/516b2703-d692-44e6-80dd-b3f5df0186e7.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/bc97875a-90f2-42c0-a62c-43d2efd7460d.bin',
|
||||
},
|
||||
countryLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/bc97875a-90f2-42c0-a62c-43d2efd7460d.bin',
|
||||
},
|
||||
cityLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/8bfbfe7e-bd0e-4bbe-84d8-629f4dc7abc4.bin',
|
||||
},
|
||||
provinceLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/778ad7ba-5a3f-4ed6-a94a-b8ab8acae9d6.bin',
|
||||
},
|
||||
},
|
||||
nationalBoundaries: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/ee493a41-0558-4c0e-bee6-520276c4f1a8.json',
|
||||
},
|
||||
nationalBoundaries2: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/f2189cc4-662b-4358-8573-36f0f918b7ca.json',
|
||||
},
|
||||
island: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/fe49b393-1147-4769-94ed-70471f4ff15d.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
province: {
|
||||
110000: '',
|
||||
},
|
||||
};
|
||||
const dataLevel2: { [key: string]: any } = {
|
||||
world: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
|
@ -121,8 +243,21 @@ let DataConfig: { [key: string]: any } = {
|
|||
},
|
||||
};
|
||||
|
||||
function setDataConfig(config: any) {
|
||||
DataConfig = merge(DataConfig, config);
|
||||
const DataLevelMap: { [key: string]: any } = {
|
||||
1: dataLevel1,
|
||||
2: dataLevel2,
|
||||
};
|
||||
|
||||
function setDataConfig(config: any, level: number = DataLevel) {
|
||||
merge(DataLevelMap[level], config);
|
||||
}
|
||||
function getDataConfig(level: number = DataLevel) {
|
||||
return DataLevelMap[level];
|
||||
}
|
||||
|
||||
export { setDataConfig, DataConfig };
|
||||
function setDataLevel(level: number) {
|
||||
DataLevel = level;
|
||||
}
|
||||
|
||||
const DataConfig = DataLevelMap[DataLevel];
|
||||
export { setDataConfig, setDataLevel, getDataConfig, DataConfig };
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { DataConfig, setDataConfig } from './config_1';
|
||||
// import { DataConfig, setDataConfig } from './config_1';
|
||||
import CityLayer from './layer/city';
|
||||
import CountryLayer from './layer/country';
|
||||
import CountyLayer from './layer/county';
|
||||
|
@ -12,6 +12,5 @@ export {
|
|||
CityLayer,
|
||||
CountyLayer,
|
||||
DrillDownLayer,
|
||||
setDataConfig,
|
||||
DataConfig,
|
||||
};
|
||||
export * from './config';
|
||||
|
|
|
@ -17,6 +17,7 @@ import isObject from 'lodash/isObject';
|
|||
import mergeWith from 'lodash/mergeWith';
|
||||
// @ts-ignore
|
||||
import Pbf from 'pbf';
|
||||
import { setDataLevel } from '../config';
|
||||
import { AttributeType, IDistrictLayerOption } from './interface';
|
||||
|
||||
function mergeCustomizer(objValue: any, srcValue: any) {
|
||||
|
@ -39,6 +40,7 @@ export default class BaseLayer extends EventEmitter {
|
|||
super();
|
||||
this.scene = scene;
|
||||
this.options = mergeWith(this.getDefaultOption(), option, mergeCustomizer);
|
||||
setDataLevel(this.options.geoDataLevel);
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
|
@ -92,6 +94,7 @@ export default class BaseLayer extends EventEmitter {
|
|||
protected getDefaultOption(): IDistrictLayerOption {
|
||||
return {
|
||||
zIndex: 0,
|
||||
geoDataLevel: 2,
|
||||
depth: 1,
|
||||
adcode: [],
|
||||
joinBy: ['name', 'name'],
|
||||
|
@ -141,7 +144,7 @@ export default class BaseLayer extends EventEmitter {
|
|||
chinaNationalWidth: 1,
|
||||
popup: {
|
||||
enable: true,
|
||||
openTriggerEvent: 'mouseenter',
|
||||
openTriggerEvent: 'mousemove',
|
||||
closeTriggerEvent: 'mouseout',
|
||||
option: {},
|
||||
Html: (properties: any) => {
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
import {
|
||||
ILayer,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Scene,
|
||||
StyleAttrField,
|
||||
} from '@antv/l7';
|
||||
// tslint:disable-next-line: no-submodule-imports
|
||||
import merge from 'lodash/merge';
|
||||
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
import {
|
||||
ILayer,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Scene,
|
||||
StyleAttrField,
|
||||
} from '@antv/l7';
|
||||
import { DataConfig } from '../index';
|
||||
import { LineLayer, PointLayer, Scene, StyleAttrField } from '@antv/l7';
|
||||
import { getDataConfig } from '../index';
|
||||
import BaseLayer from './baseLayer';
|
||||
import { IDistrictLayerOption } from './interface';
|
||||
|
||||
|
@ -16,7 +9,9 @@ export default class CountryLayer extends BaseLayer {
|
|||
const { depth } = this.options;
|
||||
this.addProvinceFill();
|
||||
this.addProvinceLabel();
|
||||
const countryConfig = DataConfig.country.CHN[depth];
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).country.CHN[
|
||||
depth
|
||||
];
|
||||
|
||||
this.addProvinceLine(countryConfig.provinceLine);
|
||||
|
||||
|
@ -29,13 +24,15 @@ export default class CountryLayer extends BaseLayer {
|
|||
}
|
||||
protected async addProvinceFill() {
|
||||
const { depth } = this.options;
|
||||
const countryConfig = DataConfig.country.CHN[depth];
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).CHN[depth];
|
||||
const fillData = await this.fetchData(countryConfig.fill);
|
||||
this.addFillLayer(fillData);
|
||||
}
|
||||
protected async addProvinceLabel() {
|
||||
const { depth } = this.options;
|
||||
const countryConfig = DataConfig.country.CHN[depth];
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).country.CHN[
|
||||
depth
|
||||
];
|
||||
const fillLabel = countryConfig.label
|
||||
? await this.fetchData(countryConfig.label)
|
||||
: null;
|
||||
|
@ -93,7 +90,9 @@ export default class CountryLayer extends BaseLayer {
|
|||
|
||||
private async loadData() {
|
||||
const { depth } = this.options;
|
||||
const countryConfig = DataConfig.country.CHN[depth];
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).country.CHN[
|
||||
depth
|
||||
];
|
||||
const fillData = await this.fetchData(countryConfig.fill);
|
||||
const fillLabel = countryConfig.label
|
||||
? await this.fetchData(countryConfig.label)
|
||||
|
|
|
@ -73,6 +73,7 @@ export interface IBubbleOption {
|
|||
export type adcodeType = string[] | string | number | number[];
|
||||
export interface IDistrictLayerOption {
|
||||
zIndex: number;
|
||||
geoDataLevel: 1 | 2;
|
||||
data?: Array<{ [key: string]: any }>;
|
||||
joinBy: [string, string];
|
||||
adcode: adcodeType;
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
} from '@antv/l7';
|
||||
// tslint:disable-next-line: no-submodule-imports
|
||||
import merge from 'lodash/merge';
|
||||
import { DataConfig } from '../';
|
||||
import { getDataConfig } from '../';
|
||||
import BaseLayer from './baseLayer';
|
||||
import { adcodeType, IDistrictLayerOption } from './interface';
|
||||
|
||||
|
@ -97,7 +97,9 @@ export default class ProvinceLayer extends BaseLayer {
|
|||
}
|
||||
private async addProvinceFillLayer() {
|
||||
const { depth, adcode } = this.options as IProvinceLayerOption;
|
||||
const countryConfig = DataConfig.country.CHN[depth];
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).country.CHN[
|
||||
depth
|
||||
];
|
||||
const fillData = await this.fetchData(countryConfig.fill);
|
||||
|
||||
this.labelRawData = fillData.features.map((feature: any) => {
|
||||
|
@ -117,7 +119,9 @@ export default class ProvinceLayer extends BaseLayer {
|
|||
|
||||
private async addProvinceLineLayer() {
|
||||
const { depth, adcode } = this.options as IProvinceLayerOption;
|
||||
const countryConfig = DataConfig.country.CHN[depth];
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).country.CHN[
|
||||
depth
|
||||
];
|
||||
const fillData = await this.fetchData(countryConfig.line);
|
||||
const data = this.filterData(fillData, adcode);
|
||||
this.lineRawData = fillData;
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
Scene,
|
||||
StyleAttrField,
|
||||
} from '@antv/l7';
|
||||
import { DataConfig } from '../';
|
||||
import { getDataConfig } from '../';
|
||||
import BaseLayer from './baseLayer';
|
||||
import { IDistrictLayerOption } from './interface';
|
||||
export default class WorldLayer extends BaseLayer {
|
||||
|
@ -16,7 +16,7 @@ export default class WorldLayer extends BaseLayer {
|
|||
this.addFillLayer(fillData);
|
||||
this.addFillLine(lineData);
|
||||
if (this.options.label?.enable) {
|
||||
this.addLabelLayer(fillLabel, 'geojson');
|
||||
this.addLabelLayer(fillLabel, 'json');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -52,11 +52,17 @@ export default class WorldLayer extends BaseLayer {
|
|||
}
|
||||
|
||||
private async loadData() {
|
||||
const countryConfig = DataConfig.world;
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).world;
|
||||
|
||||
const fillData = await this.fetchData(countryConfig.fill);
|
||||
const lineData = await this.fetchData(countryConfig.line);
|
||||
const fillLabel = await this.fetchData(countryConfig.label);
|
||||
// const fillLabel = await this.fetchData(countryConfig.label);
|
||||
const fillLabel = fillData.features.map((feature: any) => {
|
||||
return {
|
||||
...feature.properties,
|
||||
center: [feature.properties.x, feature.properties.y],
|
||||
};
|
||||
});
|
||||
return [fillData, lineData, fillLabel];
|
||||
}
|
||||
private addNationBorder(boundaries: any, boundaries2: any) {
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import { sum } from '../src/statistics';
|
||||
describe('sum', () => {
|
||||
it('sum string array', () => {
|
||||
const a = ['1', '2', '3'];
|
||||
const b = [1, 2, 3];
|
||||
// @ts-ignore
|
||||
expect(sum(a)).toEqual(6);
|
||||
expect(sum(b)).toEqual(6);
|
||||
});
|
||||
});
|
|
@ -42,27 +42,12 @@ function sum(x: number[]) {
|
|||
// Initializing the sum as the first number in the array
|
||||
let sumNum = x[0] * 1;
|
||||
|
||||
// Keeping track of the floating-point error correction
|
||||
let correction = 0;
|
||||
|
||||
let transition;
|
||||
|
||||
for (let i = 1; i < x.length; i++) {
|
||||
transition = sumNum + x[i] * 1;
|
||||
|
||||
// Here we need to update the correction in a different fashion
|
||||
// if the new absolute value is greater than the absolute sum
|
||||
if (Math.abs(sumNum) >= Math.abs(x[i])) {
|
||||
correction += sumNum - transition + x[i];
|
||||
} else {
|
||||
correction += x[i] - transition + sumNum;
|
||||
}
|
||||
|
||||
sumNum = transition;
|
||||
sumNum += x[i] * 1;
|
||||
}
|
||||
|
||||
// Returning the corrected sum
|
||||
return sumNum + correction * 1;
|
||||
return sumNum;
|
||||
}
|
||||
function mean(x: number[]) {
|
||||
if (x.length === 0) {
|
||||
|
|
|
@ -44,12 +44,12 @@ export default class Country extends React.Component {
|
|||
label: {
|
||||
enable: true,
|
||||
textAllowOverlap: false,
|
||||
field: 'Short_Name_ZH',
|
||||
field: 'NAME_CHN',
|
||||
},
|
||||
popup: {
|
||||
enable: false,
|
||||
Html: (props) => {
|
||||
return `<span>${props.Short_Name_ZH}</span>`;
|
||||
return `<span>${props.NAME_CHN}</span>`;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ export default class HexagonLayerDemo extends React.Component {
|
|||
public async componentDidMount() {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
map: new GaodeMap({
|
||||
pitch: 0,
|
||||
style: 'blank',
|
||||
center: [140.067171, 36.26186],
|
||||
|
@ -26,40 +26,46 @@ export default class HexagonLayerDemo extends React.Component {
|
|||
});
|
||||
scene.on('loaded', () => {
|
||||
fetch(
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/3dadb1f5-8f54-4449-8206-72db6e142c40.json',
|
||||
'https://gw.alipayobjects.com/os/basement_prod/7359a5e9-3c5e-453f-b207-bc892fb23b84.csv',
|
||||
)
|
||||
.then((res) => res.json())
|
||||
.then((res) => res.text())
|
||||
.then((data) => {
|
||||
const pointLayer = new HeatmapLayer({
|
||||
autoFit: true,
|
||||
})
|
||||
.source(data, {
|
||||
parser: {
|
||||
type: 'csv',
|
||||
x: 'lng',
|
||||
y: 'lat',
|
||||
},
|
||||
transforms: [
|
||||
{
|
||||
type: 'grid',
|
||||
size: 500000,
|
||||
field: 'name',
|
||||
method: 'mode',
|
||||
type: 'hexagon',
|
||||
size: 200000,
|
||||
field: 'v',
|
||||
method: 'sum',
|
||||
},
|
||||
],
|
||||
})
|
||||
.shape('square') // 支持 circle, hexagon,triangle
|
||||
.color('mode', [
|
||||
'#ffffe5',
|
||||
'#fff7bc',
|
||||
'#fee391',
|
||||
'#fec44f',
|
||||
'#fe9929',
|
||||
'#ec7014',
|
||||
'#cc4c02',
|
||||
'#993404',
|
||||
'#662506',
|
||||
])
|
||||
.active(false)
|
||||
.size('sum', (value) => {
|
||||
return value * 20;
|
||||
})
|
||||
.shape('hexagonColumn')
|
||||
.color(
|
||||
'count',
|
||||
[
|
||||
'#FF4818',
|
||||
'#F7B74A',
|
||||
'#FFF598',
|
||||
'#FF40F3',
|
||||
'#9415FF',
|
||||
'#421EB2',
|
||||
].reverse(),
|
||||
)
|
||||
.style({
|
||||
coverage: 0.7,
|
||||
// angle: 0.5,
|
||||
opacity: 1.0,
|
||||
coverage: 0.9,
|
||||
angle: 0,
|
||||
});
|
||||
scene.addLayer(pointLayer);
|
||||
console.log(pointLayer.getSource());
|
||||
|
|
Loading…
Reference in New Issue