From f3349b69c8edcb64fb2237eda62f9e238681aacd Mon Sep 17 00:00:00 2001 From: Ivan Goethals Date: Sun, 5 Jan 2025 15:29:37 +0100 Subject: [PATCH] Performance improvements: - SVG symbolen worden nu enkel in de defs-sectie opgenomen als ze ook effectief worden gebruikt - De undoredo class vermijdt externe images telkens opnieuw op te slaan door gebruikt van een externe stringstore. Verbeteringen aan de user experience: - Aanpassingen aan de manier waarop switches tussen eendraadschema en situatieschema worden geregistreerd voor undo/redo alsook wijzigingen van actieve pagina in het situatieschema - Bij printen wordt de z-Index correct toegepast Refactoring: - Handige functie in Hierarchical_List om een Electro_Item te zoeken op basis van id. - Aanzienlijke refactoring in SituationPlanElement - Beperkte refactoring in SituationPlan Documentatie - introductie typedoc en eerste testen op SituationPlanElement en SituationPlan - typedoc output zal niet aan de repository worden toegevoegd maar kan wel gegenereerd worden met het bash-script makedoc --- builddate.js | 2 +- eendraadschema.js | 879 ++++++++++++---- makedoc | 3 + package.json | 1 + src/Hierarchical_List.ts | 10 +- src/List_Item/Aansluiting.ts | 6 + src/List_Item/Aansluitpunt.ts | 2 + src/List_Item/Aftakdoos.ts | 2 + src/List_Item/Batterij.ts | 2 + src/List_Item/Bel.ts | 2 + src/List_Item/Boiler.ts | 4 + src/List_Item/Contactdoos.ts | 4 + src/List_Item/Diepvriezer.ts | 3 + .../Domotica_gestuurde_verbruiker.ts | 6 + src/List_Item/Droogkast.ts | 2 + src/List_Item/Drukknop.ts | 2 + src/List_Item/EV_lader.ts | 2 + src/List_Item/Electro_Item.ts | 19 +- src/List_Item/Elektriciteitsmeter.ts | 2 + src/List_Item/Elektrische_oven.ts | 2 + src/List_Item/Ketel.ts | 5 + src/List_Item/Koelkast.ts | 3 + src/List_Item/Kookfornuis.ts | 3 +- src/List_Item/Kring.ts | 7 + src/List_Item/Lichtpunt.ts | 9 +- src/List_Item/Media.ts | 2 + src/List_Item/Microgolfoven.ts | 3 + src/List_Item/Motor.ts | 2 + src/List_Item/Omvormer.ts | 3 + src/List_Item/Overspanningsbeveiliging.ts | 2 + src/List_Item/Schakelaars/Schakelaar.ts | 30 + src/List_Item/Stoomoven.ts | 2 + src/List_Item/Transformator.ts | 2 + src/List_Item/USB_lader.ts | 2 + src/List_Item/Vaatwasmachine.ts | 2 + src/List_Item/Ventilator.ts | 2 + src/List_Item/Verwarmingstoestel.ts | 8 +- src/List_Item/Warmtepomp.ts | 3 + src/List_Item/Wasmachine.ts | 2 + src/List_Item/Zekering.ts | 3 + src/List_Item/Zeldzame_symbolen.ts | 2 + src/List_Item/Zonnepaneel.ts | 3 + src/SVGSymbols.ts | 943 +++++++++--------- src/main.ts | 9 +- src/sitplan/SituationPlan.ts | 188 +++- src/sitplan/SituationPlanElement.ts | 445 ++++++--- src/sitplan/SituationPlanView.ts | 36 +- src/sitplan/SituationPlanView_Kringen.ts | 2 +- src/undoRedo.ts | 69 +- typedoc.json | 29 + 50 files changed, 1929 insertions(+), 847 deletions(-) create mode 100755 makedoc create mode 100644 typedoc.json diff --git a/builddate.js b/builddate.js index ff1da75..b4a2af4 100644 --- a/builddate.js +++ b/builddate.js @@ -1 +1 @@ -var CONF_builddate="20250101-192145" +var CONF_builddate="20250105-150906" diff --git a/eendraadschema.js b/eendraadschema.js index ed7ee21..74949cd 100644 --- a/eendraadschema.js +++ b/eendraadschema.js @@ -1490,14 +1490,62 @@ var jsonStore = /** @class */ (function () { jsonStore.prototype.redoStackSize = function () { return (Math.max(this.redoStack.length, 0)); }; return jsonStore; }()); +var LargeStringStore = /** @class */ (function () { + function LargeStringStore() { + this.data = []; + } + LargeStringStore.prototype.push = function (text) { + this.data.push(text); + return (this.data.length - 1); + }; + LargeStringStore.prototype.pushIfNotExists = function (text) { + var index = this.data.indexOf(text); + if (index == -1) { + this.data.push(text); + return (this.data.length - 1); + } + else { + return index; + } + }; + LargeStringStore.prototype.get = function (index) { + return this.data[index]; + }; + LargeStringStore.prototype.clear = function () { + this.data = []; + }; + return LargeStringStore; +}()); var undoRedo = /** @class */ (function () { function undoRedo(maxSteps) { if (maxSteps === void 0) { maxSteps = 100; } + this.largeStrings = new LargeStringStore(); this.history = new jsonStore(maxSteps); } + undoRedo.prototype.replaceSVGsByStringStore = function () { + if (structure.sitplan != null) { + for (var _i = 0, _a = structure.sitplan.getElements(); _i < _a.length; _i++) { + var element = _a[_i]; + if (!element.isEendraadschemaSymbool()) + element.svg = this.largeStrings.pushIfNotExists(element.getUnscaledSVGifNotElectroItem()).toString(); + } + } + }; + undoRedo.prototype.replaceStringStoreBySVGs = function () { + if (structure.sitplan != null) { + for (var _i = 0, _a = structure.sitplan.getElements(); _i < _a.length; _i++) { + var element = _a[_i]; + if (!element.isEendraadschemaSymbool()) + element.svg = this.largeStrings.get(parseInt(element.svg)); + } + } + }; undoRedo.prototype.store = function () { + // We store the current state of the structure in the history but we replace the SVGs by a reference to a large string store + this.replaceSVGsByStringStore(); this.history.store(structure_to_json()); - if (structure.properties.currentView == 'draw') + this.replaceStringStoreBySVGs(); + if ((structure.properties.currentView == 'draw') && (structure.sitplanview != null)) structure.sitplanview.updateRibbon(); else if (structure.properties.currentView == '2col') structure.updateRibbon(); @@ -1508,6 +1556,10 @@ var undoRedo = /** @class */ (function () { var text = this.history.undo(); if (text != null) json_to_structure(text, 0, false); + // We replace the references to the large string store by the actual SVGs + this.replaceStringStoreBySVGs(); + // We need to resort and clean the structure to avoid bad references + structure.reSort(); structure.mode = lastmode; if (structure.properties.currentView != lastView) toggleAppView(structure.properties.currentView); @@ -1532,6 +1584,10 @@ var undoRedo = /** @class */ (function () { var text = this.history.redo(); if (text != null) json_to_structure(text, 0, false); + // We replace the references to the large string store by the actual SVGs + this.replaceStringStoreBySVGs(); + // We need to resort and clean the structure to avoid bad references + structure.reSort(); structure.mode = lastmode; if (structure.properties.currentView != lastView) toggleAppView(structure.properties.currentView); @@ -1546,6 +1602,7 @@ var undoRedo = /** @class */ (function () { }; undoRedo.prototype.clear = function () { this.history.clear(); + this.largeStrings.clear(); structure.updateRibbon(); }; undoRedo.prototype.undoStackSize = function () { return (this.history.undoStackSize()); }; @@ -1618,70 +1675,165 @@ function showDocumentationPage() { toggleAppView('config'); document.getElementById('Btn_downloadManual').onclick = function () { window.open('Documentation/edsdoc.pdf', '_blank'); }; } +/** + * Volledig overzicht van een situatieplan. + * Werd gebouwd voor gebruik in de browser maar is redelijk browser-agnostic. + * De effectieve code om te interageren met de browser zelf zit in class SituationPlanView. + * + * GLOBALS: structure + */ var SituationPlan = /** @class */ (function () { function SituationPlan() { + this.activePage = 1; // We houden deze bij in situationplan zodat ook wijzigingen van pagina's worden opgeslagen this.numPages = 1; - this.activePage = 1; this.elements = []; } + /** + * Workaround om de private variabele elements te kunnen gebruiken in friend classs + * @returns {SituationPlanElement[]} De elementen van het situatieplan + */ + SituationPlan.prototype.getElements = function () { + return this.elements; + }; + /** + * SituationPlanElement toevoegen aan het situatieplan + * @param element + * @returns {void} + */ SituationPlan.prototype.addElement = function (element) { this.elements.push(element); }; + /** + * Laad een SVG-inhoud vanuit een bestand en voegt deze toe aan het situatieplan. + * De SVG werd geselecteerd in een fileInput HTML element en komt binnen via het event in de functie header. + * + * @param {any} event Het event dat aangaf dat er een bestand was gekozen om te uploaden. + * @param {number} page Het pagina-nummer van het element in het situatieplan. + * @param {number} posx De x-coordinaat van het element in het situatieplan. + * @param {number} posy De y-coordinaat van het element in het situatieplan. + * @param {() => void} callback Een callback-functie die wordt aangeroepen wanneer het element is toegevoegd. + * @returns {SituationPlanElement} Het element dat is toegevoegd. + */ SituationPlan.prototype.addElementFromFile = function (event, page, posx, posy, callback) { - var element = new SituationPlanElement(page, posx, posy, 0, 0, 11, 0, SITPLANVIEW_DEFAULT_SCALE, randomId("SP_"), ""); + var element = new SituationPlanElement(); + element.setVars({ page: page, posx: posx, posy: posy }); element.importFromFile(event, callback); this.elements.push(element); return element; }; - SituationPlan.prototype.addElementFromSVG = function (svg, page, posx, posy) { - var element = new SituationPlanElement(page, posx, posy, 0, 0, 11, 0, SITPLANVIEW_DEFAULT_SCALE, randomId("SP_"), svg); - element.getSizeFromString(); - this.elements.push(element); - }; - SituationPlan.prototype.addElectroItem = function (id, page, posx, posy, adrestype, adres, adreslocation, labelfontsize, scale, rotate) { - var electroItem = structure.data[structure.getOrdinalById(id)]; - if (electroItem != null) { - var element = electroItem.toSituationPlanElement(); - Object.assign(element, { page: page, posx: posx, posy: posy, labelfontsize: labelfontsize, scale: scale, rotate: rotate }); - element.setElectroItemId(id); - element.setAdres(adrestype, adres, adreslocation); - this.elements.push(element); - return element; - } - else { + /** + * Creëer een nieuw element in het situatieplan dat gelinkt is aan een Electro_Item + * + * @param {number} electroItemId Het ID van de Electro_Item. + * @param {number} page Het pagina-nummer van het element in het situatieplan. + * @param {number} posx De x-coordinaat van het element in het situatieplan. + * @param {number} posy De y-coordinaat van het element in het situatieplan. + * @param {AdresType} adrestype Het type van het adres, bijvoorbeeld 'manueel'. + * AdresType wordt definieerd in SituationPlanElement.ts + * @param {string} adres Het adres. + * @param {AdresLocation} adreslocation De locatie van het adres in het label ('boven' of 'onder' of 'rechts' of 'links'). + * AdresLocation wordt definieerd in SituationPlanElement.ts + * @param {number} labelfontsize De lettergrootte van het label. + * @param {number} scale De schaal van het element. + * @param {number} rotate De rotatie van het element. + * @returns {SituationPlanElement} Het element dat is toegevoegd. + */ + SituationPlan.prototype.addElementFromElectroItem = function (electroItemId, page, posx, posy, adrestype, adres, adreslocation, labelfontsize, scale, rotate) { + var electroItem = structure.getElectroItemById(electroItemId); + if (!electroItem) return null; - } + var element = electroItem.toSituationPlanElement(); + Object.assign(element, { page: page, posx: posx, posy: posy, labelfontsize: labelfontsize, scale: scale, rotate: rotate }); + element.setElectroItemId(electroItemId); + element.setAdres(adrestype, adres, adreslocation); + this.elements.push(element); + return element; }; + /** + * Verwijder een element van het situatieplan. + * In principe is er altijd maar één maar de functie gebruikt recursie in het geval er meerdere zouden zijn + * om ze allemaal te verwijderen. + * + * @param {SituationPlanElement} element Het element dat verwijderd moet worden. + * @returns {void} + */ SituationPlan.prototype.removeElement = function (element) { - for (var i = this.elements.length - 1; i >= 0; i--) { - if (this.elements[i] == element) { - this.elements.splice(i, 1); - } - } + var index = this.elements.indexOf(element); + if (index === -1) + return; + this.elements.splice(index, 1); if (element.boxref != null) element.boxref.remove(); if (element.boxlabelref != null) element.boxlabelref.remove(); + this.removeElement(element); // Recurse in het geval er meerdere zouden zijn maar dit zou niet mogen gebeuren + }; + /** + * Sorteer de elementen in het situatieplan op basis van de z-index van hun boxref elementen in de DOM. + * Elementen met een `null` `boxref` worden naar het einde van de lijst verplaatst. + * + * Het sorteren is nodig om ervoor te zorgen dat bij het printen wanneer lineair door de elementen wordt gegaan + * de elementen in de juiste volgorde worden gestacked. + * + * @returns {void} + */ + SituationPlan.prototype.orderByZIndex = function () { + this.elements.sort(function (a, b) { + if (a.boxref == null) + return 1; + if (b.boxref == null) + return -1; + return parseInt(a.boxref.style.zIndex) - parseInt(b.boxref.style.zIndex); + }); + }; + /** + * Initialiseer het situatieplan vanuit een json-object. + * + * @param {Object} json Het json-object dat het situatieplan bevat. + * Het object bevat een 'numPages' property dat het aantal pagina's in het situatieplan aangeeft. + * Verder bevat het een 'elements' property dat een array is van json-objecten die elk een element in het situatieplan vertegenwoordigen. + * Elke json-object in de array bevat de properties van een SituationPlanElement. + * @returns {void} + */ + SituationPlan.prototype.fromJsonObject = function (json) { + if (json.numPages !== undefined) { + this.numPages = json.numPages; + } + else { + this.numPages = 1; + } + if (json.activePage !== undefined) { + this.activePage = json.activePage; + } + else { + this.activePage = 1; + } + if (Array.isArray(json.elements)) { + this.elements = json.elements.map(function (element) { + var newElement = new SituationPlanElement(); + newElement.fromJsonObject(element); + return newElement; + }); + } + else { + this.elements = []; + } }; + /** + * Converteer het situatieplan naar een JSON-object. + * + * @returns {any} Het JSON-object. + */ SituationPlan.prototype.toJsonObject = function () { var elements = []; for (var _i = 0, _a = this.elements; _i < _a.length; _i++) { var element = _a[_i]; elements.push(element.toJsonObject()); } - return { numPages: this.numPages, elements: elements }; - }; - SituationPlan.prototype.fromJsonObject = function (json) { - this.numPages = json.numPages; - this.elements = []; - for (var _i = 0, _a = json.elements; _i < _a.length; _i++) { - var element = _a[_i]; - var newElement = new SituationPlanElement(1, 0, 0, 0, 0, 11, 0, SITPLANVIEW_DEFAULT_SCALE, randomId("SP_"), ""); - newElement.fromJsonObject(element); - this.elements.push(newElement); - } + return { numPages: this.numPages, activePage: this.activePage, elements: elements }; }; SituationPlan.prototype.toSitPlanPrint = function () { + this.orderByZIndex(); var outstruct = {}; outstruct.numpages = (this.elements.length > 0 ? structure.sitplan.numPages : 0); outstruct.pages = []; @@ -1697,10 +1849,8 @@ var SituationPlan = /** @class */ (function () { if (fontsize == null) fontsize = 11; svgstr += element.getScaledSVG(true); - var rotatedimgwidth = element.sizex * element.scale; - var rotatedimgheight = element.sizey * element.scale; - rotatedimgwidth = Math.max(rotatedimgwidth * Math.cos(element.rotate * Math.PI / 180), rotatedimgheight * Math.sin(element.rotate * Math.PI / 180)); - rotatedimgheight = Math.max(rotatedimgwidth * Math.sin(element.rotate * Math.PI / 180), rotatedimgheight * Math.cos(element.rotate * Math.PI / 180)); + var rotatedimgwidth = Math.max(element.sizex * element.scale * Math.cos(element.rotate * Math.PI / 180), element.sizey * element.scale * Math.sin(element.rotate * Math.PI / 180)); + var rotatedimgheight = Math.max(element.sizex * element.scale * Math.sin(element.rotate * Math.PI / 180), element.sizey * element.scale * Math.cos(element.rotate * Math.PI / 180)); maxx = Math.max(maxx, element.posx + rotatedimgwidth / 2); maxy = Math.max(maxy, element.posy + rotatedimgheight / 2); svgstr += "").concat(element.getAdres(), ""); @@ -1713,60 +1863,75 @@ var SituationPlan = /** @class */ (function () { }; return SituationPlan; }()); +/** + * Class SituationPlanElement + * + * GLOBALS: structure, SITPLANVIEW_DEFAULT_SCALE + */ var SituationPlanElement = /** @class */ (function () { - function SituationPlanElement(page, posx, posy, sizex, sizey, labelfontsize, rotate, scale, id, svg) { - this.page = 1; + /** + * Constructor + */ + function SituationPlanElement() { + this.electroItemId = null; // Referentie naar het electro-element in de datastructuur indien van toepassing + // -- Basis eigenschappen van het element zelf -- + this.boxref = null; // Referentie naar het DIV document in de browser waar het element wordt afgebeeld + this.svg = ''; /* SVG content van het element indien van toepassing + Indien electroItemId == null dan is dit de SVG content van het element zelf + Indien electroItemId != null dan is dit de laatste geladen SVG content van het electro-element + Altijd te verifiëren dat deze niet leeg is en evenueel een update forceren */ + // -- Basis eigenschappen van het label -- + // adres gegevens zijn private gedefinieerd omwille van consistentie (bvb adres kan leeg gelaten worden als het type auto is) + this.boxlabelref = null; // Referentie naar het DIV document in de browser waar het label wordt afgebeeld + this.adrestype = null; + this.adres = null; + this.adreslocation = 'rechts'; + // -- Positionering van het element zelf -- + this.page = 1; //pagina waarop het element zich bevindt this.posx = 0; //center positie-x in het schema this.posy = 0; //center positie-y in het schema this.sizex = 0; //breedte this.sizey = 0; //hoogte + this.rotate = 0; + this.scale = SITPLANVIEW_DEFAULT_SCALE; + // -- Positionering van het label -- this.labelposx = 0; this.labelposy = 0; this.labelfontsize = 11; - this.rotate = 0; - this.scale = SITPLANVIEW_DEFAULT_SCALE; - this.boxref = null; - this.boxlabelref = null; - this.svg = ""; - this.electroItemId = null; - this.adrestype = null; - this.adres = null; - this.adreslocation = "rechts"; - this.page = page; - this.posx = posx; - this.posy = posy; - this.sizex = sizex, this.sizey = sizey; - this.labelfontsize = labelfontsize; - this.rotate = rotate; - this.scale = scale; - this.id = id; - this.svg = svg; + this.id = randomId("SP_"); } - SituationPlanElement.prototype.isEDSymbol = function () { + /** + * isEendraadschemaSymbool + * + * Controleer of het element een geldig electro-element is + * Hiervoor is een geldige electroItemId nodig en moet het element in de datastructuur voorkomen. + * + * @returns boolean + */ + SituationPlanElement.prototype.isEendraadschemaSymbool = function () { if (this.electroItemId != null) { - var idnum = Number(this.electroItemId); - if (!isNaN(idnum)) { - var ordinal = structure.getOrdinalById(idnum); - if (ordinal != null) { - var electroElement = structure.data[ordinal]; - if (electroElement != null) - return true; - } - } + return (structure.getElectroItemById(this.electroItemId) != null); } return false; }; - SituationPlanElement.prototype.needsTextMirroring = function () { - if (this.isEDSymbol()) { - var electroElement = structure.data[structure.getOrdinalById(Number(this.getElectroItemId()))]; - var type = electroElement.getType(); - if (['Contactdoos', 'Lichtpunt', 'Drukknop', 'Media', 'Schakelaars', 'Lichtcircuit'].includes(type)) - return true; - else - return false; + SituationPlanElement.prototype.rotates360degrees = function () { + if (this.isEendraadschemaSymbool()) { + var electroElement = structure.getElectroItemById(this.electroItemId); + if (electroElement != null) { + var type = electroElement.getType(); + return SituationPlanElement.ROTATES_360_DEGREES_TYPES.has(type); + } + return false; } return true; }; + /** + * setAdres + * + * @param adrestype string : 'auto' of 'manueel' + * @param adres string : Indien manueel, het adres. Indien auto wordt deze genegeerd en this.adres altijd op null gezet. + * @param adreslocation string: 'rechts' of 'links' of 'boven' of 'onder' + */ SituationPlanElement.prototype.setAdres = function (adrestype, adres, adreslocation) { this.adrestype = adrestype; this.adreslocation = adreslocation; @@ -1775,152 +1940,251 @@ var SituationPlanElement = /** @class */ (function () { else this.adres = null; }; + /** + * getAdresType + * + * @returns string : 'auto' of 'manueel' + */ SituationPlanElement.prototype.getAdresType = function () { return this.adrestype; }; + /** + * getAdres + * + * @returns string : adres + */ SituationPlanElement.prototype.getAdres = function () { - if (this.electroItemId == null) - return ""; - var id = this.electroItemId; - var element = structure.data[structure.getOrdinalById(id)]; - switch (this.adrestype) { - case 'auto': - return element.getReadableAdres(); - break; - case 'adres': - return "Adres"; - case 'manueel': - default: - return (this.adres == null) ? "" : this.adres; + var _a; + if (!this.isEendraadschemaSymbool()) + return ''; // Geen adres voor niet-elektro-elementen + var element = structure.getElectroItemById(this.electroItemId); + if (element == null) + return ''; // zou redundant moeten zijn want we controleerden al in isEendraadschemaSymbool + if (this.adrestype === 'auto') { + return element.getReadableAdres(); + } + else { + return (_a = this.adres) !== null && _a !== void 0 ? _a : ''; } }; + /** + * getAdresLocation + * + * @returns 'rechts'|'links'|'boven'|'onder' + */ SituationPlanElement.prototype.getAdresLocation = function () { return this.adreslocation; }; - SituationPlanElement.prototype.setElectroItemId = function (id) { - this.electroItemId = id; + /** + * setElectroItemId + * + * @param electroItemId number : id van het electroitem in structure + * + * TODO: zou beter een private functie zijn en niet worden aangeroepen vanuit SituationPlan en SituationPlanView + */ + SituationPlanElement.prototype.setElectroItemId = function (electroItemId) { + this.electroItemId = electroItemId; }; + /** + * getElectroItemId + * + * @returns number : id van het electroitem in structure + */ SituationPlanElement.prototype.getElectroItemId = function () { - return this.electroItemId; + if (this.isEendraadschemaSymbool()) + return this.electroItemId; + else + return null; }; - SituationPlanElement.prototype.setSVG = function (svg) { - this.svg = svg; - this.getSizeFromString(); + /** + * updateElectroItemSVG + * + * @param svg string : nieuwe gegenereerde SVG door het electro-element + * @param width number : breedte van de SVG zonder schaling en rotatie, indien niet gegeven wordt de breedte gezocht met functie getSizeFromString + * @param height number : hoogte van de SVG zonder schaling en rotatie + */ + SituationPlanElement.prototype.updateElectroItemSVG = function (svg, width, height) { + if (width === void 0) { width = undefined; } + if (height === void 0) { height = undefined; } + if (this.isEendraadschemaSymbool()) { + this.svg = svg; + if (width != null) + this.sizex = width; + if (height != null) + this.sizey = height; + if (width == null || height == null) + this.getSizeFromString(); + } }; - SituationPlanElement.prototype.getSVG = function () { - if (this.electroItemId != null) { - var ordinal = structure.getOrdinalById(this.electroItemId); - if (ordinal != null) { - var electroItem = structure.data[ordinal]; - electroItem.updateSituationPlanElement(this); - } + /** + * getUnscaledSVGifNotElectroItem + * + * @returns string : SVG content van het element op voorwaarde dat het geen electro-element is + */ + SituationPlanElement.prototype.getUnscaledSVGifNotElectroItem = function () { + // cleanSVG(): Deze functie is nodig omdat gebleken is dat de print SVG commando's in jsPDF niet overweg kunnen met SVG's die niet dadelijk beginnen met '= 90) && (rotate < 270)) { - if (this.needsTextMirroring()) + if (_this.rotates360degrees()) spiegel = true; - if (this.isEDSymbol()) + if (_this.isEendraadschemaSymbool()) rotate = rotate + 180; } - transform = "transform=\"rotate(".concat(rotate, " ").concat(this.posx, " ").concat(this.posy, ")").concat((spiegel ? ' scale(-1,1) translate(' + (-2 * this.posx) + ' 0)' : ''), "\""); - return "\n ").concat(svg, "\n "); + return [rotate, spiegel]; + }; + if (this.isEendraadschemaSymbool()) { + var electroItem = structure.getElectroItemById(this.electroItemId); + if (electroItem != null) + electroItem.updateSituationPlanElement(this); } - else { - return "").concat(svg, ""); + var posinfo = ''; + var transform = ''; + if (positioned) { // Indien we de SVG willen positioneren en roteren, bvb voor gebruik in een print + posinfo = "x=\"".concat(this.posx - this.sizex / 2 * this.scale, "\" y=\"").concat(this.posy - this.sizey / 2 * this.scale, "\""); + var _a = berekenAfbeeldingsRotatieEnSpiegeling(), rotate = _a[0], spiegel = _a[1]; + transform = "transform=\"rotate(".concat(rotate, " ").concat(this.posx, " ").concat(this.posy, ")").concat((spiegel ? " scale(-1,1) translate(".concat(-this.posx * 2, " 0)") : ''), "\""); + return "\n ").concat(this.svg, "\n "); + } + else { // Indien we de SVG willen gebruiken in een innerHTML van een div element en dit element dan zelf positioneren en roteren + return "").concat(this.svg, ""); } }; + /** + * getSizeFromString + * + * Haal de grootte van het SVG element uit de SVG string + */ SituationPlanElement.prototype.getSizeFromString = function () { // Create a DOMParser to parse the SVG string var parser = new DOMParser(); var svgDoc = parser.parseFromString(this.svg, "image/svg+xml"); // Access the SVG element var svgElement = svgDoc.querySelector('svg'); - // Extract the height and width attributes - this.sizey = parseInt(svgElement.getAttribute('height')); - this.sizex = parseInt(svgElement.getAttribute('width')); + if (svgElement) { + // Extract the height and width attributes + this.sizey = parseInt(svgElement.getAttribute('height')); + this.sizex = parseInt(svgElement.getAttribute('width')); + } + else { + console.error('Invalid SVG string'); + } }; + /** + * Leest de inhoud van een situatieplanelement uit een image bestand + * Enkel image bestanden ondersteund door de browser worden ondersteund + * + * @param event Event van het file input element gedefinieerd in index.html + * @param callback Callback functie die wordt uitgevoerd na het inladen van de file + */ SituationPlanElement.prototype.importFromFile = function (event, callback) { var _this = this; - var file = event.target.files[0]; + var input = event.target; + var file = input.files[0]; if (file) { var reader = new FileReader(); var fileName = file.name.toLowerCase(); var mimeType = file.type; - if (fileName.endsWith('.svg')) { - //Handle SVG - reader.onload = function (e) { - var fileContent = e.target.result; - _this.svg = fileContent; - _this.getSizeFromString(); + reader.onload = function (e) { + var fileContent = e.target.result; + var image = new Image(); + image.src = fileContent; + image.onload = function () { + _this.sizex = image.width; + _this.sizey = image.height; + _this.svg = ""); callback(); }; - reader.readAsText(file); // Read the file as a text string - } - else { - //Handle image - reader.onload = function (e) { - var fileContent = e.target.result; - var image = new Image(); - image.src = fileContent; - image.onload = function () { - _this.sizex = image.width; - _this.sizey = image.height; - _this.svg = ""); - callback(); - }; - image.onerror = function () { - console.error('Unsupported image format or failed to load image.'); - }; + image.onerror = function () { + alert('Het formaat van deze file wordt niet ondersteund.'); }; - reader.readAsDataURL(file); // Read the file as a data URL - } + }; + reader.readAsDataURL(file); // Read the file as a data URL + } + else { + alert('Geen bestand geselecteerd'); } }; + /** + * setVars + * + * @param object Object : object met de variabelen die moeten worden ingesteld + */ + SituationPlanElement.prototype.setVars = function (object) { + Object.assign(this, object); + }; + /** + * toJsonObject + * + * @returns Object : object met de variabelen van het element dat dadelijk kan worden omgezet naar een JSON string + */ SituationPlanElement.prototype.toJsonObject = function () { - var svg = ((this.electroItemId != null) ? "" : this.svg); return { - page: this.page, posx: this.posx, posy: this.posy, - sizex: this.sizex, sizey: this.sizey, - labelposx: this.labelposx, labelposy: this.labelposy, + page: this.page, + posx: this.posx, + posy: this.posy, + sizex: this.sizex, + sizey: this.sizey, + labelposx: this.labelposx, + labelposy: this.labelposy, labelfontsize: this.labelfontsize, - adrestype: this.adrestype, adres: this.adres, adreslocation: this.adreslocation, - rotate: this.rotate, scale: this.scale, - svg: svg, electroItemId: this.electroItemId + adrestype: this.adrestype, + adres: this.adres, + adreslocation: this.adreslocation, + rotate: this.rotate, + scale: this.scale, + svg: (this.isEendraadschemaSymbool() ? '' : this.svg), + electroItemId: this.electroItemId }; }; + /** + * fromJsonObject + * + * @param json any : object met de variabelen van het element dat dadelijk kan worden omgezet naar een JSON string + */ SituationPlanElement.prototype.fromJsonObject = function (json) { - this.page = (json.page != null) ? json.page : 1; + this.page = json.page; this.posx = json.posx; this.posy = json.posy; + this.sizex = json.sizex; + this.sizey = json.sizey; this.labelposx = (json.labelposx != null) ? json.labelposx : this.posx + 20; this.labelposy = (json.labelposy != null) ? json.labelposy : this.posy; this.labelfontsize = (json.labelfontsize != null ? json.labelfontsize : 11); - this.sizex = json.sizex; - this.sizey = json.sizey; this.adrestype = (json.adrestype != null) ? json.adrestype : "manueel"; this.adres = json.adres; this.adreslocation = (json.adreslocation != null) ? json.adreslocation : "rechts"; @@ -1929,6 +2193,20 @@ var SituationPlanElement = /** @class */ (function () { this.svg = json.svg; this.electroItemId = json.electroItemId; }; + /** + * rotates360degrees + * + * Per default wordt er vanuit gegaan dat bij rotatie over rotatiehoeken alpha tussen 90 en 270 graden deze rotatie kan vervangen worden. + * door een rotatie over alpha-180 graden. Om een voorbeeld te geven, een batterij roteren over 180 graden heeft geen zin, dat blijft het originele symbool. + * + * Voor bepaalde elementen is dit niet het geval. Een contactdoos gedraaid over 180 graden moet de opening naar rechts hebben in plaats van naar links. + * Deze functie geeft true terug indien een volledige rotatie nodig is. + * + * @returns boolean + * + * TODO: functie verplaatsen naar Electro_Item + */ + SituationPlanElement.ROTATES_360_DEGREES_TYPES = new Set(['Contactdoos', 'Lichtpunt', 'Drukknop', 'Media', 'Schakelaars', 'Lichtcircuit']); return SituationPlanElement; }()); function isDevMode() { @@ -2135,7 +2413,7 @@ var SituationPlanView = /** @class */ (function () { // Display an html input dialog in the browser and ask for a number, return the number as variable id SituationPlanView_ElementPropertiesPopup(null, function (id, adrestype, adres, adreslocation, labelfontsize, scale, rotate) { if (id != null) { - var element = _this.sitplan.addElectroItem(id, _this.sitplan.activePage, 550, 300, adrestype, adres, adreslocation, labelfontsize, scale, rotate); + var element = _this.sitplan.addElementFromElectroItem(id, _this.sitplan.activePage, 550, 300, adrestype, adres, adreslocation, labelfontsize, scale, rotate); if (element != null) { _this.reloadSitPlan(); _this.clearSelection(); @@ -2216,17 +2494,33 @@ var SituationPlanView = /** @class */ (function () { this.selectedBox.style.transform = "rotate(".concat(pic.rotate, "deg)"); } }; + /** + * Send the selected box to the back of the z-index stack and reorder the elements of the situation plan accordingly + * so that after saving or during printing the elements are drawn in the same order. + * + * @returns void + */ SituationPlanView.prototype.sendToBack = function () { if (this.selectedBox) { - var boxes = this.paper.querySelectorAll('.box'); - var newzIndex = 0; - for (var _i = 0, _a = Array.from(boxes); _i < _a.length; _i++) { - var box = _a[_i]; - box.style.zIndex = ((parseInt(box.style.zIndex) || 0) + 1).toString(); + for (var _i = 0, _a = this.sitplan.elements; _i < _a.length; _i++) { + var element = _a[_i]; + if (element.boxref != null) { + var newzindex = void 0; + if (element.boxref != this.selectedBox) { + newzindex = (parseInt(element.boxref.style.zIndex) || 0) + 1; + } + else { + newzindex = 0; + } + element.boxref.style.zIndex = newzindex.toString(); + if (element.boxlabelref != null) { + element.boxlabelref.style.zIndex = newzindex.toString(); + } + } } - newzIndex--; - this.selectedBox.style.zIndex = "0"; } + this.sitplan.orderByZIndex(); + undostruct.store(); }; SituationPlanView.prototype.updateBoxPosition = function (box) { var pic = box.picref; @@ -2239,9 +2533,9 @@ var SituationPlanView = /** @class */ (function () { var spiegel = false; rotate = rotate % 360; if ((rotate >= 90) && (rotate < 270)) { - if (pic.needsTextMirroring()) + if (pic.rotates360degrees()) spiegel = true; - if (pic.isEDSymbol()) + if (pic.isEendraadschemaSymbool()) rotate = rotate - 180; } box.style.transform = "rotate(".concat(rotate, "deg)") + (spiegel ? ' scaleX(-1)' : ''); @@ -2425,6 +2719,7 @@ var SituationPlanView = /** @class */ (function () { document.getElementById('id_sitplanpage').onchange = function (event) { var target = event.target; _this.selectPage(Number(target.value)); + undostruct.store(); }; document.getElementById('btn_sitplan_addpage').onclick = function () { _this.sitplan.numPages++; @@ -2707,7 +3002,7 @@ function SituationPlanView_Kringen() { var kringnaam = structure.findKringName(id).trim(); if (kringnaam != '') { var type = structure.data[i].getType(); - if (excludedTypes.indexOf(type) === -1) { + if ((type != null) && (excludedTypes.indexOf(type) === -1)) { var adres = structure.data[i].getReadableAdres(); output.alldata.push({ id: id, kringnaam: kringnaam, adres: adres, type: type }); } @@ -3035,8 +3330,8 @@ var Electro_Item = /** @class */ (function (_super) { * @returns {SituationPlanElement} The SituationPlanElement that represents this Electro_Item */ Electro_Item.prototype.toSituationPlanElement = function () { - var myElement = new SituationPlanElement(1, 0, 0, 0, 0, 11, 0, 1, randomId("SP_"), ""); - this.updateSituationPlanElement(myElement); + var myElement = new SituationPlanElement(); + //this.updateSituationPlanElement(myElement); //Lijkt niet nodig aangezien dit zoiezo gebeurt in getScaledSVG bij iedere update return (myElement); }; Electro_Item.prototype.updateSituationPlanElement = function (myElement) { @@ -3044,6 +3339,7 @@ var Electro_Item = /** @class */ (function (_super) { var rotate = myElement.rotate % 360; if ((rotate >= 90) && (rotate < 270)) spiegeltext = true; + SVGSymbols.clearSymbols(); // We gaan enkel de symbolen gebruiken die nodig zijn voor dit element var mySVGElement = this.toSVG(true, spiegeltext); var sizex = mySVGElement.xright + mySVGElement.xleft + 10; var sizey = mySVGElement.yup + mySVGElement.ydown; @@ -3055,11 +3351,13 @@ var Electro_Item = /** @class */ (function (_super) { clipleft = 12; } var addright = 0; - myElement.setSVG("") - + SVGSymbols.outputSVGSymbols() - + mySVGElement.data - + ''); - myElement.getSizeFromString(); + var width = sizex - clipleft + addright; + var height = sizey; + myElement.updateElectroItemSVG('") + + SVGSymbols.getNeededSymbols() + // enkel de symbolen die nodig zijn voor dit element + mySVGElement.data + + '', width, height); }; return Electro_Item; }(List_Item)); @@ -3081,6 +3379,7 @@ var Schakelaar = /** @class */ (function () { } Schakelaar.prototype.schakelaarAttributentoSVGString = function (endx, isdubbel) { if (isdubbel === void 0) { isdubbel = false; } + SVGSymbols.addSymbol('signalisatielamp'); var outputstr = ""; if (this.signalisatielamp) outputstr += ''; @@ -3108,6 +3407,7 @@ var Schakelaar = /** @class */ (function () { Schakelaar.prototype.enkeltoDrawReturnObj = function (startx) { var outputstr = ""; var endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_enkel'); outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx); @@ -3116,6 +3416,7 @@ var Schakelaar = /** @class */ (function () { Schakelaar.prototype.dubbeltoDrawReturnObj = function (startx) { var outputstr = ""; var endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_dubbel'); outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx, true); @@ -3124,6 +3425,7 @@ var Schakelaar = /** @class */ (function () { Schakelaar.prototype.driepoligtoDrawReturnObj = function (startx) { var outputstr = ""; var endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_trippel'); outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx, true); @@ -3132,6 +3434,7 @@ var Schakelaar = /** @class */ (function () { Schakelaar.prototype.dubbelaanstekingtoDrawReturnObj = function (startx) { var outputstr = ""; var endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_dubbelaansteking'); outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx); @@ -3140,6 +3443,7 @@ var Schakelaar = /** @class */ (function () { Schakelaar.prototype.wissel_enkeltoDrawReturnObj = function (startx) { var outputstr = ""; var endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_wissel_enkel'); outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx); @@ -3148,6 +3452,7 @@ var Schakelaar = /** @class */ (function () { Schakelaar.prototype.wissel_dubbeltoDrawReturnObj = function (startx) { var outputstr = ""; var endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_wissel_dubbel'); outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx, true); @@ -3156,6 +3461,7 @@ var Schakelaar = /** @class */ (function () { Schakelaar.prototype.kruis_enkeltoDrawReturnObj = function (startx) { var outputstr = ""; var endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_kruis_enkel'); outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx); @@ -3164,6 +3470,7 @@ var Schakelaar = /** @class */ (function () { Schakelaar.prototype.dimschakelaartoDrawReturnObj = function (startx) { var outputstr = ""; var endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_enkel_dim'); outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx); @@ -3172,6 +3479,7 @@ var Schakelaar = /** @class */ (function () { Schakelaar.prototype.dimschakelaarWisseltoDrawReturnObj = function (startx) { var outputstr = ""; var endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_wissel_dim'); outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx); @@ -3180,6 +3488,9 @@ var Schakelaar = /** @class */ (function () { Schakelaar.prototype.bewegingsschakelaartoDrawReturnObj = function (startx) { var outputstr = ""; var endx = startx + 20; + SVGSymbols.addSymbol('relais'); + SVGSymbols.addSymbol('moving_man'); + SVGSymbols.addSymbol('detectie_klein'); outputstr += '' + '' + '' @@ -3192,6 +3503,7 @@ var Schakelaar = /** @class */ (function () { Schakelaar.prototype.rolluikschakelaartoDrawReturnObj = function (startx) { var outputstr = ""; var endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_rolluik'); outputstr += '' + ''; if (this.halfwaterdicht) { @@ -3206,6 +3518,7 @@ var Schakelaar = /** @class */ (function () { Schakelaar.prototype.magneetcontacttoDrawReturnObj = function (startx) { var outputstr = ""; var endx = startx + 20; + SVGSymbols.addSymbol('magneetcontact'); // Alles naar beneden schuiven als we het aantal laders boven het symbool willen plaatsen if (this.aantal > 1) { var textoptions = 'style="text-anchor:middle" font-family="Arial, Helvetica, sans-serif" font-size="10"'; @@ -3221,6 +3534,7 @@ var Schakelaar = /** @class */ (function () { Schakelaar.prototype.defaulttoDrawReturnObj = function (startx, symbol) { var outputstr = ""; var endx = startx + 20; + SVGSymbols.addSymbol(symbol); outputstr += '' + ''; return ({ endx: endx, str: outputstr, lowerbound: null }); @@ -3305,6 +3619,7 @@ var Schakelaar = /** @class */ (function () { endx += 40; break; case "schemerschakelaar": + SVGSymbols.addSymbol('arrow'); // nodig voor de schemerschakelaar (_p = (this.defaulttoDrawReturnObj(startx, '#schemerschakelaar')), endx = _p.endx, outputstr = _p.str); endx += 40; break; @@ -3769,6 +4084,11 @@ var Aansluiting = /** @class */ (function (_super) { }; Aansluiting.prototype.toSVG = function () { var mySVG = new SVGelement(); + SVGSymbols.addSymbol('zekering_automatisch'); + SVGSymbols.addSymbol('zekering_empty'); + SVGSymbols.addSymbol('arrow'); + SVGSymbols.addSymbol('zekering_smelt'); + SVGSymbols.addSymbol('elekriciteitsmeter'); // Indien er een kabeltype vóór de teller is schuiven we alles op var extrashift = 0; if (this.props.type_kabel_voor_teller != "") @@ -4022,6 +4342,7 @@ var Aansluitpunt = /** @class */ (function (_super) { Aansluitpunt.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('aansluitpunt'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 29; mySVG.yup = 25; @@ -4057,6 +4378,7 @@ var Aftakdoos = /** @class */ (function (_super) { Aftakdoos.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('aftakdoos'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 49; mySVG.yup = 25; @@ -4093,6 +4415,7 @@ var Batterij = /** @class */ (function (_super) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); var outputstr = ""; + SVGSymbols.addSymbol('batterij'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; @@ -4128,6 +4451,7 @@ var Bel = /** @class */ (function (_super) { Bel.prototype.toSVG = function () { var mySVG = new SVGelement(); var outputstr = ""; + SVGSymbols.addSymbol('bel'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 40; mySVG.yup = 25; @@ -4174,9 +4498,13 @@ var Boiler = /** @class */ (function (_super) { mySVG.data = (sitplan ? "" : ''); switch (this.props.heeft_accumulatie) { //accumulatie case false: + SVGSymbols.addSymbol('VerticalStripe'); + SVGSymbols.addSymbol('boiler'); mySVG.data += ''; break; case true: + SVGSymbols.addSymbol('VerticalStripe'); + SVGSymbols.addSymbol('boiler_accu'); mySVG.data += ''; break; } @@ -4322,6 +4650,9 @@ var Contactdoos = /** @class */ (function (_super) { if (sitplan === void 0) { sitplan = false; } if (mirrortext === void 0) { mirrortext = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('contactdoos'); + SVGSymbols.addSymbol('contactdoos_aarding'); + SVGSymbols.addSymbol('contactdoos_kinderveilig'); mySVG.xleft = 1; // Links voldoende ruimte voor een eventuele kring voorzien mySVG.xright = 20; // We starten met breedte 20 (leidings links) en vullen later aan in functie van wat moet getekend worden mySVG.yup = 25; @@ -4424,6 +4755,8 @@ var Diepvriezer = /** @class */ (function (_super) { Diepvriezer.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('ster'); + SVGSymbols.addSymbol('diepvriezer'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 60; mySVG.yup = 25; @@ -4557,6 +4890,11 @@ var Domotica_gestuurde_verbruiker = /** @class */ (function (_super) { Domotica_gestuurde_verbruiker.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('draadloos_klein'); + SVGSymbols.addSymbol('drukknop_klein'); + SVGSymbols.addSymbol('tijdschakelaar_klein'); + SVGSymbols.addSymbol('detectie_klein'); + SVGSymbols.addSymbol('schakelaar_klein'); // Eerst de tekening van de aangestuurde verbruiker maken var childcounter = 0; // Variabele voor het aantal kinderen, op dit moment ondersteunt de tool slechts 1 kind // Kind 1 is het element dat effectief gestuurd wordt. @@ -4706,6 +5044,7 @@ var Droogkast = /** @class */ (function (_super) { Droogkast.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('droogkast'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; @@ -4760,6 +5099,7 @@ var Drukknop = /** @class */ (function (_super) { if (sitplan === void 0) { sitplan = false; } if (mirrortext === void 0) { mirrortext = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('drukknop'); mySVG.xleft = 1; // Links voldoende ruimte voor een eventuele kring voorzien mySVG.xright = 43; mySVG.yup = 25; @@ -4853,6 +5193,7 @@ var EV_lader = /** @class */ (function (_super) { EV_lader.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('EVlader'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 60; mySVG.yup = 25; @@ -4888,6 +5229,7 @@ var Elektriciteitsmeter = /** @class */ (function (_super) { Elektriciteitsmeter.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('elektriciteitsmeter'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; @@ -4923,6 +5265,7 @@ var Elektrische_oven = /** @class */ (function (_super) { Elektrische_oven.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('oven'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; @@ -4970,6 +5313,10 @@ var Ketel = /** @class */ (function (_super) { Ketel.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('verbruiker'); + SVGSymbols.addSymbol('gas_ventilator'); + SVGSymbols.addSymbol('gas_atmosferisch'); + SVGSymbols.addSymbol('bliksem'); // Alles naar beneden schuiven als we het aantal laders boven het symbool willen plaatsen var shifty = 0; if (this.props.aantal > 1) { @@ -5071,6 +5418,8 @@ var Koelkast = /** @class */ (function (_super) { Koelkast.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('ster'); + SVGSymbols.addSymbol('koelkast'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; @@ -5106,7 +5455,7 @@ var Kookfornuis = /** @class */ (function (_super) { Kookfornuis.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); - var outputstr = ""; + SVGSymbols.addSymbol('kookfornuis'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; @@ -5263,6 +5612,12 @@ var Kring = /** @class */ (function (_super) { }; Kring.prototype.toSVG = function () { var mySVG = new SVGelement(); + SVGSymbols.addSymbol('zekering_automatisch'); + SVGSymbols.addSymbol('zekering_empty'); + SVGSymbols.addSymbol('zekering_smelt'); + SVGSymbols.addSymbol('overspanningsbeveiliging_inline'); + SVGSymbols.addSymbol('arrow'); + SVGSymbols.addSymbol('relais_kring'); // Bepalen of we de hele kring naar rechts moeten opschuiven om rekening te houden met symbooltjes qua kabel-locatie var cable_location_available = 0; if (this.props.kabel_is_aanwezig /* kabel aanwezig */ && (this.props.kabel_is_in_buis /* kabel in buis */ || contains(["Ondergronds", "In wand", "Op wand"], this.props.kabel_locatie))) { @@ -5684,6 +6039,7 @@ var Lichtpunt = /** @class */ (function (_super) { print_str_upper = "x" + this.props.aantal; switch (this.props.type_lamp) { case "led": + SVGSymbols.addSymbol('led'); // Teken led mySVG.data += ''; // Teken wandlamp indien van toepassing @@ -5737,6 +6093,7 @@ var Lichtpunt = /** @class */ (function (_super) { mySVG.data += (sitplan ? "" : this.addAddressToSVG(mySVG, 50, 5, 2)); break; case "spot": + SVGSymbols.addSymbol('spot'); // teken spot mySVG.data += ''; // Teken wandlamp indien van toepassing @@ -5841,17 +6198,20 @@ var Lichtpunt = /** @class */ (function (_super) { default: //Normaal lichtpunt (kruisje) switch (this.props.type_noodverlichting) { case "Centraal": + SVGSymbols.addSymbol('lamp'); mySVG.data += '' + ''; if ((this.heeftVerbruikerAlsKind()) && (!sitplan)) mySVG.data += ''; break; case "Decentraal": + SVGSymbols.addSymbol('noodlamp_decentraal'); mySVG.data += ''; if (this.props.heeft_ingebouwde_schakelaar) mySVG.data += ''; //Ingebouwde schakelaar break; default: + SVGSymbols.addSymbol('lamp'); mySVG.data += ''; if ((this.heeftVerbruikerAlsKind()) && (!sitplan)) mySVG.data += ''; @@ -5921,6 +6281,7 @@ var Media = /** @class */ (function (_super) { Media.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('luidspreker'); // Alles naar beneden schuiven als we het aantal laders boven het symbool willen plaatsen var shifty = 0; if (this.props.aantal > 1) { @@ -6016,6 +6377,8 @@ var Microgolfoven = /** @class */ (function (_super) { Microgolfoven.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('sinus'); + SVGSymbols.addSymbol('microgolf'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; @@ -6051,6 +6414,7 @@ var Motor = /** @class */ (function (_super) { Motor.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('motor'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; @@ -6086,6 +6450,8 @@ var Omvormer = /** @class */ (function (_super) { Omvormer.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('sinus'); + SVGSymbols.addSymbol('omvormer'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; @@ -6121,6 +6487,7 @@ var Overspanningsbeveiliging = /** @class */ (function (_super) { Overspanningsbeveiliging.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('overspanningsbeveiliging'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 34; mySVG.yup = 25; @@ -6206,6 +6573,7 @@ var Stoomoven = /** @class */ (function (_super) { Stoomoven.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('stoomoven'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; @@ -6244,6 +6612,7 @@ var Transformator = /** @class */ (function (_super) { Transformator.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('transformator'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 47; mySVG.yup = 25; @@ -6284,6 +6653,7 @@ var USB_lader = /** @class */ (function (_super) { USB_lader.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('usblader'); // Alles naar beneden schuiven als we het aantal laders boven het symbool willen plaatsen var shifty = 0; if (this.props.aantal > 1) { @@ -6325,6 +6695,7 @@ var Vaatwasmachine = /** @class */ (function (_super) { Vaatwasmachine.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('vaatwasmachine'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; @@ -6360,6 +6731,7 @@ var Ventilator = /** @class */ (function (_super) { Ventilator.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('ventilator'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 49; mySVG.yup = 25; @@ -6568,14 +6940,20 @@ var Verwarmingstoestel = /** @class */ (function (_super) { mySVG.data = (sitplan ? "" : ''); switch (this.props.heeft_accumulatie) { //accumulatie case false: + SVGSymbols.addSymbol('VerticalStripe'); + SVGSymbols.addSymbol('verwarmingstoestel'); mySVG.data += ''; break; case true: switch (this.props.heeft_ventilator) { //ventilator case false: + SVGSymbols.addSymbol('VerticalStripe'); + SVGSymbols.addSymbol('verwarmingstoestel_accu'); mySVG.data += ''; break; case true: + SVGSymbols.addSymbol('VerticalStripe'); + SVGSymbols.addSymbol('verwarmingstoestel_accu_ventilator'); mySVG.data += ''; mySVG.xright = 89; break; @@ -6789,6 +7167,8 @@ var Warmtepomp = /** @class */ (function (_super) { Warmtepomp.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('verbruiker'); + SVGSymbols.addSymbol('bliksem'); // Alles naar beneden schuiven als we het aantal laders boven het symbool willen plaatsen var shifty = 0; if (this.props.aantal > 1) { @@ -6856,6 +7236,7 @@ var Wasmachine = /** @class */ (function (_super) { Wasmachine.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('wasmachine'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; @@ -6935,6 +7316,8 @@ var Zekering = /** @class */ (function (_super) { Zekering.prototype.toSVG = function () { var mySVG = new SVGelement(); var outputstr = ""; + SVGSymbols.addSymbol('zekering_automatisch_horizontaal'); + SVGSymbols.addSymbol('zekering_smelt_horizontaal'); mySVG.xleft = 1; // Links voldoende ruimte voor een eventuele kring voorzien mySVG.xright = 50; mySVG.yup = 25; @@ -7098,6 +7481,7 @@ var Zeldzame_symbolen = /** @class */ (function (_super) { Zeldzame_symbolen.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('deurslot'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; @@ -7146,6 +7530,8 @@ var Zonnepaneel = /** @class */ (function (_super) { Zonnepaneel.prototype.toSVG = function (sitplan) { if (sitplan === void 0) { sitplan = false; } var mySVG = new SVGelement(); + SVGSymbols.addSymbol('arrow'); + SVGSymbols.addSymbol('zonnepaneel'); mySVG.xleft = 1; // Links voldoende ruimte voor een eventuele kring voorzien mySVG.xright = 69; mySVG.yup = 35; @@ -7180,10 +7566,122 @@ var Properties = /** @class */ (function () { var SVGSymbols = /** @class */ (function () { function SVGSymbols() { } + SVGSymbols.addSymbol = function (symbol) { + if (!this.neededSymbols.includes(symbol)) { + this.neededSymbols.push(symbol); + } + }; + SVGSymbols.clearSymbols = function () { + this.neededSymbols = []; + }; + SVGSymbols.getNeededSymbols = function () { + var output = ''; + if (this.neededSymbols.includes('VerticalStripe')) { + output += '' + + '' + + ''; + } + for (var key in this.data) { + if (this.neededSymbols.includes(key)) { + output += "").concat(this.data[key].replace(/\n/g, ''), ""); + } + } + output += ''; + return (output); + }; SVGSymbols.outputSVGSymbols = function () { - var output = "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n V\n E\n E\n V\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n S\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n PIR\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n M\n \n \n \n \n kWh\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n t\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \"\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \"\n \n \n \n \n \n \n \n \n \n \"\n \"\n \"\n \n \n \n \n \n \n \n \n \n \n AC/DC\n USB\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n -> shift x -7.5 y -15\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n "; + var output = '' + + '' + + '' + + ''; + for (var key in this.data) { + if (key != 'VerticalStripe') + output += "").concat(this.data[key].replace(/\n/g, ''), ""); + } + output += ''; return (output); }; + SVGSymbols.neededSymbols = []; + SVGSymbols.data = { + batterij: "\n\n\n\n\n\n\n", + contactdoos: "\n\n\n\n", + deurslot: "\n\n\n\n\n\n", + ster: "\n\n\n\n", + EVlader: "\n\n\n\n\n\n\n\n\n\n\n\n\nV\nE\nE\nV\n", + lamp: "\n\n\n", + led: "\n\n\n\n\n\n\n\n\n\n\n", + luidspreker: "\n\n\n", + magneetcontact: "\n\n", + sinus: "\n\n", + spot: "\n\n\n\n\n\n", + noodlamp_decentraal: "\n\n\n\n\n", + signalisatielamp: "\n\n\n\n", + schakelaar_enkel: "\n\n\n\n", + schakelaar_klein: "\n\n\n\n", + schakelaar_dubbel: "\n\n\n\n\n", + schakelaar_trippel: "\n\n\n\n\n\n", + schakelaar_wissel_enkel: "\n\n\n\n\n\n", + schakelaar_rolluik: "\n\n\n\n\n\nS\n", + schakelaar_enkel_dim: "\n\n\n\n\n", + schakelaar_wissel_dim: "\n\n\n\n\n\n\n", + schakelaar_kruis_enkel: "\n\n\n\n\n\n\n\n\n\n", + schakelaar_dubbelaansteking: "\n\n\n\n\n\n", + schakelaar_wissel_dubbel: "\n\n\n\n\n\n\n\n", + aansluitpunt: "\n\n", + aftakdoos: "\n\n\n", + bewegingsschakelaar: "\n\n\n\n\n\n\nPIR\n", + schakelaar: "\n\n\n\n", + schemerschakelaar: "\n\n\n\n\n\n", + stoomoven: "\n\n\n\n\n", + contactdoos_aarding: "\n\n", + contactdoos_kinderveilig: "\n\n\n", + bel: "\n\n\n\n", + boiler: "\n\n", + boiler_accu: "\n\n\n", + motor: "\n\nM\n", + elektriciteitsmeter: "\n\n\nkWh\n", + diepvriezer: "\n\n\n\n\n", + zonnepaneel: "\n\n\n\n\n", + drukknop_klein: "\n\n\n", + draadloos_klein: "\n \n \n \n", + detectie_klein: "\n \n \n", + drukknop: "\n\n\n", + teleruptor: "\n\n\n\n\n\n", + dimmer: "\n\n\n\n\n", + relais: "\n\n\n", + minuterie: "\n\nt\n", + thermostaat: "\n\n\n\n", + tijdschakelaar: "\n\n\n\n\n\n\n\n", + tijdschakelaar_klein: "\n\n\n\n", + droogkast: "\n\n\n\n\n", + omvormer: "\n\n\n\"\n\n\n", + overspanningsbeveiliging: "\n\n\n\n\n\n\n\n", + koelkast: "\n\n\"\n", + kookfornuis: "\n\n\n\n\n", + microgolf: "\n\n\"\n\"\n\"\n", + oven: "\n\n\n\n", + usblader: "\n\n\n\nAC/DC\nUSB\n", + vaatwasmachine: "\n\n\n\n\n", + ventilator: "\n\n\n\n", + transformator: "\n\n\n", + verwarmingstoestel: "\n\n", + verwarmingstoestel_accu: "\n\n\n", + verwarmingstoestel_accu_ventilator: "\n\n\n\n\n", + verbruiker: "\n\n", + wasmachine: "\n\n\n\n", + zekering_automatisch: "\n\n\n\n\n", + zekering_automatisch_horizontaal: "\n\n\n\n\n", + zekering_smelt: "\n\n\n", + zekering_smelt_horizontaal: "\n\n\n", + relais_kring: "\n\n\n", + overspanningsbeveiliging_inline: "\n-> shift x -7.5 y -15\n\n\n\n\n\n\n\n", + zekering_empty: "\n\n\n\n", + arrow: "\n\n\n\n", + gas_ventilator: "\n\n", + gas_atmosferisch: "\n\n", + bliksem: "\n\n\n\n\n\n", + moving_man: "\n\n\n\n\n" + }; return SVGSymbols; }()); /***************************************************************************** @@ -7204,6 +7702,8 @@ var SVGSymbols = /** @class */ (function () { remove inactive members from the array. getOrdinalById(my_id: number) : number Returns the element in the array for a given ID + getElectroItemById(my_id: number) : Electro_Item + Returns the Electro_Item in the array for a given ID getNumChilds(parent_id: number) : number Returns the number of childs for a given parent ID getMaxNumChilds(parent_id: number) : number @@ -7332,6 +7832,12 @@ var Hierarchical_List = /** @class */ (function () { } return null; }; + Hierarchical_List.prototype.getElectroItemById = function (my_id) { + var ordinal = this.getOrdinalById(my_id); + if (ordinal !== null) + return this.data[ordinal]; + return null; + }; // -- Aantal actieve kinderen van id = parent_id -- Hierarchical_List.prototype.getNumChilds = function (parent_id) { var returnval = 0; @@ -8266,8 +8772,7 @@ function restart_all() { } } function toggleAppView(type) { - if ((['2col', 'draw'].includes(type)) && (['2col', 'draw'].includes(structure.properties.currentView)) && (type !== structure.properties.currentView)) - undostruct.store(); + var lastview = structure.properties.currentView; structure.properties.currentView = type; if (type === '2col') { document.getElementById("configsection").style.display = 'none'; @@ -8288,6 +8793,8 @@ function toggleAppView(type) { document.getElementById("ribbon").style.display = 'flex'; document.getElementById("canvas_2col").style.display = 'none'; } + if ((['2col', 'draw'].includes(type)) && (['2col', 'draw'].includes(lastview)) && (type !== lastview)) + undostruct.store(); } function load_example(nr) { switch (nr) { diff --git a/makedoc b/makedoc new file mode 100755 index 0000000..bfd5dc0 --- /dev/null +++ b/makedoc @@ -0,0 +1,3 @@ +#!/usr/bin/bash + +npx typedoc --options typedoc.json \ No newline at end of file diff --git a/package.json b/package.json index c108480..e88fb82 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "devDependencies": { + "typedoc": "^0.27.6", "typescript": "^5.6.2" }, "dependencies": { diff --git a/src/Hierarchical_List.ts b/src/Hierarchical_List.ts index f278d64..9fe6fa3 100644 --- a/src/Hierarchical_List.ts +++ b/src/Hierarchical_List.ts @@ -16,6 +16,8 @@ remove inactive members from the array. getOrdinalById(my_id: number) : number Returns the element in the array for a given ID + getElectroItemById(my_id: number) : Electro_Item + Returns the Electro_Item in the array for a given ID getNumChilds(parent_id: number) : number Returns the number of childs for a given parent ID getMaxNumChilds(parent_id: number) : number @@ -164,13 +166,19 @@ class Hierarchical_List { // -- Plaats in de array zoeken op basis van de id -- - getOrdinalById(my_id: number) : number { + getOrdinalById(my_id: number) : number | null { for (let i = 0; i'); switch (this.props.heeft_accumulatie) { //accumulatie case false: + SVGSymbols.addSymbol('VerticalStripe'); + SVGSymbols.addSymbol('boiler'); mySVG.data += ''; break; case true: + SVGSymbols.addSymbol('VerticalStripe'); + SVGSymbols.addSymbol('boiler_accu'); mySVG.data += ''; break; } diff --git a/src/List_Item/Contactdoos.ts b/src/List_Item/Contactdoos.ts index e440b19..ea08ea3 100644 --- a/src/List_Item/Contactdoos.ts +++ b/src/List_Item/Contactdoos.ts @@ -55,6 +55,10 @@ class Contactdoos extends Electro_Item { toSVG(sitplan: boolean = false, mirrortext: boolean = false): SVGelement { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('contactdoos'); + SVGSymbols.addSymbol('contactdoos_aarding'); + SVGSymbols.addSymbol('contactdoos_kinderveilig'); + mySVG.xleft = 1; // Links voldoende ruimte voor een eventuele kring voorzien mySVG.xright = 20; // We starten met breedte 20 (leidings links) en vullen later aan in functie van wat moet getekend worden mySVG.yup = 25; diff --git a/src/List_Item/Diepvriezer.ts b/src/List_Item/Diepvriezer.ts index 9763801..35e3d6f 100644 --- a/src/List_Item/Diepvriezer.ts +++ b/src/List_Item/Diepvriezer.ts @@ -24,6 +24,9 @@ class Diepvriezer extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('ster'); + SVGSymbols.addSymbol('diepvriezer'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 60; mySVG.yup = 25; diff --git a/src/List_Item/Domotica_gestuurde_verbruiker.ts b/src/List_Item/Domotica_gestuurde_verbruiker.ts index f36f6e1..af17ef0 100644 --- a/src/List_Item/Domotica_gestuurde_verbruiker.ts +++ b/src/List_Item/Domotica_gestuurde_verbruiker.ts @@ -52,6 +52,12 @@ class Domotica_gestuurde_verbruiker extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('draadloos_klein'); + SVGSymbols.addSymbol('drukknop_klein'); + SVGSymbols.addSymbol('tijdschakelaar_klein'); + SVGSymbols.addSymbol('detectie_klein'); + SVGSymbols.addSymbol('schakelaar_klein'); + // Eerst de tekening van de aangestuurde verbruiker maken let childcounter = 0; // Variabele voor het aantal kinderen, op dit moment ondersteunt de tool slechts 1 kind diff --git a/src/List_Item/Droogkast.ts b/src/List_Item/Droogkast.ts index 3eba638..f2ff012 100644 --- a/src/List_Item/Droogkast.ts +++ b/src/List_Item/Droogkast.ts @@ -24,6 +24,8 @@ class Droogkast extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('droogkast'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; diff --git a/src/List_Item/Drukknop.ts b/src/List_Item/Drukknop.ts index 05f5432..aecfee7 100644 --- a/src/List_Item/Drukknop.ts +++ b/src/List_Item/Drukknop.ts @@ -41,6 +41,8 @@ class Drukknop extends Electro_Item { toSVG(sitplan: boolean = false, mirrortext: boolean = false) { let mySVG:SVGelement = new SVGelement(); + + SVGSymbols.addSymbol('drukknop'); mySVG.xleft = 1; // Links voldoende ruimte voor een eventuele kring voorzien mySVG.xright = 43; diff --git a/src/List_Item/EV_lader.ts b/src/List_Item/EV_lader.ts index 23a2520..77a7674 100644 --- a/src/List_Item/EV_lader.ts +++ b/src/List_Item/EV_lader.ts @@ -24,6 +24,8 @@ class EV_lader extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('EVlader'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 60; mySVG.yup = 25; diff --git a/src/List_Item/Electro_Item.ts b/src/List_Item/Electro_Item.ts index 0a43b44..6a417ed 100644 --- a/src/List_Item/Electro_Item.ts +++ b/src/List_Item/Electro_Item.ts @@ -245,8 +245,8 @@ class Electro_Item extends List_Item { */ toSituationPlanElement() { - let myElement = new SituationPlanElement(1,0,0,0,0,11,0,1,randomId("SP_"),""); - this.updateSituationPlanElement(myElement); + let myElement = new SituationPlanElement(); + //this.updateSituationPlanElement(myElement); //Lijkt niet nodig aangezien dit zoiezo gebeurt in getScaledSVG bij iedere update return(myElement); } @@ -256,6 +256,8 @@ class Electro_Item extends List_Item { let rotate = myElement.rotate % 360; if ( (rotate >= 90) && (rotate < 270) ) spiegeltext = true; + SVGSymbols.clearSymbols(); // We gaan enkel de symbolen gebruiken die nodig zijn voor dit element + let mySVGElement:SVGelement = this.toSVG(true, spiegeltext); let sizex = mySVGElement.xright + mySVGElement.xleft + 10; let sizey = mySVGElement.yup + mySVGElement.ydown; @@ -269,13 +271,14 @@ class Electro_Item extends List_Item { let addright = 0; - myElement.setSVG(`` - + SVGSymbols.outputSVGSymbols() - + mySVGElement.data - + ''); + let width = sizex-clipleft+addright; + let height = sizey; - myElement.getSizeFromString(); + myElement.updateElectroItemSVG( '` + + SVGSymbols.getNeededSymbols() + // enkel de symbolen die nodig zijn voor dit element + mySVGElement.data + + '',width,height); } } diff --git a/src/List_Item/Elektriciteitsmeter.ts b/src/List_Item/Elektriciteitsmeter.ts index 35cf8d9..722b818 100644 --- a/src/List_Item/Elektriciteitsmeter.ts +++ b/src/List_Item/Elektriciteitsmeter.ts @@ -24,6 +24,8 @@ class Elektriciteitsmeter extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('elektriciteitsmeter'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; diff --git a/src/List_Item/Elektrische_oven.ts b/src/List_Item/Elektrische_oven.ts index a0bbcc7..cf4830e 100644 --- a/src/List_Item/Elektrische_oven.ts +++ b/src/List_Item/Elektrische_oven.ts @@ -24,6 +24,8 @@ class Elektrische_oven extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('oven'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; diff --git a/src/List_Item/Ketel.ts b/src/List_Item/Ketel.ts index 3c2b259..7f37efa 100644 --- a/src/List_Item/Ketel.ts +++ b/src/List_Item/Ketel.ts @@ -36,6 +36,11 @@ class Ketel extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('verbruiker'); + SVGSymbols.addSymbol('gas_ventilator'); + SVGSymbols.addSymbol('gas_atmosferisch'); + SVGSymbols.addSymbol('bliksem'); + // Alles naar beneden schuiven als we het aantal laders boven het symbool willen plaatsen var shifty = 0; if (this.props.aantal>1) { diff --git a/src/List_Item/Koelkast.ts b/src/List_Item/Koelkast.ts index b12bb0d..84077c8 100644 --- a/src/List_Item/Koelkast.ts +++ b/src/List_Item/Koelkast.ts @@ -24,6 +24,9 @@ class Koelkast extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('ster'); + SVGSymbols.addSymbol('koelkast'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; diff --git a/src/List_Item/Kookfornuis.ts b/src/List_Item/Kookfornuis.ts index eaddb2a..338f7d2 100644 --- a/src/List_Item/Kookfornuis.ts +++ b/src/List_Item/Kookfornuis.ts @@ -23,7 +23,8 @@ class Kookfornuis extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); - let outputstr:string = ""; + + SVGSymbols.addSymbol('kookfornuis'); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; diff --git a/src/List_Item/Kring.ts b/src/List_Item/Kring.ts index bd87560..93bae8a 100644 --- a/src/List_Item/Kring.ts +++ b/src/List_Item/Kring.ts @@ -155,6 +155,13 @@ class Kring extends Electro_Item { toSVG() { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('zekering_automatisch'); + SVGSymbols.addSymbol('zekering_empty'); + SVGSymbols.addSymbol('zekering_smelt'); + SVGSymbols.addSymbol('overspanningsbeveiliging_inline'); + SVGSymbols.addSymbol('arrow'); + SVGSymbols.addSymbol('relais_kring'); + // Bepalen of we de hele kring naar rechts moeten opschuiven om rekening te houden met symbooltjes qua kabel-locatie let cable_location_available: number = 0; diff --git a/src/List_Item/Lichtpunt.ts b/src/List_Item/Lichtpunt.ts index 2b59421..b978271 100644 --- a/src/List_Item/Lichtpunt.ts +++ b/src/List_Item/Lichtpunt.ts @@ -69,6 +69,8 @@ class Lichtpunt extends Electro_Item { switch (this.props.type_lamp) { case "led": + SVGSymbols.addSymbol('led'); + // Teken led mySVG.data += ''; @@ -122,6 +124,8 @@ class Lichtpunt extends Electro_Item { break; case "spot": + SVGSymbols.addSymbol('spot'); + // teken spot mySVG.data += ''; @@ -231,18 +235,21 @@ class Lichtpunt extends Electro_Item { break; default: //Normaal lichtpunt (kruisje) - + switch (this.props.type_noodverlichting) { case "Centraal": + SVGSymbols.addSymbol('lamp'); mySVG.data += '' + ''; if ( (this.heeftVerbruikerAlsKind()) && (!sitplan) ) mySVG.data += ''; break; case "Decentraal": + SVGSymbols.addSymbol('noodlamp_decentraal'); mySVG.data += ''; if (this.props.heeft_ingebouwde_schakelaar) mySVG.data += ''; //Ingebouwde schakelaar break; default: + SVGSymbols.addSymbol('lamp'); mySVG.data += ''; if ( (this.heeftVerbruikerAlsKind()) && (!sitplan) ) mySVG.data += ''; break; diff --git a/src/List_Item/Media.ts b/src/List_Item/Media.ts index 4d4c1df..3da7a8d 100644 --- a/src/List_Item/Media.ts +++ b/src/List_Item/Media.ts @@ -40,6 +40,8 @@ class Media extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('luidspreker'); + // Alles naar beneden schuiven als we het aantal laders boven het symbool willen plaatsen var shifty = 0; if (this.props.aantal>1) { diff --git a/src/List_Item/Microgolfoven.ts b/src/List_Item/Microgolfoven.ts index bf92133..93f3443 100644 --- a/src/List_Item/Microgolfoven.ts +++ b/src/List_Item/Microgolfoven.ts @@ -24,6 +24,9 @@ class Microgolfoven extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('sinus'); + SVGSymbols.addSymbol('microgolf'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; diff --git a/src/List_Item/Motor.ts b/src/List_Item/Motor.ts index 61f5c7d..5ca4ef5 100644 --- a/src/List_Item/Motor.ts +++ b/src/List_Item/Motor.ts @@ -24,6 +24,8 @@ class Motor extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('motor'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; diff --git a/src/List_Item/Omvormer.ts b/src/List_Item/Omvormer.ts index ef511a5..d0ee66a 100644 --- a/src/List_Item/Omvormer.ts +++ b/src/List_Item/Omvormer.ts @@ -24,6 +24,9 @@ class Omvormer extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('sinus'); + SVGSymbols.addSymbol('omvormer'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; diff --git a/src/List_Item/Overspanningsbeveiliging.ts b/src/List_Item/Overspanningsbeveiliging.ts index 535288f..f3ac886 100644 --- a/src/List_Item/Overspanningsbeveiliging.ts +++ b/src/List_Item/Overspanningsbeveiliging.ts @@ -24,6 +24,8 @@ class Overspanningsbeveiliging extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('overspanningsbeveiliging'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 34; mySVG.yup = 25; diff --git a/src/List_Item/Schakelaars/Schakelaar.ts b/src/List_Item/Schakelaars/Schakelaar.ts index 4d39d9a..174179d 100644 --- a/src/List_Item/Schakelaars/Schakelaar.ts +++ b/src/List_Item/Schakelaars/Schakelaar.ts @@ -26,6 +26,7 @@ class Schakelaar { } schakelaarAttributentoSVGString(endx: number, isdubbel: boolean = false) { + SVGSymbols.addSymbol('signalisatielamp'); let outputstr:string = ""; if (this.signalisatielamp) outputstr += ''; if (this.halfwaterdicht) { @@ -49,6 +50,8 @@ class Schakelaar { let outputstr:string = ""; let endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_enkel'); + outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx); @@ -60,6 +63,8 @@ class Schakelaar { let outputstr:string = ""; let endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_dubbel'); + outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx,true); @@ -71,6 +76,8 @@ class Schakelaar { let outputstr:string = ""; let endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_trippel'); + outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx,true); @@ -82,6 +89,8 @@ class Schakelaar { let outputstr:string = ""; let endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_dubbelaansteking'); + outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx); @@ -93,6 +102,8 @@ class Schakelaar { let outputstr:string = ""; let endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_wissel_enkel'); + outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx); @@ -104,6 +115,8 @@ class Schakelaar { let outputstr:string = ""; let endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_wissel_dubbel'); + outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx,true); @@ -115,6 +128,8 @@ class Schakelaar { let outputstr:string = ""; let endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_kruis_enkel'); + outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx); @@ -126,6 +141,8 @@ class Schakelaar { let outputstr:string = ""; let endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_enkel_dim'); + outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx); @@ -137,6 +154,8 @@ class Schakelaar { let outputstr:string = ""; let endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_wissel_dim'); + outputstr += '' + '' + this.schakelaarAttributentoSVGString(endx); @@ -148,6 +167,10 @@ class Schakelaar { let outputstr:string = ""; let endx = startx + 20; + SVGSymbols.addSymbol('relais'); + SVGSymbols.addSymbol('moving_man'); + SVGSymbols.addSymbol('detectie_klein'); + outputstr += '' + '' + '' @@ -163,6 +186,8 @@ class Schakelaar { let outputstr:string = ""; let endx = startx + 30; + SVGSymbols.addSymbol('schakelaar_rolluik'); + outputstr += '' + ''; @@ -181,6 +206,8 @@ class Schakelaar { let outputstr:string = ""; let endx = startx + 20; + SVGSymbols.addSymbol('magneetcontact'); + // Alles naar beneden schuiven als we het aantal laders boven het symbool willen plaatsen if (this.aantal>1) { let textoptions = 'style="text-anchor:middle" font-family="Arial, Helvetica, sans-serif" font-size="10"'; @@ -200,6 +227,8 @@ class Schakelaar { let outputstr:string = ""; let endx = startx + 20; + SVGSymbols.addSymbol(symbol); + outputstr += '' + ''; @@ -283,6 +312,7 @@ class Schakelaar { endx += 40; break; case "schemerschakelaar": + SVGSymbols.addSymbol('arrow'); // nodig voor de schemerschakelaar ( {endx: endx, str: outputstr} = (this.defaulttoDrawReturnObj(startx,'#schemerschakelaar')) ); endx += 40; break; diff --git a/src/List_Item/Stoomoven.ts b/src/List_Item/Stoomoven.ts index 69242cc..79dec8c 100644 --- a/src/List_Item/Stoomoven.ts +++ b/src/List_Item/Stoomoven.ts @@ -24,6 +24,8 @@ class Stoomoven extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('stoomoven'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; diff --git a/src/List_Item/Transformator.ts b/src/List_Item/Transformator.ts index 823c849..a351a28 100644 --- a/src/List_Item/Transformator.ts +++ b/src/List_Item/Transformator.ts @@ -27,6 +27,8 @@ class Transformator extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('transformator'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 47; mySVG.yup = 25; diff --git a/src/List_Item/USB_lader.ts b/src/List_Item/USB_lader.ts index 0095443..52b0906 100644 --- a/src/List_Item/USB_lader.ts +++ b/src/List_Item/USB_lader.ts @@ -27,6 +27,8 @@ class USB_lader extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('usblader'); + // Alles naar beneden schuiven als we het aantal laders boven het symbool willen plaatsen var shifty = 0; if (this.props.aantal > 1) { diff --git a/src/List_Item/Vaatwasmachine.ts b/src/List_Item/Vaatwasmachine.ts index ee3cdb4..53a9312 100644 --- a/src/List_Item/Vaatwasmachine.ts +++ b/src/List_Item/Vaatwasmachine.ts @@ -24,6 +24,8 @@ class Vaatwasmachine extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('vaatwasmachine'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; diff --git a/src/List_Item/Ventilator.ts b/src/List_Item/Ventilator.ts index 6fa0d64..108d724 100644 --- a/src/List_Item/Ventilator.ts +++ b/src/List_Item/Ventilator.ts @@ -24,6 +24,8 @@ class Ventilator extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('ventilator'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 49; mySVG.yup = 25; diff --git a/src/List_Item/Verwarmingstoestel.ts b/src/List_Item/Verwarmingstoestel.ts index 8c3f730..2c2e3cc 100644 --- a/src/List_Item/Verwarmingstoestel.ts +++ b/src/List_Item/Verwarmingstoestel.ts @@ -33,7 +33,7 @@ class Verwarmingstoestel extends Electro_Item { } toSVG(sitplan = false) { - let mySVG:SVGelement = new SVGelement(); + let mySVG:SVGelement = new SVGelement(); mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 69; @@ -43,14 +43,20 @@ class Verwarmingstoestel extends Electro_Item { mySVG.data = (sitplan? "" : ''); switch (this.props.heeft_accumulatie) { //accumulatie case false: + SVGSymbols.addSymbol('VerticalStripe'); + SVGSymbols.addSymbol('verwarmingstoestel'); mySVG.data += ''; break; case true: switch (this.props.heeft_ventilator) { //ventilator case false: + SVGSymbols.addSymbol('VerticalStripe'); + SVGSymbols.addSymbol('verwarmingstoestel_accu'); mySVG.data += ''; break; case true: + SVGSymbols.addSymbol('VerticalStripe'); + SVGSymbols.addSymbol('verwarmingstoestel_accu_ventilator'); mySVG.data += ''; mySVG.xright = 89; break; diff --git a/src/List_Item/Warmtepomp.ts b/src/List_Item/Warmtepomp.ts index e981e0b..8b427a1 100644 --- a/src/List_Item/Warmtepomp.ts +++ b/src/List_Item/Warmtepomp.ts @@ -30,6 +30,9 @@ class Warmtepomp extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('verbruiker'); + SVGSymbols.addSymbol('bliksem'); + // Alles naar beneden schuiven als we het aantal laders boven het symbool willen plaatsen var shifty = 0; if (this.props.aantal>1) { diff --git a/src/List_Item/Wasmachine.ts b/src/List_Item/Wasmachine.ts index 94d5d15..027dc6d 100644 --- a/src/List_Item/Wasmachine.ts +++ b/src/List_Item/Wasmachine.ts @@ -24,6 +24,8 @@ class Wasmachine extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('wasmachine'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; diff --git a/src/List_Item/Zekering.ts b/src/List_Item/Zekering.ts index 92ec887..93716c4 100644 --- a/src/List_Item/Zekering.ts +++ b/src/List_Item/Zekering.ts @@ -73,6 +73,9 @@ class Zekering extends Electro_Item { let mySVG:SVGelement = new SVGelement(); let outputstr:string = ""; + SVGSymbols.addSymbol('zekering_automatisch_horizontaal'); + SVGSymbols.addSymbol('zekering_smelt_horizontaal'); + mySVG.xleft = 1; // Links voldoende ruimte voor een eventuele kring voorzien mySVG.xright = 50; mySVG.yup = 25; diff --git a/src/List_Item/Zeldzame_symbolen.ts b/src/List_Item/Zeldzame_symbolen.ts index 7e80907..0bd8a08 100644 --- a/src/List_Item/Zeldzame_symbolen.ts +++ b/src/List_Item/Zeldzame_symbolen.ts @@ -27,6 +27,8 @@ class Zeldzame_symbolen extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('deurslot'); + mySVG.xleft = 1; // foresee at least some space for the conductor mySVG.xright = 59; mySVG.yup = 25; diff --git a/src/List_Item/Zonnepaneel.ts b/src/List_Item/Zonnepaneel.ts index fd229f6..70de353 100644 --- a/src/List_Item/Zonnepaneel.ts +++ b/src/List_Item/Zonnepaneel.ts @@ -28,6 +28,9 @@ class Zonnepaneel extends Electro_Item { toSVG(sitplan = false) { let mySVG:SVGelement = new SVGelement(); + SVGSymbols.addSymbol('arrow'); + SVGSymbols.addSymbol('zonnepaneel'); + mySVG.xleft = 1; // Links voldoende ruimte voor een eventuele kring voorzien mySVG.xright = 69; mySVG.yup = 35; diff --git a/src/SVGSymbols.ts b/src/SVGSymbols.ts index 4d3f757..dc582c4 100644 --- a/src/SVGSymbols.ts +++ b/src/SVGSymbols.ts @@ -1,453 +1,496 @@ class SVGSymbols { -static outputSVGSymbols() { - var output: string = ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - V - E - E - V - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - S - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PIR - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - M - - - - - kWh - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - t - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " - - - - - - - - - - - - - - - " - - - - - - - - - - " - " - " - - - - - - - - - - - AC/DC - USB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -> shift x -7.5 y -15 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ` - return(output); + + static neededSymbols: string[] = []; + + static addSymbol(symbol: string) { + if (!this.neededSymbols.includes(symbol)) { + this.neededSymbols.push(symbol); + } + } + + static clearSymbols() { + this.neededSymbols = []; + } + + static getNeededSymbols() { + let output: string = ''; + + if (this.neededSymbols.includes('VerticalStripe')) { + output += '' + + '' + + ''; + } + + for (let key in this.data) { + if (this.neededSymbols.includes(key)) { + output += `${this.data[key].replace(/\n/g, '')}`; + } + } + output += ''; + return(output); + } + + static outputSVGSymbols() { + let output: string = '' + + '' + + '' + + ''; + for (let key in this.data) { + if (key != 'VerticalStripe') output += `${this.data[key].replace(/\n/g, '')}`; + } + output += ''; + return(output); + } + +static data = { + +batterij: ` + + + + + + +`, +contactdoos: ` + + + +`, +deurslot: ` + + + + + +`, +ster: ` + + + +`, +EVlader: ` + + + + + + + + + + + + +V +E +E +V +`, +lamp: ` + + +`, +led: ` + + + + + + + + + + +`, +luidspreker: ` + + +`, +magneetcontact: ` + +`, +sinus: ` + +`, +spot: ` + + + + + +`, +noodlamp_decentraal: ` + + + + +`, +signalisatielamp: ` + + + +`, +schakelaar_enkel: ` + + + +`, +schakelaar_klein: ` + + + +`, +schakelaar_dubbel: ` + + + + +`, +schakelaar_trippel: ` + + + + + +`, +schakelaar_wissel_enkel: ` + + + + + +`, +schakelaar_rolluik: ` + + + + + +S +`, +schakelaar_enkel_dim: ` + + + + +`, +schakelaar_wissel_dim: ` + + + + + + +`, +schakelaar_kruis_enkel: ` + + + + + + + + + +`, +schakelaar_dubbelaansteking: ` + + + + + +`, +schakelaar_wissel_dubbel: ` + + + + + + + +`, +aansluitpunt: ` + +`, +aftakdoos: ` + + +`, +bewegingsschakelaar: ` + + + + + + +PIR +`, +schakelaar: ` + + + +`, +schemerschakelaar: ` + + + + + +`, +stoomoven: ` + + + + +`, +contactdoos_aarding: ` + +`, +contactdoos_kinderveilig: ` + + +`, +bel: ` + + + +`, +boiler: ` + +`, +boiler_accu: ` + + +`, +motor: ` + +M +`, +elektriciteitsmeter: ` + + +kWh +`, +diepvriezer: ` + + + + +`, +zonnepaneel: ` + + + + +`, +drukknop_klein: ` + + +`, +draadloos_klein: ` + + + +`, +detectie_klein: ` + + +`, +drukknop: ` + + +`, +teleruptor: ` + + + + + +`, +dimmer: ` + + + + +`, +relais: ` + + +`, +minuterie: ` + +t +`, +thermostaat: ` + + + +`, +tijdschakelaar: ` + + + + + + + +`, +tijdschakelaar_klein: ` + + + +`, +droogkast: ` + + + + +`, +omvormer: ` + + +" + + +`, +overspanningsbeveiliging: ` + + + + + + + +`, +koelkast: ` + +" +`, +kookfornuis: ` + + + + +`, +microgolf: ` + +" +" +" +`, +oven: ` + + + +`, +usblader: ` + + + +AC/DC +USB +`, +vaatwasmachine: ` + + + + +`, +ventilator: ` + + + +`, +transformator: ` + + +`, +verwarmingstoestel: ` + +`, +verwarmingstoestel_accu: ` + + +`, +verwarmingstoestel_accu_ventilator: ` + + + + +`, +verbruiker: ` + +`, +wasmachine: ` + + + +`, +zekering_automatisch: ` + + + + +`, +zekering_automatisch_horizontaal: ` + + + + +`, +zekering_smelt: ` + + +`, +zekering_smelt_horizontaal: ` + + +`, +relais_kring: ` + + +`, +overspanningsbeveiliging_inline: ` +-> shift x -7.5 y -15 + + + + + + + +`, +zekering_empty: ` + + + +`, +arrow: ` + + + +`, +gas_ventilator: ` + +`, +gas_atmosferisch: ` + +`, +bliksem: ` + + + + + +`, +moving_man: ` + + + + +` } + + } diff --git a/src/main.ts b/src/main.ts index 07bfffa..24f6d11 100644 --- a/src/main.ts +++ b/src/main.ts @@ -286,9 +286,8 @@ function restart_all() { } function toggleAppView(type: '2col' | 'config' | 'draw') { - if ( (['2col','draw'].includes(type)) && (['2col','draw'].includes(structure.properties.currentView)) && (type !== structure.properties.currentView) ) - undostruct.store(); - + let lastview = structure.properties.currentView; + structure.properties.currentView = type; if (type === '2col') { document.getElementById("configsection").style.display = 'none'; @@ -307,6 +306,10 @@ function toggleAppView(type: '2col' | 'config' | 'draw') { document.getElementById("ribbon").style.display = 'flex'; document.getElementById("canvas_2col").style.display = 'none'; } + + if ( (['2col','draw'].includes(type)) && (['2col','draw'].includes(lastview)) && (type !== lastview) ) + undostruct.store(); + } function load_example(nr: number) { diff --git a/src/sitplan/SituationPlan.ts b/src/sitplan/SituationPlan.ts index b031a85..c0c352e 100644 --- a/src/sitplan/SituationPlan.ts +++ b/src/sitplan/SituationPlan.ts @@ -1,72 +1,173 @@ +/** + * Volledig overzicht van een situatieplan. + * Werd gebouwd voor gebruik in de browser maar is redelijk browser-agnostic. + * De effectieve code om te interageren met de browser zelf zit in class SituationPlanView. + * + * GLOBALS: structure + */ + + class SituationPlan { + public activePage: number = 1; // We houden deze bij in situationplan zodat ook wijzigingen van pagina's worden opgeslagen private numPages: number = 1; - private activePage: number = 1; + private elements: SituationPlanElement[] = []; - public elements: SituationPlanElement[]; + /** + * Workaround om de private variabele elements te kunnen gebruiken in friend classs + * @returns {SituationPlanElement[]} De elementen van het situatieplan + */ - constructor() { - this.elements = []; + getElements(): SituationPlanElement[] { + return this.elements; } + /** + * SituationPlanElement toevoegen aan het situatieplan + * @param element + * @returns {void} + */ + addElement(element: SituationPlanElement) { this.elements.push(element); } - addElementFromFile(event: any, page: number, posx: number, posy: number, callback): SituationPlanElement { - let element: SituationPlanElement = new SituationPlanElement(page,posx,posy,0,0,11,0,SITPLANVIEW_DEFAULT_SCALE,randomId("SP_"),""); + /** + * Laad een SVG-inhoud vanuit een bestand en voegt deze toe aan het situatieplan. + * De SVG werd geselecteerd in een fileInput HTML element en komt binnen via het event in de functie header. + * + * @param {any} event Het event dat aangaf dat er een bestand was gekozen om te uploaden. + * @param {number} page Het pagina-nummer van het element in het situatieplan. + * @param {number} posx De x-coordinaat van het element in het situatieplan. + * @param {number} posy De y-coordinaat van het element in het situatieplan. + * @param {() => void} callback Een callback-functie die wordt aangeroepen wanneer het element is toegevoegd. + * @returns {SituationPlanElement} Het element dat is toegevoegd. + */ + + addElementFromFile(event: InputEvent, page: number, posx: number, posy: number, callback: () => void): SituationPlanElement { + let element: SituationPlanElement = new SituationPlanElement(); + element.setVars({page: page, posx: posx, posy: posy}); element.importFromFile(event, callback); this.elements.push(element); return element; } - addElementFromSVG(svg: string, page: number, posx: number, posy: number) { - let element: SituationPlanElement = new SituationPlanElement(page,posx,posy,0,0,11,0,SITPLANVIEW_DEFAULT_SCALE,randomId("SP_"),svg); - element.getSizeFromString(); - this.elements.push(element); + /** + * Creëer een nieuw element in het situatieplan dat gelinkt is aan een Electro_Item + * + * @param {number} electroItemId Het ID van de Electro_Item. + * @param {number} page Het pagina-nummer van het element in het situatieplan. + * @param {number} posx De x-coordinaat van het element in het situatieplan. + * @param {number} posy De y-coordinaat van het element in het situatieplan. + * @param {AdresType} adrestype Het type van het adres, bijvoorbeeld 'manueel'. + * AdresType wordt definieerd in SituationPlanElement.ts + * @param {string} adres Het adres. + * @param {AdresLocation} adreslocation De locatie van het adres in het label ('boven' of 'onder' of 'rechts' of 'links'). + * AdresLocation wordt definieerd in SituationPlanElement.ts + * @param {number} labelfontsize De lettergrootte van het label. + * @param {number} scale De schaal van het element. + * @param {number} rotate De rotatie van het element. + * @returns {SituationPlanElement} Het element dat is toegevoegd. + */ + addElementFromElectroItem(electroItemId: number, page: number, posx: number, posy: number, adrestype: AdresType, adres:string, adreslocation: AdresLocation, + labelfontsize: number, scale: number, rotate: number): SituationPlanElement | null{ + + const electroItem: Electro_Item = structure.getElectroItemById(electroItemId); + if (!electroItem) return null; + + const element: SituationPlanElement = electroItem.toSituationPlanElement(); + Object.assign(element, {page, posx, posy, labelfontsize, scale, rotate}); + element.setElectroItemId(electroItemId); + element.setAdres(adrestype,adres,adreslocation); + this.elements.push(element) + return element; } - addElectroItem(id: number, page: number, posx: number, posy: number, adrestype: string, adres:string, adreslocation: string, - labelfontsize: number, scale: number, rotate: number): SituationPlanElement { - let electroItem: Electro_Item = structure.data[structure.getOrdinalById(id)] as Electro_Item; - if (electroItem != null) { - let element: SituationPlanElement = electroItem.toSituationPlanElement(); - Object.assign(element, {page: page, posx: posx, posy: posy, labelfontsize: labelfontsize, scale: scale, rotate: rotate}); - element.setElectroItemId(id); - element.setAdres(adrestype,adres,adreslocation); - this.elements.push(element) - return element; - } else { - return null; - } + /** + * Verwijder een element van het situatieplan. + * In principe is er altijd maar één maar de functie gebruikt recursie in het geval er meerdere zouden zijn + * om ze allemaal te verwijderen. + * + * @param {SituationPlanElement} element Het element dat verwijderd moet worden. + * @returns {void} + */ + + removeElement(element: SituationPlanElement): void { + const index = this.elements.indexOf(element); + if (index === -1) return; + this.elements.splice(index, 1); + if (element.boxref != null) element.boxref.remove(); + if (element.boxlabelref != null) element.boxlabelref.remove(); + this.removeElement(element); // Recurse in het geval er meerdere zouden zijn maar dit zou niet mogen gebeuren } - removeElement(element: SituationPlanElement) { - for (let i = this.elements.length - 1; i >= 0; i--) { - if (this.elements[i] == element) { this.elements.splice(i, 1); } + /** + * Sorteer de elementen in het situatieplan op basis van de z-index van hun boxref elementen in de DOM. + * Elementen met een `null` `boxref` worden naar het einde van de lijst verplaatst. + * + * Het sorteren is nodig om ervoor te zorgen dat bij het printen wanneer lineair door de elementen wordt gegaan + * de elementen in de juiste volgorde worden gestacked. + * + * @returns {void} + */ + + orderByZIndex() { + this.elements.sort((a, b) => { + if (a.boxref == null) return 1; + if (b.boxref == null) return -1; + return parseInt(a.boxref.style.zIndex) - parseInt(b.boxref.style.zIndex); + }); + } + + /** + * Initialiseer het situatieplan vanuit een json-object. + * + * @param {Object} json Het json-object dat het situatieplan bevat. + * Het object bevat een 'numPages' property dat het aantal pagina's in het situatieplan aangeeft. + * Verder bevat het een 'elements' property dat een array is van json-objecten die elk een element in het situatieplan vertegenwoordigen. + * Elke json-object in de array bevat de properties van een SituationPlanElement. + * @returns {void} + */ + + fromJsonObject(json: any) { + if (json.numPages !== undefined) { + this.numPages = json.numPages; + } else { + this.numPages = 1; } + + if (json.activePage !== undefined) { + this.activePage = json.activePage; + } else { + this.activePage = 1; } + + if (Array.isArray(json.elements)) { + this.elements = json.elements.map((element: any) => { + const newElement = new SituationPlanElement(); + newElement.fromJsonObject(element); + return newElement; + }); + } else { + this.elements = []; } - if (element.boxref != null) element.boxref.remove(); - if (element.boxlabelref != null) element.boxlabelref.remove(); } - toJsonObject() { + /** + * Converteer het situatieplan naar een JSON-object. + * + * @returns {any} Het JSON-object. + */ + + toJsonObject(): any { let elements = []; for (let element of this.elements) { elements.push(element.toJsonObject()); } - return {numPages: this.numPages, elements: elements}; + return {numPages: this.numPages, activePage: this.activePage, elements: elements}; } - fromJsonObject(json: any) { - this.numPages = json.numPages; - this.elements = []; - for (let element of json.elements) { - let newElement = new SituationPlanElement(1,0,0,0,0,11,0,SITPLANVIEW_DEFAULT_SCALE,randomId("SP_"),""); - newElement.fromJsonObject(element); - this.elements.push(newElement); - } - } toSitPlanPrint() { + this.orderByZIndex(); + let outstruct:any = {}; outstruct.numpages = (this.elements.length > 0 ? structure.sitplan.numPages : 0); @@ -87,11 +188,10 @@ class SituationPlan { if (fontsize == null) fontsize = 11; svgstr += element.getScaledSVG(true); - let rotatedimgwidth = element.sizex*element.scale; - let rotatedimgheight = element.sizey*element.scale; - - rotatedimgwidth = Math.max(rotatedimgwidth * Math.cos(element.rotate*Math.PI/180), rotatedimgheight * Math.sin(element.rotate*Math.PI/180)); - rotatedimgheight = Math.max(rotatedimgwidth * Math.sin(element.rotate*Math.PI/180), rotatedimgheight * Math.cos(element.rotate*Math.PI/180)); + let rotatedimgwidth = Math.max(element.sizex*element.scale * Math.cos(element.rotate*Math.PI/180), + element.sizey*element.scale * Math.sin(element.rotate*Math.PI/180)); + let rotatedimgheight = Math.max(element.sizex*element.scale * Math.sin(element.rotate*Math.PI/180), + element.sizey*element.scale * Math.cos(element.rotate*Math.PI/180)); maxx = Math.max(maxx, element.posx + rotatedimgwidth/2); maxy = Math.max(maxy, element.posy + rotatedimgheight/2); diff --git a/src/sitplan/SituationPlanElement.ts b/src/sitplan/SituationPlanElement.ts index cb8ccc5..b4007d1 100644 --- a/src/sitplan/SituationPlanElement.ts +++ b/src/sitplan/SituationPlanElement.ts @@ -1,160 +1,282 @@ +type AdresLocation = 'rechts'|'links'|'boven'|'onder'; +type AdresType = 'auto'|'manueel'; + +/** + * Class SituationPlanElement + * + * GLOBALS: structure, SITPLANVIEW_DEFAULT_SCALE + */ + class SituationPlanElement { - public page:number = 1; + // -- Identificatie -- + public id:string; //unieke identificatie van het element + private electroItemId: number | null = null; // Referentie naar het electro-element in de datastructuur indien van toepassing + + // -- Basis eigenschappen van het element zelf -- + public boxref: HTMLDivElement | null = null; // Referentie naar het DIV document in de browser waar het element wordt afgebeeld + public svg:string = ''; /* SVG content van het element indien van toepassing + Indien electroItemId == null dan is dit de SVG content van het element zelf + Indien electroItemId != null dan is dit de laatste geladen SVG content van het electro-element + Altijd te verifiëren dat deze niet leeg is en evenueel een update forceren */ + + + // -- Basis eigenschappen van het label -- + // adres gegevens zijn private gedefinieerd omwille van consistentie (bvb adres kan leeg gelaten worden als het type auto is) + + public boxlabelref = null; // Referentie naar het DIV document in de browser waar het label wordt afgebeeld + + private adrestype: string | null = null; + private adres: string | null = null + private adreslocation: AdresLocation = 'rechts'; + + // -- Positionering van het element zelf -- + public page:number = 1; //pagina waarop het element zich bevindt public posx:number = 0; //center positie-x in het schema public posy:number = 0; //center positie-y in het schema public sizex:number = 0; //breedte public sizey:number = 0; //hoogte + public rotate:number = 0; + public scale:number = SITPLANVIEW_DEFAULT_SCALE; + + // -- Positionering van het label -- public labelposx = 0; public labelposy = 0; public labelfontsize = 11; - public rotate:number = 0; - public scale:number = SITPLANVIEW_DEFAULT_SCALE; - public id:string; - - public boxref = null; - public boxlabelref = null; - - private svg:string = ""; - private electroItemId:number = null; - private adrestype:string = null; - private adres:string = null - private adreslocation:string = "rechts"; - - constructor( - page: number, - posx: number, posy: number, - sizex: number, sizey: number, - labelfontsize: number, - rotate: number, scale: number, - id: string, svg: string ) - { - this.page = page; - this.posx = posx; this.posy = posy; - this.sizex = sizex, this.sizey = sizey; - this.labelfontsize = labelfontsize; - this.rotate = rotate; this.scale = scale; - this.id = id; this.svg = svg; - } - - isEDSymbol(): Boolean { + /** + * Constructor + */ + + constructor() { + this.id = randomId("SP_"); + } + + /** + * isEendraadschemaSymbool + * + * Controleer of het element een geldig electro-element is + * Hiervoor is een geldige electroItemId nodig en moet het element in de datastructuur voorkomen. + * + * @returns boolean + */ + + isEendraadschemaSymbool(): boolean { if (this.electroItemId != null) { - let idnum = Number(this.electroItemId); - if (!isNaN(idnum)) { - let ordinal = structure.getOrdinalById(idnum); - if (ordinal != null) { - let electroElement = structure.data[ordinal]; - if (electroElement != null) return true; - } - } + return (structure.getElectroItemById(this.electroItemId) != null); } return false; } - needsTextMirroring(): boolean { - if (this.isEDSymbol()) { - let electroElement: Electro_Item = (structure.data[structure.getOrdinalById(Number(this.getElectroItemId()))] as Electro_Item); - let type = electroElement.getType(); - if (['Contactdoos','Lichtpunt','Drukknop','Media','Schakelaars','Lichtcircuit'].includes(type)) return true; else return false; + /** + * rotates360degrees + * + * Per default wordt er vanuit gegaan dat bij rotatie over rotatiehoeken alpha tussen 90 en 270 graden deze rotatie kan vervangen worden. + * door een rotatie over alpha-180 graden. Om een voorbeeld te geven, een batterij roteren over 180 graden heeft geen zin, dat blijft het originele symbool. + * + * Voor bepaalde elementen is dit niet het geval. Een contactdoos gedraaid over 180 graden moet de opening naar rechts hebben in plaats van naar links. + * Deze functie geeft true terug indien een volledige rotatie nodig is. + * + * @returns boolean + * + * TODO: functie verplaatsen naar Electro_Item + */ + + private static readonly ROTATES_360_DEGREES_TYPES = new Set(['Contactdoos','Lichtpunt','Drukknop','Media','Schakelaars','Lichtcircuit']); + + rotates360degrees(): boolean { + if (this.isEendraadschemaSymbool()) { + let electroElement: Electro_Item = structure.getElectroItemById(this.electroItemId); + if (electroElement != null) { + let type = electroElement.getType(); + return SituationPlanElement.ROTATES_360_DEGREES_TYPES.has(type); + } + return false; } return true; } - setAdres(adrestype: string, adres:string, adreslocation: string) { + /** + * setAdres + * + * @param adrestype string : 'auto' of 'manueel' + * @param adres string : Indien manueel, het adres. Indien auto wordt deze genegeerd en this.adres altijd op null gezet. + * @param adreslocation string: 'rechts' of 'links' of 'boven' of 'onder' + */ + + setAdres(adrestype: AdresType, adres: string, adreslocation: AdresLocation) { this.adrestype = adrestype; this.adreslocation = adreslocation; - if (this.adrestype === 'manueel') this.adres = adres; - else this.adres = null; + if (this.adrestype === 'manueel') this.adres = adres; else this.adres = null; } - getAdresType() { + /** + * getAdresType + * + * @returns string : 'auto' of 'manueel' + */ + + getAdresType(): string { return this.adrestype; } - getAdres() { - if (this.electroItemId == null) return ""; + /** + * getAdres + * + * @returns string : adres + */ + + getAdres(): string { + if (!this.isEendraadschemaSymbool()) return ''; // Geen adres voor niet-elektro-elementen - let id = this.electroItemId; - let element = structure.data[structure.getOrdinalById(id)] as Electro_Item; + let element = structure.getElectroItemById(this.electroItemId); + if (element == null) return ''; // zou redundant moeten zijn want we controleerden al in isEendraadschemaSymbool - switch (this.adrestype) { - case 'auto': - return element.getReadableAdres(); - break; - case 'adres': - return "Adres"; - case 'manueel': - default: - return (this.adres == null) ? "" : this.adres; + if (this.adrestype === 'auto') { + return element.getReadableAdres(); + } else { + return this.adres ?? ''; } } - getAdresLocation() { + /** + * getAdresLocation + * + * @returns 'rechts'|'links'|'boven'|'onder' + */ + + getAdresLocation(): AdresLocation { return this.adreslocation; } - setElectroItemId(id: number) { - this.electroItemId = id; + /** + * setElectroItemId + * + * @param electroItemId number : id van het electroitem in structure + * + * TODO: zou beter een private functie zijn en niet worden aangeroepen vanuit SituationPlan en SituationPlanView + */ + + setElectroItemId(electroItemId: number) { + this.electroItemId = electroItemId; } - getElectroItemId() { - return this.electroItemId; + /** + * getElectroItemId + * + * @returns number : id van het electroitem in structure + */ + + getElectroItemId(): number | null { + if (this.isEendraadschemaSymbool()) return this.electroItemId; + else return null; } - setSVG(svg: string) { // Set the SVG string and update the size, this only works when the id-field is empty - this.svg = svg; - this.getSizeFromString(); + /** + * updateElectroItemSVG + * + * @param svg string : nieuwe gegenereerde SVG door het electro-element + * @param width number : breedte van de SVG zonder schaling en rotatie, indien niet gegeven wordt de breedte gezocht met functie getSizeFromString + * @param height number : hoogte van de SVG zonder schaling en rotatie + */ + + updateElectroItemSVG(svg: string, width: number | undefined = undefined, height: number | undefined = undefined) { // Set the SVG string and update the size, this only works with an electro item + if (this.isEendraadschemaSymbool()) { + this.svg = svg; + if (width != null) this.sizex = width; + if (height != null) this.sizey = height; + if (width == null || height == null) this.getSizeFromString(); + } } - getSVG() { - if (this.electroItemId != null) { - let ordinal = structure.getOrdinalById(this.electroItemId); - if (ordinal != null) { - let electroItem = structure.data[ordinal] as Electro_Item; - electroItem.updateSituationPlanElement(this); - } else { - return null; + /** + * getUnscaledSVGifNotElectroItem + * + * @returns string : SVG content van het element op voorwaarde dat het geen electro-element is + */ + + getUnscaledSVGifNotElectroItem() { + + // cleanSVG(): Deze functie is nodig omdat gebleken is dat de print SVG commando's in jsPDF niet overweg kunnen met SVG's die niet dadelijk beginnen met ' { + if (this.svg == null) this.svg = ''; + else { + const index = this.svg.indexOf(' { - if (positioned) { - posinfo = `x="${this.posx-this.sizex/2*this.scale}" y="${this.posy-this.sizey/2*this.scale}"`; let rotate = this.rotate; while (rotate < 0) rotate = rotate + 360; rotate = rotate % 360; + let spiegel = false; + if ( (rotate >= 90) && (rotate < 270) ) { - if (this.needsTextMirroring()) spiegel = true; - if (this.isEDSymbol()) rotate = rotate + 180; + if (this.rotates360degrees()) spiegel = true; + if (this.isEendraadschemaSymbool()) rotate = rotate + 180; } - transform = `transform="rotate(${rotate} ${this.posx} ${this.posy})${(spiegel ? ' scale(-1,1) translate(' + (-2*this.posx) + ' 0)' : '')}"`; + + return [rotate, spiegel]; + } + + if (this.isEendraadschemaSymbool()) { + let electroItem = structure.getElectroItemById(this.electroItemId); + if (electroItem != null) electroItem.updateSituationPlanElement(this); + } + + let posinfo = ''; + let transform = ''; + + if (positioned) { // Indien we de SVG willen positioneren en roteren, bvb voor gebruik in een print + + posinfo = `x="${this.posx-this.sizex/2*this.scale}" y="${this.posy-this.sizey/2*this.scale}"`; + + const [rotate, spiegel] = berekenAfbeeldingsRotatieEnSpiegeling(); + + transform = `transform="rotate(${rotate} ${this.posx} ${this.posy})${(spiegel ? ` scale(-1,1) translate(${-this.posx * 2} 0)` : '')}"`; + return ` - ${svg} + ${this.svg} `; - } else { - return `${svg}`; + + } else { // Indien we de SVG willen gebruiken in een innerHTML van een div element en dit element dan zelf positioneren en roteren + + return `${this.svg}`; } } - getSizeFromString() { + /** + * getSizeFromString + * + * Haal de grootte van het SVG element uit de SVG string + */ + + private getSizeFromString() { // Create a DOMParser to parse the SVG string const parser = new DOMParser(); const svgDoc = parser.parseFromString(this.svg, "image/svg+xml"); @@ -162,75 +284,122 @@ class SituationPlanElement { // Access the SVG element const svgElement = svgDoc.querySelector('svg'); - // Extract the height and width attributes - this.sizey = parseInt(svgElement.getAttribute('height')); - this.sizex = parseInt(svgElement.getAttribute('width')); + if (svgElement) { + // Extract the height and width attributes + this.sizey = parseInt(svgElement.getAttribute('height')); + this.sizex = parseInt(svgElement.getAttribute('width')); + } else { + console.error('Invalid SVG string'); + } } - importFromFile(event: any, callback) { - const file = event.target.files[0]; + /** + * Leest de inhoud van een situatieplanelement uit een image bestand + * Enkel image bestanden ondersteund door de browser worden ondersteund + * + * @param event Event van het file input element gedefinieerd in index.html + * @param callback Callback functie die wordt uitgevoerd na het inladen van de file + */ + + importFromFile(event: InputEvent, callback: () => void) { + const input = event.target as HTMLInputElement; + const file = input.files[0]; + if (file) { const reader = new FileReader(); const fileName = file.name.toLowerCase(); const mimeType = file.type; - if (fileName.endsWith('.svg')) { - //Handle SVG - reader.onload = (e) => { - const fileContent = e.target.result as string; - this.svg = fileContent; - this.getSizeFromString(); + reader.onload = (e) => { + const fileContent = e.target.result as string; + const image = new Image(); + image.src = fileContent; + image.onload = () => { + this.sizex = image.width; + this.sizey = image.height; + this.svg = ``; callback(); - }; - reader.readAsText(file); // Read the file as a text string - } else { - //Handle image - reader.onload = (e) => { - const fileContent = e.target.result as string; - const image = new Image(); - image.src = fileContent; - image.onload = () => { - this.sizex = image.width; - this.sizey = image.height; - this.svg = ``; - callback(); - }; - image.onerror = () => { - console.error('Unsupported image format or failed to load image.'); - }; - }; - reader.readAsDataURL(file); // Read the file as a data URL - } + }; + image.onerror = () => { + alert('Het formaat van deze file wordt niet ondersteund.'); + }; + }; + reader.readAsDataURL(file); // Read the file as a data URL + } else { + alert('Geen bestand geselecteerd'); } } + /** + * setVars + * + * @param object Object : object met de variabelen die moeten worden ingesteld + */ + + setVars(object: Object) { + Object.assign(this, object); + } + + /** + * toJsonObject + * + * @returns Object : object met de variabelen van het element dat dadelijk kan worden omgezet naar een JSON string + */ + toJsonObject() { - let svg:string = ((this.electroItemId != null) ? "" : this.svg) return { - page: this.page, posx: this.posx, posy: this.posy, - sizex: this.sizex, sizey: this.sizey, - labelposx: this.labelposx, labelposy: this.labelposy, + page: this.page, + + posx: this.posx, + posy: this.posy, + + sizex: this.sizex, + sizey: this.sizey, + + labelposx: this.labelposx, + labelposy: this.labelposy, + labelfontsize: this.labelfontsize, - adrestype: this.adrestype, adres: this.adres, adreslocation: this.adreslocation, - rotate: this.rotate, scale: this.scale, - svg: svg, electroItemId: this.electroItemId + + adrestype: this.adrestype, + adres: this.adres, + adreslocation: this.adreslocation, + + rotate: this.rotate, + scale: this.scale, + + svg: (this.isEendraadschemaSymbool() ? '' : this.svg), + electroItemId: this.electroItemId }; } + /** + * fromJsonObject + * + * @param json any : object met de variabelen van het element dat dadelijk kan worden omgezet naar een JSON string + */ + fromJsonObject(json: any) { - this.page = (json.page != null) ? json.page : 1; + this.page = json.page; + this.posx = json.posx; this.posy = json.posy; + + this.sizex = json.sizex; + this.sizey = json.sizey; + this.labelposx = (json.labelposx != null) ? json.labelposx : this.posx + 20; this.labelposy = (json.labelposy != null) ? json.labelposy : this.posy; + this.labelfontsize = (json.labelfontsize != null ? json.labelfontsize : 11); - this.sizex = json.sizex; - this.sizey = json.sizey; + this.adrestype = (json.adrestype != null) ? json.adrestype : "manueel"; this.adres = json.adres; this.adreslocation = (json.adreslocation != null) ? json.adreslocation : "rechts"; + this.rotate = (json.rotate != null) ? json.rotate : 0; this.scale = (json.scale != null) ? json.scale : SITPLANVIEW_DEFAULT_SCALE; + this.svg = json.svg; this.electroItemId = json.electroItemId; } diff --git a/src/sitplan/SituationPlanView.ts b/src/sitplan/SituationPlanView.ts index 5900e60..5aaa936 100644 --- a/src/sitplan/SituationPlanView.ts +++ b/src/sitplan/SituationPlanView.ts @@ -180,7 +180,7 @@ class SituationPlanView { SituationPlanView_ElementPropertiesPopup(null, (id, adrestype, adres, adreslocation, labelfontsize, scale, rotate) => { if (id != null) { - let element = this.sitplan.addElectroItem(id, this.sitplan.activePage, 550, 300, + let element = this.sitplan.addElementFromElectroItem(id, this.sitplan.activePage, 550, 300, adrestype, adres, adreslocation, labelfontsize, scale, rotate); if (element != null) { @@ -277,14 +277,33 @@ class SituationPlanView { } } + /** + * Send the selected box to the back of the z-index stack and reorder the elements of the situation plan accordingly + * so that after saving or during printing the elements are drawn in the same order. + * + * @returns void + */ + sendToBack() { if (this.selectedBox) { - let boxes: NodeListOf = this.paper.querySelectorAll('.box'); - let newzIndex = 0; - for (let box of Array.from(boxes)) { box.style.zIndex = ((parseInt(box.style.zIndex) || 0)+1).toString(); } - newzIndex--; - this.selectedBox.style.zIndex = "0"; + for (let element of this.sitplan.elements) { + if (element.boxref != null) { + let newzindex; + + if (element.boxref != this.selectedBox) { + newzindex = (parseInt(element.boxref.style.zIndex) || 0)+1; + } else { + newzindex = 0; } + + element.boxref.style.zIndex = newzindex.toString(); + if (element.boxlabelref != null) { + element.boxlabelref.style.zIndex = newzindex.toString(); } + + } + } } + this.sitplan.orderByZIndex(); + undostruct.store(); } private updateBoxPosition(box) { @@ -301,8 +320,8 @@ class SituationPlanView { let spiegel = false; rotate = rotate % 360; if ( (rotate >= 90) && (rotate < 270) ) { - if (pic.needsTextMirroring()) spiegel = true; - if (pic.isEDSymbol()) rotate = rotate - 180; + if (pic.rotates360degrees()) spiegel = true; + if (pic.isEendraadschemaSymbool()) rotate = rotate - 180; } box.style.transform = `rotate(${rotate}deg)` + (spiegel ? ' scaleX(-1)' : ''); @@ -652,6 +671,7 @@ class SituationPlanView { document.getElementById('id_sitplanpage')!.onchange = (event: Event) => { const target = event.target as HTMLSelectElement; this.selectPage(Number(target.value)); + undostruct.store(); }; document.getElementById('btn_sitplan_addpage')!.onclick = () => { diff --git a/src/sitplan/SituationPlanView_Kringen.ts b/src/sitplan/SituationPlanView_Kringen.ts index f05378b..4c66df7 100644 --- a/src/sitplan/SituationPlanView_Kringen.ts +++ b/src/sitplan/SituationPlanView_Kringen.ts @@ -32,7 +32,7 @@ function SituationPlanView_Kringen(): any { let kringnaam:string = structure.findKringName(id).trim(); if (kringnaam != '') { let type:string = (structure.data[i] as Electro_Item).getType(); - if (excludedTypes.indexOf(type) === -1) { + if ( (type != null) && (excludedTypes.indexOf(type) === -1) ) { let adres:string = (structure.data[i] as Electro_Item).getReadableAdres(); output.alldata.push({id: id, kringnaam: kringnaam, adres:adres, type: type}); } diff --git a/src/undoRedo.ts b/src/undoRedo.ts index 377ba5e..a0866a3 100644 --- a/src/undoRedo.ts +++ b/src/undoRedo.ts @@ -45,16 +45,64 @@ class jsonStore { redoStackSize():number {return(Math.max(this.redoStack.length,0));} } +class LargeStringStore { + private data = []; + + push(text: string): number { + this.data.push(text); + return (this.data.length-1); + } + + pushIfNotExists(text: string): number { + let index = this.data.indexOf(text); + if (index == -1) { + this.data.push(text); + return (this.data.length-1); + } else { + return index; + } + } + + get(index: number): string { + return this.data[index]; + } + + clear() { + this.data = []; + } +} + class undoRedo { private history: jsonStore; + private largeStrings: LargeStringStore = new LargeStringStore(); constructor(maxSteps: number = 100) { this.history = new jsonStore(maxSteps); } - store() { + replaceSVGsByStringStore() { + if (structure.sitplan != null) { + for (let element of structure.sitplan.getElements()) { + if (!element.isEendraadschemaSymbool()) element.svg = this.largeStrings.pushIfNotExists(element.getUnscaledSVGifNotElectroItem()).toString(); + } + } + } + + replaceStringStoreBySVGs() { + if (structure.sitplan != null) { + for (let element of structure.sitplan.getElements()) { + if (!element.isEendraadschemaSymbool()) element.svg = this.largeStrings.get(parseInt(element.svg)); + } + } + } + + store() { + // We store the current state of the structure in the history but we replace the SVGs by a reference to a large string store + this.replaceSVGsByStringStore(); this.history.store(structure_to_json()); - if (structure.properties.currentView == 'draw') structure.sitplanview.updateRibbon(); + this.replaceStringStoreBySVGs(); + + if ( (structure.properties.currentView == 'draw') && (structure.sitplanview != null) ) structure.sitplanview.updateRibbon(); else if (structure.properties.currentView == '2col') structure.updateRibbon(); } @@ -62,7 +110,13 @@ class undoRedo { let lastView = structure.properties.currentView; let lastmode = structure.mode; let text:string = this.history.undo(); - if (text != null) json_to_structure(text, 0, false); + if (text != null) json_to_structure(text, 0, false); + + // We replace the references to the large string store by the actual SVGs + this.replaceStringStoreBySVGs(); + // We need to resort and clean the structure to avoid bad references + structure.reSort(); + structure.mode = lastmode; if (structure.properties.currentView != lastView) toggleAppView(structure.properties.currentView as '2col' | 'config' | 'draw'); switch (structure.properties.currentView) { @@ -76,7 +130,13 @@ class undoRedo { let lastView = structure.properties.currentView; let lastmode = structure.mode; let text:string = this.history.redo(); - if (text != null) json_to_structure(text, 0, false); + if (text != null) json_to_structure(text, 0, false); + + // We replace the references to the large string store by the actual SVGs + this.replaceStringStoreBySVGs(); + // We need to resort and clean the structure to avoid bad references + structure.reSort(); + structure.mode = lastmode; if (structure.properties.currentView != lastView) toggleAppView(structure.properties.currentView as '2col' | 'config' | 'draw'); if (structure.properties.currentView == 'draw') { @@ -90,6 +150,7 @@ class undoRedo { clear() { this.history.clear(); + this.largeStrings.clear(); structure.updateRibbon(); } diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 0000000..e24400f --- /dev/null +++ b/typedoc.json @@ -0,0 +1,29 @@ +{ + "tsconfig": "./src/tsconfig.json", + "entryPoints": [ + "src/general.ts", + "src/Session.ts", + "src/SVGelement.ts", + "src/print/*.ts", + "src/importExport.ts", + "src/undoRedo.ts", + "src/TopMenu.ts", + "src/documentation.ts", + "src/sitplan/*.ts", + "src/List_Item/List_Item.ts", + "src/List_Item/Electro_Item.ts", + "src/List_Item/Schakelaars/Schakelaar.ts", + "src/List_Item/Schakelaars/Schakelaars.ts", + "src/List_Item/Schakelaars/Lichtcircuit.ts", + "src/List_Item/*.ts", + "src/Properties.ts", + "src/SVGSymbols.ts", + "src/Hierarchical_List.ts", + "src/config.ts", + "prop/prop_scripts.ts", + "src/main.ts" + ], + "out": "docs", // Output directory for the documentation + "exclude": ["node_modules"] +} + \ No newline at end of file