Skip to content

Commit c99b6c2

Browse files
authored
Merge pull request #5506 from plotly/parcoords_text_shadow
Parcoords: Use paper background color for text shadow for better dark mode
2 parents cfa7720 + 409e319 commit c99b6c2

20 files changed

+101
-13
lines changed

Diff for: src/lib/svg_text_utils.js

+10
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,16 @@ function alignHTMLWith(_base, container, options) {
755755
};
756756
}
757757

758+
exports.makeTextShadow = function(offset, color) {
759+
var x = offset + 'px ';
760+
var y = offset + 'px ';
761+
var b = '1px ';
762+
return x + y + b + color + ', ' +
763+
'-' + x + '-' + y + b + color + ', ' +
764+
x + '-' + y + b + color + ', ' +
765+
'-' + x + y + b + color;
766+
};
767+
758768
/*
759769
* Editable title
760770
* @param {d3.selection} context: the element being edited. Normally text,

Diff for: src/traces/parcats/parcats.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,7 @@ function performPlot(parcatsModels, graphDiv, layout, svg) {
238238
})
239239
.attr('alignment-baseline', 'middle')
240240

241-
.style('text-shadow',
242-
paperColor + ' -1px 1px 2px, ' +
243-
paperColor + ' 1px 1px 2px, ' +
244-
paperColor + ' 1px -1px 2px, ' +
245-
paperColor + ' -1px -1px 2px')
241+
.style('text-shadow', svgTextUtils.makeTextShadow(1, paperColor))
246242
.style('fill', 'rgb(0, 0, 0)')
247243
.attr('x',
248244
function(d) {

Diff for: src/traces/parcoords/axisbrush.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ function attachDragBehavior(selection) {
354354

355355
function startAsc(a, b) { return a[0] - b[0]; }
356356

357-
function renderAxisBrush(axisBrush) {
357+
function renderAxisBrush(axisBrush, paperColor) {
358358
var background = axisBrush.selectAll('.background').data(repeat);
359359

360360
background.enter()
@@ -378,7 +378,7 @@ function renderAxisBrush(axisBrush) {
378378
.classed('highlight-shadow', true)
379379
.attr('x', -c.bar.width / 2)
380380
.attr('stroke-width', c.bar.width + c.bar.strokeWidth)
381-
.attr('stroke', c.bar.strokeColor)
381+
.attr('stroke', paperColor)
382382
.attr('opacity', c.bar.strokeOpacity)
383383
.attr('stroke-linecap', 'butt');
384384

@@ -402,15 +402,15 @@ function renderAxisBrush(axisBrush) {
402402
.call(styleHighlight);
403403
}
404404

405-
function ensureAxisBrush(axisOverlays) {
405+
function ensureAxisBrush(axisOverlays, paperColor) {
406406
var axisBrush = axisOverlays.selectAll('.' + c.cn.axisBrush)
407407
.data(repeat, keyFun);
408408

409409
axisBrush.enter()
410410
.append('g')
411411
.classed(c.cn.axisBrush, true);
412412

413-
renderAxisBrush(axisBrush);
413+
renderAxisBrush(axisBrush, paperColor);
414414
}
415415

416416
function getBrushExtent(brush) {

Diff for: src/traces/parcoords/constants.js

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ module.exports = {
2020
snapDuration: 150, // tween duration in ms for brush snap for ordinal axes
2121
snapRatio: 0.25, // ratio of bar extension relative to the distance between two adjacent ordinal values
2222
snapClose: 0.01, // fraction of inter-value distance to snap to the closer one, even if you're not over it
23-
strokeColor: 'white', // Color of the filter bar side lines
2423
strokeOpacity: 1, // Filter bar side stroke opacity
2524
strokeWidth: 1, // Filter bar side stroke width in pixels
2625
handleHeight: 8, // Height of the filter bar vertical resize areas on top and bottom

Diff for: src/traces/parcoords/parcoords.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ module.exports = function parcoords(gd, cdModule, layout, callbacks) {
433433
var fullLayout = gd._fullLayout;
434434
var svg = fullLayout._toppaper;
435435
var glContainer = fullLayout._glcontainer;
436+
var paperColor = gd._fullLayout.paper_bgcolor;
436437

437438
calcAllTicks(cdModule);
438439

@@ -451,6 +452,7 @@ module.exports = function parcoords(gd, cdModule, layout, callbacks) {
451452
.each(function(d) {
452453
// FIXME: figure out how to handle multiple instances
453454
d.viewModel = vm[0];
455+
d.viewModel.paperColor = paperColor;
454456
d.model = d.viewModel ? d.viewModel.model : null;
455457
});
456458

@@ -647,7 +649,7 @@ module.exports = function parcoords(gd, cdModule, layout, callbacks) {
647649
.attr('stroke-width', '1px');
648650

649651
axis.selectAll('text')
650-
.style('text-shadow', '1px 1px 1px #fff, -1px -1px 1px #fff, 1px -1px 1px #fff, -1px 1px 1px #fff')
652+
.style('text-shadow', svgTextUtils.makeTextShadow(1, paperColor))
651653
.style('cursor', 'default');
652654

653655
var axisHeading = axisOverlays.selectAll('.' + c.cn.axisHeading)
@@ -749,5 +751,5 @@ module.exports = function parcoords(gd, cdModule, layout, callbacks) {
749751
.text(function(d) { return extremeText(d, false); })
750752
.each(function(d) { Drawing.font(d3.select(this), d.model.rangeFont); });
751753

752-
brush.ensureAxisBrush(axisOverlays);
754+
brush.ensureAxisBrush(axisOverlays, paperColor);
753755
};

Diff for: src/traces/sankey/render.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ var keyFun = gup.keyFun;
1515
var repeat = gup.repeat;
1616
var unwrap = gup.unwrap;
1717
var interpolateNumber = require('d3-interpolate').interpolateNumber;
18+
var svgTextUtils = require('../../lib/svg_text_utils');
1819

1920
var Registry = require('../../registry');
2021

@@ -1024,7 +1025,7 @@ module.exports = function(gd, svg, calcData, layout, callbacks) {
10241025

10251026
nodeLabel
10261027
.style('text-shadow', function(d) {
1027-
return d.horizontal ? '-1px 1px 1px #fff, 1px 1px 1px #fff, 1px -1px 1px #fff, -1px -1px 1px #fff' : 'none';
1028+
return d.horizontal ? svgTextUtils.makeTextShadow(1, '#fff') : 'none';
10281029
})
10291030
.each(function(d) {Drawing.font(nodeLabel, d.textFont);});
10301031

122 KB
Loading

Diff for: test/image/baselines/parcats_bad-displayindex.png

-219 Bytes
Loading

Diff for: test/image/baselines/parcats_basic.png

-227 Bytes
Loading

Diff for: test/image/baselines/parcats_basic_freeform.png

-227 Bytes
Loading

Diff for: test/image/baselines/parcats_bundled.png

9 Bytes
Loading

Diff for: test/image/baselines/parcats_bundled_reversed.png

6 Bytes
Loading

Diff for: test/image/baselines/parcats_colorscale_template.png

-198 Bytes
Loading

Diff for: test/image/baselines/parcats_dark.png

-126 Bytes
Loading

Diff for: test/image/baselines/parcats_grid_subplots.png

-366 Bytes
Loading

Diff for: test/image/baselines/parcats_hoveron_color.png

-93 Bytes
Loading

Diff for: test/image/baselines/parcats_hoveron_dimension.png

-173 Bytes
Loading

Diff for: test/image/baselines/parcats_reordered.png

-59 Bytes
Loading

Diff for: test/image/baselines/parcats_unbundled.png

-93 Bytes
Loading

Diff for: test/image/mocks/gl2d_parcoords_dark_background.json

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
{
2+
"layout": {
3+
"width": 1184,
4+
"height": 400,
5+
"title": {"text": "Widget parameters and cost"},
6+
"font": {"color": "white"},
7+
"paper_bgcolor": "black"
8+
},
9+
10+
"data": [{
11+
12+
"type": "parcoords",
13+
14+
"line": {
15+
"showscale": true,
16+
"reversescale": true,
17+
"colorscale": "Jet",
18+
"cmin": -4000,
19+
"cmax": -100,
20+
"color": [-41, -1317, -164, -1856, -79, -931, -191, -2983, -341, -3846, -278, -3019, -523, -2357, -985, -3447, -211, -2842, -458, -4388, -784, -2563, -935, -2253, -313, -3667, -1479, -1030, -632, -623, -1945, -1324, -1221, -878, -947, -1615, -697, -575, -482, -905, -869, -433, -484, -349, -667, -248, -1135, -888, -1019, -223, -2067, -729, -579, -659, -334, -340, -554, -455, -377, -375, -453, -834, -934, -334, -369, -290, -354, -497, -490, -329, -729, -1794, -151, -1162, -3935, -1013, -509, -825, -997, -320, -680, -422, -785, -542, -563, -489, -1283, -680, -78, -450, -514, -449, -548, -661, -641, -503, -570, -257, -394, -450]
21+
},
22+
23+
"dimensions": [
24+
{
25+
"constraintrange": [100000, 150000],
26+
"label": "Block height",
27+
"values": [32000, 162666, 32000, 162666, 32000, 162666, 32000, 162666, 32000, 162666, 32000, 162666, 32000, 162666, 32000, 162666, 32000, 162666, 32000, 162666, 32000, 162666, 32000, 162666, 32000, 162666, 86600, 163400, 162600, 90000, 93100, 163000, 140500, 130000, 100700, 164500, 147700, 121700, 107500, 176600, 133600, 111100, 93100, 72400, 130100, 54500, 182600, 160300, 218100, 66500, 95800, 164800, 107200, 101600, 91100, 91100, 78100, 63300, 75700, 69600, 88500, 115800, 195700, 88900, 74800, 65400, 74900, 115300, 91400, 67800, 85300, 171300, 32000, 227900, 163200, 122899, 112300, 101500, 111199, 73300, 120800, 93100, 117200, 118500, 104800, 108500, 146500, 90300, 32000, 93000, 110700, 103500, 93300, 106300, 118500, 93000, 67600, 51400, 89000, 94000]
28+
},
29+
{
30+
"label": "Block width",
31+
"range": [0, 700000],
32+
"tickformat": "",
33+
"values": [268630, 489543, 379086, 600000, 489543, 268630, 600000, 379086, 268630, 489543, 379086, 600000, 489543, 268630, 600000, 379086, 268630, 489543, 379086, 600000, 489543, 268630, 600000, 379086, 268630, 489543, 436900, 373600, 268630, 439000, 381800, 491200, 402800, 381400, 485600, 600000, 372200, 394700, 383800, 401100, 356500, 313200, 487100, 490700, 432299, 530300, 521500, 456700, 333800, 343200, 394000, 328200, 487700, 383600, 317700, 324600, 482900, 515100, 500100, 562700, 486000, 453400, 352900, 331300, 496200, 469099, 472500, 354700, 507700, 509000, 439300, 525300, 347600, 379000, 432800, 378800, 383200, 523800, 600000, 313600, 497700, 411300, 420000, 381100, 342800, 385900, 268630, 495800, 488000, 446400, 397900, 373300, 385700, 396500, 475700, 510600, 586800, 596000, 407600, 439200]
34+
},
35+
{
36+
"label": "Cylinder material",
37+
"tickvals": [0, 0.5, 1, 2, 3],
38+
"ticktext": ["A", "AB", "B", "Y", "Z"],
39+
"values": [0, 0, 1, 0.5, 2, 3, 3, 0, 1, 1, 2, 2, 3, 0, 0, 1, 2, 2, 3, 3, 0, 1, 1, 2, 3, 3, 3, 0, 2, 3, 1, 0, 1, 3, 1, 0, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 3, 2, 2, 0, 0, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 1, 1, 2, 0, 3, 0, 2, 2, 0, 2, 0, 2, 2, 0, 2, 2, 2, 2, 0, 0, 2, 2, 0, 2, 2, 2]
40+
},
41+
{
42+
"label": "Block material",
43+
"tickvals": [0, 1, 2, 3],
44+
"range": [-1, 4],
45+
"values": [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
46+
},
47+
{
48+
"label": "Total weight",
49+
"visible": true,
50+
"values": [160, 1324, 252, 1711, 173, 624, 228, 2474, 371, 3103, 312, 2408, 460, 1727, 754, 2457, 227, 1963, 354, 2797, 377, 1327, 462, 1009, 166, 1415, 1118, 1063, 593, 498, 959, 1331, 1146, 645, 921, 1596, 663, 568, 492, 833, 630, 445, 504, 394, 647, 314, 1039, 829, 911, 282, 925, 681, 581, 506, 368, 373, 628, 538, 418, 419, 478, 884, 847, 369, 410, 344, 396, 501, 510, 379, 733, 1649, 239, 1035, 1839, 967, 514, 875, 794, 414, 664, 447, 839, 540, 636, 499, 1059, 743, 173, 473, 519, 465, 623, 726, 631, 521, 643, 323, 424, 472]
51+
},
52+
{
53+
"visible": false,
54+
"values": [1125, 9274, 2735, 16920, 2193, 20704, 4814, 34689, 5565, 46554, 5225, 38887, 9746, 37715, 17798, 55250, 5697, 49083, 11226, 81939, 24258, 62488, 27363, 61924, 12511, 106196, 24444, 7443, 9111, 12527, 50738, 9320, 12291, 17571, 9508, 11176, 9142, 7687, 6724, 11219, 17825, 6506, 6367, 4966, 8495, 3860, 12844, 10688, 13026, 4007, 57281, 9790, 7335, 13748, 5358, 5393, 4401, 3769, 5233, 5058, 6047, 6188, 11899, 5297, 5154, 4406, 5061, 7022, 6358, 4721, 7723, 16745, 2651, 14194, 100772, 10504, 7021, 6131, 16730, 2904, 8334, 5968, 5876, 7394, 4454, 6800, 18376, 5204, 2190, 6146, 7013, 6412, 4361, 5082, 8028, 6484, 4504, 3832, 5687, 6174]
55+
},
56+
{
57+
"label": "Assembly penalty weight",
58+
"values": [9, 794, 34, 1409, 17, 536, 39, 7133, 115, 9843, 107, 7017, 273, 5131, 1210, 9032, 82, 7312, 252, 16778, 760, 4349, 891, 4228, 123, 10800, 1593, 467, 260, 226, 2940, 803, 689, 420, 422, 1229, 275, 198, 150, 423, 423, 134, 146, 89, 248, 55, 612, 401, 546, 52, 4208, 307, 194, 257, 91, 93, 178, 133, 99, 98, 131, 345, 461, 90, 96, 69, 91, 160, 148, 81, 274, 1332, 31, 667, 11733, 502, 163, 354, 480, 67, 252, 120, 303, 181, 162, 153, 1142, 251, 17, 131, 165, 135, 162, 222, 230, 154, 198, 58, 109, 132]
59+
},
60+
{
61+
"label": "Height st width",
62+
"values": [236630, 326876, 347086, 437333, 457543, 105963, 568000, 216420, 236630, 326876, 347086, 437333, 457543, 105963, 568000, 216420, 236630, 326876, 347086, 437333, 457543, 105963, 568000, 216420, 236630, 326876, 350300, 210200, 106030, 349000, 288700, 328200, 262300, 251400, 384900, 435500, 224500, 273000, 276300, 224500, 222900, 202100, 394000, 418300, 302200, 475800, 338900, 296400, 115700, 276700, 298200, 163400, 380500, 282000, 226600, 233500, 404799, 451800, 424400, 493100, 397500, 337600, 157200, 242399, 421400, 403700, 397600, 239400, 416300, 441200, 354000, 354000, 315599, 151100, 269600, 255900, 270900, 422299, 488800, 240300, 376900, 318200, 302800, 262600, 238000, 277400, 122130, 405500, 455999, 353400, 287200, 269800, 292400, 290200, 357200, 417600, 519200, 544600, 318600, 345200]
63+
},
64+
{
65+
"label": "Min height width",
66+
"range": [200000, -30000],
67+
"constraintrange": [0, 100000],
68+
"values": [5137, 113712, -5909, 102666, -16955, 135803, -28000, 124758, 5137, 113712, -5909, 102666, -16955, 135803, -28000, 124758, 5137, 113712, -5909, 102666, -16955, 135803, -28000, 124758, 5137, 113712, 42910, 126039, 135736, 46100, 54920, 113880, 100220, 91860, 52140, 104500, 110480, 82230, 69120, 136490, 97950, 79780, 44390, 23330, 86870, 1469, 130450, 114629, 184720, 32180, 56400, 131980, 58430, 63240, 59330, 58640, 29810, 11790, 25690, 13330, 39900, 70460, 160410, 55770, 25179, 18490, 27650, 79830, 40630, 16900, 41369, 118770, -2760, 190000, 119920, 85020, 73980, 49120, 51200, 41940, 71030, 51970, 75200, 80390, 70520, 69910, 119636, 40720, -16800, 48360, 70910, 66170, 54730, 66650, 70930, 41940, 8919, -8201, 48240, 50080]
69+
},
70+
{
71+
"label": "Min width diameter",
72+
"values": [98453, 319366, 234498, 455411, 391333, 147711, 479081, 208910, 124041, 344954, 280876, 501789, 368624, 98453, 429823, 234498, 170419, 391333, 258167, 479081, 319366, 124041, 455411, 280876, 147711, 368624, 315981, 203423, 170419, 318081, 237211, 321023, 258211, 260481, 341011, 429823, 273989, 296489, 285589, 302889, 235581, 214989, 388889, 392489, 334089, 432089, 423289, 358489, 235589, 244989, 223823, 229989, 389489, 262681, 219489, 226389, 312723, 344923, 401889, 464489, 387789, 283223, 254689, 233089, 397989, 370889, 374289, 256489, 409489, 410789, 294711, 380711, 203011, 280789, 288211, 234211, 284989, 353623, 479081, 143423, 399489, 313089, 249823, 282889, 172623, 287689, 170419, 325623, 389789, 348189, 299689, 275089, 215523, 226323, 377489, 412389, 416623, 497789, 309389, 340989]
73+
},
74+
{
75+
"label": "RF block",
76+
"values": [1417, 23377, 3376, 33336, 5635, 10812, 6898, 21273, 2484, 35126, 5626, 51096, 7384, 22020, 18912, 52449, 7498, 87528, 11359, 107154, 9197, 18159, 13115, 41120, 4254, 53966, 17129, 14957, 12469, 12882, 19875, 23547, 16325, 15238, 15452, 31817, 18210, 16237, 13815, 24070, 14163, 10748, 16292, 12787, 19559, 10597, 34781, 25859, 23121, 7331, 19298, 17056, 18788, 12009, 8997, 9280, 10990, 9825, 13690, 14547, 15443, 14758, 22429, 9324, 13396, 10915, 12615, 13307, 16842, 12533, 11312, 29347, 2923, 28796, 42332, 12953, 14401, 16151, 23973, 4730, 21716, 13116, 13175, 15085, 8140, 14046, 15629, 13231, 5612, 14571, 14929, 12812, 9048, 10826, 20129, 17258, 12673, 11513, 12391, 14423]
77+
}
78+
]
79+
}]
80+
}

0 commit comments

Comments
 (0)