@d3plus/color 3.0.0-alpha.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.
@@ -0,0 +1,710 @@
1
+ /*
2
+ @d3plus/color v3.0.0
3
+ Color functions that extent the ability of d3-color.
4
+ Copyright (c) 2025 D3plus - https://d3plus.org
5
+ @license MIT
6
+ */
7
+
8
+ (function (factory) {
9
+ typeof define === 'function' && define.amd ? define(factory) :
10
+ factory();
11
+ })((function () { 'use strict';
12
+
13
+ if (typeof window !== "undefined") {
14
+ (function () {
15
+ try {
16
+ if (typeof SVGElement === 'undefined' || Boolean(SVGElement.prototype.innerHTML)) {
17
+ return;
18
+ }
19
+ } catch (e) {
20
+ return;
21
+ }
22
+
23
+ function serializeNode (node) {
24
+ switch (node.nodeType) {
25
+ case 1:
26
+ return serializeElementNode(node);
27
+ case 3:
28
+ return serializeTextNode(node);
29
+ case 8:
30
+ return serializeCommentNode(node);
31
+ }
32
+ }
33
+
34
+ function serializeTextNode (node) {
35
+ return node.textContent.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
36
+ }
37
+
38
+ function serializeCommentNode (node) {
39
+ return '<!--' + node.nodeValue + '-->'
40
+ }
41
+
42
+ function serializeElementNode (node) {
43
+ var output = '';
44
+
45
+ output += '<' + node.tagName;
46
+
47
+ if (node.hasAttributes()) {
48
+ [].forEach.call(node.attributes, function(attrNode) {
49
+ output += ' ' + attrNode.name + '="' + attrNode.value + '"';
50
+ });
51
+ }
52
+
53
+ output += '>';
54
+
55
+ if (node.hasChildNodes()) {
56
+ [].forEach.call(node.childNodes, function(childNode) {
57
+ output += serializeNode(childNode);
58
+ });
59
+ }
60
+
61
+ output += '</' + node.tagName + '>';
62
+
63
+ return output;
64
+ }
65
+
66
+ Object.defineProperty(SVGElement.prototype, 'innerHTML', {
67
+ get: function () {
68
+ var output = '';
69
+
70
+ [].forEach.call(this.childNodes, function(childNode) {
71
+ output += serializeNode(childNode);
72
+ });
73
+
74
+ return output;
75
+ },
76
+ set: function (markup) {
77
+ while (this.firstChild) {
78
+ this.removeChild(this.firstChild);
79
+ }
80
+
81
+ try {
82
+ var dXML = new DOMParser();
83
+ dXML.async = false;
84
+
85
+ var sXML = '<svg xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'>' + markup + '</svg>';
86
+ var svgDocElement = dXML.parseFromString(sXML, 'text/xml').documentElement;
87
+
88
+ [].forEach.call(svgDocElement.childNodes, function(childNode) {
89
+ this.appendChild(this.ownerDocument.importNode(childNode, true));
90
+ }.bind(this));
91
+ } catch (e) {
92
+ throw new Error('Error parsing markup string');
93
+ }
94
+ }
95
+ });
96
+
97
+ Object.defineProperty(SVGElement.prototype, 'innerSVG', {
98
+ get: function () {
99
+ return this.innerHTML;
100
+ },
101
+ set: function (markup) {
102
+ this.innerHTML = markup;
103
+ }
104
+ });
105
+
106
+ })();
107
+ }
108
+
109
+ }));
110
+
111
+ (function (global, factory) {
112
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
113
+ typeof define === 'function' && define.amd ? define('@d3plus/color', ['exports'], factory) :
114
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3plus = {}));
115
+ })(this, (function (exports) {
116
+ function define(constructor, factory, prototype) {
117
+ constructor.prototype = factory.prototype = prototype;
118
+ prototype.constructor = constructor;
119
+ }
120
+ function extend(parent, definition) {
121
+ var prototype = Object.create(parent.prototype);
122
+ for(var key in definition)prototype[key] = definition[key];
123
+ return prototype;
124
+ }
125
+
126
+ function Color() {}
127
+ var darker = 0.7;
128
+ var brighter = 1 / darker;
129
+ var reI = "\\s*([+-]?\\d+)\\s*", reN = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*", reP = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*", reHex = /^#([0-9a-f]{3,8})$/, reRgbInteger = new RegExp(`^rgb\\(${reI},${reI},${reI}\\)$`), reRgbPercent = new RegExp(`^rgb\\(${reP},${reP},${reP}\\)$`), reRgbaInteger = new RegExp(`^rgba\\(${reI},${reI},${reI},${reN}\\)$`), reRgbaPercent = new RegExp(`^rgba\\(${reP},${reP},${reP},${reN}\\)$`), reHslPercent = new RegExp(`^hsl\\(${reN},${reP},${reP}\\)$`), reHslaPercent = new RegExp(`^hsla\\(${reN},${reP},${reP},${reN}\\)$`);
130
+ var named = {
131
+ aliceblue: 0xf0f8ff,
132
+ antiquewhite: 0xfaebd7,
133
+ aqua: 0x00ffff,
134
+ aquamarine: 0x7fffd4,
135
+ azure: 0xf0ffff,
136
+ beige: 0xf5f5dc,
137
+ bisque: 0xffe4c4,
138
+ black: 0x000000,
139
+ blanchedalmond: 0xffebcd,
140
+ blue: 0x0000ff,
141
+ blueviolet: 0x8a2be2,
142
+ brown: 0xa52a2a,
143
+ burlywood: 0xdeb887,
144
+ cadetblue: 0x5f9ea0,
145
+ chartreuse: 0x7fff00,
146
+ chocolate: 0xd2691e,
147
+ coral: 0xff7f50,
148
+ cornflowerblue: 0x6495ed,
149
+ cornsilk: 0xfff8dc,
150
+ crimson: 0xdc143c,
151
+ cyan: 0x00ffff,
152
+ darkblue: 0x00008b,
153
+ darkcyan: 0x008b8b,
154
+ darkgoldenrod: 0xb8860b,
155
+ darkgray: 0xa9a9a9,
156
+ darkgreen: 0x006400,
157
+ darkgrey: 0xa9a9a9,
158
+ darkkhaki: 0xbdb76b,
159
+ darkmagenta: 0x8b008b,
160
+ darkolivegreen: 0x556b2f,
161
+ darkorange: 0xff8c00,
162
+ darkorchid: 0x9932cc,
163
+ darkred: 0x8b0000,
164
+ darksalmon: 0xe9967a,
165
+ darkseagreen: 0x8fbc8f,
166
+ darkslateblue: 0x483d8b,
167
+ darkslategray: 0x2f4f4f,
168
+ darkslategrey: 0x2f4f4f,
169
+ darkturquoise: 0x00ced1,
170
+ darkviolet: 0x9400d3,
171
+ deeppink: 0xff1493,
172
+ deepskyblue: 0x00bfff,
173
+ dimgray: 0x696969,
174
+ dimgrey: 0x696969,
175
+ dodgerblue: 0x1e90ff,
176
+ firebrick: 0xb22222,
177
+ floralwhite: 0xfffaf0,
178
+ forestgreen: 0x228b22,
179
+ fuchsia: 0xff00ff,
180
+ gainsboro: 0xdcdcdc,
181
+ ghostwhite: 0xf8f8ff,
182
+ gold: 0xffd700,
183
+ goldenrod: 0xdaa520,
184
+ gray: 0x808080,
185
+ green: 0x008000,
186
+ greenyellow: 0xadff2f,
187
+ grey: 0x808080,
188
+ honeydew: 0xf0fff0,
189
+ hotpink: 0xff69b4,
190
+ indianred: 0xcd5c5c,
191
+ indigo: 0x4b0082,
192
+ ivory: 0xfffff0,
193
+ khaki: 0xf0e68c,
194
+ lavender: 0xe6e6fa,
195
+ lavenderblush: 0xfff0f5,
196
+ lawngreen: 0x7cfc00,
197
+ lemonchiffon: 0xfffacd,
198
+ lightblue: 0xadd8e6,
199
+ lightcoral: 0xf08080,
200
+ lightcyan: 0xe0ffff,
201
+ lightgoldenrodyellow: 0xfafad2,
202
+ lightgray: 0xd3d3d3,
203
+ lightgreen: 0x90ee90,
204
+ lightgrey: 0xd3d3d3,
205
+ lightpink: 0xffb6c1,
206
+ lightsalmon: 0xffa07a,
207
+ lightseagreen: 0x20b2aa,
208
+ lightskyblue: 0x87cefa,
209
+ lightslategray: 0x778899,
210
+ lightslategrey: 0x778899,
211
+ lightsteelblue: 0xb0c4de,
212
+ lightyellow: 0xffffe0,
213
+ lime: 0x00ff00,
214
+ limegreen: 0x32cd32,
215
+ linen: 0xfaf0e6,
216
+ magenta: 0xff00ff,
217
+ maroon: 0x800000,
218
+ mediumaquamarine: 0x66cdaa,
219
+ mediumblue: 0x0000cd,
220
+ mediumorchid: 0xba55d3,
221
+ mediumpurple: 0x9370db,
222
+ mediumseagreen: 0x3cb371,
223
+ mediumslateblue: 0x7b68ee,
224
+ mediumspringgreen: 0x00fa9a,
225
+ mediumturquoise: 0x48d1cc,
226
+ mediumvioletred: 0xc71585,
227
+ midnightblue: 0x191970,
228
+ mintcream: 0xf5fffa,
229
+ mistyrose: 0xffe4e1,
230
+ moccasin: 0xffe4b5,
231
+ navajowhite: 0xffdead,
232
+ navy: 0x000080,
233
+ oldlace: 0xfdf5e6,
234
+ olive: 0x808000,
235
+ olivedrab: 0x6b8e23,
236
+ orange: 0xffa500,
237
+ orangered: 0xff4500,
238
+ orchid: 0xda70d6,
239
+ palegoldenrod: 0xeee8aa,
240
+ palegreen: 0x98fb98,
241
+ paleturquoise: 0xafeeee,
242
+ palevioletred: 0xdb7093,
243
+ papayawhip: 0xffefd5,
244
+ peachpuff: 0xffdab9,
245
+ peru: 0xcd853f,
246
+ pink: 0xffc0cb,
247
+ plum: 0xdda0dd,
248
+ powderblue: 0xb0e0e6,
249
+ purple: 0x800080,
250
+ rebeccapurple: 0x663399,
251
+ red: 0xff0000,
252
+ rosybrown: 0xbc8f8f,
253
+ royalblue: 0x4169e1,
254
+ saddlebrown: 0x8b4513,
255
+ salmon: 0xfa8072,
256
+ sandybrown: 0xf4a460,
257
+ seagreen: 0x2e8b57,
258
+ seashell: 0xfff5ee,
259
+ sienna: 0xa0522d,
260
+ silver: 0xc0c0c0,
261
+ skyblue: 0x87ceeb,
262
+ slateblue: 0x6a5acd,
263
+ slategray: 0x708090,
264
+ slategrey: 0x708090,
265
+ snow: 0xfffafa,
266
+ springgreen: 0x00ff7f,
267
+ steelblue: 0x4682b4,
268
+ tan: 0xd2b48c,
269
+ teal: 0x008080,
270
+ thistle: 0xd8bfd8,
271
+ tomato: 0xff6347,
272
+ turquoise: 0x40e0d0,
273
+ violet: 0xee82ee,
274
+ wheat: 0xf5deb3,
275
+ white: 0xffffff,
276
+ whitesmoke: 0xf5f5f5,
277
+ yellow: 0xffff00,
278
+ yellowgreen: 0x9acd32
279
+ };
280
+ define(Color, color, {
281
+ copy (channels) {
282
+ return Object.assign(new this.constructor, this, channels);
283
+ },
284
+ displayable () {
285
+ return this.rgb().displayable();
286
+ },
287
+ hex: color_formatHex,
288
+ formatHex: color_formatHex,
289
+ formatHex8: color_formatHex8,
290
+ formatHsl: color_formatHsl,
291
+ formatRgb: color_formatRgb,
292
+ toString: color_formatRgb
293
+ });
294
+ function color_formatHex() {
295
+ return this.rgb().formatHex();
296
+ }
297
+ function color_formatHex8() {
298
+ return this.rgb().formatHex8();
299
+ }
300
+ function color_formatHsl() {
301
+ return hslConvert(this).formatHsl();
302
+ }
303
+ function color_formatRgb() {
304
+ return this.rgb().formatRgb();
305
+ }
306
+ function color(format) {
307
+ var m, l;
308
+ format = (format + "").trim().toLowerCase();
309
+ return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000
310
+ : l === 3 ? new Rgb(m >> 8 & 0xf | m >> 4 & 0xf0, m >> 4 & 0xf | m & 0xf0, (m & 0xf) << 4 | m & 0xf, 1) // #f00
311
+ : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000
312
+ : l === 4 ? rgba(m >> 12 & 0xf | m >> 8 & 0xf0, m >> 8 & 0xf | m >> 4 & 0xf0, m >> 4 & 0xf | m & 0xf0, ((m & 0xf) << 4 | m & 0xf) / 0xff) // #f000
313
+ : null // invalid hex
314
+ ) : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
315
+ : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
316
+ : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
317
+ : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
318
+ : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
319
+ : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
320
+ : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins
321
+ : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null;
322
+ }
323
+ function rgbn(n) {
324
+ return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
325
+ }
326
+ function rgba(r, g, b, a) {
327
+ if (a <= 0) r = g = b = NaN;
328
+ return new Rgb(r, g, b, a);
329
+ }
330
+ function rgbConvert(o) {
331
+ if (!(o instanceof Color)) o = color(o);
332
+ if (!o) return new Rgb;
333
+ o = o.rgb();
334
+ return new Rgb(o.r, o.g, o.b, o.opacity);
335
+ }
336
+ function rgb(r, g, b, opacity) {
337
+ return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
338
+ }
339
+ function Rgb(r, g, b, opacity) {
340
+ this.r = +r;
341
+ this.g = +g;
342
+ this.b = +b;
343
+ this.opacity = +opacity;
344
+ }
345
+ define(Rgb, rgb, extend(Color, {
346
+ brighter (k) {
347
+ k = k == null ? brighter : Math.pow(brighter, k);
348
+ return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
349
+ },
350
+ darker (k) {
351
+ k = k == null ? darker : Math.pow(darker, k);
352
+ return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
353
+ },
354
+ rgb () {
355
+ return this;
356
+ },
357
+ clamp () {
358
+ return new Rgb(clampi(this.r), clampi(this.g), clampi(this.b), clampa(this.opacity));
359
+ },
360
+ displayable () {
361
+ return -0.5 <= this.r && this.r < 255.5 && -0.5 <= this.g && this.g < 255.5 && -0.5 <= this.b && this.b < 255.5 && 0 <= this.opacity && this.opacity <= 1;
362
+ },
363
+ hex: rgb_formatHex,
364
+ formatHex: rgb_formatHex,
365
+ formatHex8: rgb_formatHex8,
366
+ formatRgb: rgb_formatRgb,
367
+ toString: rgb_formatRgb
368
+ }));
369
+ function rgb_formatHex() {
370
+ return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}`;
371
+ }
372
+ function rgb_formatHex8() {
373
+ return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}${hex((isNaN(this.opacity) ? 1 : this.opacity) * 255)}`;
374
+ }
375
+ function rgb_formatRgb() {
376
+ const a = clampa(this.opacity);
377
+ return `${a === 1 ? "rgb(" : "rgba("}${clampi(this.r)}, ${clampi(this.g)}, ${clampi(this.b)}${a === 1 ? ")" : `, ${a})`}`;
378
+ }
379
+ function clampa(opacity) {
380
+ return isNaN(opacity) ? 1 : Math.max(0, Math.min(1, opacity));
381
+ }
382
+ function clampi(value) {
383
+ return Math.max(0, Math.min(255, Math.round(value) || 0));
384
+ }
385
+ function hex(value) {
386
+ value = clampi(value);
387
+ return (value < 16 ? "0" : "") + value.toString(16);
388
+ }
389
+ function hsla(h, s, l, a) {
390
+ if (a <= 0) h = s = l = NaN;
391
+ else if (l <= 0 || l >= 1) h = s = NaN;
392
+ else if (s <= 0) h = NaN;
393
+ return new Hsl(h, s, l, a);
394
+ }
395
+ function hslConvert(o) {
396
+ if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
397
+ if (!(o instanceof Color)) o = color(o);
398
+ if (!o) return new Hsl;
399
+ if (o instanceof Hsl) return o;
400
+ o = o.rgb();
401
+ var r = o.r / 255, g = o.g / 255, b = o.b / 255, min = Math.min(r, g, b), max = Math.max(r, g, b), h = NaN, s = max - min, l = (max + min) / 2;
402
+ if (s) {
403
+ if (r === max) h = (g - b) / s + (g < b) * 6;
404
+ else if (g === max) h = (b - r) / s + 2;
405
+ else h = (r - g) / s + 4;
406
+ s /= l < 0.5 ? max + min : 2 - max - min;
407
+ h *= 60;
408
+ } else {
409
+ s = l > 0 && l < 1 ? 0 : h;
410
+ }
411
+ return new Hsl(h, s, l, o.opacity);
412
+ }
413
+ function hsl(h, s, l, opacity) {
414
+ return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
415
+ }
416
+ function Hsl(h, s, l, opacity) {
417
+ this.h = +h;
418
+ this.s = +s;
419
+ this.l = +l;
420
+ this.opacity = +opacity;
421
+ }
422
+ define(Hsl, hsl, extend(Color, {
423
+ brighter (k) {
424
+ k = k == null ? brighter : Math.pow(brighter, k);
425
+ return new Hsl(this.h, this.s, this.l * k, this.opacity);
426
+ },
427
+ darker (k) {
428
+ k = k == null ? darker : Math.pow(darker, k);
429
+ return new Hsl(this.h, this.s, this.l * k, this.opacity);
430
+ },
431
+ rgb () {
432
+ var h = this.h % 360 + (this.h < 0) * 360, s = isNaN(h) || isNaN(this.s) ? 0 : this.s, l = this.l, m2 = l + (l < 0.5 ? l : 1 - l) * s, m1 = 2 * l - m2;
433
+ return new Rgb(hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), hsl2rgb(h, m1, m2), hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), this.opacity);
434
+ },
435
+ clamp () {
436
+ return new Hsl(clamph(this.h), clampt(this.s), clampt(this.l), clampa(this.opacity));
437
+ },
438
+ displayable () {
439
+ return (0 <= this.s && this.s <= 1 || isNaN(this.s)) && 0 <= this.l && this.l <= 1 && 0 <= this.opacity && this.opacity <= 1;
440
+ },
441
+ formatHsl () {
442
+ const a = clampa(this.opacity);
443
+ return `${a === 1 ? "hsl(" : "hsla("}${clamph(this.h)}, ${clampt(this.s) * 100}%, ${clampt(this.l) * 100}%${a === 1 ? ")" : `, ${a})`}`;
444
+ }
445
+ }));
446
+ function clamph(value) {
447
+ value = (value || 0) % 360;
448
+ return value < 0 ? value + 360 : value;
449
+ }
450
+ function clampt(value) {
451
+ return Math.max(0, Math.min(1, value || 0));
452
+ }
453
+ /* From FvD 13.37, CSS Color Module Level 3 */ function hsl2rgb(h, m1, m2) {
454
+ return (h < 60 ? m1 + (m2 - m1) * h / 60 : h < 180 ? m2 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 : m1) * 255;
455
+ }
456
+
457
+ /**
458
+ @function colorAdd
459
+ @desc Adds two colors together.
460
+ @param {String} c1 The first color, a valid CSS color string.
461
+ @param {String} c2 The second color, also a valid CSS color string.
462
+ @param {String} [o1 = 1] Value from 0 to 1 of the first color's opacity.
463
+ @param {String} [o2 = 1] Value from 0 to 1 of the first color's opacity.
464
+ @returns {String}
465
+ */ function add(c1, c2, o1 = 1, o2 = 1) {
466
+ c1 = hsl(c1);
467
+ c2 = hsl(c2);
468
+ let d = Math.abs(c2.h * o2 - c1.h * o1);
469
+ if (d > 180) d -= 360;
470
+ let h = (Math.min(c1.h, c2.h) + d / 2) % 360;
471
+ const l = c1.l + (c2.l * o2 - c1.l * o1) / 2, s = c1.s + (c2.s * o2 - c1.s * o1) / 2;
472
+ // a = o1 + (o2 - o1) / 2;
473
+ if (h < 0) h += 360;
474
+ return hsl(`hsl(${h},${s * 100}%,${l * 100}%)`).toString();
475
+ // return hsl(`hsl(${h},${s * 100}%,${l * 100}%,${a})`).toString();
476
+ }
477
+
478
+ class InternMap extends Map {
479
+ get(key) {
480
+ return super.get(intern_get(this, key));
481
+ }
482
+ has(key) {
483
+ return super.has(intern_get(this, key));
484
+ }
485
+ set(key, value) {
486
+ return super.set(intern_set(this, key), value);
487
+ }
488
+ delete(key) {
489
+ return super.delete(intern_delete(this, key));
490
+ }
491
+ constructor(entries, key = keyof){
492
+ super();
493
+ Object.defineProperties(this, {
494
+ _intern: {
495
+ value: new Map()
496
+ },
497
+ _key: {
498
+ value: key
499
+ }
500
+ });
501
+ if (entries != null) for (const [key, value] of entries)this.set(key, value);
502
+ }
503
+ }
504
+ function intern_get({ _intern, _key }, value) {
505
+ const key = _key(value);
506
+ return _intern.has(key) ? _intern.get(key) : value;
507
+ }
508
+ function intern_set({ _intern, _key }, value) {
509
+ const key = _key(value);
510
+ if (_intern.has(key)) return _intern.get(key);
511
+ _intern.set(key, value);
512
+ return value;
513
+ }
514
+ function intern_delete({ _intern, _key }, value) {
515
+ const key = _key(value);
516
+ if (_intern.has(key)) {
517
+ value = _intern.get(key);
518
+ _intern.delete(key);
519
+ }
520
+ return value;
521
+ }
522
+ function keyof(value) {
523
+ return value !== null && typeof value === "object" ? value.valueOf() : value;
524
+ }
525
+
526
+ function initRange(domain, range) {
527
+ switch(arguments.length){
528
+ case 0:
529
+ break;
530
+ case 1:
531
+ this.range(domain);
532
+ break;
533
+ default:
534
+ this.range(range).domain(domain);
535
+ break;
536
+ }
537
+ return this;
538
+ }
539
+
540
+ const implicit = Symbol("implicit");
541
+ function ordinal() {
542
+ var index = new InternMap(), domain = [], range = [], unknown = implicit;
543
+ function scale(d) {
544
+ let i = index.get(d);
545
+ if (i === undefined) {
546
+ if (unknown !== implicit) return unknown;
547
+ index.set(d, i = domain.push(d) - 1);
548
+ }
549
+ return range[i % range.length];
550
+ }
551
+ scale.domain = function(_) {
552
+ if (!arguments.length) return domain.slice();
553
+ domain = [], index = new InternMap();
554
+ for (const value of _){
555
+ if (index.has(value)) continue;
556
+ index.set(value, domain.push(value) - 1);
557
+ }
558
+ return scale;
559
+ };
560
+ scale.range = function(_) {
561
+ return arguments.length ? (range = Array.from(_), scale) : range.slice();
562
+ };
563
+ scale.unknown = function(_) {
564
+ return arguments.length ? (unknown = _, scale) : unknown;
565
+ };
566
+ scale.copy = function() {
567
+ return ordinal(domain, range).unknown(unknown);
568
+ };
569
+ initRange.apply(scale, arguments);
570
+ return scale;
571
+ }
572
+
573
+ /**
574
+ @namespace {Object} colorDefaults
575
+ @desc A set of default color values used when assigning colors based on data.
576
+ *
577
+ * | Name | Default | Description |
578
+ * |---|---|---|
579
+ * | dark | "#555555" | Used in the [contrast](#contrast) function when the color given is very light. |
580
+ * | light | "#f7f7f7" | Used in the [contrast](#contrast) function when the color given is very dark. |
581
+ * | missing | "#cccccc" | Used in the [assign](#assign) function when the value passed is `null` or `undefined`. |
582
+ * | off | "#C44536" | Used in the [assign](#assign) function when the value passed is `false`. |
583
+ * | on | "#6A994E" | Used in the [assign](#assign) function when the value passed is `true`. |
584
+ * | scale | "#4281A4", "#F6AE2D", "#C44536", "#2A9D8F", "#6A994E", "#CEB54A", "#5E548E", "#C08497", "#99582A", "#8C8C99", "#1D3557", "#D08C60", "#6D2E46", "#8BB19C", "#52796F", "#5E60CE", "#985277", "#5C374C" | An ordinal scale used in the [assign](#assign) function for non-valid color strings and numbers. |
585
+ */ const defaults = {
586
+ dark: "#555555",
587
+ light: "#f7f7f7",
588
+ missing: "#cccccc",
589
+ off: "#C44536",
590
+ on: "#6A994E",
591
+ scale: ordinal().range([
592
+ "#4281A4",
593
+ "#F6AE2D",
594
+ "#C44536",
595
+ "#2A9D8F",
596
+ "#6A994E",
597
+ "#CEB54A",
598
+ "#5E548E",
599
+ "#C08497",
600
+ "#99582A",
601
+ "#8C8C99",
602
+ "#1D3557",
603
+ "#D08C60",
604
+ "#6D2E46",
605
+ "#8BB19C",
606
+ "#52796F",
607
+ "#5E60CE",
608
+ "#985277",
609
+ "#5C374C"
610
+ ])
611
+ };
612
+ /**
613
+ Returns a color based on a key, whether it is present in a user supplied object or in the default object.
614
+ @returns {String}
615
+ @private
616
+ */ function getColor(k, u = {}) {
617
+ return k in u ? u[k] : k in defaults ? defaults[k] : defaults.missing;
618
+ }
619
+
620
+ /**
621
+ @function colorAssign
622
+ @desc Assigns a color to a value using a predefined set of defaults.
623
+ @param {String} c A valid CSS color string.
624
+ @param {Object} [u = defaults] An object containing overrides of the default colors.
625
+ @returns {String}
626
+ */ function assign(c, u = {}) {
627
+ // If the value is null or undefined, set to grey.
628
+ if ([
629
+ null,
630
+ void 0
631
+ ].indexOf(c) >= 0) return getColor("missing", u);
632
+ else if (c === true) return getColor("on", u);
633
+ else if (c === false) return getColor("off", u);
634
+ const p = color(c);
635
+ // If the value is not a valid color string, use the color scale.
636
+ if (!p) return getColor("scale", u)(c);
637
+ return c.toString();
638
+ }
639
+
640
+ /**
641
+ @function colorContrast
642
+ @desc A set of default color values used when assigning colors based on data.
643
+ @param {String} c A valid CSS color string.
644
+ @param {Object} [u = defaults] An object containing overrides of the default colors.
645
+ @returns {String}
646
+ */ function contrast(c, u = {}) {
647
+ c = rgb(c);
648
+ const yiq = (c.r * 299 + c.g * 587 + c.b * 114) / 1000;
649
+ return yiq >= 128 ? getColor("dark", u) : getColor("light", u);
650
+ }
651
+
652
+ /**
653
+ @function colorLegible
654
+ @desc Darkens a color so that it will appear legible on a white background.
655
+ @param {String} c A valid CSS color string.
656
+ @returns {String}
657
+ */ function legible(c) {
658
+ c = hsl(c);
659
+ if (c.l > 0.45) {
660
+ if (c.s > 0.8) c.s = 0.8;
661
+ c.l = 0.45;
662
+ }
663
+ return c.toString();
664
+ }
665
+
666
+ /**
667
+ @function colorLighter
668
+ @desc Similar to d3.color.brighter, except that this also reduces saturation so that colors don't appear neon.
669
+ @param {String} c A valid CSS color string.
670
+ @param {String} [i = 0.5] A value from 0 to 1 dictating the strength of the function.
671
+ @returns {String}
672
+ */ function lighter(c, i = 0.5) {
673
+ c = hsl(c);
674
+ i *= 1 - c.l;
675
+ c.l += i;
676
+ c.s -= i;
677
+ return c.toString();
678
+ }
679
+
680
+ /**
681
+ @function colorSubtract
682
+ @desc Subtracts one color from another.
683
+ @param {String} c1 The base color, a valid CSS color string.
684
+ @param {String} c2 The color to remove from the base color, also a valid CSS color string.
685
+ @param {String} [o1 = 1] Value from 0 to 1 of the first color's opacity.
686
+ @param {String} [o2 = 1] Value from 0 to 1 of the first color's opacity.
687
+ @returns {String}
688
+ */ function subtract(c1, c2, o1 = 1, o2 = 1) {
689
+ c1 = hsl(c1);
690
+ c2 = hsl(c2);
691
+ let d = c2.h * o2 - c1.h * o1;
692
+ if (Math.abs(d) > 180) d -= 360;
693
+ let h = (c1.h - d) % 360;
694
+ const l = c1.l - (c2.l * o2 - c1.l * o1) / 2, s = c1.s - (c2.s * o2 - c1.s * o1) / 2;
695
+ // a = o1 - (o2 - o1) / 2;
696
+ if (h < 0) h += 360;
697
+ return hsl(`hsl(${h},${s * 100}%,${l * 100}%)`).toString();
698
+ // return hsl(`hsl(${h},${s * 100}%,${l * 100}%,${a})`).toString();
699
+ }
700
+
701
+ exports.colorAdd = add;
702
+ exports.colorAssign = assign;
703
+ exports.colorContrast = contrast;
704
+ exports.colorDefaults = defaults;
705
+ exports.colorLegible = legible;
706
+ exports.colorLighter = lighter;
707
+ exports.colorSubtract = subtract;
708
+
709
+ }));
710
+ //# sourceMappingURL=d3plus-color.full.js.map