From e24cf1ab8d6e38ba9cde8a1771d313ebd32b71e2 Mon Sep 17 00:00:00 2001 From: David Manthey Date: Mon, 9 Dec 2024 08:32:54 -0500 Subject: [PATCH] perf: Add addMultipleAnnotations method This is primarily faster because of the less events being triggered. The addAnnotation method can also ask to not trigger events. --- CHANGELOG.md | 42 +++++++++++++++++++++++++++++ src/annotationLayer.js | 49 ++++++++++++++++++++++++++++++---- src/event.js | 11 +++++--- tests/cases/annotationLayer.js | 12 +++++++++ 4 files changed, 105 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02a30d15b6..5b2af44f5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,47 @@ # GeoJS Change Log +## Version 1.12.9 + +### Performance Improvements + +- Add addMultipleAnnotations method ([#1351](../../pull/1351)) + +## Version 1.12.8 + +### Performance Improvements + +- Switch to more native functions ([#1345](../../pull/1345)) + +## Version 1.12.7 + +### Performance Improvements + +- Make adding and removing annotations somewhat more efficient ([#1343](../../pull/1343)) + +## Version 1.12.6 + +### Performance Improvements + +- Stop using jquery extend ([#1342](../../pull/1342)) + +## Version 1.12.5 + +### Bug Fixes + +- Change how webpack builds some libraries ([#1341](../../pull/1341)) + +## Version 1.12.4 + +### Performance Improvements + +- Speed up adding annotations ([#1340](../../pull/1340)) + +## Version 1.12.3 + +### Bug Fixes + +- Improve encoding html for screenshots ([#1334](../../pull/1334)) + ## Version 1.12.2 ### Improvements diff --git a/src/annotationLayer.js b/src/annotationLayer.js index 1616f89d25..54a7c37116 100644 --- a/src/annotationLayer.js +++ b/src/annotationLayer.js @@ -491,18 +491,22 @@ var annotationLayer = function (arg) { * gcs, `null` to use the map gcs, or any other transform. * @param {boolean} [update] If `false`, don't update the layer after adding * the annotation. + * @param {boolean} [trigger] If `false`, do trigger add_before and add + * events. * @returns {this} The current layer. * @fires geo.event.annotation.add_before * @fires geo.event.annotation.add */ - this.addAnnotation = function (annotation, gcs, update) { + this.addAnnotation = function (annotation, gcs, update, trigger) { if (m_annotationIds[annotation.id()] === undefined) { while (m_this.annotationById(annotation.id())) { annotation.newId(); } - m_this.geoTrigger(geo_event.annotation.add_before, { - annotation: annotation - }); + if (trigger !== false) { + m_this.geoTrigger(geo_event.annotation.add_before, { + annotation: annotation + }); + } m_annotations.push(annotation); m_annotationIds[annotation.id()] = annotation; annotation.layer(m_this); @@ -516,8 +520,43 @@ var annotationLayer = function (arg) { m_this.modified(); m_this.draw(); } + if (trigger !== false) { + m_this.geoTrigger(geo_event.annotation.add, { + annotation: annotation + }); + } + } + return m_this; + }; + + /** + * Add multiple annotations to the layer. The annotations could be in any + * state. + * + * @param {geo.annotation[]} annotations The annotations to add. + * @param {string|geo.transform|null} [gcs] `undefined` to use the interface + * gcs, `null` to use the map gcs, or any other transform. + * @param {boolean} [update] If `false`, don't update the layer after adding + * the annotation. + * @returns {this} The current layer. + * @fires geo.event.annotation.add_before + * @fires geo.event.annotation.add + */ + this.addMultipleAnnotations = function (annotations, gcs, update) { + const added = []; + m_this.geoTrigger(geo_event.annotation.add_before, { + annotations: annotations + }); + for (let i = 0; i < annotations.length; i += 1) { + const annotation = annotations[i]; + if (m_annotationIds[annotation.id()] === undefined) { + this.addAnnotation(annotation, gcs, update, false); + added.push(annotation); + } + } + if (added.length) { m_this.geoTrigger(geo_event.annotation.add, { - annotation: annotation + annotations: added }); } return m_this; diff --git a/src/event.js b/src/event.js index 814afbd848..ecf1f304ca 100644 --- a/src/event.js +++ b/src/event.js @@ -656,20 +656,23 @@ geo_event.camera.viewport = 'geo_camera_viewport'; geo_event.annotation = {}; /** - * Triggered when an annotation has been added. + * Triggered when or more multiple annotations have been added. * * @event geo.event.annotation.add * @type {geo.event.base} - * @property {geo.annotation} annotation The annotation that was added. + * @property {geo.annotation} [annotation] The annotation that was added. + * @property {geo.annotation} [annotations] The annotations that were added. */ geo_event.annotation.add = 'geo_annotation_add'; /** - * Triggered when an annotation is about to be added. + * Triggered when one or multiple annotations are about to be added. * * @event geo.event.annotation.add_before * @type {geo.event.base} - * @property {geo.annotation} annotation The annotation that will be added. + * @property {geo.annotation} [annotation] The annotation that will be added. + * @property {geo.annotation[]} [annotations] The annotations that will be + * added. */ geo_event.annotation.add_before = 'geo_annotation_add_before'; diff --git a/tests/cases/annotationLayer.js b/tests/cases/annotationLayer.js index 3005bd372d..46cd4c28a1 100644 --- a/tests/cases/annotationLayer.js +++ b/tests/cases/annotationLayer.js @@ -110,6 +110,18 @@ describe('geo.annotationLayer', function () { layer.removeAllAnnotations(); expect(layer.annotations().length).toBe(0); }); + it('multipleAnnotations', function () { + var poly = geo.annotation.polygonAnnotation({ + state: geo.annotation.state.create, layer: layer}), + rect = geo.annotation.rectangleAnnotation({ + layer: layer, + corners: [{x: 0, y: 0}, {x: 1, y: 0}, {x: 1, y: 1}, {x: 0, y: 1}]}); + expect(layer.annotations().length).toBe(0); + layer.addMultipleAnnotations([poly, rect]); + expect(layer.annotations().length).toBe(2); + expect(layer.annotations()[0]).toBe(poly); + expect(layer.annotations()[1]).toBe(rect); + }); }); describe('Public utility functions', function () { var map, layer,