@liquidcars/atlas 0.1.53 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,15 @@
1
1
  import { validateRuntimeModel, canonicalRelation } from "./model.js";
2
2
  import * as THREE from "./three.module.js";
3
3
  import atlasPackage from "../package.json" with { type: "json" };
4
- import { renderDiagramSvg, diagramSvgToPng } from "./diagram-svg.js";
4
+ import { renderDiagramSvg, diagramSvgToPng, computeDiagramLayout } from "./diagram-svg.js";
5
5
  import { DiagramView, DIAGRAM_VIEW_CSS, DIAGRAM_TOOLBAR } from "./diagram-view.js";
6
6
 
7
- export { renderDiagramSvg, diagramSvgToPng };
7
+ export { renderDiagramSvg, diagramSvgToPng, computeDiagramLayout };
8
+ import {installPlanarAtlas} from './diagram-webgl.js';
9
+ export {orthographicFit, diagramViewForModel} from './diagram-webgl.js';
10
+ export {DiagramScene} from './diagram-scene.js';
11
+ export const OrthographicCamera = THREE.OrthographicCamera;
12
+ export const DiagramGraphics = Object.fromEntries(['Group','BoxGeometry','Vector3','Color','BufferGeometry','Float32BufferAttribute','Mesh','MeshBasicMaterial','LineSegments','LineBasicMaterial','PlaneGeometry','CanvasTexture'].map(name => [name, THREE[name]]));
8
13
  import { resolveAtlasReference, atlasReferenceTarget } from "./document-navigation.js";
9
14
  export { resolveAtlasReference, atlasReferenceTarget } from "./document-navigation.js";
10
15
  import { renderPanelContent } from "./panel-content.js";
@@ -355,7 +360,7 @@ const CSS = [
355
360
  "*{box-sizing:border-box}.atlas{display:grid;grid-template-columns:minmax(0,1fr) 300px;height:100%}.atlas[data-panel=hidden]{grid-template-columns:1fr}.viewport{position:relative;min-width:0;overflow:hidden;background:radial-gradient(ellipse at 50% 45%,var(--lc-bg-glow,#1c2b39),var(--lc-bg-fade,#0a111a) 82%)}canvas{display:block;width:100%;height:100%;cursor:grab;touch-action:none}.toolbar{position:absolute;z-index:10;bottom:28px;left:50%;transform:translateX(-50%);display:flex;gap:3px;padding:6px;background:var(--lc-toolbar-bg,#15232fe8);border:1px solid var(--lc-toolbar-border,#3a5062);border-radius:8px;white-space:nowrap}.toolbar[data-hidden=true],.toolbar[hidden],.panel[data-hidden=true],.panel[hidden],.crumbs[data-hidden=true],.crumbs[hidden],.hint[data-hidden=true],.hint[hidden]{display:none!important}.toolbar button{height:30px;padding:0 9px;border:0;border-radius:5px;background:none;color:var(--lc-toolbar-text,#dbe7ec);cursor:pointer}.toolbar button:hover,.toolbar button.active{background:var(--lc-toolbar-active,#1f3d4b);color:var(--lc-toolbar-active-text,#c5f2e9)}.toolbar i{display:block;width:1px;margin:2px 3px;background:#38515f}.hint{position:absolute;z-index:9;top:8px;bottom:auto;left:0;right:0;text-align:center;padding:2px 8px;font-size:11px;line-height:16px;color:var(--lc-hint,#8da6b8);pointer-events:none}.panel{overflow:auto;padding:24px 20px;background:var(--lc-panel-bg,linear-gradient(140deg,#182633,#0e1925 65%));border-left:1px solid var(--lc-panel-border,#2a3a48)}.panel h2{font-size:26px;line-height:1.12;font-weight:470;margin:12px 0;color:var(--lc-panel-title,#e9f0f5)}.panel h3{font-size:11px;letter-spacing:1.4px;color:#91aabd;margin:24px 0 10px}.panel p{font-size:14px;line-height:1.55;color:var(--lc-panel-text,#b5c6d2)}.panel .eyebrow{font-size:11px;letter-spacing:1.7px;color:#6ad7c0}.panel .sub{font-size:13px;color:#8fa8bd;margin-bottom:16px}.panel .external-link{display:inline-flex;align-items:center;gap:6px;margin:2px 0 12px;color:#6ad7c0;font-size:13px;font-weight:600;text-decoration:none}.panel .external-link:hover{text-decoration:underline}.panel button{display:block;width:100%;padding:10px 0;text-align:left;background:none;border:0;border-bottom:1px solid var(--lc-panel-border,#2a3a48);color:#d9e7eb;cursor:pointer}.panel button:hover{color:#6ad7c0}.panel .relation{padding:10px 0;border-bottom:1px solid var(--lc-panel-border,#2a3a48)}.panel .relation.selected{padding-left:9px;border-left:2px solid #6ad7c0;background:#18343f}.panel .relation strong{display:block;font-weight:550}.panel .relation small{display:block;color:#86a6b9;font-size:12px;margin-top:4px}.panel .back{color:#9db7c8;font-size:13px}.panel .crumbs{display:flex;flex-wrap:wrap;gap:5px;align-items:center;margin:0 0 12px}.panel .crumbs button{display:inline;width:auto;padding:3px 7px;border:0;border-radius:4px;background:var(--lc-crumb-bg,#142733);color:var(--lc-crumb-text,#91b6c7);font-size:12px}.panel .crumbs button.current{background:var(--lc-crumb-active,#1c4a4d);color:var(--lc-crumb-active-text,#c5f2e9)}.panel .note{border-top:1px solid var(--lc-panel-border,#2a3a48);padding-top:16px;margin-top:22px;font-size:12px;color:#7692a6}.error{position:absolute;inset:20%;padding:18px;background:#172b3b;border:1px solid #7896a9;line-height:1.5;z-index:4}@media(max-width:900px){.toolbar{gap:0}.toolbar button{padding:0 6px;font-size:12px}}@media(max-width:760px){:host{height:680px}.atlas{grid-template-columns:1fr;grid-template-rows:minmax(420px,1fr) auto}.panel{max-height:250px;border-left:0;border-top:1px solid var(--lc-panel-border,#2a3a48);padding:18px}.toolbar{bottom:24px}.hint{top:8px;bottom:auto;display:block}}"
356
361
  ].join("");
357
362
 
358
- const TOOLBAR_CSS = ".toolbar{max-width:calc(100% - 16px);overflow:visible}.toolbar-group{display:flex;align-items:center;gap:2px}.toolbar-group+.toolbar-group{padding-left:6px;border-left:1px solid #38515f}.toolbar .toolbar-icon{display:grid;width:30px;padding:0;place-items:center}.toolbar-icon svg,.toolbar-menu>summary svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}.toolbar-menu{position:relative}.toolbar-menu>summary{display:flex;align-items:center;height:30px;padding:0 8px;gap:6px;border-radius:5px;color:var(--lc-toolbar-text,#dbe7ec);cursor:pointer;list-style:none;user-select:none}.toolbar-menu>summary::-webkit-details-marker{display:none}.toolbar-menu>summary:hover,.toolbar-menu[open]>summary{background:var(--lc-toolbar-active,#1f3d4b);color:var(--lc-toolbar-active-text,#c5f2e9)}.toolbar-menu-status{max-width:92px;overflow:hidden;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.toolbar-menu-chevron{width:10px;height:10px!important;transition:transform .16s ease}.toolbar-menu[open] .toolbar-menu-chevron{transform:rotate(180deg)}.toolbar-popover{position:absolute;right:0;bottom:calc(100% + 8px);display:grid;min-width:218px;padding:6px;border:1px solid var(--lc-toolbar-border,#3a5062);border-radius:9px;background:var(--lc-toolbar-bg,#15232ff7);box-shadow:0 14px 36px #0009}.toolbar-popover-title{padding:7px 9px 5px;color:var(--lc-hint,#8da6b8);font-size:9px;font-weight:700;letter-spacing:.1em;text-transform:uppercase}.toolbar .toolbar-option{display:grid;grid-template-columns:minmax(0,1fr) 18px;align-items:center;width:100%;height:auto;min-height:34px;padding:7px 9px;text-align:left}.toolbar-option span:first-child{overflow:hidden;text-overflow:ellipsis}.toolbar-option-check{color:var(--lc-toolbar-active-text,#c5f2e9);font-weight:700;text-align:center;visibility:hidden}.toolbar-option.active .toolbar-option-check{visibility:visible}.toolbar-option-separator{height:1px;margin:5px 7px;background:#38515f}.toolbar button[disabled]{opacity:.42;cursor:not-allowed}@media(max-width:620px){.toolbar-menu-status{display:none}.toolbar-menu>summary{width:30px;padding:0;justify-content:center}.toolbar-menu-chevron{display:none}.toolbar-group+.toolbar-group{padding-left:3px}.toolbar-popover{right:-4px}}";
363
+ const TOOLBAR_CSS = ".toolbar{max-width:calc(100% - 16px);overflow:visible}.toolbar-group{display:flex;align-items:center;gap:2px}.toolbar-group+.toolbar-group{padding-left:6px;border-left:1px solid #38515f}.toolbar .toolbar-icon{display:grid;width:30px;padding:0;place-items:center}.toolbar-icon svg,.toolbar-menu>summary svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}.toolbar-menu{position:relative}.toolbar-menu>summary{display:flex;align-items:center;height:30px;padding:0 8px;gap:6px;border-radius:5px;color:var(--lc-toolbar-text,#dbe7ec);cursor:pointer;list-style:none;user-select:none}.toolbar-menu>summary::-webkit-details-marker{display:none}.toolbar-menu>summary:hover,.toolbar-menu[open]>summary{background:var(--lc-toolbar-active,#1f3d4b);color:var(--lc-toolbar-active-text,#c5f2e9)}.toolbar-menu-status{max-width:92px;overflow:hidden;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.toolbar-menu-chevron{width:10px;height:10px!important;transition:transform .16s ease}.toolbar-menu[open] .toolbar-menu-chevron{transform:rotate(180deg)}.toolbar-popover{max-height:min(420px,calc(100dvh - 160px),var(--lc-menu-height,420px));overflow-y:auto;overscroll-behavior:contain;max-width:calc(100vw - 32px);position:absolute;right:0;bottom:calc(100% + 8px);display:grid;min-width:218px;padding:6px;border:1px solid var(--lc-toolbar-border,#3a5062);border-radius:9px;background:var(--lc-toolbar-bg,#15232ff7);box-shadow:0 14px 36px #0009}.toolbar-popover-title{padding:7px 9px 5px;color:var(--lc-hint,#8da6b8);font-size:9px;font-weight:700;letter-spacing:.1em;text-transform:uppercase}.toolbar .toolbar-option{display:grid;grid-template-columns:minmax(0,1fr) 18px;align-items:center;width:100%;height:auto;min-height:34px;padding:7px 9px;text-align:left}.toolbar-option span:first-child{overflow:hidden;text-overflow:ellipsis}.toolbar-option-check{color:var(--lc-toolbar-active-text,#c5f2e9);font-weight:700;text-align:center;visibility:hidden}.toolbar-option.active .toolbar-option-check{visibility:visible}.toolbar-option-separator{height:1px;margin:5px 7px;background:#38515f}.toolbar button[disabled]{opacity:.42;cursor:not-allowed}@media(max-width:620px){.toolbar-menu-status{display:none}.toolbar-menu>summary{width:30px;padding:0;justify-content:center}.toolbar-menu-chevron{display:none}.toolbar-group+.toolbar-group{padding-left:3px}.toolbar-popover{right:-4px}}";
359
364
 
360
365
  const NAVIGATION_CSS = ".toolbar-group[data-toolbar-group=navigation]{position:relative}.toolbar-group[hidden]{display:none}.atlas-history-popover{position:absolute;left:0;bottom:calc(100% + 8px);min-width:250px;max-width:min(360px,80vw);max-height:300px;overflow:auto;padding:6px;border:1px solid var(--lc-toolbar-border,#3a5062);border-radius:9px;background:var(--lc-toolbar-bg,#15232ff7);box-shadow:0 14px 36px #0009;z-index:12}.atlas-history-popover[hidden]{display:none}.atlas-history-popover .history-heading{padding:7px 9px 5px;color:var(--lc-hint,#8da6b8);font-size:10px;text-transform:uppercase;letter-spacing:.1em}.toolbar .atlas-history-popover button{display:block;width:100%;height:auto;padding:8px 9px;text-align:left;white-space:normal;overflow-wrap:anywhere}.atlas-history-popover small{display:block;opacity:.65;font-size:10px}.atlas-jump{position:absolute;z-index:9;display:grid;place-items:center;width:34px;height:34px;border:1px solid #73d9c7;border-radius:50%;background:#173e49;color:#c8fff2;box-shadow:0 4px 16px #0009;cursor:pointer}.atlas-jump[hidden]{display:none}.atlas-jump:hover,.atlas-jump:focus-visible{background:#286776;outline:2px solid #c8fff2}.atlas-jump svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.panel .rich-content{color:var(--lc-panel-text,#b5c6d2);font-size:14px;line-height:1.55}.panel .rich-content h1,.panel .rich-content h2,.panel .rich-content h3{color:var(--lc-panel-title,#e9f0f5);letter-spacing:normal;margin:14px 0 8px}.panel .rich-content a{color:#6ad7c0}.panel .rich-content pre{overflow:auto;padding:8px;background:#091622;border-radius:5px}.panel .rich-content code{font-size:.9em}.panel .rich-content ul,.panel .rich-content ol{padding-left:20px}";
361
366
  const DOCUMENT_NAV_CSS = ".document-navigation{position:absolute;top:12px;right:12px;z-index:10;display:flex;padding:5px;border:1px solid var(--lc-toolbar-border,#3a5062);border-radius:8px;background:var(--lc-toolbar-bg,#15232fe8)}.document-navigation[hidden],:host([navigation-controls=external]) .document-navigation{display:none!important}.document-navigation button{display:grid;width:30px;height:30px;place-items:center;padding:0;border:0;border-radius:5px;background:none;color:var(--lc-toolbar-text,#dbe7ec);cursor:pointer}.document-navigation button:hover{background:var(--lc-toolbar-active,#1f3d4b);color:var(--lc-toolbar-active-text,#c5f2e9)}.document-navigation button:disabled{opacity:.42;cursor:not-allowed}.document-navigation svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}.document-navigation .atlas-history-popover{top:calc(100% + 8px);right:0;bottom:auto;left:auto}.document-navigation .atlas-history-popover button{display:block;width:100%;height:auto;padding:8px 9px;text-align:left;white-space:normal;overflow-wrap:anywhere}@media print{.document-navigation,.atlas-jump{display:none!important}}";
@@ -1458,7 +1463,7 @@ function makeLabel(text, color, dimensions, type = "", outlined = true) {
1458
1463
  const context = bitmap.getContext("2d");
1459
1464
  const width = dimensions.x * .88;
1460
1465
  const height = Math.min(.82, dimensions.y * .64);
1461
- const density = 320;
1466
+ const density = Math.min(320, 4096 / Math.max(width, height));
1462
1467
  bitmap.width = Math.ceil(width * density);
1463
1468
  bitmap.height = Math.ceil(height * density);
1464
1469
  context.imageSmoothingEnabled = true;
@@ -1828,6 +1833,7 @@ class LiquidCarsAtlas extends HTMLElement {
1828
1833
  globalThis.removeEventListener?.("afterprint", this._afterPrintListener);
1829
1834
  if (typeof this._printMedia?.removeEventListener === "function") this._printMedia.removeEventListener("change", this._printMediaListener);
1830
1835
  else this._printMedia?.removeListener?.(this._printMediaListener);
1836
+ this.dispatchEvent(new CustomEvent("lc-disconnect"));
1831
1837
  this.restoreAfterPrint();
1832
1838
  if (this._copyStatusTimer) globalThis.clearTimeout?.(this._copyStatusTimer);
1833
1839
  if (this._historyPressTimer) globalThis.clearTimeout?.(this._historyPressTimer);
@@ -2807,7 +2813,7 @@ class LiquidCarsAtlas extends HTMLElement {
2807
2813
  }
2808
2814
 
2809
2815
  zoomOut() {
2810
- this.targetZoom = Math.max(MIN_ZOOM, this.targetZoom / 1.18);
2816
+ this.targetZoom = Math.max(this._webglPlanar ? .001 : MIN_ZOOM, this.targetZoom / 1.18);
2811
2817
  this.invalidate();
2812
2818
  return this;
2813
2819
  }
@@ -2824,7 +2830,7 @@ class LiquidCarsAtlas extends HTMLElement {
2824
2830
  let zoom = 1.22;
2825
2831
  if (this.selected) {
2826
2832
  target = this._worldPosition(this.selected);
2827
- zoom = this.selected.parent ? 1.35 : 1.1;
2833
+ zoom = isContainerType(this.selected.type) ? 1.35 : 3.5;
2828
2834
  } else if (this.selectedRelationIndex !== null) {
2829
2835
  const relation = this.relations[this.selectedRelationIndex];
2830
2836
  const from = relation && this.nodes.get(relation.from);
@@ -2889,6 +2895,7 @@ class LiquidCarsAtlas extends HTMLElement {
2889
2895
  }
2890
2896
 
2891
2897
  setCameraView(view = {}, options = {}) {
2898
+ if (!view || typeof view !== "object") return this;
2892
2899
  const position = Array.isArray(view.position) && view.position.length === 3 && view.position.every(Number.isFinite)
2893
2900
  ? new THREE.Vector3().fromArray(view.position)
2894
2901
  : null;
@@ -3365,7 +3372,7 @@ class LiquidCarsAtlas extends HTMLElement {
3365
3372
  node.edge.scale.fromArray(baked ? [1, 1, 1] : entity.s);
3366
3373
  node.group.add(node.edge);
3367
3374
  }
3368
- node.label = makeLabel(entity.name, color, node.labelSize, entity.type, this.showShellLabels);
3375
+ node.label = makeLabel(this._webglPlanar ? "" : entity.name, color, this._webglPlanar ? new THREE.Vector3(1, .1, 1) : node.labelSize, entity.type, this.showShellLabels);
3369
3376
  node.labelAnchor = resolveEntityLabelAnchor(entity, this.modelData.style);
3370
3377
  node.label.userData.node = node;
3371
3378
  node.label.traverse(labelFace => { labelFace.userData.node = node; });
@@ -3832,7 +3839,7 @@ class LiquidCarsAtlas extends HTMLElement {
3832
3839
  }
3833
3840
 
3834
3841
  invalidate() {
3835
- if (this.viewMode === "3d" && !this.animationFrame && this.renderer) this.animationFrame = requestAnimationFrame(time => this._renderFrame(time));
3842
+ if ((this.viewMode === "3d" || this._webglPlanar) && !this.animationFrame && this.renderer) this.animationFrame = requestAnimationFrame(time => this._renderFrame(time));
3836
3843
  }
3837
3844
 
3838
3845
  _geometryContentUpdated() {
@@ -3844,7 +3851,7 @@ class LiquidCarsAtlas extends HTMLElement {
3844
3851
 
3845
3852
  _renderFrame(time) {
3846
3853
  this.animationFrame = 0;
3847
- if (!this.renderer || this.viewMode !== "3d") return;
3854
+ if (!this.renderer || (this.viewMode !== "3d" && !this._webglPlanar)) return;
3848
3855
  const zoomGap = Math.abs(this.targetZoom - this.zoom);
3849
3856
  const focusGap = this.targetFocus.distanceTo(this.focus);
3850
3857
  this.zoom += (this.targetZoom - this.zoom) * .12;
@@ -3852,12 +3859,12 @@ class LiquidCarsAtlas extends HTMLElement {
3852
3859
  const distance = this._baseCameraDistance() / this.zoom;
3853
3860
  this.cameraTarget.set(this.focus.x, this.focus.y, this.focus.z);
3854
3861
  this.cameraPosition.set(Math.sin(this.yaw) * Math.cos(this.pitch), Math.sin(this.pitch), Math.cos(this.yaw) * Math.cos(this.pitch)).multiplyScalar(distance).add(this.cameraTarget);
3855
- this.camera.position.copy(this.cameraPosition);
3856
- this.camera.lookAt(this.cameraTarget);
3862
+ if (this._webglPlanar) this._updatePlanarCamera();
3863
+ else { this.camera.position.copy(this.cameraPosition); this.camera.lookAt(this.cameraTarget); }
3857
3864
  // Camera-facing is a presentation transform only. Positions, container
3858
3865
  // shells and relation routing remain in model space while leaf visuals
3859
3866
  // inherit the camera orientation around their unchanged centres.
3860
- this._applyItemFacing();
3867
+ if (!this._webglPlanar) this._applyItemFacing();
3861
3868
  const focused = this._focusedEntityIds();
3862
3869
  for (const node of this.nodes.values()) {
3863
3870
  const focusAlpha = this._focusAlpha(node, focused);
@@ -4002,9 +4009,10 @@ class LiquidCarsAtlas extends HTMLElement {
4002
4009
  child.position.lerpVectors(child.userData.start, child.userData.end, factor);
4003
4010
  }
4004
4011
  }
4012
+ if (this._webglPlanar) this._applyDiagramPresentation();
4005
4013
  this.renderer.render(this.scene, this.camera);
4006
4014
  this._positionJumpButton();
4007
- if (zoomGap > .001 || focusGap > .001 || this.relationGroup.children.length || this.drag) this.invalidate();
4015
+ if (zoomGap > .001 || focusGap > .001 || (!this._webglPlanar && this.relationGroup.children.length) || this.drag) this.invalidate();
4008
4016
  }
4009
4017
 
4010
4018
  _pick(event) {
@@ -4124,7 +4132,7 @@ class LiquidCarsAtlas extends HTMLElement {
4124
4132
  });
4125
4133
  this.shadowRoot.addEventListener("click", event => {
4126
4134
  const actionControl = closestEventElement(event, "[data-action]");
4127
- const action = actionControl?.dataset.action;
4135
+ const action = actionControl?.dataset?.action;
4128
4136
  if (this._historyLongPress === action) { this._historyLongPress = null; return; }
4129
4137
  if (!closestEventElement(event, ".atlas-history-popover")) this._closeHistoryPopover();
4130
4138
  if (!closestEventElement(event, ".toolbar-menu")) this._closeToolbarMenus();
@@ -4187,7 +4195,7 @@ class LiquidCarsAtlas extends HTMLElement {
4187
4195
  if (this.drag.mode !== "touch-pan") this.drag = { mode: "touch-pan", x, y, distance, moved: true };
4188
4196
  else {
4189
4197
  this._panByPixels(x - this.drag.x, y - this.drag.y);
4190
- this.targetZoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, this.targetZoom * distance / Math.max(1, this.drag.distance)));
4198
+ this.targetZoom = Math.min(MAX_ZOOM, Math.max(this._webglPlanar ? .001 : MIN_ZOOM, this.targetZoom * distance / Math.max(1, this.drag.distance)));
4191
4199
  Object.assign(this.drag, { x, y, distance, moved: true });
4192
4200
  }
4193
4201
  this.invalidate();
@@ -4199,7 +4207,7 @@ class LiquidCarsAtlas extends HTMLElement {
4199
4207
  if (Math.abs(dx) + Math.abs(dy) > 3) this.drag.moved = true;
4200
4208
  this.drag.x = event.clientX;
4201
4209
  this.drag.y = event.clientY;
4202
- if (this.drag.mode === "pan" || event.shiftKey) this._panByPixels(dx, dy);
4210
+ if (this._webglPlanar || this.drag.mode === "pan" || event.shiftKey) this._panByPixels(dx, dy);
4203
4211
  else {
4204
4212
  this.yaw -= dx * .005;
4205
4213
  this.pitch = Math.max(-1.56, Math.min(1.56, this.pitch + dy * .005));
@@ -4239,7 +4247,7 @@ class LiquidCarsAtlas extends HTMLElement {
4239
4247
  if (picked?.kind === "entity") this.select(picked.node.id, { source: "double-click", navigation: "fit" });
4240
4248
  if (picked?.kind === "relation") this.selectRelation(picked.index, { source: "double-click", navigation: "fit" });
4241
4249
  });
4242
- this.canvas.addEventListener("wheel", event => { event.preventDefault(); this.targetZoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, this.targetZoom * Math.exp(-event.deltaY * .001))); this.invalidate(); }, { passive: false });
4250
+ this.canvas.addEventListener("wheel", event => { event.preventDefault(); if (this._webglPlanar) this._diagramFitted = false; this.targetZoom = Math.min(MAX_ZOOM, Math.max(this._webglPlanar ? .001 : MIN_ZOOM, this.targetZoom * Math.exp(-event.deltaY * .001))); this.invalidate(); }, { passive: false });
4243
4251
  }
4244
4252
 
4245
4253
  _showError(message) {
@@ -4250,5 +4258,7 @@ class LiquidCarsAtlas extends HTMLElement {
4250
4258
  }
4251
4259
  }
4252
4260
 
4261
+ installPlanarAtlas(LiquidCarsAtlas, OrthographicCamera, computeDiagramLayout, DiagramGraphics);
4262
+
4253
4263
  if (!customElements.get("liquidcars-atlas")) customElements.define("liquidcars-atlas", LiquidCarsAtlas);
4254
4264
  export { LiquidCarsAtlas, normalizeModel };