@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.
- package/README.md +130 -0
- package/es/index.js +7 -0
- package/es/src/add.js +22 -0
- package/es/src/assign.js +22 -0
- package/es/src/contrast.js +14 -0
- package/es/src/defaults.js +49 -0
- package/es/src/legible.js +14 -0
- package/es/src/lighter.js +15 -0
- package/es/src/subtract.js +22 -0
- package/package.json +40 -0
- package/umd/d3plus-color.full.js +710 -0
- package/umd/d3plus-color.full.js.map +1 -0
- package/umd/d3plus-color.full.min.js +84 -0
- package/umd/d3plus-color.js +275 -0
- package/umd/d3plus-color.js.map +1 -0
- package/umd/d3plus-color.min.js +83 -0
|
@@ -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, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
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
|