Skip to content

Commit 87799fe

Browse files
committed
Merge branch 'interpolate-color' into 3.2.4
2 parents 2f4d3d8 + ce6526c commit 87799fe

21 files changed

Lines changed: 262 additions & 171 deletions

d3.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4903,7 +4903,10 @@ d3 = function() {
49034903
b = d3.rgb(b);
49044904
var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab;
49054905
return function(t) {
4906-
return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t));
4906+
a.r = Math.round(ar + br * t);
4907+
a.g = Math.round(ag + bg * t);
4908+
a.b = Math.round(ab + bb * t);
4909+
return a;
49074910
};
49084911
}
49094912
d3.interpolateObject = d3_interpolateObject;
@@ -5128,7 +5131,10 @@ d3 = function() {
51285131
if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac;
51295132
if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360;
51305133
return function(t) {
5131-
return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + "";
5134+
a.h = ah + bh * t;
5135+
a.c = ac + bc * t;
5136+
a.l = al + bl * t;
5137+
return a;
51325138
};
51335139
}
51345140
d3.interpolateHsl = d3_interpolateHsl;
@@ -5139,7 +5145,10 @@ d3 = function() {
51395145
if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as;
51405146
if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360;
51415147
return function(t) {
5142-
return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + "";
5148+
a.h = ah + bh * t;
5149+
a.s = as + bs * t;
5150+
a.l = al + bl * t;
5151+
return a;
51435152
};
51445153
}
51455154
d3.interpolateLab = d3_interpolateLab;
@@ -5148,7 +5157,10 @@ d3 = function() {
51485157
b = d3.lab(b);
51495158
var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab;
51505159
return function(t) {
5151-
return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + "";
5160+
a.l = al + bl * t;
5161+
a.a = aa + ba * t;
5162+
a.b = ab + bb * t;
5163+
return a;
51525164
};
51535165
}
51545166
d3.interpolateRound = d3_interpolateRound;

d3.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/interpolate/hcl.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ function d3_interpolateHcl(a, b) {
1515
if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah;
1616
else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; // shortest path
1717
return function(t) {
18-
return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + "";
18+
a.h = ah + bh * t;
19+
a.c = ac + bc * t;
20+
a.l = al + bl * t;
21+
return a;
1922
};
2023
}

src/interpolate/hsl.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import "../color/hsl";
22

33
d3.interpolateHsl = d3_interpolateHsl;
44

5-
// interpolates HSL space, but outputs RGB string (for compatibility)
6-
75
function d3_interpolateHsl(a, b) {
86
a = d3.hsl(a);
97
b = d3.hsl(b);
@@ -17,6 +15,9 @@ function d3_interpolateHsl(a, b) {
1715
if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah;
1816
else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; // shortest path
1917
return function(t) {
20-
return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + "";
18+
a.h = ah + bh * t;
19+
a.s = as + bs * t;
20+
a.l = al + bl * t;
21+
return a;
2122
};
2223
}

src/interpolate/lab.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ function d3_interpolateLab(a, b) {
1212
ba = b.a - aa,
1313
bb = b.b - ab;
1414
return function(t) {
15-
return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + "";
15+
a.l = al + bl * t;
16+
a.a = aa + ba * t;
17+
a.b = ab + bb * t;
18+
return a;
1619
};
1720
}

src/interpolate/rgb.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ function d3_interpolateRgb(a, b) {
1212
bg = b.g - ag,
1313
bb = b.b - ab;
1414
return function(t) {
15-
return "#"
16-
+ d3_rgb_hex(Math.round(ar + br * t))
17-
+ d3_rgb_hex(Math.round(ag + bg * t))
18-
+ d3_rgb_hex(Math.round(ab + bb * t));
15+
a.r = Math.round(ar + br * t);
16+
a.g = Math.round(ag + bg * t);
17+
a.b = Math.round(ab + bb * t);
18+
return a;
1919
};
2020
}

test/assert.js

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
var assert = require("assert");
1+
var assert = require("assert"),
2+
_ = require("../");
23

34
assert = module.exports = Object.create(assert);
45

@@ -27,14 +28,62 @@ assert.domEqual = function(actual, expected, message) {
2728
};
2829

2930
assert.rgbEqual = function(actual, r, g, b, message) {
30-
if (actual.r !== r || actual.g !== g || actual.b !== b) {
31-
assert.fail("rgb(" + actual.r + "," + actual.g + "," + actual.b + ")", "rgb(" + r + ", " + g + ", " + b + ")", message || "expected {expected}, got {actual}", "===", assert.rgbEqual);
31+
var ar = Math.round(actual.r),
32+
ag = Math.round(actual.g),
33+
ab = Math.round(actual.b),
34+
er = Math.round(r),
35+
eg = Math.round(g),
36+
eb = Math.round(b);
37+
if (ar !== er || ag !== eg || ab !== eb) {
38+
assert.fail(
39+
"rgb(" + ar + "," + ag + "," + ab + ")",
40+
"rgb(" + er + ", " + eg + ", " + eb + ")",
41+
message || "expected {expected}, got {actual}", "===", assert.rgbEqual);
3242
}
3343
};
3444

3545
assert.hslEqual = function(actual, h, s, l, message) {
36-
if (Math.abs(actual.h - h) > 1e-6 || Math.abs(actual.s - s) > 1e-6 || Math.abs(actual.l - l) > 1e-6) {
37-
assert.fail("hsl(" + actual.h + "," + (actual.s * 100) + "%," + (actual.l * 100) + "%)", "hsl(" + h + "," + (s * 100) + "%," + (l * 100) + "%)", message || "expected {expected}, got {actual}", null, assert.hslEqual);
46+
var ah = _.round(actual.h, 2),
47+
as = _.round(actual.s, 2),
48+
al = _.round(actual.l, 2),
49+
eh = _.round(h, 2),
50+
es = _.round(s, 2),
51+
el = _.round(l, 2);
52+
if ((!(isNaN(ah) && isNaN(eh)) && ah !== eh) || (!(isNaN(as) && isNaN(es)) && as !== es) || al !== el) {
53+
assert.fail(
54+
"hsl(" + ah + "," + as + "," + al + ")",
55+
"hsl(" + eh + "," + es + "," + el + ")",
56+
message || "expected {expected}, got {actual}", null, assert.hslEqual);
57+
}
58+
};
59+
60+
assert.hclEqual = function(actual, h, c, l, message) {
61+
var ah = _.round(actual.h, 2),
62+
ac = _.round(actual.c, 2),
63+
al = _.round(actual.l, 2),
64+
eh = _.round(h, 2),
65+
ec = _.round(c, 2),
66+
el = _.round(l, 2);
67+
if ((!(isNaN(ah) && isNaN(eh)) && ah !== eh) || ac !== ec || al !== el) {
68+
assert.fail(
69+
"hcl(" + ah + "," + ac + "," + al + ")",
70+
"hcl(" + eh + "," + ec + "," + el + ")",
71+
message || "expected {expected}, got {actual}", null, assert.hclEqual);
72+
}
73+
};
74+
75+
assert.labEqual = function(actual, l, a, b, message) {
76+
var al = _.round(actual.l, 2),
77+
aa = _.round(actual.a, 2),
78+
ab = _.round(actual.b, 2),
79+
el = _.round(l, 2),
80+
ea = _.round(a, 2),
81+
eb = _.round(b, 2);
82+
if (al !== el || aa !== ea || ab !== eb) {
83+
assert.fail(
84+
"lab(" + al + ", " + aa + ", " + ab + ")",
85+
"lab(" + el + ", " + ea + ", " + eb + ")",
86+
message || "expected {expected}, got {actual}", null, assert.labEqual);
3887
}
3988
};
4089

test/color/hcl-test.js

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ suite.addBatch({
99
"hcl": {
1010
topic: load("color/hcl").expression("d3.hcl"),
1111
"converts string channel values to numbers": function(hcl) {
12-
assertHclEqual(hcl("50", "-4", "32"), 50, -4, 32);
12+
assert.hclEqual(hcl("50", "-4", "32"), 50, -4, 32);
1313
},
1414
"converts null channel values to zero": function(hcl) {
15-
assertHclEqual(hcl(null, null, null), 0, 0, 0);
15+
assert.hclEqual(hcl(null, null, null), 0, 0, 0);
1616
},
1717
"exposes h, c and l properties": function(hcl) {
1818
var color = hcl(50, -4, 32);
@@ -31,49 +31,49 @@ suite.addBatch({
3131
assert.equal(color + "", "#494f51");
3232
},
3333
"parses hexadecimal shorthand format (e.g., \"#abc\")": function(hcl) {
34-
assertHclEqual(hcl("#abc"), -102.28223831811077, 10.774886733325554, 75.10497524893663);
34+
assert.hclEqual(hcl("#abc"), -102.28223831811077, 10.774886733325554, 75.10497524893663);
3535
},
3636
"parses hexadecimal format (e.g., \"#abcdef\")": function(hcl) {
37-
assertHclEqual(hcl("#abcdef"), -100.15785184209284, 20.768234621934273, 81.04386565274363);
37+
assert.hclEqual(hcl("#abcdef"), -100.15785184209284, 20.768234621934273, 81.04386565274363);
3838
},
3939
"parses HSL format (e.g., \"hsl(210, 64%, 13%)\")": function(hcl) {
40-
assertHclEqual(hcl("hsl(210, 64.7058%, 13.33333%)"), -89.58282792342067, 16.833655998102003, 12.65624852526134);
40+
assert.hclEqual(hcl("hsl(210, 64.7058%, 13.33333%)"), -89.58282792342067, 16.833655998102003, 12.65624852526134);
4141
},
4242
"parses color names (e.g., \"moccasin\")": function(hcl) {
43-
assertHclEqual(hcl("moccasin"), 84.71288921124494, 26.472460854104156, 91.72317744746022);
43+
assert.hclEqual(hcl("moccasin"), 84.71288921124494, 26.472460854104156, 91.72317744746022);
4444
},
4545
"parses and converts RGB format (e.g., \"rgb(102, 102, 0)\")": function(hcl) {
46-
assertHclEqual(hcl("rgb(102, 102, 0)"), 102.85124420310271, 49.44871600399321, 41.73251953866431);
46+
assert.hclEqual(hcl("rgb(102, 102, 0)"), 102.85124420310271, 49.44871600399321, 41.73251953866431);
4747
},
4848
"can convert from RGB": function(hcl) {
49-
assertHclEqual(hcl(_.rgb(12, 34, 56)), -89.58282792342067, 16.833655998102003, 12.65624852526134);
49+
assert.hclEqual(hcl(_.rgb(12, 34, 56)), -89.58282792342067, 16.833655998102003, 12.65624852526134);
5050
},
5151
"can convert from HSL": function(hcl) {
52-
assertHclEqual(hcl(hcl(20, .8, .3)), 20, 0.8, 0.3);
52+
assert.hclEqual(hcl(hcl(20, .8, .3)), 20, 0.8, 0.3);
5353
},
5454
"can convert to RGB": function(hcl) {
5555
assert.rgbEqual(hcl("steelblue").rgb(), 70, 130, 180);
5656
},
5757
"can derive a brighter color": function(hcl) {
58-
assertHclEqual(hcl("steelblue").brighter(), -97.21873224090723, 32.44906314974561, 70.46551718768575);
59-
assertHclEqual(hcl("steelblue").brighter(.5), -97.21873224090723, 32.44906314974561, 61.46551718768575);
58+
assert.hclEqual(hcl("steelblue").brighter(), -97.21873224090723, 32.44906314974561, 70.46551718768575);
59+
assert.hclEqual(hcl("steelblue").brighter(.5), -97.21873224090723, 32.44906314974561, 61.46551718768575);
6060
},
6161
"can derive a darker color": function(hcl) {
62-
assertHclEqual(hcl("lightsteelblue").darker(), -94.8160116310511, 15.26488988314746, 60.45157936968134);
63-
assertHclEqual(hcl("lightsteelblue").darker(.5), -94.8160116310511, 15.26488988314746, 69.45157936968134);
62+
assert.hclEqual(hcl("lightsteelblue").darker(), -94.8160116310511, 15.26488988314746, 60.45157936968134);
63+
assert.hclEqual(hcl("lightsteelblue").darker(.5), -94.8160116310511, 15.26488988314746, 69.45157936968134);
6464
},
6565
"string coercion returns RGB format": function(hcl) {
6666
assert.strictEqual(hcl("hsl(60, 100%, 20%)") + "", "#666600");
6767
assert.strictEqual(hcl(hcl(60, -4, 32)) + "", "#454c51");
6868
},
6969
"roundtrip to HSL is idempotent": function(hcl) {
70-
assert.hslEqual(_.hsl(hcl("steelblue")), _.hsl("steelblue"));
70+
assert.deepEqual(_.hsl(hcl("steelblue")), _.hsl("steelblue"));
7171
},
7272
"roundtrip to RGB is idempotent": function(hcl) {
73-
assert.hslEqual(_.rgb(hcl("steelblue")), _.rgb("steelblue"));
73+
assert.deepEqual(_.rgb(hcl("steelblue")), _.rgb("steelblue"));
7474
},
7575
"roundtrip to Lab is idempotent": function(hcl) {
76-
assert.hslEqual(_.lab(hcl("steelblue")), _.lab("steelblue"));
76+
assert.deepEqual(_.lab(hcl("steelblue")), _.lab("steelblue"));
7777
},
7878
"h is defined for non-black grayscale colors (because of the color profile)": function(hcl) {
7979
assert.inDelta(hcl("#ccc").h, 158.1986, 1e-3);
@@ -110,9 +110,3 @@ suite.addBatch({
110110
});
111111

112112
suite.export(module);
113-
114-
function assertHclEqual(actual, h, c, l, message) {
115-
if (Math.abs(actual.h - h) > 1e-6 || Math.abs(actual.c - c) > 1e-6 || Math.abs(actual.l - l) > 1e-6) {
116-
assert.fail("hcl(" + actual.h + ", " + actual.c + ", " + actual.l + ")", "hcl(" + h + ", " + c + ", " + l + ")", message || "expected {expected}, got {actual}", null, assertHclEqual);
117-
}
118-
}

test/color/hsl-test.js

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ suite.addBatch({
1919
assert.hslEqual(hsl(null, null, null), 0, 0, 0);
2020
},
2121
"exposes h, s and l properties": function(hsl) {
22-
var color = hsl("hsl(180, 50%, 60%)");
23-
assert.equal(color.h, 180);
24-
assert.equal(color.s, .5);
25-
assert.equal(color.l, .6);
22+
assert.hslEqual(hsl("hsl(180, 50%, 60%)"), 180, .5, .6);
2623
},
2724
"changing h, s or l affects the string format": function(hsl) {
2825
var color = hsl("hsl(180, 50%, 60%)");
@@ -74,38 +71,38 @@ suite.addBatch({
7471
assert.strictEqual(hsl(hsl(60, 1, .2)) + "", "#666600");
7572
},
7673
"h is preserved when explicitly specified, even for grayscale colors": function(hsl) {
77-
assert.strictEqual(hsl(0, 0, 0).h, 0);
78-
assert.strictEqual(hsl(42, 0, .5).h, 42);
79-
assert.strictEqual(hsl(118, 0, 1).h, 118);
74+
assert.hslEqual(hsl(0, 0, 0), 0, 0, 0);
75+
assert.hslEqual(hsl(42, 0, .5), 42, 0, .5);
76+
assert.hslEqual(hsl(118, 0, 1), 118, 0, 1);
8077
},
8178
"h is undefined when not explicitly specified for grayscale colors": function(hsl) {
82-
assert.isNaN(hsl("#000").h);
83-
assert.isNaN(hsl("black").h);
84-
assert.isNaN(hsl(_.rgb("black")).h);
85-
assert.isNaN(hsl("#ccc").h);
86-
assert.isNaN(hsl("gray").h);
87-
assert.isNaN(hsl(_.rgb("gray")).h);
88-
assert.isNaN(hsl("#fff").h);
89-
assert.isNaN(hsl("white").h);
90-
assert.isNaN(hsl(_.rgb("white")).h);
79+
assert.hslEqual(hsl("#000"), NaN, NaN, 0);
80+
assert.hslEqual(hsl("black"), NaN, NaN, 0);
81+
assert.hslEqual(hsl(_.rgb("black")), NaN, NaN, 0);
82+
assert.hslEqual(hsl("#ccc"), NaN, 0, .8);
83+
assert.hslEqual(hsl("gray"), NaN, 0, .5);
84+
assert.hslEqual(hsl(_.rgb("gray")), NaN, 0, .5);
85+
assert.hslEqual(hsl("#fff"), NaN, NaN, 1);
86+
assert.hslEqual(hsl("white"), NaN, NaN, 1);
87+
assert.hslEqual(hsl(_.rgb("white")), NaN, NaN, 1);
9188
},
9289
"s is preserved when explicitly specified, even for white or black": function(hsl) {
93-
assert.strictEqual(hsl(0, 0, 0).s, 0);
94-
assert.strictEqual(hsl(0, .18, 0).s, .18);
95-
assert.strictEqual(hsl(0, .42, 1).s, .42);
96-
assert.strictEqual(hsl(0, 1, 1).s, 1);
90+
assert.hslEqual(hsl(0, 0, 0), 0, 0, 0);
91+
assert.hslEqual(hsl(0, .18, 0), 0, .18, 0);
92+
assert.hslEqual(hsl(0, .42, 1), 0, .42, 1);
93+
assert.hslEqual(hsl(0, 1, 1), 0, 1, 1);
9794
},
9895
"s is zero for grayscale colors (but not white and black)": function(hsl) {
99-
assert.strictEqual(hsl("#ccc").s, 0);
100-
assert.strictEqual(hsl("#777").s, 0);
96+
assert.hslEqual(hsl("#ccc"), NaN, 0, .8);
97+
assert.hslEqual(hsl("#777"), NaN, 0, .47);
10198
},
10299
"s is undefined when not explicitly specified for white or black": function(hsl) {
103-
assert.isNaN(hsl("#000").s);
104-
assert.isNaN(hsl("black").s);
105-
assert.isNaN(hsl(_.rgb("black")).s);
106-
assert.isNaN(hsl("#fff").s);
107-
assert.isNaN(hsl("white").s);
108-
assert.isNaN(hsl(_.rgb("white")).s);
100+
assert.hslEqual(hsl("#000"), NaN, NaN, 0);
101+
assert.hslEqual(hsl("black"), NaN, NaN, 0);
102+
assert.hslEqual(hsl(_.rgb("black")), NaN, NaN, 0);
103+
assert.hslEqual(hsl("#fff"), NaN, NaN, 1);
104+
assert.hslEqual(hsl("white"), NaN, NaN, 1);
105+
assert.hslEqual(hsl(_.rgb("white")), NaN, NaN, 1);
109106
},
110107
"can convert grayscale colors (with undefined hue) to RGB": function(hsl) {
111108
assert.strictEqual(hsl(NaN, 0, .2) + "", "#333333");

0 commit comments

Comments
 (0)