Skip to content

Commit 89657a1

Browse files
Filmbostock
andauthored
support for fillOpacity in swatch and ramp color legends (#1407)
* support for fillOpacity in swatch and ramp color legends closes #1356 * opacity * fill opacity it is * use fill-opacity * minimize diff * minimize diff; add default * regenerate test snapshots --------- Co-authored-by: Mike Bostock <[email protected]>
1 parent 1d67219 commit 89657a1

12 files changed

+331
-3
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,7 @@ Categorical and ordinal color legends are rendered as swatches, unless *options*
653653
* *options*.**columns** - the number of swatches per row
654654
* *options*.**marginLeft** - the legend’s left margin
655655
* *options*.**className** - a class name, that defaults to a randomly generated string scoping the styles
656+
* *options*.**opacity** - the swatch fill opacity
656657
* *options*.**width** - the legend’s width (in pixels)
657658

658659
Symbol legends are rendered as swatches and support the options above in addition to the following options:
@@ -679,6 +680,7 @@ Continuous color legends are rendered as a ramp, and can be configured with the
679680
* *options*.**marginRight** - the legend’s right margin
680681
* *options*.**marginBottom** - the legend’s bottom margin
681682
* *options*.**marginLeft** - the legend’s left margin
683+
* *options*.**opacity** - the ramp’s fill opacity
682684

683685
The **style** legend option allows custom styles to override Plot’s defaults; it has the same behavior as in Plot’s top-level [layout options](#layout-options).
684686

src/legends.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ export interface LegendOptions {
5151
fill?: string;
5252
/** The desired fill opacity of symbols. For *symbol* legends only. */
5353
fillOpacity?: number;
54+
/** The desired opacity of the color swatches or ramp. For *color* legends only. */
55+
opacity?: number;
5456
/** The desired stroke color of symbols; use *color* for a redundant encoding. For *symbol* legends only. */
5557
stroke?: string;
5658
/** The desired stroke opacity of symbols. For *symbol* legends only. */

src/legends/ramp.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {quantize, interpolateNumber, piecewise, format, scaleBand, scaleLinear, axisBottom} from "d3";
22
import {inferFontVariant} from "../axes.js";
33
import {createContext, create} from "../context.js";
4-
import {map} from "../options.js";
4+
import {map, maybeNumberChannel} from "../options.js";
55
import {interpolatePiecewise} from "../scales/quantitative.js";
66
import {applyInlineStyles, impliedString, maybeClassName} from "../style.js";
77

@@ -20,10 +20,12 @@ export function legendRamp(color, options) {
2020
tickFormat,
2121
fontVariant = inferFontVariant(color),
2222
round = true,
23+
opacity,
2324
className
2425
} = options;
2526
const context = createContext(options);
2627
className = maybeClassName(className);
28+
opacity = maybeNumberChannel(opacity)[1];
2729
if (tickFormat === null) tickFormat = () => null;
2830

2931
const svg = create("svg", context)
@@ -96,6 +98,7 @@ export function legendRamp(color, options) {
9698

9799
svg
98100
.append("image")
101+
.attr("opacity", opacity)
99102
.attr("x", marginLeft)
100103
.attr("y", marginTop)
101104
.attr("width", width - marginLeft - marginRight)
@@ -117,6 +120,7 @@ export function legendRamp(color, options) {
117120

118121
svg
119122
.append("g")
123+
.attr("fill-opacity", opacity)
120124
.selectAll()
121125
.data(range)
122126
.enter()
@@ -137,6 +141,7 @@ export function legendRamp(color, options) {
137141

138142
svg
139143
.append("g")
144+
.attr("fill-opacity", opacity)
140145
.selectAll()
141146
.data(domain)
142147
.enter()

src/legends/swatches.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,20 @@ function maybeScale(scale, key) {
1212
return s;
1313
}
1414

15-
export function legendSwatches(color, options) {
15+
export function legendSwatches(color, {opacity, ...options} = {}) {
1616
if (!isOrdinalScale(color) && !isThresholdScale(color))
1717
throw new Error(`swatches legend requires ordinal or threshold color scale (not ${color.type})`);
1818
return legendItems(
1919
color,
2020
options,
2121
(selection, scale) =>
22-
selection.append("svg").attr("fill", scale.scale).append("rect").attr("width", "100%").attr("height", "100%"),
22+
selection
23+
.append("svg")
24+
.attr("fill", scale.scale)
25+
.attr("fill-opacity", maybeNumberChannel(opacity)[1])
26+
.append("rect")
27+
.attr("width", "100%")
28+
.attr("height", "100%"),
2329
(className) => `.${className}-swatch svg {
2430
width: var(--swatchWidth);
2531
height: var(--swatchHeight);

test/output/colorLegendOpacity.html

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<div class="plot" style="
2+
--swatchWidth: 15px;
3+
--swatchHeight: 15px;
4+
">
5+
<style>
6+
.plot {
7+
font-family: system-ui, sans-serif;
8+
font-size: 10px;
9+
margin-bottom: 0.5em;
10+
margin-left: 0px;
11+
}
12+
13+
.plot-swatch svg {
14+
width: var(--swatchWidth);
15+
height: var(--swatchHeight);
16+
margin-right: 0.5em;
17+
}
18+
19+
.plot {
20+
display: flex;
21+
align-items: center;
22+
min-height: 33px;
23+
flex-wrap: wrap;
24+
}
25+
26+
.plot-swatch {
27+
display: inline-flex;
28+
align-items: center;
29+
margin-right: 1em;
30+
}
31+
</style><span class="plot-swatch"><svg fill="#4e79a7" fill-opacity="0.5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
32+
<rect width="100%" height="100%"></rect>
33+
</svg>Dream</span><span class="plot-swatch"><svg fill="#f28e2c" fill-opacity="0.5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
34+
<rect width="100%" height="100%"></rect>
35+
</svg>Torgersen</span><span class="plot-swatch"><svg fill="#e15759" fill-opacity="0.5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
36+
<rect width="100%" height="100%"></rect>
37+
</svg>Biscoe</span>
38+
</div>
Loading
+43
Loading
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<div class="plot" style="
2+
--swatchWidth: 15px;
3+
--swatchHeight: 15px;
4+
">
5+
<style>
6+
.plot {
7+
font-family: system-ui, sans-serif;
8+
font-size: 10px;
9+
margin-bottom: 0.5em;
10+
margin-left: 0px;
11+
}
12+
13+
.plot-swatch>svg {
14+
width: var(--swatchWidth);
15+
height: var(--swatchHeight);
16+
margin-right: 0.5em;
17+
overflow: visible;
18+
fill: none;
19+
fill-opacity: 1;
20+
stroke: undefined;
21+
stroke-width: 1.5px;
22+
stroke-opacity: 0.5;
23+
}
24+
25+
.plot {
26+
display: flex;
27+
align-items: center;
28+
min-height: 33px;
29+
flex-wrap: wrap;
30+
}
31+
32+
.plot-swatch {
33+
display: inline-flex;
34+
align-items: center;
35+
margin-right: 1em;
36+
}
37+
</style><span class="plot-swatch"><svg viewBox="-8 -8 16 16" stroke="#4e79a7" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
38+
<path d="M4.5,0A4.5,4.5,0,1,1,-4.5,0A4.5,4.5,0,1,1,4.5,0"></path>
39+
</svg>A</span><span class="plot-swatch"><svg viewBox="-8 -8 16 16" stroke="#f28e2c" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
40+
<path d="M-6.873,0L6.873,0M0,6.873L0,-6.873"></path>
41+
</svg>B</span><span class="plot-swatch"><svg viewBox="-8 -8 16 16" stroke="#e15759" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
42+
<path d="M-4.87,-4.87L4.87,4.87M-4.87,4.87L4.87,-4.87"></path>
43+
</svg>C</span><span class="plot-swatch"><svg viewBox="-8 -8 16 16" stroke="#76b7b2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
44+
<path d="M0,-5.443L4.714,2.721L-4.714,2.721Z"></path>
45+
</svg>D</span><span class="plot-swatch"><svg viewBox="-8 -8 16 16" stroke="#59a14f" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
46+
<path d="M0,4.769L0,-4.769M-4.13,-2.384L4.13,2.384M-4.13,2.384L4.13,-2.384"></path>
47+
</svg>E</span><span class="plot-swatch"><svg viewBox="-8 -8 16 16" stroke="#edc949" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
48+
<path d="M3.534,3.534L3.534,-3.534L-3.534,-3.534L-3.534,3.534Z"></path>
49+
</svg>F</span>
50+
</div>
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<div class="plot" style="
2+
--swatchWidth: 15px;
3+
--swatchHeight: 15px;
4+
">
5+
<style>
6+
.plot {
7+
font-family: system-ui, sans-serif;
8+
font-size: 10px;
9+
margin-bottom: 0.5em;
10+
margin-left: 0px;
11+
}
12+
13+
.plot-swatch>svg {
14+
width: var(--swatchWidth);
15+
height: var(--swatchHeight);
16+
margin-right: 0.5em;
17+
overflow: visible;
18+
fill: red;
19+
fill-opacity: 0.5;
20+
stroke: none;
21+
stroke-width: 1.5px;
22+
stroke-opacity: 1;
23+
}
24+
25+
.plot {
26+
display: flex;
27+
align-items: center;
28+
min-height: 33px;
29+
flex-wrap: wrap;
30+
}
31+
32+
.plot-swatch {
33+
display: inline-flex;
34+
align-items: center;
35+
margin-right: 1em;
36+
}
37+
</style><span class="plot-swatch"><svg viewBox="-8 -8 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
38+
<path d="M4.5,0A4.5,4.5,0,1,1,-4.5,0A4.5,4.5,0,1,1,4.5,0"></path>
39+
</svg>Dream</span><span class="plot-swatch"><svg viewBox="-8 -8 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
40+
<path d="M-5.35,-1.783L-1.783,-1.783L-1.783,-5.35L1.783,-5.35L1.783,-1.783L5.35,-1.783L5.35,1.783L1.783,1.783L1.783,5.35L-1.783,5.35L-1.783,1.783L-5.35,1.783Z"></path>
41+
</svg>Torgersen</span><span class="plot-swatch"><svg viewBox="-8 -8 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
42+
<path d="M0,-7.423L4.285,0L0,7.423L-4.285,0Z"></path>
43+
</svg>Biscoe</span>
44+
</div>
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<div class="plot" style="
2+
--swatchWidth: 15px;
3+
--swatchHeight: 15px;
4+
">
5+
<style>
6+
.plot {
7+
font-family: system-ui, sans-serif;
8+
font-size: 10px;
9+
margin-bottom: 0.5em;
10+
margin-left: 0px;
11+
}
12+
13+
.plot-swatch>svg {
14+
width: var(--swatchWidth);
15+
height: var(--swatchHeight);
16+
margin-right: 0.5em;
17+
overflow: visible;
18+
fill: none;
19+
fill-opacity: 1;
20+
stroke: red;
21+
stroke-width: 1.5px;
22+
stroke-opacity: 0.5;
23+
}
24+
25+
.plot {
26+
display: flex;
27+
align-items: center;
28+
min-height: 33px;
29+
flex-wrap: wrap;
30+
}
31+
32+
.plot-swatch {
33+
display: inline-flex;
34+
align-items: center;
35+
margin-right: 1em;
36+
}
37+
</style><span class="plot-swatch"><svg viewBox="-8 -8 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
38+
<path d="M4.5,0A4.5,4.5,0,1,1,-4.5,0A4.5,4.5,0,1,1,4.5,0"></path>
39+
</svg>Dream</span><span class="plot-swatch"><svg viewBox="-8 -8 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
40+
<path d="M-6.873,0L6.873,0M0,6.873L0,-6.873"></path>
41+
</svg>Torgersen</span><span class="plot-swatch"><svg viewBox="-8 -8 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
42+
<path d="M-4.87,-4.87L4.87,4.87M-4.87,4.87L4.87,-4.87"></path>
43+
</svg>Biscoe</span>
44+
</div>

0 commit comments

Comments
 (0)