[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:
parent
f7efb79015
commit
adc982923d
@ -94,6 +94,8 @@ export type MarkerSettings = {
|
|||||||
tooltipFunction: GenericFunction;
|
tooltipFunction: GenericFunction;
|
||||||
labelFunction: GenericFunction;
|
labelFunction: GenericFunction;
|
||||||
markerImageFunction?: MarkerImageFunction;
|
markerImageFunction?: MarkerImageFunction;
|
||||||
|
markerOffsetX: number;
|
||||||
|
markerOffsetY: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormattedData {
|
export interface FormattedData {
|
||||||
|
|||||||
@ -96,7 +96,7 @@ export class MapWidgetController implements MapWidgetInterface {
|
|||||||
const schema = initSchema();
|
const schema = initSchema();
|
||||||
addToSchema(schema, this.getProvidersSchema(mapProvider));
|
addToSchema(schema, this.getProvidersSchema(mapProvider));
|
||||||
addGroupInfo(schema, 'Map Provider Settings');
|
addGroupInfo(schema, 'Map Provider Settings');
|
||||||
addToSchema(schema, addCondition(commonMapSettingsSchema, 'model.provider !== "image-map"'));
|
addToSchema(schema, commonMapSettingsSchema);
|
||||||
addGroupInfo(schema, 'Common Map Settings');
|
addGroupInfo(schema, 'Common Map Settings');
|
||||||
addToSchema(schema, addCondition(mapPolygonSchema, 'model.showPolygon === true', ['showPolygon']));
|
addToSchema(schema, addCondition(mapPolygonSchema, 'model.showPolygon === true', ['showPolygon']));
|
||||||
addGroupInfo(schema, 'Polygon Settings');
|
addGroupInfo(schema, 'Polygon Settings');
|
||||||
|
|||||||
@ -18,10 +18,12 @@ import L, { LeafletMouseEvent } from 'leaflet';
|
|||||||
import { FormattedData, MarkerSettings } from './map-models';
|
import { FormattedData, MarkerSettings } from './map-models';
|
||||||
import { aspectCache, createTooltip, parseWithTranslation, safeExecute } from './maps-utils';
|
import { aspectCache, createTooltip, parseWithTranslation, safeExecute } from './maps-utils';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
|
import { isDefined } from '@core/utils';
|
||||||
|
|
||||||
export class Marker {
|
export class Marker {
|
||||||
leafletMarker: L.Marker;
|
leafletMarker: L.Marker;
|
||||||
tooltipOffset: [number, number];
|
tooltipOffset: [number, number];
|
||||||
|
markerOffset: [number, number];
|
||||||
tooltip: L.Popup;
|
tooltip: L.Popup;
|
||||||
location: L.LatLngExpression;
|
location: L.LatLngExpression;
|
||||||
data: FormattedData;
|
data: FormattedData;
|
||||||
@ -34,9 +36,14 @@ export class Marker {
|
|||||||
draggable: settings.draggableMarker
|
draggable: settings.draggableMarker
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.markerOffset = [
|
||||||
|
isDefined(settings.markerOffsetX) ? settings.markerOffsetX : 0.5,
|
||||||
|
isDefined(settings.markerOffsetY) ? settings.markerOffsetY : 1,
|
||||||
|
];
|
||||||
|
|
||||||
this.createMarkerIcon((iconInfo) => {
|
this.createMarkerIcon((iconInfo) => {
|
||||||
this.leafletMarker.setIcon(iconInfo.icon);
|
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);
|
this.updateMarkerLabel(settings);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -95,7 +102,7 @@ export class Marker {
|
|||||||
updateMarkerIcon(settings: MarkerSettings) {
|
updateMarkerIcon(settings: MarkerSettings) {
|
||||||
this.createMarkerIcon((iconInfo) => {
|
this.createMarkerIcon((iconInfo) => {
|
||||||
this.leafletMarker.setIcon(iconInfo.icon);
|
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);
|
this.updateMarkerLabel(settings);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -130,7 +137,7 @@ export class Marker {
|
|||||||
const icon = L.icon({
|
const icon = L.icon({
|
||||||
iconUrl: currentImage.url,
|
iconUrl: currentImage.url,
|
||||||
iconSize: [width, height],
|
iconSize: [width, height],
|
||||||
iconAnchor: [width / 2, height],
|
iconAnchor: [width * this.markerOffset[0], height * this.markerOffset[1]],
|
||||||
popupAnchor: [0, -height]
|
popupAnchor: [0, -height]
|
||||||
});
|
});
|
||||||
const iconInfo = {
|
const iconInfo = {
|
||||||
@ -152,7 +159,7 @@ export class Marker {
|
|||||||
const icon = L.icon({
|
const icon = L.icon({
|
||||||
iconUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + color,
|
iconUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + color,
|
||||||
iconSize: [21, 34],
|
iconSize: [21, 34],
|
||||||
iconAnchor: [10, 34],
|
iconAnchor: [21 * this.markerOffset[0], 34 * this.markerOffset[1]],
|
||||||
popupAnchor: [0, -34],
|
popupAnchor: [0, -34],
|
||||||
shadowUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_shadow',
|
shadowUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_shadow',
|
||||||
shadowSize: [40, 37],
|
shadowSize: [40, 37],
|
||||||
|
|||||||
@ -30,10 +30,11 @@ export class ImageMap extends LeafletMap {
|
|||||||
width = 0;
|
width = 0;
|
||||||
height = 0;
|
height = 0;
|
||||||
imageUrl;
|
imageUrl;
|
||||||
|
posFunction;
|
||||||
|
|
||||||
constructor($container: HTMLElement, options: UnitedMapSettings) {
|
constructor($container: HTMLElement, options: UnitedMapSettings) {
|
||||||
super($container, options);
|
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;
|
this.imageUrl = options.mapUrl;
|
||||||
aspectCache(this.imageUrl).subscribe(aspect => {
|
aspectCache(this.imageUrl).subscribe(aspect => {
|
||||||
this.aspect = aspect;
|
this.aspect = aspect;
|
||||||
@ -132,9 +133,10 @@ export class ImageMap extends LeafletMap {
|
|||||||
|
|
||||||
convertPosition(expression): L.LatLng {
|
convertPosition(expression): L.LatLng {
|
||||||
if (isNaN(expression[this.options.xPosKeyName]) || isNaN(expression[this.options.yPosKeyName])) return null;
|
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(
|
return this.pointToLatLng(
|
||||||
expression[this.options.xPosKeyName] * this.width,
|
expression.x * this.width,
|
||||||
expression[this.options.yPosKeyName] * this.height);
|
expression.y * this.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
pointToLatLng(x, y): L.LatLng {
|
pointToLatLng(x, y): L.LatLng {
|
||||||
|
|||||||
@ -275,6 +275,16 @@ export const commonMapSettingsSchema =
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
default: 'longitude'
|
default: 'longitude'
|
||||||
},
|
},
|
||||||
|
xPosKeyName: {
|
||||||
|
title: 'X position key name',
|
||||||
|
type: 'string',
|
||||||
|
default: 'xPos'
|
||||||
|
},
|
||||||
|
yPosKeyName: {
|
||||||
|
title: 'Y position key name',
|
||||||
|
type: 'string',
|
||||||
|
default: 'yPos'
|
||||||
|
},
|
||||||
showLabel: {
|
showLabel: {
|
||||||
title: 'Show label',
|
title: 'Show label',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
@ -323,6 +333,21 @@ export const commonMapSettingsSchema =
|
|||||||
title: 'Tooltip function: f(data, dsData, dsIndex)',
|
title: 'Tooltip function: f(data, dsData, dsIndex)',
|
||||||
type: 'string'
|
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: {
|
color: {
|
||||||
title: 'Color',
|
title: 'Color',
|
||||||
type: 'string'
|
type: 'string'
|
||||||
@ -366,14 +391,40 @@ export const commonMapSettingsSchema =
|
|||||||
required: []
|
required: []
|
||||||
},
|
},
|
||||||
form: [
|
form: [
|
||||||
'defaultZoomLevel',
|
{
|
||||||
'useDefaultCenterPosition',
|
key: 'defaultZoomLevel',
|
||||||
'defaultCenterPosition',
|
condition: 'model.provider !== "image-map"'
|
||||||
'fitMapBounds',
|
},
|
||||||
|
{
|
||||||
|
key: 'useDefaultCenterPosition',
|
||||||
|
condition: 'model.provider !== "image-map"'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'defaultCenterPosition',
|
||||||
|
condition: 'model.provider !== "image-map"'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'fitMapBounds',
|
||||||
|
condition: 'model.provider !== "image-map"'
|
||||||
|
},
|
||||||
'draggableMarker',
|
'draggableMarker',
|
||||||
'disableScrollZooming',
|
'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',
|
'showLabel',
|
||||||
'label',
|
'label',
|
||||||
'useLabelFunction',
|
'useLabelFunction',
|
||||||
@ -407,6 +458,19 @@ export const commonMapSettingsSchema =
|
|||||||
key: 'tooltipFunction',
|
key: 'tooltipFunction',
|
||||||
type: 'javascript'
|
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',
|
key: 'color',
|
||||||
type: 'color'
|
type: 'color'
|
||||||
@ -632,123 +696,6 @@ export const imageMapSettingsSchema =
|
|||||||
title: 'Image URL source entity attribute',
|
title: 'Image URL source entity attribute',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
default: ''
|
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: []
|
required: []
|
||||||
@ -759,77 +706,7 @@ export const imageMapSettingsSchema =
|
|||||||
type: 'image'
|
type: 'image'
|
||||||
},
|
},
|
||||||
'imageEntityAlias',
|
'imageEntityAlias',
|
||||||
'imageUrlAttribute',
|
'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'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user