Commit adc982923da5f6c3433518eb73147d06f822e0c1

Authored by Vladyslav
Committed by GitHub
1 parent f7efb790

[3.0] Improvment image map (#2729)

* Add support setting position function

* Improved setting image map

* Add support setting offset marker
... ... @@ -94,6 +94,8 @@ export type MarkerSettings = {
94 94 tooltipFunction: GenericFunction;
95 95 labelFunction: GenericFunction;
96 96 markerImageFunction?: MarkerImageFunction;
  97 + markerOffsetX: number;
  98 + markerOffsetY: number;
97 99 }
98 100
99 101 export interface FormattedData {
... ...
... ... @@ -96,7 +96,7 @@ export class MapWidgetController implements MapWidgetInterface {
96 96 const schema = initSchema();
97 97 addToSchema(schema, this.getProvidersSchema(mapProvider));
98 98 addGroupInfo(schema, 'Map Provider Settings');
99   - addToSchema(schema, addCondition(commonMapSettingsSchema, 'model.provider !== "image-map"'));
  99 + addToSchema(schema, commonMapSettingsSchema);
100 100 addGroupInfo(schema, 'Common Map Settings');
101 101 addToSchema(schema, addCondition(mapPolygonSchema, 'model.showPolygon === true', ['showPolygon']));
102 102 addGroupInfo(schema, 'Polygon Settings');
... ...
... ... @@ -18,10 +18,12 @@ import L, { LeafletMouseEvent } from 'leaflet';
18 18 import { FormattedData, MarkerSettings } from './map-models';
19 19 import { aspectCache, createTooltip, parseWithTranslation, safeExecute } from './maps-utils';
20 20 import tinycolor from 'tinycolor2';
  21 +import { isDefined } from '@core/utils';
21 22
22 23 export class Marker {
23 24 leafletMarker: L.Marker;
24 25 tooltipOffset: [number, number];
  26 + markerOffset: [number, number];
25 27 tooltip: L.Popup;
26 28 location: L.LatLngExpression;
27 29 data: FormattedData;
... ... @@ -34,9 +36,14 @@ export class Marker {
34 36 draggable: settings.draggableMarker
35 37 });
36 38
  39 + this.markerOffset = [
  40 + isDefined(settings.markerOffsetX) ? settings.markerOffsetX : 0.5,
  41 + isDefined(settings.markerOffsetY) ? settings.markerOffsetY : 1,
  42 + ];
  43 +
37 44 this.createMarkerIcon((iconInfo) => {
38 45 this.leafletMarker.setIcon(iconInfo.icon);
39   - this.tooltipOffset = [0, -iconInfo.size[1] + 10];
  46 + this.tooltipOffset = [0, -iconInfo.size[1] * this.markerOffset[1] + 10];
40 47 this.updateMarkerLabel(settings);
41 48 });
42 49
... ... @@ -95,7 +102,7 @@ export class Marker {
95 102 updateMarkerIcon(settings: MarkerSettings) {
96 103 this.createMarkerIcon((iconInfo) => {
97 104 this.leafletMarker.setIcon(iconInfo.icon);
98   - this.tooltipOffset = [0, -iconInfo.size[1] + 10];
  105 + this.tooltipOffset = [0, -iconInfo.size[1] * this.markerOffset[1] + 10];
99 106 this.updateMarkerLabel(settings);
100 107 });
101 108 }
... ... @@ -130,7 +137,7 @@ export class Marker {
130 137 const icon = L.icon({
131 138 iconUrl: currentImage.url,
132 139 iconSize: [width, height],
133   - iconAnchor: [width / 2, height],
  140 + iconAnchor: [width * this.markerOffset[0], height * this.markerOffset[1]],
134 141 popupAnchor: [0, -height]
135 142 });
136 143 const iconInfo = {
... ... @@ -152,7 +159,7 @@ export class Marker {
152 159 const icon = L.icon({
153 160 iconUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + color,
154 161 iconSize: [21, 34],
155   - iconAnchor: [10, 34],
  162 + iconAnchor: [21 * this.markerOffset[0], 34 * this.markerOffset[1]],
156 163 popupAnchor: [0, -34],
157 164 shadowUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_shadow',
158 165 shadowSize: [40, 37],
... ...
... ... @@ -30,10 +30,11 @@ export class ImageMap extends LeafletMap {
30 30 width = 0;
31 31 height = 0;
32 32 imageUrl;
  33 + posFunction;
33 34
34 35 constructor($container: HTMLElement, options: UnitedMapSettings) {
35 36 super($container, options);
36   - options.posFunction = parseFunction(options.posFunction, ['origXPos', 'origYPos']) as ((origXPos, origYPos) => { x, y });
  37 + this.posFunction = parseFunction(options.posFunction, ['origXPos', 'origYPos']) as ((origXPos, origYPos) => { x, y });
37 38 this.imageUrl = options.mapUrl;
38 39 aspectCache(this.imageUrl).subscribe(aspect => {
39 40 this.aspect = aspect;
... ... @@ -132,9 +133,10 @@ export class ImageMap extends LeafletMap {
132 133
133 134 convertPosition(expression): L.LatLng {
134 135 if (isNaN(expression[this.options.xPosKeyName]) || isNaN(expression[this.options.yPosKeyName])) return null;
  136 + Object.assign(expression, this.posFunction(expression[this.options.xPosKeyName], expression[this.options.yPosKeyName]))
135 137 return this.pointToLatLng(
136   - expression[this.options.xPosKeyName] * this.width,
137   - expression[this.options.yPosKeyName] * this.height);
  138 + expression.x * this.width,
  139 + expression.y * this.height);
138 140 }
139 141
140 142 pointToLatLng(x, y): L.LatLng {
... ...
... ... @@ -275,6 +275,16 @@ export const commonMapSettingsSchema =
275 275 type: 'string',
276 276 default: 'longitude'
277 277 },
  278 + xPosKeyName: {
  279 + title: 'X position key name',
  280 + type: 'string',
  281 + default: 'xPos'
  282 + },
  283 + yPosKeyName: {
  284 + title: 'Y position key name',
  285 + type: 'string',
  286 + default: 'yPos'
  287 + },
278 288 showLabel: {
279 289 title: 'Show label',
280 290 type: 'boolean',
... ... @@ -323,6 +333,21 @@ export const commonMapSettingsSchema =
323 333 title: 'Tooltip function: f(data, dsData, dsIndex)',
324 334 type: 'string'
325 335 },
  336 + posFunction: {
  337 + title: 'Position conversion function: f(origXPos, origYPos), should return x,y coordinates as double from 0 to 1 each',
  338 + type: 'string',
  339 + default: 'return {x: origXPos, y: origYPos};'
  340 + },
  341 + markerOffsetX: {
  342 + title: 'Marker X offset relative to position',
  343 + type: 'number',
  344 + default: 0.5
  345 + },
  346 + markerOffsetY: {
  347 + title: 'Marker Y offset relative to position',
  348 + type: 'number',
  349 + default: 1
  350 + },
326 351 color: {
327 352 title: 'Color',
328 353 type: 'string'
... ... @@ -366,14 +391,40 @@ export const commonMapSettingsSchema =
366 391 required: []
367 392 },
368 393 form: [
369   - 'defaultZoomLevel',
370   - 'useDefaultCenterPosition',
371   - 'defaultCenterPosition',
372   - 'fitMapBounds',
  394 + {
  395 + key: 'defaultZoomLevel',
  396 + condition: 'model.provider !== "image-map"'
  397 + },
  398 + {
  399 + key: 'useDefaultCenterPosition',
  400 + condition: 'model.provider !== "image-map"'
  401 + },
  402 + {
  403 + key: 'defaultCenterPosition',
  404 + condition: 'model.provider !== "image-map"'
  405 + },
  406 + {
  407 + key: 'fitMapBounds',
  408 + condition: 'model.provider !== "image-map"'
  409 + },
373 410 'draggableMarker',
374 411 'disableScrollZooming',
375   - 'latKeyName',
376   - 'lngKeyName',
  412 + {
  413 + key: 'latKeyName',
  414 + condition: 'model.provider !== "image-map"'
  415 + },
  416 + {
  417 + key: 'lngKeyName',
  418 + condition: 'model.provider !== "image-map"'
  419 + },
  420 + {
  421 + key: 'xPosKeyName',
  422 + condition: 'model.provider === "image-map"'
  423 + },
  424 + {
  425 + key: 'yPosKeyName',
  426 + condition: 'model.provider === "image-map"'
  427 + },
377 428 'showLabel',
378 429 'label',
379 430 'useLabelFunction',
... ... @@ -408,6 +459,19 @@ export const commonMapSettingsSchema =
408 459 type: 'javascript'
409 460 },
410 461 {
  462 + key: 'markerOffsetX',
  463 + condition: 'model.provider === "image-map"'
  464 + },
  465 + {
  466 + key: 'markerOffsetY',
  467 + condition: 'model.provider === "image-map"'
  468 + },
  469 + {
  470 + key: 'posFunction',
  471 + type: 'javascript',
  472 + condition: 'model.provider === "image-map"'
  473 + },
  474 + {
411 475 key: 'color',
412 476 type: 'color'
413 477 },
... ... @@ -632,123 +696,6 @@ export const imageMapSettingsSchema =
632 696 title: 'Image URL source entity attribute',
633 697 type: 'string',
634 698 default: ''
635   - },
636   - disableScrollZooming: {
637   - title: 'Disable scroll zooming',
638   - type: 'boolean',
639   - default: false
640   - },
641   - xPosKeyName: {
642   - title: 'X position key name',
643   - type: 'string',
644   - default: 'xPos'
645   - },
646   - yPosKeyName: {
647   - title: 'Y position key name',
648   - type: 'string',
649   - default: 'yPos'
650   - },
651   - showLabel: {
652   - title: 'Show label',
653   - type: 'boolean',
654   - default: true
655   - },
656   - label: {
657   - title: 'Label (pattern examples: \'${entityName}\', \'${entityName}: (Text ${keyName} units.)\' )',
658   - type: 'string',
659   - default: '${entityName}'
660   - },
661   - useLabelFunction: {
662   - title: 'Use label function',
663   - type: 'boolean',
664   - default: false
665   - },
666   - labelFunction: {
667   - title: 'Label function: f(data, dsData, dsIndex)',
668   - type: 'string'
669   - },
670   - showTooltip: {
671   - title: 'Show tooltip',
672   - type: 'boolean',
673   - default: true
674   - },
675   - showTooltipAction: {
676   - title: 'Action for displaying the tooltip',
677   - type: 'string',
678   - default: 'click'
679   - },
680   - autocloseTooltip: {
681   - title: 'Auto-close tooltips',
682   - type: 'boolean',
683   - default: true
684   - },
685   - tooltipPattern: {
686   - title: 'Tooltip (for ex. \'Text ${keyName} units.\' or <link-act name=\'my-action\'>Link text</link-act>\')',
687   - type: 'string',
688   - default: '<b>${entityName}</b><br/><br/><b>X Pos:</b> ${xPos:2}<br/><b>Y Pos:</b> ${yPos:2}'
689   - },
690   - useTooltipFunction: {
691   - title: 'Use tooltip function',
692   - type: 'boolean',
693   - default: false
694   - },
695   - tooltipFunction: {
696   - title: 'Tooltip function: f(data, dsData, dsIndex)',
697   - type: 'string'
698   - },
699   - color: {
700   - title: 'Color',
701   - type: 'string'
702   - },
703   - posFunction: {
704   - title: 'Position conversion function: f(origXPos, origYPos), should return x,y coordinates as double from 0 to 1 each',
705   - type: 'string',
706   - default: 'return {x: origXPos, y: origYPos};'
707   - },
708   - markerOffsetX: {
709   - title: 'Marker X offset relative to position',
710   - type: 'number',
711   - default: 0.5
712   - },
713   - markerOffsetY: {
714   - title: 'Marker Y offset relative to position',
715   - type: 'number',
716   - default: 1
717   - },
718   - useColorFunction: {
719   - title: 'Use color function',
720   - type: 'boolean',
721   - default: false
722   - },
723   - colorFunction: {
724   - title: 'Color function: f(data, dsData, dsIndex)',
725   - type: 'string'
726   - },
727   - markerImage: {
728   - title: 'Custom marker image',
729   - type: 'string'
730   - },
731   - markerImageSize: {
732   - title: 'Custom marker image size (px)',
733   - type: 'number',
734   - default: 34
735   - },
736   - useMarkerImageFunction: {
737   - title: 'Use marker image function',
738   - type: 'boolean',
739   - default: false
740   - },
741   - markerImageFunction: {
742   - title: 'Marker image function: f(data, images, dsData, dsIndex)',
743   - type: 'string'
744   - },
745   - markerImages: {
746   - title: 'Marker images',
747   - type: 'array',
748   - items: {
749   - title: 'Marker image',
750   - type: 'string'
751   - }
752 699 }
753 700 },
754 701 required: []
... ... @@ -759,77 +706,7 @@ export const imageMapSettingsSchema =
759 706 type: 'image'
760 707 },
761 708 'imageEntityAlias',
762   - 'imageUrlAttribute',
763   - 'disableScrollZooming',
764   - 'xPosKeyName',
765   - 'yPosKeyName',
766   - 'showLabel',
767   - 'label',
768   - 'useLabelFunction',
769   - {
770   - key: 'labelFunction',
771   - type: 'javascript'
772   - },
773   - 'showTooltip',
774   - {
775   - key: 'showTooltipAction',
776   - type: 'rc-select',
777   - multiple: false,
778   - items: [
779   - {
780   - value: 'click',
781   - label: 'Show tooltip on click (Default)'
782   - },
783   - {
784   - value: 'hover',
785   - label: 'Show tooltip on hover'
786   - }
787   - ]
788   - },
789   - 'autocloseTooltip',
790   - {
791   - key: 'tooltipPattern',
792   - type: 'textarea'
793   - },
794   - 'useTooltipFunction',
795   - {
796   - key: 'tooltipFunction',
797   - type: 'javascript'
798   - },
799   - {
800   - key: 'color',
801   - type: 'color'
802   - },
803   - {
804   - key: 'posFunction',
805   - type: 'javascript'
806   - },
807   - 'markerOffsetX',
808   - 'markerOffsetY',
809   - 'useColorFunction',
810   - {
811   - key: 'colorFunction',
812   - type: 'javascript'
813   - },
814   - {
815   - key: 'markerImage',
816   - type: 'image'
817   - },
818   - 'markerImageSize',
819   - 'useMarkerImageFunction',
820   - {
821   - key: 'markerImageFunction',
822   - type: 'javascript'
823   - },
824   - {
825   - key: 'markerImages',
826   - items: [
827   - {
828   - key: 'markerImages[]',
829   - type: 'image'
830   - }
831   - ]
832   - }
  709 + 'imageUrlAttribute'
833 710 ]
834 711 };
835 712
... ...