@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/canvas-renderer.js +21 -9
- package/dist/esm/canvas-renderer.js.map +1 -1
- package/dist/esm/color.js +91 -0
- package/dist/esm/color.js.map +1 -1
- package/dist/ssdiagram-headless.js +66 -7
- package/dist/ssdiagram-headless.js.map +2 -2
- package/dist/ssdiagram.js +66 -7
- package/dist/ssdiagram.js.map +2 -2
- package/dist/types/canvas-renderer.d.ts +2 -0
- package/dist/types/canvas-renderer.d.ts.map +1 -1
- package/dist/types/color.d.ts +3 -0
- package/dist/types/color.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/canvas-renderer.ts +22 -8
- package/src/color.ts +108 -0
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
|
package/dist/esm/color.js.map
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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.
|
|
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" :
|
|
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.
|
|
3895
|
+
ctx.strokeStyle = this.linkColor(colorType);
|
|
3837
3896
|
if (snapped !== null) {
|
|
3838
3897
|
ctx.setLineDash([]);
|
|
3839
3898
|
ctx.lineWidth = 2.6;
|