[3.0] Improvment image map (#2729)

* Add support setting position function

* Improved setting image map

* Add support setting offset marker
This commit is contained in:
Vladyslav 2020-05-05 13:47:37 +03:00 committed by GitHub
parent f7efb79015
commit adc982923d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 202 deletions

View File

@ -94,6 +94,8 @@ export type MarkerSettings = {
tooltipFunction: GenericFunction;
labelFunction: GenericFunction;
markerImageFunction?: MarkerImageFunction;
markerOffsetX: number;
markerOffsetY: number;
}
export interface FormattedData {

View File

@ -96,7 +96,7 @@ export class MapWidgetController implements MapWidgetInterface {
const schema = initSchema();
addToSchema(schema, this.getProvidersSchema(mapProvider));
addGroupInfo(schema, 'Map Provider Settings');
addToSchema(schema, addCondition(commonMapSettingsSchema, 'model.provider !== "image-map"'));
addToSchema(schema, commonMapSettingsSchema);
addGroupInfo(schema, 'Common Map Settings');
addToSchema(schema, addCondition(mapPolygonSchema, 'model.showPolygon === true', ['showPolygon']));
addGroupInfo(schema, 'Polygon Settings');

View File

@ -18,10 +18,12 @@ import L, { LeafletMouseEvent } from 'leaflet';
import { FormattedData, MarkerSettings } from './map-models';
import { aspectCache, createTooltip, parseWithTranslation, safeExecute } from './maps-utils';
import tinycolor from 'tinycolor2';
import { isDefined } from '@core/utils';
export class Marker {
leafletMarker: L.Marker;
tooltipOffset: [number, number];
markerOffset: [number, number];
tooltip: L.Popup;
location: L.LatLngExpression;
data: FormattedData;
@ -34,9 +36,14 @@ export class Marker {
draggable: settings.draggableMarker
});
this.markerOffset = [
isDefined(settings.markerOffsetX) ? settings.markerOffsetX : 0.5,
isDefined(settings.markerOffsetY) ? settings.markerOffsetY : 1,
];
this.createMarkerIcon((iconInfo) => {
this.leafletMarker.setIcon(iconInfo.icon);
this.tooltipOffset = [0, -iconInfo.size[1] + 10];
this.tooltipOffset = [0, -iconInfo.size[1] * this.markerOffset[1] + 10];
this.updateMarkerLabel(settings);
});
@ -95,7 +102,7 @@ export class Marker {
updateMarkerIcon(settings: MarkerSettings) {
this.createMarkerIcon((iconInfo) => {
this.leafletMarker.setIcon(iconInfo.icon);
this.tooltipOffset = [0, -iconInfo.size[1] + 10];
this.tooltipOffset = [0, -iconInfo.size[1] * this.markerOffset[1] + 10];
this.updateMarkerLabel(settings);
});
}
@ -130,7 +137,7 @@ export class Marker {
const icon = L.icon({
iconUrl: currentImage.url,
iconSize: [width, height],
iconAnchor: [width / 2, height],
iconAnchor: [width * this.markerOffset[0], height * this.markerOffset[1]],
popupAnchor: [0, -height]
});
const iconInfo = {
@ -152,7 +159,7 @@ export class Marker {
const icon = L.icon({
iconUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + color,
iconSize: [21, 34],
iconAnchor: [10, 34],
iconAnchor: [21 * this.markerOffset[0], 34 * this.markerOffset[1]],
popupAnchor: [0, -34],
shadowUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_shadow',
shadowSize: [40, 37],

View File

@ -30,10 +30,11 @@ export class ImageMap extends LeafletMap {
width = 0;
height = 0;
imageUrl;
posFunction;
constructor($container: HTMLElement, options: UnitedMapSettings) {
super($container, options);
options.posFunction = parseFunction(options.posFunction, ['origXPos', 'origYPos']) as ((origXPos, origYPos) => { x, y });
this.posFunction = parseFunction(options.posFunction, ['origXPos', 'origYPos']) as ((origXPos, origYPos) => { x, y });
this.imageUrl = options.mapUrl;
aspectCache(this.imageUrl).subscribe(aspect => {
this.aspect = aspect;
@ -132,9 +133,10 @@ export class ImageMap extends LeafletMap {
convertPosition(expression): L.LatLng {
if (isNaN(expression[this.options.xPosKeyName]) || isNaN(expression[this.options.yPosKeyName])) return null;
Object.assign(expression, this.posFunction(expression[this.options.xPosKeyName], expression[this.options.yPosKeyName]))
return this.pointToLatLng(
expression[this.options.xPosKeyName] * this.width,
expression[this.options.yPosKeyName] * this.height);
expression.x * this.width,
expression.y * this.height);
}
pointToLatLng(x, y): L.LatLng {

View File

@ -275,6 +275,16 @@ export const commonMapSettingsSchema =
type: 'string',
default: 'longitude'
},
xPosKeyName: {
title: 'X position key name',
type: 'string',
default: 'xPos'
},
yPosKeyName: {
title: 'Y position key name',
type: 'string',
default: 'yPos'
},
showLabel: {
title: 'Show label',
type: 'boolean',
@ -323,6 +333,21 @@ export const commonMapSettingsSchema =
title: 'Tooltip function: f(data, dsData, dsIndex)',
type: 'string'
},
posFunction: {
title: 'Position conversion function: f(origXPos, origYPos), should return x,y coordinates as double from 0 to 1 each',
type: 'string',
default: 'return {x: origXPos, y: origYPos};'
},
markerOffsetX: {
title: 'Marker X offset relative to position',
type: 'number',
default: 0.5
},
markerOffsetY: {
title: 'Marker Y offset relative to position',
type: 'number',
default: 1
},
color: {
title: 'Color',
type: 'string'
@ -366,14 +391,40 @@ export const commonMapSettingsSchema =
required: []
},
form: [
'defaultZoomLevel',
'useDefaultCenterPosition',
'defaultCenterPosition',
'fitMapBounds',
{
key: 'defaultZoomLevel',
condition: 'model.provider !== "image-map"'
},
{
key: 'useDefaultCenterPosition',
condition: 'model.provider !== "image-map"'
},
{
key: 'defaultCenterPosition',
condition: 'model.provider !== "image-map"'
},
{
key: 'fitMapBounds',
condition: 'model.provider !== "image-map"'
},
'draggableMarker',
'disableScrollZooming',
'latKeyName',
'lngKeyName',
{
key: 'latKeyName',
condition: 'model.provider !== "image-map"'
},
{
key: 'lngKeyName',
condition: 'model.provider !== "image-map"'
},
{
key: 'xPosKeyName',
condition: 'model.provider === "image-map"'
},
{
key: 'yPosKeyName',
condition: 'model.provider === "image-map"'
},
'showLabel',
'label',
'useLabelFunction',
@ -407,6 +458,19 @@ export const commonMapSettingsSchema =
key: 'tooltipFunction',
type: 'javascript'
},
{
key: 'markerOffsetX',
condition: 'model.provider === "image-map"'
},
{
key: 'markerOffsetY',
condition: 'model.provider === "image-map"'
},
{
key: 'posFunction',
type: 'javascript',
condition: 'model.provider === "image-map"'
},
{
key: 'color',
type: 'color'
@ -632,123 +696,6 @@ export const imageMapSettingsSchema =
title: 'Image URL source entity attribute',
type: 'string',
default: ''
},
disableScrollZooming: {
title: 'Disable scroll zooming',
type: 'boolean',
default: false
},
xPosKeyName: {
title: 'X position key name',
type: 'string',
default: 'xPos'
},
yPosKeyName: {
title: 'Y position key name',
type: 'string',
default: 'yPos'
},
showLabel: {
title: 'Show label',
type: 'boolean',
default: true
},
label: {
title: 'Label (pattern examples: \'${entityName}\', \'${entityName}: (Text ${keyName} units.)\' )',
type: 'string',
default: '${entityName}'
},
useLabelFunction: {
title: 'Use label function',
type: 'boolean',
default: false
},
labelFunction: {
title: 'Label function: f(data, dsData, dsIndex)',
type: 'string'
},
showTooltip: {
title: 'Show tooltip',
type: 'boolean',
default: true
},
showTooltipAction: {
title: 'Action for displaying the tooltip',
type: 'string',
default: 'click'
},
autocloseTooltip: {
title: 'Auto-close tooltips',
type: 'boolean',
default: true
},
tooltipPattern: {
title: 'Tooltip (for ex. \'Text ${keyName} units.\' or <link-act name=\'my-action\'>Link text</link-act>\')',
type: 'string',
default: '<b>${entityName}</b><br/><br/><b>X Pos:</b> ${xPos:2}<br/><b>Y Pos:</b> ${yPos:2}'
},
useTooltipFunction: {
title: 'Use tooltip function',
type: 'boolean',
default: false
},
tooltipFunction: {
title: 'Tooltip function: f(data, dsData, dsIndex)',
type: 'string'
},
color: {
title: 'Color',
type: 'string'
},
posFunction: {
title: 'Position conversion function: f(origXPos, origYPos), should return x,y coordinates as double from 0 to 1 each',
type: 'string',
default: 'return {x: origXPos, y: origYPos};'
},
markerOffsetX: {
title: 'Marker X offset relative to position',
type: 'number',
default: 0.5
},
markerOffsetY: {
title: 'Marker Y offset relative to position',
type: 'number',
default: 1
},
useColorFunction: {
title: 'Use color function',
type: 'boolean',
default: false
},
colorFunction: {
title: 'Color function: f(data, dsData, dsIndex)',
type: 'string'
},
markerImage: {
title: 'Custom marker image',
type: 'string'
},
markerImageSize: {
title: 'Custom marker image size (px)',
type: 'number',
default: 34
},
useMarkerImageFunction: {
title: 'Use marker image function',
type: 'boolean',
default: false
},
markerImageFunction: {
title: 'Marker image function: f(data, images, dsData, dsIndex)',
type: 'string'
},
markerImages: {
title: 'Marker images',
type: 'array',
items: {
title: 'Marker image',
type: 'string'
}
}
},
required: []
@ -759,77 +706,7 @@ export const imageMapSettingsSchema =
type: 'image'
},
'imageEntityAlias',
'imageUrlAttribute',
'disableScrollZooming',
'xPosKeyName',
'yPosKeyName',
'showLabel',
'label',
'useLabelFunction',
{
key: 'labelFunction',
type: 'javascript'
},
'showTooltip',
{
key: 'showTooltipAction',
type: 'rc-select',
multiple: false,
items: [
{
value: 'click',
label: 'Show tooltip on click (Default)'
},
{
value: 'hover',
label: 'Show tooltip on hover'
}
]
},
'autocloseTooltip',
{
key: 'tooltipPattern',
type: 'textarea'
},
'useTooltipFunction',
{
key: 'tooltipFunction',
type: 'javascript'
},
{
key: 'color',
type: 'color'
},
{
key: 'posFunction',
type: 'javascript'
},
'markerOffsetX',
'markerOffsetY',
'useColorFunction',
{
key: 'colorFunction',
type: 'javascript'
},
{
key: 'markerImage',
type: 'image'
},
'markerImageSize',
'useMarkerImageFunction',
{
key: 'markerImageFunction',
type: 'javascript'
},
{
key: 'markerImages',
items: [
{
key: 'markerImages[]',
type: 'image'
}
]
}
'imageUrlAttribute'
]
};