Skip to content

Commit

Permalink
fix icon layer text label
Browse files Browse the repository at this point in the history
Signed-off-by: Shan He <heshan0131@gmail.com>
  • Loading branch information
heshan0131 committed Feb 18, 2020
1 parent d824566 commit 9b903f8
Show file tree
Hide file tree
Showing 8 changed files with 277 additions and 106 deletions.
9 changes: 8 additions & 1 deletion src/layers/base-layer.js
Expand Up @@ -819,7 +819,14 @@ export default class Layer {

return {
getData: {datasetId: id, columns, filteredIndex},
getMeta: {datasetId: id, columns}
getMeta: {datasetId: id, columns},
...(this.config.textLabel || []).reduce(
(accu, tl, i) => ({
...accu,
[`getLabelCharacterSet-${i}`]: tl.field ? tl.field.name : null
}),
{}
)
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/layers/geojson-layer/geojson-layer.js
Expand Up @@ -205,7 +205,6 @@ export default class GeoJsonLayer extends Layer {
// TODO: fix complexity
/* eslint-disable complexity */
formatLayerData(datasets, oldLayerData, opt = {}) {
console.log('formatLayerData')

const {
colorScale,
Expand Down Expand Up @@ -421,7 +420,7 @@ export default class GeoJsonLayer extends Layer {
getFilterValue: gpuFilter.filterValueUpdateTriggers
};

const defaultLayerProps = this.getDefau
const defaultLayerProps = this.getDefaultDeckLayerProps(opts);
return [
new DeckGLGeoJsonLayer({
...defaultLayerProps,
Expand Down
90 changes: 70 additions & 20 deletions src/layers/icon-layer/icon-layer.js
Expand Up @@ -27,6 +27,7 @@ import IconLayerIcon from './icon-layer-icon';
import {ICON_FIELDS, CLOUDFRONT} from 'constants/default-settings';
import IconInfoModalFactory from './icon-info-modal';
import Layer from '../base-layer';
import {getTextOffsetByRadius, formatTextLabelData} from '../layer-text-label';

const brushingExtension = new BrushingExtension();

Expand All @@ -49,9 +50,16 @@ export const pointVisConfigs = {
};

function flatterIconPositions(icon) {
// had to flip y, since @luma modal has changed
return icon.mesh.cells.reduce((prev, cell) => {
cell.forEach(p => {
Array.prototype.push.apply(prev, icon.mesh.positions[p]);
prev.push(...(
[
icon.mesh.positions[p][0],
-icon.mesh.positions[p][1],
icon.mesh.positions[p][2]
]
))
});
return prev;
}, []);
Expand Down Expand Up @@ -204,12 +212,16 @@ export default class IconLayer extends Layer {
sizeField,
sizeScale,
sizeDomain,
textLabel,
visConfig: {radiusRange, colorRange}
} = this.config;
const getPosition = this.getPositionAccessor();

const {gpuFilter} = datasets[this.config.dataId];
const {data} = this.updateData(datasets, oldLayerData);
const {data, triggerChanged} = this.updateData(
datasets,
oldLayerData
);

// point color
const cScale =
Expand All @@ -231,12 +243,21 @@ export default class IconLayer extends Layer {
? d => this.getEncodedChannelValue(cScale, d.data, colorField)
: color;

// get all distinct characters in the text labels
const textLabels = formatTextLabelData({
textLabel,
triggerChanged,
oldLayerData,
data
});

return {
data,
getPosition,
getFillColor,
getFilterValue: gpuFilter.filterValueAccessor(),
getRadius
getRadius,
textLabels
};
}

Expand All @@ -254,13 +275,52 @@ export default class IconLayer extends Layer {
interactionConfig
} = opts;

const radiusScale = this.getRadiusScaleByZoom(mapState);

const layerProps = {
radiusScale: this.getRadiusScaleByZoom(mapState),
radiusScale,
...(this.config.visConfig.fixedRadius ? {} : {radiusMaxPixels: 500})
};

const updateTriggers = {
getFilterValue: gpuFilter.filterValueUpdateTriggers,
getRadius: {
sizeField: this.config.colorField,
radiusRange: this.config.visConfig.radiusRange,
sizeScale: this.config.sizeScale
},
getFillColor: {
color: this.config.color,
colorField: this.config.colorField,
colorRange: this.config.visConfig.colorRange,
colorScale: this.config.colorScale
}
};

const defaultLayerProps = this.getDefaultDeckLayerProps(opts);
const brushingProps = this.getBrushingExtensionProps(interactionConfig);
const getPixelOffset = getTextOffsetByRadius(
radiusScale,
data.getRadius,
mapState
);
const extensions = [...defaultLayerProps.extensions, brushingExtension];

// shared Props point layer and tex layer
const sharedProps = {
getFilterValue: data.getFilterValue,
extensions,
filterRange: defaultLayerProps.filterRange,
...brushingProps
};
const labelLayers = [
...this.renderTextLabelLayer({
getPosition: data.getPosition,
sharedProps,
getPixelOffset,
updateTriggers
}, opts)
]

return !this.iconGeometry
? []
Expand All @@ -273,21 +333,8 @@ export default class IconLayer extends Layer {
getIconGeometry: id => this.iconGeometry[id],

// update triggers
updateTriggers: {
getFilterValue: gpuFilter.filterValueUpdateTriggers,
getRadius: {
sizeField: this.config.colorField,
radiusRange: this.config.visConfig.radiusRange,
sizeScale: this.config.sizeScale
},
getFillColor: {
color: this.config.color,
colorField: this.config.colorField,
colorRange: this.config.visConfig.colorRange,
colorScale: this.config.colorScale
}
},
extensions: [...defaultLayerProps.extensions, brushingExtension]
updateTriggers,
extensions
}),

...(this.isLayerHovered(objectHovered)
Expand All @@ -302,7 +349,10 @@ export default class IconLayer extends Layer {
getIconGeometry: id => this.iconGeometry[id]
})
]
: [])
: []),

// text label layer
...labelLayers
];
}
}
86 changes: 86 additions & 0 deletions src/layers/layer-text-label.js
@@ -0,0 +1,86 @@

// Copyright (c) 2020 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import {getDistanceScales} from 'viewport-mercator-project';
import {notNullorUndefined} from 'utils/data-utils';
import uniq from 'lodash.uniq';

export function getTextOffsetByRadius(radiusScale, getRadius, mapState) {

return textLabel => {
const distanceScale = getDistanceScales(mapState);
const xMult =
textLabel.anchor === 'middle' ? 0 : textLabel.anchor === 'start' ? 1 : -1;
const yMult =
textLabel.alignment === 'center' ? 0 : textLabel.alignment === 'bottom' ? 1 : -1;

const sizeOffset =
textLabel.alignment === 'center'
? 0
: textLabel.alignment === 'bottom'
? textLabel.size
: textLabel.size;

const pixelRadius = radiusScale * distanceScale.pixelsPerMeter[0];
const padding = 20;

return typeof getRadius === 'function'
? d => [
xMult * (getRadius(d) * pixelRadius + padding),
yMult * (getRadius(d) * pixelRadius + padding + sizeOffset)
]
: [
xMult * (getRadius * pixelRadius + padding),
yMult * (getRadius * pixelRadius + padding + sizeOffset)
];
}
}

export const textLabelAccessor = textLabel => d => {
const val = d.data[textLabel.field.tableFieldIndex - 1];
return notNullorUndefined(val) ? String(val) : '';
};

export const formatTextLabelData = ({textLabel, triggerChanged, oldLayerData, data}) => {
return textLabel.map((tl, i) => {
if (!tl.field) {
// if no field selected,
return {
getText: null,
characterSet: []
};
}

const getText = textLabelAccessor(tl);
let characterSet;

if (!triggerChanged[`getLabelCharacterSet-${i}`]) {
characterSet = oldLayerData.textLabels[i].characterSet;
} else {
const allLabels = tl.field ? data.map(getText) : [];
characterSet = uniq(allLabels.join(''));
}

return {
characterSet,
getText
};
});
}

0 comments on commit 9b903f8

Please sign in to comment.