@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.
package/dist/esm/color.js CHANGED
@@ -106,4 +106,95 @@ export function readableTextOn(fill) {
106
106
  ? LIGHT_TEXT
107
107
  : DARK_TEXT;
108
108
  }
109
+ // Opaque on purpose: a translucent edge takes part of its colour from the fill underneath, so
110
+ // two sockets side by side end up with visibly different edges and the one rule looks like two.
111
+ const DARK_OUTLINE = '#3a3d45';
112
+ const LIGHT_OUTLINE = '#c8ccd4';
113
+ /// Outline colour for a shape drawn on `surface`.
114
+ ///
115
+ /// A socket is filled with its type's colour, which comes from the host and spans the whole
116
+ /// range -- StockSharp sends #000000 for Any. What the outline has to separate the socket
117
+ /// from is the canvas, so it is measured against the canvas: one outline for every socket on
118
+ /// it, and none of them left without an edge. Choosing per fill instead would edge two
119
+ /// neighbouring sockets differently, which reads as a mistake rather than as a rule.
120
+ ///
121
+ /// A surface this cannot read keeps the dark outline, for the same reason the title stays
122
+ /// dark: the canvas shipped so far is dark, and a light outline on a light one would vanish.
123
+ export function readableOutlineOn(surface) {
124
+ const background = relativeLuminance(surface);
125
+ if (background < 0)
126
+ return DARK_OUTLINE;
127
+ return contrast(background, relativeLuminance(LIGHT_OUTLINE))
128
+ > contrast(background, relativeLuminance(DARK_OUTLINE))
129
+ ? LIGHT_OUTLINE
130
+ : DARK_OUTLINE;
131
+ }
132
+ /// A colour's hue, saturation and lightness, or null when it cannot be read.
133
+ function toHsl(color) {
134
+ const hsl = color.trim().match(/^hsl\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*\)$/i);
135
+ if (hsl !== null)
136
+ return [+hsl[1], +hsl[2] / 100, +hsl[3] / 100];
137
+ const rgb = parseRgb(color);
138
+ if (rgb === null)
139
+ return null;
140
+ const [r, g, b] = rgb.map((channel) => channel / 255);
141
+ const max = Math.max(r, g, b);
142
+ const min = Math.min(r, g, b);
143
+ const lightness = (max + min) / 2;
144
+ if (max === min)
145
+ return [0, 0, lightness];
146
+ const span = max - min;
147
+ const saturation = lightness > 0.5 ? span / (2 - max - min) : span / (max + min);
148
+ const hue = max === r
149
+ ? ((g - b) / span + (g < b ? 6 : 0))
150
+ : max === g
151
+ ? (b - r) / span + 2
152
+ : (r - g) / span + 4;
153
+ return [hue * 60, saturation, lightness];
154
+ }
155
+ /// Lightest a colour may be drawn on a light canvas, and darkest on a dark one. Wide enough
156
+ /// that a hue is still itself, narrow enough that neither end of the palette disappears.
157
+ const DARK_CANVAS_FLOOR = 0.42;
158
+ const LIGHT_CANVAS_CEILING = 0.45;
159
+ /// The same colour, moved into the band the canvas leaves room for.
160
+ ///
161
+ /// A socket type's colour belongs to the host and spans the whole range -- StockSharp sends
162
+ /// #000000 for Any and near-white for Side. As a socket that is fine: it is a filled square
163
+ /// with an outline. As a wire it is a thin line with nothing behind it, so a colour at the
164
+ /// same end of the range as the canvas cannot be seen at all. Only the lightness moves; the
165
+ /// hue and saturation are the host's answer to which type this is, and are left alone.
166
+ ///
167
+ /// A colour that already sits in the band is returned exactly as it came, and one that cannot
168
+ /// be read is passed through: guessing at it would be worse than drawing what was asked for.
169
+ export function legibleOn(color, background) {
170
+ const hsl = toHsl(color);
171
+ if (hsl === null)
172
+ return color;
173
+ const canvas = relativeLuminance(background);
174
+ const [hue, saturation, lightness] = hsl;
175
+ const moved = canvas < 0
176
+ ? lightness
177
+ : canvas > 0.18
178
+ ? Math.min(lightness, LIGHT_CANVAS_CEILING)
179
+ : Math.max(lightness, DARK_CANVAS_FLOOR);
180
+ if (moved === lightness && /^hsl/i.test(color.trim()))
181
+ return color;
182
+ return `hsl(${Math.round(hue * 10) / 10}, ${Math.round(saturation * 1000) / 10}%, ${Math.round(moved * 1000) / 10}%)`;
183
+ }
184
+ /// The same colour with its lightness capped at `maxLightness` (0..1), hue and saturation kept.
185
+ ///
186
+ /// Any colour, not only one already written as hsl(): a host's palette arrives as hex, and a
187
+ /// ceiling that only understood one notation left exactly those colours uncapped -- so a light
188
+ /// theme darkened the hues the control invents and left the ones it was given.
189
+ ///
190
+ /// A colour that cannot be read is returned untouched.
191
+ export function cappedLightness(color, maxLightness) {
192
+ const hsl = toHsl(color);
193
+ if (hsl === null)
194
+ return color;
195
+ const [hue, saturation, lightness] = hsl;
196
+ if (lightness <= maxLightness)
197
+ return color;
198
+ return `hsl(${Math.round(hue * 10) / 10}, ${Math.round(saturation * 1000) / 10}%, ${Math.round(maxLightness * 1000) / 10}%)`;
199
+ }
109
200
  //# sourceMappingURL=color.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"color.js","sourceRoot":"","sources":["../../src/color.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"color.js","sourceRoot":"","sources":["../../src/color.ts"],"names":[],"mappings":"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"}
@@ -410,6 +410,54 @@ var SSDiagramHeadless = (() => {
410
410
  return DARK_TEXT;
411
411
  return contrast(background, relativeLuminance(LIGHT_TEXT)) > contrast(background, relativeLuminance(DARK_TEXT)) ? LIGHT_TEXT : DARK_TEXT;
412
412
  }
413
+ var DARK_OUTLINE = "#3a3d45";
414
+ var LIGHT_OUTLINE = "#c8ccd4";
415
+ function readableOutlineOn(surface) {
416
+ const background = relativeLuminance(surface);
417
+ if (background < 0)
418
+ return DARK_OUTLINE;
419
+ return contrast(background, relativeLuminance(LIGHT_OUTLINE)) > contrast(background, relativeLuminance(DARK_OUTLINE)) ? LIGHT_OUTLINE : DARK_OUTLINE;
420
+ }
421
+ function toHsl(color) {
422
+ const hsl = color.trim().match(/^hsl\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*\)$/i);
423
+ if (hsl !== null)
424
+ return [+hsl[1], +hsl[2] / 100, +hsl[3] / 100];
425
+ const rgb = parseRgb(color);
426
+ if (rgb === null)
427
+ return null;
428
+ const [r, g, b] = rgb.map((channel) => channel / 255);
429
+ const max = Math.max(r, g, b);
430
+ const min = Math.min(r, g, b);
431
+ const lightness = (max + min) / 2;
432
+ if (max === min)
433
+ return [0, 0, lightness];
434
+ const span = max - min;
435
+ const saturation = lightness > 0.5 ? span / (2 - max - min) : span / (max + min);
436
+ const hue = max === r ? (g - b) / span + (g < b ? 6 : 0) : max === g ? (b - r) / span + 2 : (r - g) / span + 4;
437
+ return [hue * 60, saturation, lightness];
438
+ }
439
+ var DARK_CANVAS_FLOOR = 0.42;
440
+ var LIGHT_CANVAS_CEILING = 0.45;
441
+ function legibleOn(color, background) {
442
+ const hsl = toHsl(color);
443
+ if (hsl === null)
444
+ return color;
445
+ const canvas = relativeLuminance(background);
446
+ const [hue, saturation, lightness] = hsl;
447
+ const moved = canvas < 0 ? lightness : canvas > 0.18 ? Math.min(lightness, LIGHT_CANVAS_CEILING) : Math.max(lightness, DARK_CANVAS_FLOOR);
448
+ if (moved === lightness && /^hsl/i.test(color.trim()))
449
+ return color;
450
+ return `hsl(${Math.round(hue * 10) / 10}, ${Math.round(saturation * 1e3) / 10}%, ${Math.round(moved * 1e3) / 10}%)`;
451
+ }
452
+ function cappedLightness(color, maxLightness) {
453
+ const hsl = toHsl(color);
454
+ if (hsl === null)
455
+ return color;
456
+ const [hue, saturation, lightness] = hsl;
457
+ if (lightness <= maxLightness)
458
+ return color;
459
+ return `hsl(${Math.round(hue * 10) / 10}, ${Math.round(saturation * 1e3) / 10}%, ${Math.round(maxLightness * 1e3) / 10}%)`;
460
+ }
413
461
 
414
462
  // src/core/json.ts
415
463
  function setJsonKey(target, key, value) {
@@ -1187,9 +1235,7 @@ var SSDiagramHeadless = (() => {
1187
1235
  return (h % 360 + 360) % 360;
1188
1236
  }
1189
1237
  function clampLightness(color, maxL) {
1190
- const m = color.match(/^hsl\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*\)$/i);
1191
- if (m === null) return color;
1192
- return `hsl(${m[1]}, ${m[2]}%, ${Math.min(+m[3], maxL * 100)}%)`;
1238
+ return cappedLightness(color, maxL);
1193
1239
  }
1194
1240
  function colorLuminance(color) {
1195
1241
  if (color === void 0) return 0;
@@ -1206,6 +1252,8 @@ var SSDiagramHeadless = (() => {
1206
1252
  }
1207
1253
  var Diagram = class {
1208
1254
  constructor(opts) {
1255
+ /// Outline every socket is edged with, refreshed from the background each draw.
1256
+ this.portOutline = readableOutlineOn("#1b1b1f");
1209
1257
  this.nodes = [];
1210
1258
  this.links = [];
1211
1259
  this.zones = [];
@@ -2516,6 +2564,15 @@ var SSDiagramHeadless = (() => {
2516
2564
  if (p.direction !== "in" || p.type === "" || !isWildcardPortType(p.type)) return p.type;
2517
2565
  return this.portFeed.get(p) ?? p.type;
2518
2566
  }
2567
+ /// A type's colour as a wire.
2568
+ ///
2569
+ /// The same colour a socket of that type is filled with, moved into the band the canvas
2570
+ /// leaves room for. A socket can afford the host's exact colour because it is a filled
2571
+ /// square with an outline; a wire is a thin line with nothing behind it, and one drawn in
2572
+ /// #000000 on a dark canvas is not there at all.
2573
+ linkColor(type) {
2574
+ return legibleOn(this.portColor(type), this.opts.background ?? "#1b1b1f");
2575
+ }
2519
2576
  portColor(type) {
2520
2577
  const maxL = this.opts.linkMaxLightness;
2521
2578
  const light = maxL !== void 0 && maxL < 0.5;
@@ -3355,8 +3412,10 @@ var SSDiagramHeadless = (() => {
3355
3412
  draw(options = SCREEN_RENDER_OPTIONS) {
3356
3413
  const ctx = this.ctx;
3357
3414
  ctx.clearRect(0, 0, this.width, this.height);
3358
- ctx.fillStyle = this.opts.background ?? "#1b1b1f";
3415
+ const background = this.opts.background ?? "#1b1b1f";
3416
+ ctx.fillStyle = background;
3359
3417
  ctx.fillRect(0, 0, this.width, this.height);
3418
+ this.portOutline = readableOutlineOn(background);
3360
3419
  let introDy = 0;
3361
3420
  let introAlpha = 1;
3362
3421
  if (options.transient && this.introStart !== null) {
@@ -3385,7 +3444,7 @@ var SSDiagramHeadless = (() => {
3385
3444
  const b = this.endpoint(l, "to");
3386
3445
  if (a === null || b === null) continue;
3387
3446
  const fp = this.nodes.find((n2) => n2.id === l.from)?.outPorts.find((p) => p.id === l.fromPort);
3388
- const baseColor = (this.opts.typedLinkColors ?? false) && fp !== void 0 ? this.portColor(fp.type) : this.portColor("");
3447
+ const baseColor = (this.opts.typedLinkColors ?? false) && fp !== void 0 ? this.linkColor(fp.type) : this.portColor("");
3389
3448
  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";
3390
3449
  const color = state === "sel" ? this.selectionColor() : state === "hov" ? this.linkHoverColor() : baseColor;
3391
3450
  const width = state === "sel" ? 3 : state === "hov" ? 2.6 : 2;
@@ -3681,7 +3740,7 @@ ${runtime.error}`;
3681
3740
  ctx.fillStyle = this.portColor(this.portFillType(p));
3682
3741
  ctx.fill();
3683
3742
  ctx.lineWidth = magnet ? 1.5 : 1;
3684
- ctx.strokeStyle = magnet ? "#ffffff" : "rgba(12,12,16,0.55)";
3743
+ ctx.strokeStyle = magnet ? "#ffffff" : this.portOutline;
3685
3744
  ctx.stroke();
3686
3745
  const runtimeSelected = runtime?.selected === true || options.selection && this.selectedPort?.port === p;
3687
3746
  const breakpoint = runtime?.breakpoint === true;
@@ -3833,7 +3892,7 @@ ${runtime.error}`;
3833
3892
  }
3834
3893
  if (snapped !== null) excludedNodes.add(snapped.node.id);
3835
3894
  const points = this.routeLink(a, b, excludedNodes);
3836
- ctx.strokeStyle = this.portColor(colorType);
3895
+ ctx.strokeStyle = this.linkColor(colorType);
3837
3896
  if (snapped !== null) {
3838
3897
  ctx.setLineDash([]);
3839
3898
  ctx.lineWidth = 2.6;