Skip to content

Commit dee33b9

Browse files
committed
reserve space for title and color legend
1 parent b91f073 commit dee33b9

File tree

2 files changed

+70
-21
lines changed

2 files changed

+70
-21
lines changed

src/legend.js

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,59 @@ import {axisBottom, create, format, interpolate, interpolateRound, range, scaleB
22

33
export function Legend(
44
{color: colorScale},
5-
{color} = {}
5+
{color, title} = {}
66
) {
7+
78
return {
8-
...(color && color.legend && {color: new ColorLegend(colorScale, color)})
9+
...(color && color.legend && {color: new ColorLegend(colorScale, color.legend)}),
10+
...(title && {title: new TitleLegend(title)})
911
};
1012
}
1113

14+
export class TitleLegend {
15+
constructor(title) {
16+
this.title = typeof title === "string" ? { text: title } : title;
17+
if (this.title.fontSize === undefined) this.title.fontSize = 22;
18+
if (this.title.top === undefined) this.title.top = this.title.fontSize - 2;
19+
}
20+
render(
21+
index,
22+
scales,
23+
channels,
24+
{
25+
width: canvasWidth,
26+
height: canvasHeight
27+
}
28+
) {
29+
const {
30+
text,
31+
bottom,
32+
fontSize,
33+
top,
34+
right,
35+
left = 0
36+
} = this.title;
37+
const tx = right !== undefined ? canvasWidth - right : left;
38+
const ty = bottom !== undefined ? canvasHeight - bottom - fontSize / 3 : top;
39+
return create("svg:g")
40+
.attr("transform", `translate(${tx},${ty})`)
41+
.call(g => g.append("text")
42+
.text(text)
43+
.attr("fill", "currentColor")
44+
.attr("text-anchor", right !== undefined ? "end" : "start")
45+
.style("font-size", fontSize)
46+
)
47+
.node();
48+
}
49+
}
50+
1251
export class ColorLegend {
13-
constructor({name}, color) {
52+
constructor({name, scale}, legend) {
53+
this.color = scale,
1454
this.name = name || "color";
15-
this.color = color;
55+
this.legend = typeof legend === "object" ? legend : {};
56+
if (this.legend.tickSize === undefined) this.legend.tickSize = 6;
57+
if (this.legend.height === undefined) this.legend.height = 44 + this.legend.tickSize;
1658
}
1759
render(
1860
index,
@@ -24,22 +66,20 @@ export class ColorLegend {
2466
height: canvasHeight
2567
}
2668
) {
27-
const { color: {
28-
legend: {
29-
title,
30-
tickSize = 6,
31-
width = 320,
32-
height = 44 + tickSize,
33-
top = title === undefined ? -20 : -3,
34-
right = 0,
35-
bottom,
36-
left,
37-
ticks = width / 64,
38-
tickFormat,
39-
tickValues
40-
} = {}
69+
const { legend: {
70+
title,
71+
tickSize = 6,
72+
width = 320,
73+
height = 44 + tickSize,
74+
top = title === undefined ? -20 : -3,
75+
right = 0,
76+
bottom,
77+
left,
78+
ticks = width / 64,
79+
tickFormat,
80+
tickValues
4181
} = {} } = this;
42-
const tx = left !== undefined ? left : canvasWidth - width + right;
82+
const tx = left !== undefined ? left : canvasWidth - width - right;
4383
const ty = bottom !== undefined ? canvasHeight - bottom - height : top;
4484
return create("svg:g")
4585
.attr("transform", `translate(${tx},${ty})`)

src/plot.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export function plot(options = {}) {
7373
if (axes[y]) marks.unshift(axes[y]);
7474

7575
if (legend.color) marks.push(legend.color);
76+
if (legend.title) marks.push(legend.title);
7677

7778
const {width, height} = dimensions;
7879

@@ -107,7 +108,8 @@ function Dimensions(
107108
fy: {axis: fyAxis} = {}
108109
},
109110
{
110-
color
111+
color,
112+
title
111113
},
112114
{
113115
width = 640,
@@ -124,7 +126,14 @@ function Dimensions(
124126
marginLeft = Math.max((yAxis === "left" ? 40 : 0) + facetMarginLeft, xAxis || fxAxis ? 20 : 0)
125127
} = {}
126128
) {
127-
color; // TDB: reserve space for the color legend?
129+
const reserve = { top: [], bottom: [] };
130+
if (title && (title.title.bottom === undefined)) reserve.top.push(title.title.fontSize * 2);
131+
if (title && (title.title.bottom !== undefined)) reserve.bottom.push(title.title.fontSize * 1.6);
132+
if (color && (color.legend.bottom === undefined)) reserve.top.push(color.legend.height);
133+
if (color && (color.legend.bottom !== undefined)) reserve.bottom.push(color.legend.height);
134+
if (reserve.top.length) marginTop += Math.max(...reserve.top);
135+
if (reserve.bottom.length) marginBottom += Math.max(...reserve.bottom);
136+
128137
return {
129138
width,
130139
height,

0 commit comments

Comments
 (0)