@stocksharp/diagram 1.3.0 → 1.4.0

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.
package/dist/ssdiagram.js CHANGED
@@ -873,6 +873,46 @@ var SSDiagram = (() => {
873
873
  return DARK_OUTLINE;
874
874
  return contrast(background, relativeLuminance(LIGHT_OUTLINE)) > contrast(background, relativeLuminance(DARK_OUTLINE)) ? LIGHT_OUTLINE : DARK_OUTLINE;
875
875
  }
876
+ function toHsl(color) {
877
+ const hsl = color.trim().match(/^hsl\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*\)$/i);
878
+ if (hsl !== null)
879
+ return [+hsl[1], +hsl[2] / 100, +hsl[3] / 100];
880
+ const rgb = parseRgb(color);
881
+ if (rgb === null)
882
+ return null;
883
+ const [r, g, b] = rgb.map((channel) => channel / 255);
884
+ const max = Math.max(r, g, b);
885
+ const min = Math.min(r, g, b);
886
+ const lightness = (max + min) / 2;
887
+ if (max === min)
888
+ return [0, 0, lightness];
889
+ const span = max - min;
890
+ const saturation = lightness > 0.5 ? span / (2 - max - min) : span / (max + min);
891
+ const hue = max === r ? (g - b) / span + (g < b ? 6 : 0) : max === g ? (b - r) / span + 2 : (r - g) / span + 4;
892
+ return [hue * 60, saturation, lightness];
893
+ }
894
+ var DARK_CANVAS_FLOOR = 0.42;
895
+ var LIGHT_CANVAS_CEILING = 0.45;
896
+ function legibleOn(color, background) {
897
+ const hsl = toHsl(color);
898
+ if (hsl === null)
899
+ return color;
900
+ const canvas = relativeLuminance(background);
901
+ const [hue, saturation, lightness] = hsl;
902
+ const moved = canvas < 0 ? lightness : canvas > 0.18 ? Math.min(lightness, LIGHT_CANVAS_CEILING) : Math.max(lightness, DARK_CANVAS_FLOOR);
903
+ if (moved === lightness && /^hsl/i.test(color.trim()))
904
+ return color;
905
+ return `hsl(${Math.round(hue * 10) / 10}, ${Math.round(saturation * 1e3) / 10}%, ${Math.round(moved * 1e3) / 10}%)`;
906
+ }
907
+ function cappedLightness(color, maxLightness) {
908
+ const hsl = toHsl(color);
909
+ if (hsl === null)
910
+ return color;
911
+ const [hue, saturation, lightness] = hsl;
912
+ if (lightness <= maxLightness)
913
+ return color;
914
+ return `hsl(${Math.round(hue * 10) / 10}, ${Math.round(saturation * 1e3) / 10}%, ${Math.round(maxLightness * 1e3) / 10}%)`;
915
+ }
876
916
 
877
917
  // src/core/history.ts
878
918
  var DiagramCommandHistory = class {
@@ -1256,9 +1296,7 @@ var SSDiagram = (() => {
1256
1296
  return (h % 360 + 360) % 360;
1257
1297
  }
1258
1298
  function clampLightness(color, maxL) {
1259
- const m = color.match(/^hsl\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*\)$/i);
1260
- if (m === null) return color;
1261
- return `hsl(${m[1]}, ${m[2]}%, ${Math.min(+m[3], maxL * 100)}%)`;
1299
+ return cappedLightness(color, maxL);
1262
1300
  }
1263
1301
  function colorLuminance(color) {
1264
1302
  if (color === void 0) return 0;
@@ -2587,6 +2625,15 @@ var SSDiagram = (() => {
2587
2625
  if (p.direction !== "in" || p.type === "" || !isWildcardPortType(p.type)) return p.type;
2588
2626
  return this.portFeed.get(p) ?? p.type;
2589
2627
  }
2628
+ /// A type's colour as a wire.
2629
+ ///
2630
+ /// The same colour a socket of that type is filled with, moved into the band the canvas
2631
+ /// leaves room for. A socket can afford the host's exact colour because it is a filled
2632
+ /// square with an outline; a wire is a thin line with nothing behind it, and one drawn in
2633
+ /// #000000 on a dark canvas is not there at all.
2634
+ linkColor(type) {
2635
+ return legibleOn(this.portColor(type), this.opts.background ?? "#1b1b1f");
2636
+ }
2590
2637
  portColor(type) {
2591
2638
  const maxL = this.opts.linkMaxLightness;
2592
2639
  const light = maxL !== void 0 && maxL < 0.5;
@@ -3458,7 +3505,7 @@ var SSDiagram = (() => {
3458
3505
  const b = this.endpoint(l, "to");
3459
3506
  if (a === null || b === null) continue;
3460
3507
  const fp = this.nodes.find((n2) => n2.id === l.from)?.outPorts.find((p) => p.id === l.fromPort);
3461
- const baseColor = (this.opts.typedLinkColors ?? false) && fp !== void 0 ? this.portColor(fp.type) : this.portColor("");
3508
+ const baseColor = (this.opts.typedLinkColors ?? false) && fp !== void 0 ? this.linkColor(fp.type) : this.portColor("");
3462
3509
  const state = options.selection && l === this.selectedLink ? "sel" : options.transient && (l === this.hoveredLink || hoveredNode !== null && (l.from === hoveredNode.id || l.to === hoveredNode.id)) ? "hov" : "norm";
3463
3510
  const color = state === "sel" ? this.selectionColor() : state === "hov" ? this.linkHoverColor() : baseColor;
3464
3511
  const width = state === "sel" ? 3 : state === "hov" ? 2.6 : 2;
@@ -3906,7 +3953,7 @@ ${runtime.error}`;
3906
3953
  }
3907
3954
  if (snapped !== null) excludedNodes.add(snapped.node.id);
3908
3955
  const points = this.routeLink(a, b, excludedNodes);
3909
- ctx.strokeStyle = this.portColor(colorType);
3956
+ ctx.strokeStyle = this.linkColor(colorType);
3910
3957
  if (snapped !== null) {
3911
3958
  ctx.setLineDash([]);
3912
3959
  ctx.lineWidth = 2.6;