@stocksharp/diagram 1.2.3 → 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.
@@ -1,5 +1,5 @@
1
1
  import { SvgSurface } from './svg-surface.js';
2
- import { readableTextOn } from './color.js';
2
+ import { cappedLightness, legibleOn, readableOutlineOn, readableTextOn } from './color.js';
3
3
  // Internal dependency-free canvas renderer used by StockSharpDiagram.
4
4
  //
5
5
  // Dependency-free, pure 2D canvas. Demonstrates the hard parts: typed
@@ -202,10 +202,7 @@ function hashHue(s) {
202
202
  // wash out; a light theme passes a low ceiling to darken the links just enough to stay readable
203
203
  // while keeping each hue distinct. Non-hsl inputs are returned untouched.
204
204
  function clampLightness(color, maxL) {
205
- const m = color.match(/^hsl\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*\)$/i);
206
- if (m === null)
207
- return color;
208
- return `hsl(${m[1]}, ${m[2]}%, ${Math.min(+m[3], maxL * 100)}%)`;
205
+ return cappedLightness(color, maxL);
209
206
  }
210
207
  function colorLuminance(color) {
211
208
  if (color === undefined)
@@ -227,6 +224,8 @@ function colorLuminance(color) {
227
224
  }
228
225
  export class Diagram {
229
226
  constructor(opts) {
227
+ /// Outline every socket is edged with, refreshed from the background each draw.
228
+ this.portOutline = readableOutlineOn('#1b1b1f');
230
229
  this.nodes = [];
231
230
  this.links = [];
232
231
  this.zones = [];
@@ -1689,6 +1688,15 @@ export class Diagram {
1689
1688
  return p.type;
1690
1689
  return this.portFeed.get(p) ?? p.type;
1691
1690
  }
1691
+ /// A type's colour as a wire.
1692
+ ///
1693
+ /// The same colour a socket of that type is filled with, moved into the band the canvas
1694
+ /// leaves room for. A socket can afford the host's exact colour because it is a filled
1695
+ /// square with an outline; a wire is a thin line with nothing behind it, and one drawn in
1696
+ /// #000000 on a dark canvas is not there at all.
1697
+ linkColor(type) {
1698
+ return legibleOn(this.portColor(type), this.opts.background ?? '#1b1b1f');
1699
+ }
1692
1700
  portColor(type) {
1693
1701
  const maxL = this.opts.linkMaxLightness;
1694
1702
  const light = maxL !== undefined && maxL < 0.5;
@@ -2671,8 +2679,12 @@ export class Diagram {
2671
2679
  draw(options = SCREEN_RENDER_OPTIONS) {
2672
2680
  const ctx = this.ctx;
2673
2681
  ctx.clearRect(0, 0, this.width, this.height);
2674
- ctx.fillStyle = this.opts.background ?? '#1b1b1f';
2682
+ const background = this.opts.background ?? '#1b1b1f';
2683
+ ctx.fillStyle = background;
2675
2684
  ctx.fillRect(0, 0, this.width, this.height);
2685
+ // Read here rather than per socket: an export swaps the background for the duration of
2686
+ // one draw, so this is the only point that sees the colour the sockets land on.
2687
+ this.portOutline = readableOutlineOn(background);
2676
2688
  // Entrance animation — scheme rises from below + fades in over
2677
2689
  // the opaque background.
2678
2690
  let introDy = 0;
@@ -2704,7 +2716,7 @@ export class Diagram {
2704
2716
  continue;
2705
2717
  const fp = this.nodes.find((n) => n.id === l.from)?.outPorts.find((p) => p.id === l.fromPort);
2706
2718
  const baseColor = (this.opts.typedLinkColors ?? false) && fp !== undefined
2707
- ? this.portColor(fp.type)
2719
+ ? this.linkColor(fp.type)
2708
2720
  : this.portColor('');
2709
2721
  const state = options.selection && l === this.selectedLink
2710
2722
  ? 'sel'
@@ -3033,7 +3045,7 @@ export class Diagram {
3033
3045
  ctx.fillStyle = this.portColor(this.portFillType(p));
3034
3046
  ctx.fill();
3035
3047
  ctx.lineWidth = magnet ? 1.5 : 1;
3036
- ctx.strokeStyle = magnet ? '#ffffff' : 'rgba(12,12,16,0.55)';
3048
+ ctx.strokeStyle = magnet ? '#ffffff' : this.portOutline;
3037
3049
  ctx.stroke();
3038
3050
  const runtimeSelected = runtime?.selected === true || (options.selection && this.selectedPort?.port === p);
3039
3051
  const breakpoint = runtime?.breakpoint === true;
@@ -3219,7 +3231,7 @@ export class Diagram {
3219
3231
  if (snapped !== null)
3220
3232
  excludedNodes.add(snapped.node.id);
3221
3233
  const points = this.routeLink(a, b, excludedNodes);
3222
- ctx.strokeStyle = this.portColor(colorType);
3234
+ ctx.strokeStyle = this.linkColor(colorType);
3223
3235
  if (snapped !== null) {
3224
3236
  ctx.setLineDash([]);
3225
3237
  ctx.lineWidth = 2.6;