From c4723ff246394f0783d2c8465c6ab199c99db099 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sat, 6 May 2023 15:45:21 -0700 Subject: [PATCH 01/56] tip mark --- src/index.d.ts | 1 + src/index.js | 1 + src/marks/text.js | 6 +- src/marks/tip.d.ts | 53 ++++++ src/marks/tip.js | 205 ++++++++++++++++++++ test/output/tipDot.svg | 418 +++++++++++++++++++++++++++++++++++++++++ test/plots/index.ts | 1 + test/plots/tip.ts | 24 +++ 8 files changed, 706 insertions(+), 3 deletions(-) create mode 100644 src/marks/tip.d.ts create mode 100644 src/marks/tip.js create mode 100644 test/output/tipDot.svg create mode 100644 test/plots/tip.ts diff --git a/src/index.d.ts b/src/index.d.ts index 87cb46de1b..36f4ae9059 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -31,6 +31,7 @@ export * from "./marks/rect.js"; export * from "./marks/rule.js"; export * from "./marks/text.js"; export * from "./marks/tick.js"; +export * from "./marks/tip.js"; export * from "./marks/tree.js"; export * from "./marks/vector.js"; export * from "./options.js"; diff --git a/src/index.js b/src/index.js index d0fbf51546..54997b562c 100644 --- a/src/index.js +++ b/src/index.js @@ -24,6 +24,7 @@ export {Rect, rect, rectX, rectY} from "./marks/rect.js"; export {RuleX, RuleY, ruleX, ruleY} from "./marks/rule.js"; export {Text, text, textX, textY} from "./marks/text.js"; export {TickX, TickY, tickX, tickY} from "./marks/tick.js"; +export {Tip, tip} from "./marks/tip.js"; export {tree, cluster} from "./marks/tree.js"; export {Vector, vector, vectorX, vectorY, spike} from "./marks/vector.js"; export {valueof, column, identity, indexOf} from "./options.js"; diff --git a/src/marks/text.js b/src/marks/text.js index bf3bf4ca54..087c91b052 100644 --- a/src/marks/text.js +++ b/src/marks/text.js @@ -177,7 +177,7 @@ export function textY(data, options = {}) { return new Text(data, maybeIntervalMidX({...remainingOptions, y})); } -function applyIndirectTextStyles(selection, mark, T) { +export function applyIndirectTextStyles(selection, mark, T) { applyAttr(selection, "text-anchor", mark.textAnchor); applyAttr(selection, "font-family", mark.fontFamily); applyAttr(selection, "font-size", mark.fontSize); @@ -187,7 +187,7 @@ function applyIndirectTextStyles(selection, mark, T) { } function inferFontVariant(T) { - return isNumeric(T) || isTemporal(T) ? "tabular-nums" : undefined; + return T && (isNumeric(T) || isTemporal(T)) ? "tabular-nums" : undefined; } // https://developer.mozilla.org/en-US/docs/Web/CSS/font-size @@ -444,7 +444,7 @@ function clipper({monospace, lineWidth, textOverflow}) { // given width, returns [-1, 0]. If the text needs cutting, the given inset // specifies how much space (in the same units as width and widthof) to reserve // for a possible ellipsis character. -function cut(text, width, widthof, inset) { +export function cut(text, width, widthof, inset) { const I = []; // indexes of read character boundaries let w = 0; // current line width for (let i = 0, j = 0, n = text.length; i < n; i = j) { diff --git a/src/marks/tip.d.ts b/src/marks/tip.d.ts new file mode 100644 index 0000000000..e1beae1496 --- /dev/null +++ b/src/marks/tip.d.ts @@ -0,0 +1,53 @@ +import type {ChannelValueSpec} from "../channel.js"; +import type {Data, FrameAnchor, MarkOptions, RenderableMark} from "../mark.js"; +import type {TextOptions} from "./text.js"; + +/** Options for styling text. TODO Move to TextOptions? */ +type TextStyles = Pick; // prettier-ignore + +/** Options for the tip mark. */ +export interface TipOptions extends MarkOptions, TextStyles { + /** + * The horizontal position channel specifying the tip’s anchor, typically + * bound to the *x* scale. + */ + x?: ChannelValueSpec; + + /** + * The vertical position channel specifying the tip’s anchor, typically + * bound to the *y* scale. + */ + y?: ChannelValueSpec; + + // TODO x1, y1, x2, y2 + + /** + * The frame anchor specifies defaults for **x** and **y** based on the plot’s + * frame; it may be one of the four sides (*top*, *right*, *bottom*, *left*), + * one of the four corners (*top-left*, *top-right*, *bottom-right*, + * *bottom-left*), or the *middle* of the frame. For example, for tips + * distributed horizontally at the top of the frame: + * + * ```js + * Plot.tip(data, {x: "date", frameAnchor: "top"}) + * ``` + */ + frameAnchor?: FrameAnchor; + + /** TODO */ + anchor?: "top-left" | "top-right" | "bottom-right" | "bottom-left"; +} + +/** + * Returns a new tip mark for the given *data* and *options*. + * + * If either **x** or **y** is not specified, the default is determined by the + * **frameAnchor** option. If none of **x**, **y**, and **frameAnchor** are + * specified, *data* is assumed to be an array of pairs [[*x₀*, *y₀*], [*x₁*, + * *y₁*], [*x₂*, *y₂*], …] such that **x** = [*x₀*, *x₁*, *x₂*, …] and **y** = + * [*y₀*, *y₁*, *y₂*, …]. + */ +export function tip(data?: Data, options?: TipOptions): Tip; + +/** The tip mark. */ +export class Tip extends RenderableMark {} diff --git a/src/marks/tip.js b/src/marks/tip.js new file mode 100644 index 0000000000..b2da5a09b0 --- /dev/null +++ b/src/marks/tip.js @@ -0,0 +1,205 @@ +import {select} from "d3"; +import {create} from "../context.js"; +import {formatDefault} from "../format.js"; +import {Mark} from "../mark.js"; +import {maybeFrameAnchor, maybeKeyword, maybeTuple, number, string} from "../options.js"; +import {applyChannelStyles, applyDirectStyles, applyIndirectStyles} from "../style.js"; +import {applyFrameAnchor, applyTransform} from "../style.js"; +import {template} from "../template.js"; +import {applyIndirectTextStyles, cut, defaultWidth, monospaceWidth} from "./text.js"; + +const defaults = { + ariaLabel: "tip", + fill: "currentColor", + stroke: "none" +}; + +export class Tip extends Mark { + constructor(data, options = {}) { + const { + x, + y, + x1, + x2, + y1, + y2, + anchor, + monospace, + fontFamily = monospace ? "ui-monospace, monospace" : undefined, + fontSize, + fontStyle, + fontVariant, + fontWeight, + lineHeight = 1, + lineWidth = 20, + frameAnchor + } = options; + super( + data, + { + x: {value: x1 != null && x2 != null ? null : x, scale: "x", optional: true}, // ignore midpoint + y: {value: y1 != null && y2 != null ? null : y, scale: "y", optional: true}, // ignore midpoint + x1: {value: x1, scale: "x", optional: x2 == null}, + y1: {value: y1, scale: "y", optional: y2 == null}, + x2: {value: x2, scale: "x", optional: x1 == null}, + y2: {value: y2, scale: "y", optional: y1 == null} + }, + options, + defaults + ); + this.anchor = maybeAnchor(anchor); + this.frameAnchor = maybeFrameAnchor(frameAnchor); + this.textAnchor = "start"; // TODO option + this.lineHeight = +lineHeight; + this.lineWidth = +lineWidth; + this.monospace = !!monospace; + this.fontFamily = string(fontFamily); + this.fontSize = number(fontSize); + this.fontStyle = string(fontStyle); + this.fontVariant = string(fontVariant); + this.fontWeight = string(fontWeight); + } + render(index, scales, channels, dimensions, context) { + const {x, y} = scales; + const {x: X, y: Y} = channels; // TODO X1, Y1, X2, Y2 + const [cx, cy] = applyFrameAnchor(this, dimensions); + const {anchor, monospace, lineHeight, lineWidth} = this; + const widthof = monospace ? monospaceWidth : defaultWidth; + const ellipsis = "…"; + const ee = widthof(ellipsis); + const r = 8; // “padding” + const m = 12; // “margin” (flag size) + // const {fx, fy} = scales; + // const formatFx = fx && inferTickFormat(fx); + // const formatFy = fy && inferTickFormat(fy); + // const {fx: fxv, fy: fyv} = this; + const foreground = "black"; // TODO fill option? + const background = "white"; // TODO stroke option? + const g = create("svg:g", context) + .call(applyIndirectStyles, this, dimensions, context) + .call(applyIndirectTextStyles, this) + .call(applyTransform, this, {x: X && x, y: Y && y}) + .call((g) => + g + .selectAll() + .data(index) + .enter() + .append("g") + .attr("transform", template`translate(${X ? (i) => X[i] : cx},${Y ? (i) => Y[i] : cy})`) + .call(applyDirectStyles, this) + .call(applyChannelStyles, this, channels) + .call((g) => + g + .append("path") + .attr("stroke", foreground) + .attr("fill", background) + .attr("filter", "drop-shadow(0 3px 4px rgba(0,0,0,0.2))") + ) + .call((g) => + g.append("text").each(function (i) { + const that = select(this); + // TODO fx, fy + for (const key in channels.channels) { + const channel = getSource(channels.channels, key); + if (!channel) continue; // e.g., dodgeY’s y + let name = scales[channel.scale]?.label ?? key; + let value = ` ${formatDefault(channel.value[i])}\u200b`; // zwsp for double-click + let title; + let w = lineWidth * 100; + const [j] = cut(name, w, widthof, ee); + if (j >= 0) { + // name is truncated + name = name.slice(0, j).trimEnd() + ellipsis; + value = ""; + title = value.trim(); + } else { + const [k] = cut(value, w - widthof(name), widthof, ee); + if (k >= 0) { + // value is truncated + value = value.slice(0, k).trimEnd() + ellipsis; + title = value.trim(); + } + } + const line = that.append("tspan").attr("x", 0).attr("dy", `${lineHeight}em`); + line.append("tspan").attr("font-weight", "bold").text(name); + if (value) line.append(() => context.document.createTextNode(value)); + if (title) line.append("title").text(title); + } + }) + ) + ); + + // Wait until the Plot is inserted into the page, so that we can use getBBox + // to compute the text dimensions. Perhaps this could be done synchronously; + // getting the dimensions of the SVG is easy, and although accurate text + // metrics are hard, we could use approximate heuristics. + if (typeof requestAnimationFrame !== "undefined") { + requestAnimationFrame(() => { + const {width, height} = g.node().ownerSVGElement.getBBox(); + g.selectChildren().each(function (i) { + const x = X ? X[i] : cx; + const y = Y ? Y[i] : cy; + const {width: w, height: h} = this.getBBox(); + let c; + if (anchor === undefined) { + const fitLeft = x + w + r * 2 < width; + const fitRight = x - w - r * 2 > 0; + const fitTop = y + h + m + r * 2 + 7 < height; + const fitBottom = y - h - m - r * 2 > 0; + const cx = (/-left$/.test(c) ? fitLeft || !fitRight : fitLeft && !fitRight) ? "left" : "right"; + const cy = (/^top-/.test(c) ? fitTop || !fitBottom : fitTop && !fitBottom) ? "top" : "bottom"; + c = `${cy}-${cx}`; + } + const path = this.firstChild; + const text = this.lastChild; + path.setAttribute("d", getPath(c, m, r, w, h)); + text.setAttribute("y", `${+getLineOffset(c, text.childNodes.length, lineHeight).toFixed(6)}em`); + text.setAttribute("transform", getTextTransform(c, m, r, w, h)); + }); + }); + } + + return g.node(); + } +} + +export function tip(data, {x, y, ...options} = {}) { + if (options.frameAnchor === undefined) [x, y] = maybeTuple(x, y); + return new Tip(data, {...options, x, y}); +} + +function maybeAnchor(value) { + return maybeKeyword(value, "anchor", ["top-left", "top-right", "bottom-right", "bottom-left"]); +} + +function getSource(channels, key) { + let channel = channels[key]; + if (!channel) return; + while (channel.source) channel = channel.source; + return channel.source === null ? null : channel; +} + +function getLineOffset(anchor, length, lineHeight) { + return /^top-/.test(anchor) ? 0.94 - lineHeight : -0.29 - length * lineHeight; +} + +function getTextTransform(anchor, m, r, width) { + const x = /-left$/.test(anchor) ? r : -width - r; + const y = /^top-/.test(anchor) ? m + r : -m - r; + return `translate(${x},${y})`; +} + +function getPath(anchor, m, r, width, height) { + const w = width + r * 2; + const h = height + r * 2; + switch (anchor) { + case "top-left": + return `M0,0l${m},${m}h${w - m}v${h}h${-w}z`; + case "top-right": + return `M0,0l${-m},${m}h${m - w}v${h}h${w}z`; + case "bottom-left": + return `M0,0l${m},${-m}h${w - m}v${-h}h${-w}z`; + case "bottom-right": + return `M0,0l${-m},${-m}h${m - w}v${-h}h${w}z`; + } +} diff --git a/test/output/tipDot.svg b/test/output/tipDot.svg new file mode 100644 index 0000000000..9cc59b2be4 --- /dev/null +++ b/test/output/tipDot.svg @@ -0,0 +1,418 @@ + + + + + + + + + + + + + + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + + + ↑ culmen_depth_mm + + + + + + + + + + 35 + 40 + 45 + 50 + 55 + + + culmen_length_mm → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + culmen_length_mm 32.1​culmen_depth_mm 15.5​ + + + + culmen_length_mm 59.6​culmen_depth_mm 17​ + + + + culmen_length_mm 42.9​culmen_depth_mm 13.1​ + + + + culmen_length_mm 46​culmen_depth_mm 21.5​ + + + \ No newline at end of file diff --git a/test/plots/index.ts b/test/plots/index.ts index ee9e6ab576..63442ad28a 100644 --- a/test/plots/index.ts +++ b/test/plots/index.ts @@ -271,6 +271,7 @@ export * from "./stargazers-hourly.js"; export * from "./stargazers.js"; export * from "./stocks-index.js"; export * from "./text-overflow.js"; +export * from "./tip.js"; export * from "./this-is-just-to-say.js"; export * from "./traffic-horizon.js"; export * from "./travelers-covid-drop.js"; diff --git a/test/plots/tip.ts b/test/plots/tip.ts new file mode 100644 index 0000000000..7f40f0f6fe --- /dev/null +++ b/test/plots/tip.ts @@ -0,0 +1,24 @@ +import * as Plot from "@observablehq/plot"; +import * as d3 from "d3"; + +export async function tipDot() { + const penguins = await d3.csv("data/penguins.csv", d3.autoType); + return Plot.plot({ + style: "overflow: visible;", + marks: [ + Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"}), + Plot.tip( + penguins, + Plot.select( + (I) => [ + d3.least(I, (i) => penguins[i].culmen_length_mm), + d3.greatest(I, (i) => penguins[i].culmen_length_mm), + d3.least(I, (i) => penguins[i].culmen_depth_mm), + d3.greatest(I, (i) => penguins[i].culmen_depth_mm) + ], + {x: "culmen_length_mm", y: "culmen_depth_mm"} + ) + ) + ] + }); +} From c4e627cbe4e5268493d08ff30d0bf088d66709a9 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sat, 6 May 2023 19:18:59 -0700 Subject: [PATCH 02/56] render transform! --- src/mark.d.ts | 3 +++ src/mark.js | 8 ++++++- src/marks/tip.js | 51 +++++++++++++++++++++--------------------- src/plot.js | 3 +++ test/output/tipDot.svg | 14 +----------- test/plots/tip.ts | 34 ++++++++++++++++------------ 6 files changed, 60 insertions(+), 53 deletions(-) diff --git a/src/mark.d.ts b/src/mark.d.ts index 64f4f496c9..6c497d3acf 100644 --- a/src/mark.d.ts +++ b/src/mark.d.ts @@ -126,6 +126,9 @@ export interface MarkOptions { /** A custom mark initializer. */ initializer?: InitializerFunction; + /** A custom render transform. */ + render?: RenderFunction; + /** * The horizontal facet position channel, for mark-level faceting, bound to * the *fx* scale. diff --git a/src/mark.js b/src/mark.js index d1cc8784f4..81f7a88054 100644 --- a/src/mark.js +++ b/src/mark.js @@ -22,7 +22,8 @@ export class Mark { marginBottom = margin, marginLeft = margin, clip, - channels: extraChannels + channels: extraChannels, + render } = options; this.data = data; this.sort = isDomainSort(sort) ? sort : null; @@ -78,6 +79,11 @@ export class Mark { throw new Error(`super-faceting cannot use x or y`); } } + if (render != null) { + if (typeof render !== "function") throw new TypeError(`invalid render transform: ${render}`); + this._render = this.render; + this.render = render; + } } initialize(facets, facetChannels, plotOptions) { let data = arrayify(this.data); diff --git a/src/marks/tip.js b/src/marks/tip.js index b2da5a09b0..cb1dcc23fe 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -129,35 +129,36 @@ export class Tip extends Mark { ) ); + function postrender() { + const {width, height} = context.ownerSVGElement.getBBox(); + g.selectChildren().each(function (i) { + const x = X ? X[i] : cx; + const y = Y ? Y[i] : cy; + const {width: w, height: h} = this.getBBox(); + let c; + if (anchor === undefined) { + const fitLeft = x + w + r * 2 < width; + const fitRight = x - w - r * 2 > 0; + const fitTop = y + h + m + r * 2 + 7 < height; + const fitBottom = y - h - m - r * 2 > 0; + const cx = (/-left$/.test(c) ? fitLeft || !fitRight : fitLeft && !fitRight) ? "left" : "right"; + const cy = (/^top-/.test(c) ? fitTop || !fitBottom : fitTop && !fitBottom) ? "top" : "bottom"; + c = `${cy}-${cx}`; + } + const path = this.firstChild; + const text = this.lastChild; + path.setAttribute("d", getPath(c, m, r, w, h)); + text.setAttribute("y", `${+getLineOffset(c, text.childNodes.length, lineHeight).toFixed(6)}em`); + text.setAttribute("transform", getTextTransform(c, m, r, w, h)); + }); + } + // Wait until the Plot is inserted into the page, so that we can use getBBox // to compute the text dimensions. Perhaps this could be done synchronously; // getting the dimensions of the SVG is easy, and although accurate text // metrics are hard, we could use approximate heuristics. - if (typeof requestAnimationFrame !== "undefined") { - requestAnimationFrame(() => { - const {width, height} = g.node().ownerSVGElement.getBBox(); - g.selectChildren().each(function (i) { - const x = X ? X[i] : cx; - const y = Y ? Y[i] : cy; - const {width: w, height: h} = this.getBBox(); - let c; - if (anchor === undefined) { - const fitLeft = x + w + r * 2 < width; - const fitRight = x - w - r * 2 > 0; - const fitTop = y + h + m + r * 2 + 7 < height; - const fitBottom = y - h - m - r * 2 > 0; - const cx = (/-left$/.test(c) ? fitLeft || !fitRight : fitLeft && !fitRight) ? "left" : "right"; - const cy = (/^top-/.test(c) ? fitTop || !fitBottom : fitTop && !fitBottom) ? "top" : "bottom"; - c = `${cy}-${cx}`; - } - const path = this.firstChild; - const text = this.lastChild; - path.setAttribute("d", getPath(c, m, r, w, h)); - text.setAttribute("y", `${+getLineOffset(c, text.childNodes.length, lineHeight).toFixed(6)}em`); - text.setAttribute("transform", getTextTransform(c, m, r, w, h)); - }); - }); - } + if (context.ownerSVGElement.isConnected) Promise.resolve().then(postrender); + else if (typeof requestAnimationFrame !== "undefined") requestAnimationFrame(postrender); return g.node(); } diff --git a/src/plot.js b/src/plot.js index 801f797c4a..edd80bc2a1 100644 --- a/src/plot.js +++ b/src/plot.js @@ -234,6 +234,9 @@ export function plot(options = {}) { .call(applyInlineStyles, style) .node(); + // TODO Cleaner. + context.ownerSVGElement = svg; + // Render facets. if (facets !== undefined) { const facetDomains = {x: fx?.domain(), y: fy?.domain()}; diff --git a/test/output/tipDot.svg b/test/output/tipDot.svg index 9cc59b2be4..2d705b8ce9 100644 --- a/test/output/tipDot.svg +++ b/test/output/tipDot.svg @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 7f40f0f6fe..f2f1fec2af 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -4,21 +4,27 @@ import * as d3 from "d3"; export async function tipDot() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); return Plot.plot({ - style: "overflow: visible;", marks: [ - Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"}), - Plot.tip( - penguins, - Plot.select( - (I) => [ - d3.least(I, (i) => penguins[i].culmen_length_mm), - d3.greatest(I, (i) => penguins[i].culmen_length_mm), - d3.least(I, (i) => penguins[i].culmen_depth_mm), - d3.greatest(I, (i) => penguins[i].culmen_depth_mm) - ], - {x: "culmen_length_mm", y: "culmen_depth_mm"} - ) - ) + Plot.dot(penguins, { + x: "culmen_length_mm", + y: "culmen_depth_mm" + }), + Plot.tip(penguins, { + x: "culmen_length_mm", + y: "culmen_depth_mm", + render(index, ...args) { + const mark = this; + let i = 0; + index = d3.sort(index, (i) => penguins[i].culmen_length_mm); + let g = mark._render([index[i]], ...args); + setTimeout(function tick() { + if (!g.isConnected) return; + g.replaceWith((g = mark._render([index[(i = (i + 1) % index.length)]], ...args))); + setTimeout(tick, 100); + }, 100); + return g; + } + }) ] }); } From 5a5093387dd25b8d166d07b52073b0d6e51770e1 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sat, 6 May 2023 21:00:17 -0700 Subject: [PATCH 03/56] pointer interaction --- src/context.d.ts | 3 ++ src/context.js | 4 +- src/index.d.ts | 1 + src/index.js | 1 + src/interactions/pointer.d.ts | 4 ++ src/interactions/pointer.js | 75 +++++++++++++++++++++++++++++++++++ src/plot.js | 11 ++--- src/transforms/basic.d.ts | 6 ++- test/marks/rule-test.js | 1 + test/output/tipDot.svg | 8 +--- test/plots/tip.ts | 23 ++--------- 11 files changed, 102 insertions(+), 35 deletions(-) create mode 100644 src/interactions/pointer.d.ts create mode 100644 src/interactions/pointer.js diff --git a/src/context.d.ts b/src/context.d.ts index 3e23ee0dc0..84b8d13646 100644 --- a/src/context.d.ts +++ b/src/context.d.ts @@ -8,6 +8,9 @@ export interface Context { */ document: Document; + /** The current owner SVG element. */ + ownerSVGElement: SVGSVGElement; + /** The Plot’s (typically generated) class name, for custom styles. */ className: string; diff --git a/src/context.js b/src/context.js index 56d83886bf..5a270f3f03 100644 --- a/src/context.js +++ b/src/context.js @@ -3,7 +3,9 @@ import {createProjection} from "./projection.js"; export function createContext(options = {}, dimensions, className) { const {document = typeof window !== "undefined" ? window.document : undefined} = options; - return {document, className, projection: createProjection(options, dimensions)}; + const ownerSVGElement = creator("svg").call(document.documentElement); + const projection = createProjection(options, dimensions); + return {document, ownerSVGElement, className, projection}; } export function create(name, {document}) { diff --git a/src/index.d.ts b/src/index.d.ts index 36f4ae9059..7832d5c1ef 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -52,3 +52,4 @@ export * from "./transforms/select.js"; export * from "./transforms/stack.js"; export * from "./transforms/tree.js"; export * from "./transforms/window.js"; +export * from "./interactions/pointer.js"; diff --git a/src/index.js b/src/index.js index 54997b562c..ca778ac694 100644 --- a/src/index.js +++ b/src/index.js @@ -40,6 +40,7 @@ export {window, windowX, windowY} from "./transforms/window.js"; export {select, selectFirst, selectLast, selectMaxX, selectMaxY, selectMinX, selectMinY} from "./transforms/select.js"; export {stackX, stackX1, stackX2, stackY, stackY1, stackY2} from "./transforms/stack.js"; export {treeNode, treeLink} from "./transforms/tree.js"; +export {pointer} from "./interactions/pointer.js"; export {formatIsoDate, formatWeekday, formatMonth} from "./format.js"; export {scale} from "./scales.js"; export {legend} from "./legends.js"; diff --git a/src/interactions/pointer.d.ts b/src/interactions/pointer.d.ts new file mode 100644 index 0000000000..3ce344fdcd --- /dev/null +++ b/src/interactions/pointer.d.ts @@ -0,0 +1,4 @@ +import type {Rendered} from "../transforms/basic.js"; + +/** TODO */ +export function pointer(options: T): Rendered; diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js new file mode 100644 index 0000000000..d97664daba --- /dev/null +++ b/src/interactions/pointer.js @@ -0,0 +1,75 @@ +import {pointer as pointof} from "d3"; + +export function pointer(options) { + return { + ...options, + render(index, scales, values, dimensions, context) { + const mark = this; + const svg = context.ownerSVGElement; + const {x: X, y: Y, x1: X1, y1: Y1, x2: X2, y2: Y2} = values; + // let sticky = false; // TODO + const maxRadius = 40; // TODO option + const [cx, cy] = [0, 0]; // TODO applyFrameAnchor + const [kx, ky] = [1, 1]; // TODO axis option + let i; // currently focused index + let g; // currently rendered mark + + function render(ii) { + if (i === ii) return; // abort if the tooltip hasn’t moved + i = ii; + const r = mark._render(i == null ? [] : [i], scales, values, dimensions, context); + if (g) g.replaceWith(r); + return (g = r); + } + + function pointermove(event) { + // if (sticky || (event.pointerType === "mouse" && event.buttons === 1)) return; // dragging + const rect = svg.getBoundingClientRect(); + let ii = null; + if ( + // Check if the pointer is near before scanning. + event.clientX + maxRadius > rect.left && + event.clientX - maxRadius < rect.right && + event.clientY + maxRadius > rect.top && + event.clientY - maxRadius < rect.bottom + ) { + const [xp, yp] = pointof(event, g.parentNode); + let ri = maxRadius * maxRadius; + for (const j of index) { + const xj = X2 ? (X1[j] + X2[j]) / 2 : X ? X[j] : cx; // + oxj; + const yj = Y2 ? (Y1[j] + Y2[j]) / 2 : Y ? Y[j] : cy; // + oyj; + const dx = kx * (xj - xp); + const dy = ky * (yj - yp); + const rj = dx * dx + dy * dy; + if (rj <= ri) (ii = j), (ri = rj); + } + } + render(ii); + } + + // function pointerdown(event) { + // if (event.pointerType !== "mouse") return; + // if (sticky && tip.node().contains(event.target)) return; // stay sticky + // if (sticky) (sticky = false), tip.attr("display", "none"); + // else if (i !== undefined) sticky = true; + // } + + function pointerleave(event) { + if (event.pointerType !== "mouse") return; + // if (!sticky) tip.attr("display", "none"); + render(null); + } + + // We listen to the svg element; listening to the window instead would let + // us receive pointer events from farther away, but would also make it + // hard to know when to remove the listeners. (Using a mutation observer + // to watch the entire document is likely too expensive.) + svg.addEventListener("pointerenter", pointermove); + svg.addEventListener("pointermove", pointermove); + // svg.addEventListener("pointerdown", pointerdown); + svg.addEventListener("pointerleave", pointerleave); + + return render(null); + } + }; +} diff --git a/src/plot.js b/src/plot.js index edd80bc2a1..ab25d43bf6 100644 --- a/src/plot.js +++ b/src/plot.js @@ -1,6 +1,6 @@ import {select} from "d3"; import {createChannel, inferChannelScale} from "./channel.js"; -import {createContext, create} from "./context.js"; +import {createContext} from "./context.js"; import {createDimensions} from "./dimensions.js"; import {createFacets, recreateFacets, facetExclude, facetGroups, facetTranslate, facetFilter} from "./facet.js"; import {createLegends, exposeLegends} from "./legends.js"; @@ -142,6 +142,7 @@ export function plot(options = {}) { const subdimensions = fx || fy ? innerDimensions(scaleDescriptors, dimensions) : dimensions; const superdimensions = fx || fy ? actualDimensions(scales, dimensions) : dimensions; const context = createContext(options, subdimensions, className); + const svg = context.ownerSVGElement; // Reinitialize; for deriving channels dependent on other channels. const newByScale = new Set(); @@ -204,7 +205,7 @@ export function plot(options = {}) { const {width, height} = dimensions; - const svg = create("svg", context) + select(svg) .attr("class", className) .attr("fill", "currentColor") .attr("font-family", "system-ui, sans-serif") @@ -231,11 +232,7 @@ export function plot(options = {}) { }` ) ) - .call(applyInlineStyles, style) - .node(); - - // TODO Cleaner. - context.ownerSVGElement = svg; + .call(applyInlineStyles, style); // Render facets. if (facets !== undefined) { diff --git a/src/transforms/basic.d.ts b/src/transforms/basic.d.ts index 3aee313b62..cfc7c988b2 100644 --- a/src/transforms/basic.d.ts +++ b/src/transforms/basic.d.ts @@ -1,7 +1,8 @@ -import type {PlotOptions} from "../plot.js"; import type {ChannelName, Channels, ChannelValue} from "../channel.js"; import type {Context} from "../context.js"; import type {Dimensions} from "../dimensions.js"; +import type {RenderFunction} from "../mark.js"; +import type {PlotOptions} from "../plot.js"; import type {ScaleFunctions} from "../scales.js"; /** @@ -67,6 +68,9 @@ export type Transformed = T & {transform: TransformFunction}; /** Mark options with a mark initializer. */ export type Initialized = T & {initializer: InitializerFunction}; +/** Mark options with a mark render transform. */ +export type Rendered = T & {render: RenderFunction}; + /** * Given an *options* object that may specify some basic transforms (**filter**, * **sort**, or **reverse**) or a custom **transform**, composes those diff --git a/test/marks/rule-test.js b/test/marks/rule-test.js index 8973398725..f6f91e3b3d 100644 --- a/test/marks/rule-test.js +++ b/test/marks/rule-test.js @@ -1,5 +1,6 @@ import * as Plot from "@observablehq/plot"; import assert from "assert"; +import it from "../jsdom.js"; it("ruleX() has the expected defaults", () => { const rule = Plot.ruleX(); diff --git a/test/output/tipDot.svg b/test/output/tipDot.svg index 2d705b8ce9..f40fce4c0c 100644 --- a/test/output/tipDot.svg +++ b/test/output/tipDot.svg @@ -397,10 +397,6 @@ - - - - culmen_length_mm 32.1​culmen_depth_mm 15.5​ - - + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index f2f1fec2af..0ca5d1f0a6 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -5,26 +5,9 @@ export async function tipDot() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); return Plot.plot({ marks: [ - Plot.dot(penguins, { - x: "culmen_length_mm", - y: "culmen_depth_mm" - }), - Plot.tip(penguins, { - x: "culmen_length_mm", - y: "culmen_depth_mm", - render(index, ...args) { - const mark = this; - let i = 0; - index = d3.sort(index, (i) => penguins[i].culmen_length_mm); - let g = mark._render([index[i]], ...args); - setTimeout(function tick() { - if (!g.isConnected) return; - g.replaceWith((g = mark._render([index[(i = (i + 1) % index.length)]], ...args))); - setTimeout(tick, 100); - }, 100); - return g; - } - }) + Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"}), + Plot.dot(penguins, Plot.pointer({x: "culmen_length_mm", y: "culmen_depth_mm", r: 4, stroke: "red"})), + Plot.tip(penguins, Plot.pointer({x: "culmen_length_mm", y: "culmen_depth_mm"})) ] }); } From 56a23ef815549a285d98aa654ed788350a2f5012 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sat, 6 May 2023 21:10:46 -0700 Subject: [PATCH 04/56] port mbostock/tooltip fixes --- src/channel.js | 2 +- src/marks/axis.js | 2 ++ src/marks/dot.js | 2 +- src/plot.js | 28 +++++++++---------- src/scales.js | 2 -- src/transforms/bin.d.ts | 5 +++- src/transforms/dodge.js | 11 ++++---- src/transforms/group.d.ts | 5 +++- src/transforms/stack.js | 10 +++++-- test/output/anscombeQuartet.svg | 18 ++++++------ test/output/athletesBoxingHeight.svg | 12 ++++---- test/output/athletesSampleFacet.svg | 12 ++++---- test/output/athletesSortFacet.svg | 8 +++--- test/output/athletesSportWeight.svg | 12 ++++---- test/output/autoDotFacet.svg | 18 ++++++------ test/output/autoDotFacet2.svg | 24 ++++++++-------- test/output/autoLineFacet.svg | 12 ++++---- test/output/ballotStatusRace.svg | 6 ++-- test/output/beckerBarley.svg | 18 ++++++------ test/output/boxplotFacetInterval.svg | 12 ++++---- test/output/boxplotFacetNegativeInterval.svg | 12 ++++---- test/output/emptyFacet.svg | 18 ++++++------ test/output/footballCoverage.svg | 6 ++-- test/output/frameFacet.svg | 12 ++++---- test/output/hexbinR.html | 18 ++++++------ test/output/hexbinText.svg | 18 ++++++------ test/output/industryUnemploymentTrack.svg | 6 ++-- test/output/internFacetDate.svg | 18 ++++++------ test/output/internFacetNaN.svg | 18 ++++++------ test/output/mobyDickFaceted.svg | 6 ++-- test/output/moviesRatingByGenre.svg | 6 ++-- test/output/penguinCulmen.svg | 24 ++++++++-------- test/output/penguinCulmenArray.svg | 12 ++++---- test/output/penguinCulmenMarkFacet.svg | 24 ++++++++-------- test/output/penguinDensityFill.html | 18 ++++++------ test/output/penguinDensityZ.html | 18 ++++++------ test/output/penguinDodgeHexbin.svg | 6 ++-- test/output/penguinFacetAnnotated.svg | 18 ++++++------ test/output/penguinFacetAnnotatedX.svg | 18 ++++++------ test/output/penguinFacetDodge.svg | 6 ++-- test/output/penguinFacetDodgeIdentity.svg | 6 ++-- test/output/penguinFacetDodgeIsland.html | 6 ++-- test/output/penguinMassSex.svg | 18 ++++++------ test/output/penguinMassSexSpecies.svg | 24 ++++++++-------- test/output/penguinSexMassCulmenSpecies.svg | 18 ++++++------ test/output/penguinSpeciesIslandRelative.svg | 12 ++++---- test/output/penguinSpeciesIslandSex.svg | 18 ++++++------ test/output/reducerScaleOverrideFunction.svg | 18 ++++++------ .../reducerScaleOverrideImplementation.svg | 18 ++++++------ test/output/reducerScaleOverrideName.svg | 18 ++++++------ test/output/usPopulationStateAgeGrouped.svg | 6 ++-- 51 files changed, 338 insertions(+), 325 deletions(-) diff --git a/src/channel.js b/src/channel.js index bb67310dd7..2f6ab38509 100644 --- a/src/channel.js +++ b/src/channel.js @@ -5,8 +5,8 @@ import {registry} from "./scales/index.js"; import {isSymbol, maybeSymbol} from "./symbol.js"; import {maybeReduce} from "./transforms/group.js"; -// TODO Type coercion? export function createChannel(data, {scale, type, value, filter, hint}, name) { + if (hint === undefined && typeof value?.transform === "function") hint = value.hint; return inferChannelScale(name, { scale, type, diff --git a/src/marks/axis.js b/src/marks/axis.js index e9f7402445..bfb17ce2d4 100644 --- a/src/marks/axis.js +++ b/src/marks/axis.js @@ -635,6 +635,8 @@ function inferScaleOrder(scale) { // inferred from an associated channel, adds an orientation-appropriate arrow. function inferAxisLabel(key, scale, labelAnchor) { const label = scale.label; + // Ignore the implicit label for temporal scales if it’s simply “date”. + if (label?.inferred && isTemporalScale(scale) && /^(date|time|year)$/i.test(label)) return; if (scale.bandwidth || !label?.inferred) return label; const order = inferScaleOrder(scale); return order diff --git a/src/marks/dot.js b/src/marks/dot.js index f9370a20fa..435ba798ef 100644 --- a/src/marks/dot.js +++ b/src/marks/dot.js @@ -69,7 +69,7 @@ export class Dot extends Mark { const {x: X, y: Y, r: R, rotate: A, symbol: S} = channels; const {r, rotate, symbol} = this; const [cx, cy] = applyFrameAnchor(this, dimensions); - const circle = this.symbol === symbolCircle; + const circle = symbol === symbolCircle; const size = R ? undefined : r * r * Math.PI; if (negative(r)) index = []; return create("svg:g", context) diff --git a/src/plot.js b/src/plot.js index ab25d43bf6..168c141e81 100644 --- a/src/plot.js +++ b/src/plot.js @@ -234,6 +234,20 @@ export function plot(options = {}) { ) .call(applyInlineStyles, style); + // Render non-faceted marks. + for (const mark of marks) { + if (facets !== undefined && mark.facet !== "super") continue; + const {channels, values, facets: indexes} = stateByMark.get(mark); + let index = null; + if (indexes) { + index = indexes[0]; + index = mark.filter(index, channels, values); + if (index.length === 0) continue; + } + const node = mark.render(index, scales, values, superdimensions, context); + if (node != null) svg.appendChild(node); + } + // Render facets. if (facets !== undefined) { const facetDomains = {x: fx?.domain(), y: fy?.domain()}; @@ -272,20 +286,6 @@ export function plot(options = {}) { }); } - // Render non-faceted marks. - for (const mark of marks) { - if (facets !== undefined && mark.facet !== "super") continue; - const {channels, values, facets: indexes} = stateByMark.get(mark); - let index = null; - if (indexes) { - index = indexes[0]; - index = mark.filter(index, channels, values); - if (index.length === 0) continue; - } - const node = mark.render(index, scales, values, superdimensions, context); - if (node != null) svg.appendChild(node); - } - // Wrap the plot in a figure with a caption, if desired. let figure = svg; const legends = createLegends(scaleDescriptors, context, options); diff --git a/src/scales.js b/src/scales.js index 1e0138380c..0e0de399fa 100644 --- a/src/scales.js +++ b/src/scales.js @@ -136,8 +136,6 @@ function inferScaleLabel(channels = [], scale) { else if (label !== l) return; } if (label === undefined) return; - // Ignore the implicit label for temporal scales if it’s simply “date”. - if (isTemporalScale(scale) && /^(date|time|year)$/i.test(label)) return; if (!isOrdinalScale(scale) && scale.percent) label = `${label} (%)`; return {inferred: true, toString: () => label}; } diff --git a/src/transforms/bin.d.ts b/src/transforms/bin.d.ts index 2a4a182dcf..6f5e5552cc 100644 --- a/src/transforms/bin.d.ts +++ b/src/transforms/bin.d.ts @@ -1,4 +1,4 @@ -import type {ChannelReducers, ChannelValueBinSpec} from "../channel.js"; +import type {ChannelReducers, ChannelValue, ChannelValueBinSpec} from "../channel.js"; import type {RangeInterval} from "../interval.js"; import type {Reducer} from "../reducer.js"; import type {Transformed} from "./basic.js"; @@ -102,6 +102,9 @@ export interface BinOptions { * ``` */ interval?: RangeInterval; + + /** For subdividing bins. */ + z?: ChannelValue; } /** diff --git a/src/transforms/dodge.js b/src/transforms/dodge.js index 06020c3de6..3f9b6a267a 100644 --- a/src/transforms/dodge.js +++ b/src/transforms/dodge.js @@ -61,8 +61,9 @@ function mergeOptions(options) { function dodge(y, x, anchor, padding, r, options) { if (r != null && typeof r !== "number") { - const {channels, sort, reverse} = options; - options = {...options, channels: {r: {value: r, scale: "r"}, ...maybeNamed(channels)}}; + let {channels, sort, reverse} = options; + channels = maybeNamed(channels); + if (channels?.r === undefined) options = {...options, channels: {...channels, r: {value: r, scale: "r"}}}; if (sort === undefined && reverse === undefined) options.sort = {channel: "r", order: "descending"}; } return initializer(options, function (data, facets, channels, scales, dimensions, context) { @@ -127,9 +128,9 @@ function dodge(y, x, anchor, padding, r, options) { data, facets, channels: { - [x]: {value: X}, - [y]: {value: Y}, - ...(R && {r: {value: R}}) + [y]: {value: Y, source: null}, // don’t show in tooltip + [x]: {value: X, source: channels[x]}, + ...(R && {r: {value: R, source: channels.r}}) } }; }); diff --git a/src/transforms/group.d.ts b/src/transforms/group.d.ts index a48caecc4e..24b422aa40 100644 --- a/src/transforms/group.d.ts +++ b/src/transforms/group.d.ts @@ -1,4 +1,4 @@ -import type {ChannelReducers} from "../channel.js"; +import type {ChannelReducers, ChannelValue} from "../channel.js"; import type {Reducer} from "../reducer.js"; import type {Transformed} from "./basic.js"; @@ -33,6 +33,9 @@ export interface GroupOutputOptions { /** If true, reverse the order of generated groups; defaults to false. */ reverse?: boolean; + + /** For subdividing groups. */ + z?: ChannelValue; } /** Output channels (and options) for the group transform. */ diff --git a/src/transforms/stack.js b/src/transforms/stack.js index acb9ded1d6..9cab1c694f 100644 --- a/src/transforms/stack.js +++ b/src/transforms/stack.js @@ -66,11 +66,17 @@ function mergeOptions(options) { return [{offset, order, reverse}, rest]; } +// This is a hint to the tooltip mark that the y1 and y2 channels (for stackY, +// or conversely x1 and x2 for stackX) represent a stacked length, and that the +// tooltip should therefore show y2-y1 instead of an extent. +const lengthy = {length: true}; + function stack(x, y = one, kx, ky, {offset, order, reverse}, options) { const z = maybeZ(options); const [X, setX] = maybeColumn(x); const [Y1, setY1] = column(y); const [Y2, setY2] = column(y); + Y1.hint = Y2.hint = lengthy; offset = maybeOffset(offset); order = maybeOrder(order, offset, ky); return [ @@ -87,8 +93,8 @@ function stack(x, y = one, kx, ky, {offset, order, reverse}, options) { const stacks = X ? Array.from(group(facet, (i) => X[i]).values()) : [facet]; if (O) applyOrder(stacks, O); for (const stack of stacks) { - let yn = 0, - yp = 0; + let yn = 0; + let yp = 0; if (reverse) stack.reverse(); for (const i of stack) { const y = Y[i]; diff --git a/test/output/anscombeQuartet.svg b/test/output/anscombeQuartet.svg index 23a593cb1b..e383ffed31 100644 --- a/test/output/anscombeQuartet.svg +++ b/test/output/anscombeQuartet.svg @@ -13,6 +13,15 @@ white-space: pre; } + + series + + + ↑ y + + + x → + 1 @@ -191,13 +200,4 @@ - - series - - - ↑ y - - - x → - \ No newline at end of file diff --git a/test/output/athletesBoxingHeight.svg b/test/output/athletesBoxingHeight.svg index fd1fc53b0f..ed94fc9d80 100644 --- a/test/output/athletesBoxingHeight.svg +++ b/test/output/athletesBoxingHeight.svg @@ -13,6 +13,12 @@ white-space: pre; } + + continent + + + ↑ height + Africa @@ -346,10 +352,4 @@ PNG - - continent - - - ↑ height - \ No newline at end of file diff --git a/test/output/athletesSampleFacet.svg b/test/output/athletesSampleFacet.svg index f9ef88bb65..782c9be797 100644 --- a/test/output/athletesSampleFacet.svg +++ b/test/output/athletesSampleFacet.svg @@ -13,6 +13,12 @@ white-space: pre; } + + sport + + + weight → + aquatics @@ -580,10 +586,4 @@ Natalia Vorobeva - - sport - - - weight → - \ No newline at end of file diff --git a/test/output/athletesSortFacet.svg b/test/output/athletesSortFacet.svg index bbf901026a..0dab89ce58 100644 --- a/test/output/athletesSortFacet.svg +++ b/test/output/athletesSortFacet.svg @@ -13,6 +13,10 @@ white-space: pre; } + + sport + + boxing @@ -255,8 +259,4 @@ - - sport - - \ No newline at end of file diff --git a/test/output/athletesSportWeight.svg b/test/output/athletesSportWeight.svg index a562418bb1..876f8bce17 100644 --- a/test/output/athletesSportWeight.svg +++ b/test/output/athletesSportWeight.svg @@ -13,6 +13,12 @@ white-space: pre; } + + sport + + + weight → + aquatics @@ -1311,10 +1317,4 @@ - - sport - - - weight → - \ No newline at end of file diff --git a/test/output/autoDotFacet.svg b/test/output/autoDotFacet.svg index 898d97b872..c5cbc9c01f 100644 --- a/test/output/autoDotFacet.svg +++ b/test/output/autoDotFacet.svg @@ -13,6 +13,15 @@ white-space: pre; } + + island + + + ↑ culmen_length_mm + + + body_mass_g → + Biscoe @@ -433,13 +442,4 @@ - - island - - - ↑ culmen_length_mm - - - body_mass_g → - \ No newline at end of file diff --git a/test/output/autoDotFacet2.svg b/test/output/autoDotFacet2.svg index 2a88fef132..3160af0d24 100644 --- a/test/output/autoDotFacet2.svg +++ b/test/output/autoDotFacet2.svg @@ -13,6 +13,18 @@ white-space: pre; } + + species + + + island + + + ↑ culmen_length_mm + + + body_mass_g → + Biscoe @@ -476,16 +488,4 @@ Gentoo - - species - - - island - - - ↑ culmen_length_mm - - - body_mass_g → - \ No newline at end of file diff --git a/test/output/autoLineFacet.svg b/test/output/autoLineFacet.svg index 428d706d7c..20f3f4ce36 100644 --- a/test/output/autoLineFacet.svg +++ b/test/output/autoLineFacet.svg @@ -13,6 +13,12 @@ white-space: pre; } + + industry + + + ↑ unemployed + Agriculture @@ -267,10 +273,4 @@ - - industry - - - ↑ unemployed - \ No newline at end of file diff --git a/test/output/ballotStatusRace.svg b/test/output/ballotStatusRace.svg index 59b1b21a96..7650749658 100644 --- a/test/output/ballotStatusRace.svg +++ b/test/output/ballotStatusRace.svg @@ -13,6 +13,9 @@ white-space: pre; } + + Frequency (%) → + WHITE @@ -176,7 +179,4 @@ - - Frequency (%) → - \ No newline at end of file diff --git a/test/output/beckerBarley.svg b/test/output/beckerBarley.svg index 9843c8df67..730b6577c7 100644 --- a/test/output/beckerBarley.svg +++ b/test/output/beckerBarley.svg @@ -13,6 +13,15 @@ white-space: pre; } + + site + + + variety + + + yield → + Waseca @@ -469,13 +478,4 @@ - - site - - - variety - - - yield → - \ No newline at end of file diff --git a/test/output/boxplotFacetInterval.svg b/test/output/boxplotFacetInterval.svg index f75a20e406..3c5f27600d 100644 --- a/test/output/boxplotFacetInterval.svg +++ b/test/output/boxplotFacetInterval.svg @@ -13,6 +13,12 @@ white-space: pre; } + + height + + + weight → + @@ -626,10 +632,4 @@ - - height - - - weight → - \ No newline at end of file diff --git a/test/output/boxplotFacetNegativeInterval.svg b/test/output/boxplotFacetNegativeInterval.svg index f75a20e406..3c5f27600d 100644 --- a/test/output/boxplotFacetNegativeInterval.svg +++ b/test/output/boxplotFacetNegativeInterval.svg @@ -13,6 +13,12 @@ white-space: pre; } + + height + + + weight → + @@ -626,10 +632,4 @@ - - height - - - weight → - \ No newline at end of file diff --git a/test/output/emptyFacet.svg b/test/output/emptyFacet.svg index 04215f8a30..20359d2172 100644 --- a/test/output/emptyFacet.svg +++ b/test/output/emptyFacet.svg @@ -13,6 +13,15 @@ white-space: pre; } + + TYPE + + + VALUE + + + PERIOD + a @@ -45,13 +54,4 @@ 2 - - TYPE - - - VALUE - - - PERIOD - \ No newline at end of file diff --git a/test/output/footballCoverage.svg b/test/output/footballCoverage.svg index f3e4902dec..de6d8e03fd 100644 --- a/test/output/footballCoverage.svg +++ b/test/output/footballCoverage.svg @@ -13,6 +13,9 @@ white-space: pre; } + + coverage + C2 @@ -410,7 +413,4 @@ - - coverage - \ No newline at end of file diff --git a/test/output/frameFacet.svg b/test/output/frameFacet.svg index 832a3ff663..d995f68ca6 100644 --- a/test/output/frameFacet.svg +++ b/test/output/frameFacet.svg @@ -13,6 +13,12 @@ white-space: pre; } + + species + + + body_mass_g → + Adelie @@ -395,10 +401,4 @@ - - species - - - body_mass_g → - \ No newline at end of file diff --git a/test/output/hexbinR.html b/test/output/hexbinR.html index 859360ab29..f24daf11db 100644 --- a/test/output/hexbinR.html +++ b/test/output/hexbinR.html @@ -48,6 +48,15 @@ white-space: pre; } + + sex + + + ↑ culmen_length_mm + + + culmen_depth_mm → + FEMALE @@ -289,13 +298,4 @@ 1 - - sex - - - ↑ culmen_length_mm - - - culmen_depth_mm → - \ No newline at end of file diff --git a/test/output/hexbinText.svg b/test/output/hexbinText.svg index d5ecb24894..354ab5a8da 100644 --- a/test/output/hexbinText.svg +++ b/test/output/hexbinText.svg @@ -13,6 +13,15 @@ white-space: pre; } + + sex + + + ↑ culmen_length_mm + + + culmen_depth_mm → + FEMALE @@ -368,13 +377,4 @@ 1 - - sex - - - ↑ culmen_length_mm - - - culmen_depth_mm → - \ No newline at end of file diff --git a/test/output/industryUnemploymentTrack.svg b/test/output/industryUnemploymentTrack.svg index d8f26e8554..1fdb4b52c6 100644 --- a/test/output/industryUnemploymentTrack.svg +++ b/test/output/industryUnemploymentTrack.svg @@ -13,6 +13,9 @@ white-space: pre; } + + industry + Construction @@ -1919,7 +1922,4 @@ 2 - - industry - \ No newline at end of file diff --git a/test/output/internFacetDate.svg b/test/output/internFacetDate.svg index c33b17fdc9..93fb889a26 100644 --- a/test/output/internFacetDate.svg +++ b/test/output/internFacetDate.svg @@ -13,6 +13,15 @@ white-space: pre; } + + date_of_birth + + + ↑ height + + + weight → + 1950 @@ -11111,13 +11120,4 @@ - - date_of_birth - - - ↑ height - - - weight → - \ No newline at end of file diff --git a/test/output/internFacetNaN.svg b/test/output/internFacetNaN.svg index 72f35f0da8..ee1056d738 100644 --- a/test/output/internFacetNaN.svg +++ b/test/output/internFacetNaN.svg @@ -13,6 +13,15 @@ white-space: pre; } + + height + + + sex + + + weight → + 1.2 @@ -743,13 +752,4 @@ - - height - - - sex - - - weight → - \ No newline at end of file diff --git a/test/output/mobyDickFaceted.svg b/test/output/mobyDickFaceted.svg index e492f99d5d..7e8899b166 100644 --- a/test/output/mobyDickFaceted.svg +++ b/test/output/mobyDickFaceted.svg @@ -13,6 +13,9 @@ white-space: pre; } + + ↑ Frequency + consonant @@ -285,7 +288,4 @@ - - ↑ Frequency - \ No newline at end of file diff --git a/test/output/moviesRatingByGenre.svg b/test/output/moviesRatingByGenre.svg index 52a72a4b4c..abd8f8594e 100644 --- a/test/output/moviesRatingByGenre.svg +++ b/test/output/moviesRatingByGenre.svg @@ -13,6 +13,9 @@ white-space: pre; } + + IMDB Rating → + @@ -3326,7 +3329,4 @@ - - IMDB Rating → - \ No newline at end of file diff --git a/test/output/penguinCulmen.svg b/test/output/penguinCulmen.svg index bd23be06d3..9d633b2571 100644 --- a/test/output/penguinCulmen.svg +++ b/test/output/penguinCulmen.svg @@ -13,6 +13,18 @@ white-space: pre; } + + species + + + sex + + + ↑ culmen_length_mm + + + culmen_depth_mm → + FEMALE @@ -2984,16 +2996,4 @@ - - species - - - sex - - - ↑ culmen_length_mm - - - culmen_depth_mm → - \ No newline at end of file diff --git a/test/output/penguinCulmenArray.svg b/test/output/penguinCulmenArray.svg index 0e462164d8..06166cc361 100644 --- a/test/output/penguinCulmenArray.svg +++ b/test/output/penguinCulmenArray.svg @@ -13,6 +13,12 @@ white-space: pre; } + + species + + + sex + FEMALE @@ -3318,10 +3324,4 @@ - - species - - - sex - \ No newline at end of file diff --git a/test/output/penguinCulmenMarkFacet.svg b/test/output/penguinCulmenMarkFacet.svg index dcf4a57c7c..a6d4797c7e 100644 --- a/test/output/penguinCulmenMarkFacet.svg +++ b/test/output/penguinCulmenMarkFacet.svg @@ -13,6 +13,18 @@ white-space: pre; } + + species + + + sex + + + ↑ culmen_length_mm + + + culmen_depth_mm → + FEMALE @@ -2896,16 +2908,4 @@ - - species - - - sex - - - ↑ culmen_length_mm - - - culmen_depth_mm → - \ No newline at end of file diff --git a/test/output/penguinDensityFill.html b/test/output/penguinDensityFill.html index d7a8fb6070..16e36ef585 100644 --- a/test/output/penguinDensityFill.html +++ b/test/output/penguinDensityFill.html @@ -48,6 +48,15 @@ white-space: pre; } + + island + + + ↑ culmen_length_mm + + + flipper_length_mm → + Biscoe @@ -158,13 +167,4 @@ - - island - - - ↑ culmen_length_mm - - - flipper_length_mm → - \ No newline at end of file diff --git a/test/output/penguinDensityZ.html b/test/output/penguinDensityZ.html index d449140b3e..3aaf1d1a8c 100644 --- a/test/output/penguinDensityZ.html +++ b/test/output/penguinDensityZ.html @@ -46,6 +46,15 @@ white-space: pre; } + + island + + + ↑ culmen_length_mm + + + flipper_length_mm → + Biscoe @@ -174,14 +183,5 @@ - - island - - - ↑ culmen_length_mm - - - flipper_length_mm → - \ No newline at end of file diff --git a/test/output/penguinDodgeHexbin.svg b/test/output/penguinDodgeHexbin.svg index a6282aa416..b1f509e62e 100644 --- a/test/output/penguinDodgeHexbin.svg +++ b/test/output/penguinDodgeHexbin.svg @@ -13,6 +13,9 @@ white-space: pre; } + + body_mass_g → + Adelie @@ -771,7 +774,4 @@ - - body_mass_g → - \ No newline at end of file diff --git a/test/output/penguinFacetAnnotated.svg b/test/output/penguinFacetAnnotated.svg index 4d83f42650..ac5a99b86c 100644 --- a/test/output/penguinFacetAnnotated.svg +++ b/test/output/penguinFacetAnnotated.svg @@ -13,6 +13,15 @@ white-space: pre; } + + island + + + species + + + Frequency → + Biscoe @@ -101,13 +110,4 @@ Torgersen Island only has Adelie penguins! - - island - - - species - - - Frequency → - \ No newline at end of file diff --git a/test/output/penguinFacetAnnotatedX.svg b/test/output/penguinFacetAnnotatedX.svg index 964c378852..55ea3e1300 100644 --- a/test/output/penguinFacetAnnotatedX.svg +++ b/test/output/penguinFacetAnnotatedX.svg @@ -13,6 +13,15 @@ white-space: pre; } + + island + + + species + + + Frequency → + Biscoe @@ -93,13 +102,4 @@ Torgersen Islandonly has Adeliepenguins! - - island - - - species - - - Frequency → - \ No newline at end of file diff --git a/test/output/penguinFacetDodge.svg b/test/output/penguinFacetDodge.svg index 8f4ff6ae84..841b59bf3a 100644 --- a/test/output/penguinFacetDodge.svg +++ b/test/output/penguinFacetDodge.svg @@ -13,6 +13,9 @@ white-space: pre; } + + body_mass_g → + Adelie @@ -421,7 +424,4 @@ - - body_mass_g → - \ No newline at end of file diff --git a/test/output/penguinFacetDodgeIdentity.svg b/test/output/penguinFacetDodgeIdentity.svg index d92d6064f4..33d966d178 100644 --- a/test/output/penguinFacetDodgeIdentity.svg +++ b/test/output/penguinFacetDodgeIdentity.svg @@ -13,6 +13,9 @@ white-space: pre; } + + body_mass_g → + Adelie @@ -421,7 +424,4 @@ - - body_mass_g → - \ No newline at end of file diff --git a/test/output/penguinFacetDodgeIsland.html b/test/output/penguinFacetDodgeIsland.html index 719b274dec..f4e2665a69 100644 --- a/test/output/penguinFacetDodgeIsland.html +++ b/test/output/penguinFacetDodgeIsland.html @@ -46,6 +46,9 @@ white-space: pre; } + + body_mass_g → + Adelie @@ -454,8 +457,5 @@ - - body_mass_g → - \ No newline at end of file diff --git a/test/output/penguinMassSex.svg b/test/output/penguinMassSex.svg index 065f9882de..663c9bea5f 100644 --- a/test/output/penguinMassSex.svg +++ b/test/output/penguinMassSex.svg @@ -13,6 +13,15 @@ white-space: pre; } + + sex + + + ↑ Frequency + + + Body mass (g) → + FEMALE @@ -128,13 +137,4 @@ - - sex - - - ↑ Frequency - - - Body mass (g) → - \ No newline at end of file diff --git a/test/output/penguinMassSexSpecies.svg b/test/output/penguinMassSexSpecies.svg index 4bdc3c636e..30721c6a67 100644 --- a/test/output/penguinMassSexSpecies.svg +++ b/test/output/penguinMassSexSpecies.svg @@ -13,6 +13,18 @@ white-space: pre; } + + species + + + sex + + + ↑ Frequency + + + Body mass (g) → + FEMALE @@ -189,16 +201,4 @@ - - species - - - sex - - - ↑ Frequency - - - Body mass (g) → - \ No newline at end of file diff --git a/test/output/penguinSexMassCulmenSpecies.svg b/test/output/penguinSexMassCulmenSpecies.svg index 2d8921d854..a10962acce 100644 --- a/test/output/penguinSexMassCulmenSpecies.svg +++ b/test/output/penguinSexMassCulmenSpecies.svg @@ -13,6 +13,15 @@ white-space: pre; } + + sex + + + ↑ culmen_length_mm + + + body_mass_g → + FEMALE @@ -285,13 +294,4 @@ - - sex - - - ↑ culmen_length_mm - - - body_mass_g → - \ No newline at end of file diff --git a/test/output/penguinSpeciesIslandRelative.svg b/test/output/penguinSpeciesIslandRelative.svg index e4e0a94f6f..1c3836bf2b 100644 --- a/test/output/penguinSpeciesIslandRelative.svg +++ b/test/output/penguinSpeciesIslandRelative.svg @@ -13,6 +13,12 @@ white-space: pre; } + + species + + + ↑ Frequency (%) + @@ -83,10 +89,4 @@ - - species - - - ↑ Frequency (%) - \ No newline at end of file diff --git a/test/output/penguinSpeciesIslandSex.svg b/test/output/penguinSpeciesIslandSex.svg index 4eb7e4d6d0..f9ec7067d3 100644 --- a/test/output/penguinSpeciesIslandSex.svg +++ b/test/output/penguinSpeciesIslandSex.svg @@ -13,6 +13,15 @@ white-space: pre; } + + species + + + ↑ Frequency + + + sex + Adelie @@ -171,13 +180,4 @@ - - species - - - ↑ Frequency - - - sex - \ No newline at end of file diff --git a/test/output/reducerScaleOverrideFunction.svg b/test/output/reducerScaleOverrideFunction.svg index 9c78ec2c99..56beac0a77 100644 --- a/test/output/reducerScaleOverrideFunction.svg +++ b/test/output/reducerScaleOverrideFunction.svg @@ -13,6 +13,15 @@ white-space: pre; } + + sex + + + ↑ Frequency + + + species + FEMALE @@ -85,13 +94,4 @@ - - sex - - - ↑ Frequency - - - species - \ No newline at end of file diff --git a/test/output/reducerScaleOverrideImplementation.svg b/test/output/reducerScaleOverrideImplementation.svg index 9c78ec2c99..56beac0a77 100644 --- a/test/output/reducerScaleOverrideImplementation.svg +++ b/test/output/reducerScaleOverrideImplementation.svg @@ -13,6 +13,15 @@ white-space: pre; } + + sex + + + ↑ Frequency + + + species + FEMALE @@ -85,13 +94,4 @@ - - sex - - - ↑ Frequency - - - species - \ No newline at end of file diff --git a/test/output/reducerScaleOverrideName.svg b/test/output/reducerScaleOverrideName.svg index 9c78ec2c99..56beac0a77 100644 --- a/test/output/reducerScaleOverrideName.svg +++ b/test/output/reducerScaleOverrideName.svg @@ -13,6 +13,15 @@ white-space: pre; } + + sex + + + ↑ Frequency + + + species + FEMALE @@ -85,13 +94,4 @@ - - sex - - - ↑ Frequency - - - species - \ No newline at end of file diff --git a/test/output/usPopulationStateAgeGrouped.svg b/test/output/usPopulationStateAgeGrouped.svg index a6e688877b..80ecaf64bb 100644 --- a/test/output/usPopulationStateAgeGrouped.svg +++ b/test/output/usPopulationStateAgeGrouped.svg @@ -13,6 +13,9 @@ white-space: pre; } + + ↑ population + @@ -257,7 +260,4 @@ - - ↑ population - \ No newline at end of file From 568d218e55507bc500b6d65e44f8d072ae5e2d2a Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sun, 7 May 2023 09:20:35 -0700 Subject: [PATCH 05/56] improved tip & pointer --- src/channel.d.ts | 2 +- src/index.js | 2 +- src/interactions/pointer.d.ts | 14 +- src/interactions/pointer.js | 43 ++- src/marks/tip.js | 27 +- test/output/tipDot.svg | 689 +++++++++++++++++----------------- test/output/tipLine.svg | 69 ++++ test/plots/tip.ts | 10 +- 8 files changed, 474 insertions(+), 382 deletions(-) create mode 100644 test/output/tipLine.svg diff --git a/src/channel.d.ts b/src/channel.d.ts index 1b10f889ec..11a6814b29 100644 --- a/src/channel.d.ts +++ b/src/channel.d.ts @@ -61,7 +61,7 @@ export type ChannelName = * An object literal of channel definitions. This is also used to represent * materialized channel states after mark initialization. */ -export type Channels = {[key in ChannelName]?: Channel}; +export type Channels = Record; /** * A channel definition. This is also used to represent the materialized channel diff --git a/src/index.js b/src/index.js index ca778ac694..23f1cc4973 100644 --- a/src/index.js +++ b/src/index.js @@ -40,7 +40,7 @@ export {window, windowX, windowY} from "./transforms/window.js"; export {select, selectFirst, selectLast, selectMaxX, selectMaxY, selectMinX, selectMinY} from "./transforms/select.js"; export {stackX, stackX1, stackX2, stackY, stackY1, stackY2} from "./transforms/stack.js"; export {treeNode, treeLink} from "./transforms/tree.js"; -export {pointer} from "./interactions/pointer.js"; +export {pointer, pointerX, pointerY} from "./interactions/pointer.js"; export {formatIsoDate, formatWeekday, formatMonth} from "./format.js"; export {scale} from "./scales.js"; export {legend} from "./legends.js"; diff --git a/src/interactions/pointer.d.ts b/src/interactions/pointer.d.ts index 3ce344fdcd..3a3f48521d 100644 --- a/src/interactions/pointer.d.ts +++ b/src/interactions/pointer.d.ts @@ -1,4 +1,16 @@ import type {Rendered} from "../transforms/basic.js"; /** TODO */ -export function pointer(options: T): Rendered; +export interface PointerOptions { + /** TODO */ + maxRadius?: number; +} + +/** TODO */ +export function pointer(options: T & PointerOptions): Rendered; + +/** TODO */ +export function pointerX(options: T & PointerOptions): Rendered; + +/** TODO */ +export function pointerY(options: T & PointerOptions): Rendered; diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index d97664daba..ad4febfd00 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -1,21 +1,21 @@ import {pointer as pointof} from "d3"; +import {applyFrameAnchor} from "../style.js"; -export function pointer(options) { +function pointerK(kx, ky, {maxRadius = 40, ...options} = {}) { + maxRadius = +maxRadius; return { ...options, render(index, scales, values, dimensions, context) { const mark = this; const svg = context.ownerSVGElement; const {x: X, y: Y, x1: X1, y1: Y1, x2: X2, y2: Y2} = values; - // let sticky = false; // TODO - const maxRadius = 40; // TODO option - const [cx, cy] = [0, 0]; // TODO applyFrameAnchor - const [kx, ky] = [1, 1]; // TODO axis option + const [cx, cy] = applyFrameAnchor(this, dimensions); + let sticky = false; let i; // currently focused index let g; // currently rendered mark function render(ii) { - if (i === ii) return; // abort if the tooltip hasn’t moved + if (i === ii) return; // the tooltip hasn’t moved i = ii; const r = mark._render(i == null ? [] : [i], scales, values, dimensions, context); if (g) g.replaceWith(r); @@ -23,7 +23,7 @@ export function pointer(options) { } function pointermove(event) { - // if (sticky || (event.pointerType === "mouse" && event.buttons === 1)) return; // dragging + if (sticky || (event.pointerType === "mouse" && event.buttons === 1)) return; // dragging const rect = svg.getBoundingClientRect(); let ii = null; if ( @@ -47,17 +47,16 @@ export function pointer(options) { render(ii); } - // function pointerdown(event) { - // if (event.pointerType !== "mouse") return; - // if (sticky && tip.node().contains(event.target)) return; // stay sticky - // if (sticky) (sticky = false), tip.attr("display", "none"); - // else if (i !== undefined) sticky = true; - // } + function pointerdown(event) { + if (event.pointerType !== "mouse") return; + if (sticky && g.contains(event.target)) return; // stay sticky + if (sticky) (sticky = false), render(null); + else if (i != null) sticky = true; + } function pointerleave(event) { if (event.pointerType !== "mouse") return; - // if (!sticky) tip.attr("display", "none"); - render(null); + if (!sticky) render(null); } // We listen to the svg element; listening to the window instead would let @@ -66,10 +65,22 @@ export function pointer(options) { // to watch the entire document is likely too expensive.) svg.addEventListener("pointerenter", pointermove); svg.addEventListener("pointermove", pointermove); - // svg.addEventListener("pointerdown", pointerdown); + svg.addEventListener("pointerdown", pointerdown); svg.addEventListener("pointerleave", pointerleave); return render(null); } }; } + +export function pointer(options) { + return pointerK(1, 1, options); +} + +export function pointerX(options) { + return pointerK(1, 0.01, options); +} + +export function pointerY(options) { + return pointerK(0.01, 1, options); +} diff --git a/src/marks/tip.js b/src/marks/tip.js index cb1dcc23fe..88d3de6784 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -10,8 +10,8 @@ import {applyIndirectTextStyles, cut, defaultWidth, monospaceWidth} from "./text const defaults = { ariaLabel: "tip", - fill: "currentColor", - stroke: "none" + fill: "white", + stroke: "currentColor" }; export class Tip extends Mark { @@ -61,9 +61,10 @@ export class Tip extends Mark { } render(index, scales, channels, dimensions, context) { const {x, y} = scales; - const {x: X, y: Y} = channels; // TODO X1, Y1, X2, Y2 + const {x: X, y: Y, stroke: S} = channels; // TODO X1, Y1, X2, Y2 const [cx, cy] = applyFrameAnchor(this, dimensions); - const {anchor, monospace, lineHeight, lineWidth} = this; + const {ownerSVGElement: svg, document} = context; + const {stroke, anchor, monospace, lineHeight, lineWidth} = this; const widthof = monospace ? monospaceWidth : defaultWidth; const ellipsis = "…"; const ee = widthof(ellipsis); @@ -73,8 +74,6 @@ export class Tip extends Mark { // const formatFx = fx && inferTickFormat(fx); // const formatFy = fy && inferTickFormat(fy); // const {fx: fxv, fy: fyv} = this; - const foreground = "black"; // TODO fill option? - const background = "white"; // TODO stroke option? const g = create("svg:g", context) .call(applyIndirectStyles, this, dimensions, context) .call(applyIndirectTextStyles, this) @@ -88,16 +87,12 @@ export class Tip extends Mark { .attr("transform", template`translate(${X ? (i) => X[i] : cx},${Y ? (i) => Y[i] : cy})`) .call(applyDirectStyles, this) .call(applyChannelStyles, this, channels) - .call((g) => - g - .append("path") - .attr("stroke", foreground) - .attr("fill", background) - .attr("filter", "drop-shadow(0 3px 4px rgba(0,0,0,0.2))") - ) + .call((g) => g.append("path").attr("filter", "drop-shadow(0 3px 4px rgba(0,0,0,0.2))")) .call((g) => g.append("text").each(function (i) { const that = select(this); + this.setAttribute("fill", S ? S[i] : stroke); + this.setAttribute("stroke", "none"); // TODO fx, fy for (const key in channels.channels) { const channel = getSource(channels.channels, key); @@ -122,7 +117,7 @@ export class Tip extends Mark { } const line = that.append("tspan").attr("x", 0).attr("dy", `${lineHeight}em`); line.append("tspan").attr("font-weight", "bold").text(name); - if (value) line.append(() => context.document.createTextNode(value)); + if (value) line.append(() => document.createTextNode(value)); if (title) line.append("title").text(title); } }) @@ -130,7 +125,7 @@ export class Tip extends Mark { ); function postrender() { - const {width, height} = context.ownerSVGElement.getBBox(); + const {width, height} = svg.getBBox(); g.selectChildren().each(function (i) { const x = X ? X[i] : cx; const y = Y ? Y[i] : cy; @@ -157,7 +152,7 @@ export class Tip extends Mark { // to compute the text dimensions. Perhaps this could be done synchronously; // getting the dimensions of the SVG is easy, and although accurate text // metrics are hard, we could use approximate heuristics. - if (context.ownerSVGElement.isConnected) Promise.resolve().then(postrender); + if (svg.isConnected) Promise.resolve().then(postrender); else if (typeof requestAnimationFrame !== "undefined") requestAnimationFrame(postrender); return g.node(); diff --git a/test/output/tipDot.svg b/test/output/tipDot.svg index f40fce4c0c..1991c3a98c 100644 --- a/test/output/tipDot.svg +++ b/test/output/tipDot.svg @@ -53,350 +53,349 @@ culmen_length_mm → - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + \ No newline at end of file diff --git a/test/output/tipLine.svg b/test/output/tipLine.svg new file mode 100644 index 0000000000..4a1d9412d9 --- /dev/null +++ b/test/output/tipLine.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + 60 + 70 + 80 + 90 + 100 + 110 + 120 + 130 + 140 + 150 + 160 + 170 + 180 + 190 + + + ↑ Close + + + + + + + + + + 2014 + 2015 + 2016 + 2017 + 2018 + + + + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 0ca5d1f0a6..1ebb67d184 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -5,9 +5,15 @@ export async function tipDot() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); return Plot.plot({ marks: [ - Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"}), - Plot.dot(penguins, Plot.pointer({x: "culmen_length_mm", y: "culmen_depth_mm", r: 4, stroke: "red"})), + Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm", stroke: "sex"}), Plot.tip(penguins, Plot.pointer({x: "culmen_length_mm", y: "culmen_depth_mm"})) ] }); } + +export async function tipLine() { + const aapl = await d3.csv("data/aapl.csv", d3.autoType); + return Plot.plot({ + marks: [Plot.lineY(aapl, {x: "Date", y: "Close"}), Plot.tip(aapl, Plot.pointerX({x: "Date", y: "Close"}))] + }); +} From 9854e0d38cc61e7560d8363a34617b8eadff1345 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sun, 7 May 2023 09:23:14 -0700 Subject: [PATCH 06/56] simplify --- src/interactions/pointer.js | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index ad4febfd00..5b31eec0ba 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -24,25 +24,16 @@ function pointerK(kx, ky, {maxRadius = 40, ...options} = {}) { function pointermove(event) { if (sticky || (event.pointerType === "mouse" && event.buttons === 1)) return; // dragging - const rect = svg.getBoundingClientRect(); + const [xp, yp] = pointof(event, g.parentNode); let ii = null; - if ( - // Check if the pointer is near before scanning. - event.clientX + maxRadius > rect.left && - event.clientX - maxRadius < rect.right && - event.clientY + maxRadius > rect.top && - event.clientY - maxRadius < rect.bottom - ) { - const [xp, yp] = pointof(event, g.parentNode); - let ri = maxRadius * maxRadius; - for (const j of index) { - const xj = X2 ? (X1[j] + X2[j]) / 2 : X ? X[j] : cx; // + oxj; - const yj = Y2 ? (Y1[j] + Y2[j]) / 2 : Y ? Y[j] : cy; // + oyj; - const dx = kx * (xj - xp); - const dy = ky * (yj - yp); - const rj = dx * dx + dy * dy; - if (rj <= ri) (ii = j), (ri = rj); - } + let ri = maxRadius * maxRadius; + for (const j of index) { + const xj = X2 ? (X1[j] + X2[j]) / 2 : X ? X[j] : cx; + const yj = Y2 ? (Y1[j] + Y2[j]) / 2 : Y ? Y[j] : cy; + const dx = kx * (xj - xp); + const dy = ky * (yj - yp); + const rj = dx * dx + dy * dy; + if (rj <= ri) (ii = j), (ri = rj); } render(ii); } From 98be543db94a94c838fe6e628744a9e6298fb454 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sun, 7 May 2023 09:45:41 -0700 Subject: [PATCH 07/56] better facets; stable anchor --- src/interactions/pointer.js | 6 +- src/marks/axis.js | 2 +- src/marks/tip.js | 87 +- src/plot.js | 4 +- test/output/tipDotFacets.svg | 11218 +++++++++++++++++++++++++++++++++ test/plots/tip.ts | 27 + 6 files changed, 11303 insertions(+), 41 deletions(-) create mode 100644 test/output/tipDotFacets.svg diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index 5b31eec0ba..e275f849e9 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -17,7 +17,11 @@ function pointerK(kx, ky, {maxRadius = 40, ...options} = {}) { function render(ii) { if (i === ii) return; // the tooltip hasn’t moved i = ii; - const r = mark._render(i == null ? [] : [i], scales, values, dimensions, context); + const I = i == null ? [] : [i]; + I.fx = index.fx; + I.fy = index.fy; + I.fi = index.fi; + const r = mark._render(I, scales, values, dimensions, context); if (g) g.replaceWith(r); return (g = r); } diff --git a/src/marks/axis.js b/src/marks/axis.js index bfb17ce2d4..b124724275 100644 --- a/src/marks/axis.js +++ b/src/marks/axis.js @@ -576,7 +576,7 @@ function inferTextChannel(scale, ticks, tickFormat) { // D3’s ordinal scales simply use toString by default, but if the ordinal scale // domain (or ticks) are numbers or dates (say because we’re applying a time // interval to the ordinal scale), we want Plot’s default formatter. -function inferTickFormat(scale, ticks, tickFormat) { +export function inferTickFormat(scale, ticks, tickFormat) { return scale.tickFormat ? scale.tickFormat(isIterable(ticks) ? null : ticks, tickFormat) : tickFormat === undefined diff --git a/src/marks/tip.js b/src/marks/tip.js index 88d3de6784..bc557bdce1 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -6,6 +6,7 @@ import {maybeFrameAnchor, maybeKeyword, maybeTuple, number, string} from "../opt import {applyChannelStyles, applyDirectStyles, applyIndirectStyles} from "../style.js"; import {applyFrameAnchor, applyTransform} from "../style.js"; import {template} from "../template.js"; +import {inferTickFormat} from "./axis.js"; import {applyIndirectTextStyles, cut, defaultWidth, monospaceWidth} from "./text.js"; const defaults = { @@ -60,20 +61,23 @@ export class Tip extends Mark { this.fontWeight = string(fontWeight); } render(index, scales, channels, dimensions, context) { - const {x, y} = scales; + const mark = this; + const {x, y, fx, fy} = scales; const {x: X, y: Y, stroke: S} = channels; // TODO X1, Y1, X2, Y2 const [cx, cy] = applyFrameAnchor(this, dimensions); const {ownerSVGElement: svg, document} = context; const {stroke, anchor, monospace, lineHeight, lineWidth} = this; + const {marginTop, marginLeft} = dimensions; const widthof = monospace ? monospaceWidth : defaultWidth; const ellipsis = "…"; const ee = widthof(ellipsis); const r = 8; // “padding” const m = 12; // “margin” (flag size) - // const {fx, fy} = scales; - // const formatFx = fx && inferTickFormat(fx); - // const formatFy = fy && inferTickFormat(fy); - // const {fx: fxv, fy: fyv} = this; + const labelFx = fx && (fx.label === undefined ? "fx" : fx.label); + const labelFy = fy && (fy.label === undefined ? "fy" : fy.label); + const formatFx = fx && inferTickFormat(fx); + const formatFy = fy && inferTickFormat(fy); + const g = create("svg:g", context) .call(applyIndirectStyles, this, dimensions, context) .call(applyIndirectTextStyles, this) @@ -93,58 +97,65 @@ export class Tip extends Mark { const that = select(this); this.setAttribute("fill", S ? S[i] : stroke); this.setAttribute("stroke", "none"); - // TODO fx, fy for (const key in channels.channels) { const channel = getSource(channels.channels, key); if (!channel) continue; // e.g., dodgeY’s y - let name = scales[channel.scale]?.label ?? key; - let value = ` ${formatDefault(channel.value[i])}\u200b`; // zwsp for double-click - let title; - let w = lineWidth * 100; - const [j] = cut(name, w, widthof, ee); - if (j >= 0) { - // name is truncated - name = name.slice(0, j).trimEnd() + ellipsis; - value = ""; - title = value.trim(); - } else { - const [k] = cut(value, w - widthof(name), widthof, ee); - if (k >= 0) { - // value is truncated - value = value.slice(0, k).trimEnd() + ellipsis; - title = value.trim(); - } - } - const line = that.append("tspan").attr("x", 0).attr("dy", `${lineHeight}em`); - line.append("tspan").attr("font-weight", "bold").text(name); - if (value) line.append(() => document.createTextNode(value)); - if (title) line.append("title").text(title); + renderLine(that, scales[channel.scale]?.label ?? key, formatDefault(channel.value[i])); } + if (fx) renderLine(that, labelFx, formatFx(index.fx)); + if (fy) renderLine(that, labelFy, formatFy(index.fy)); }) ) ); + function renderLine(that, name, value) { + let title; + let w = lineWidth * 100; + const [j] = cut(name, w, widthof, ee); + if (j >= 0) { + // name is truncated + name = name.slice(0, j).trimEnd() + ellipsis; + value = ""; + title = value.trim(); + } else { + value = ` ${value}\u200b`; // zwsp for double-click + const [k] = cut(value, w - widthof(name), widthof, ee); + if (k >= 0) { + // value is truncated + value = value.slice(0, k).trimEnd() + ellipsis; + title = value.trim(); + } + } + const line = that.append("tspan").attr("x", 0).attr("dy", `${lineHeight}em`); + line.append("tspan").attr("font-weight", "bold").text(name); + if (value) line.append(() => document.createTextNode(value)); + if (title) line.append("title").text(title); + } + function postrender() { const {width, height} = svg.getBBox(); + const ox = fx ? fx(index.fx) - marginLeft : 0; + const oy = fy ? fy(index.fy) - marginTop : 0; g.selectChildren().each(function (i) { - const x = X ? X[i] : cx; - const y = Y ? Y[i] : cy; + const x = (X ? X[i] : cx) + ox; + const y = (Y ? Y[i] : cy) + oy; const {width: w, height: h} = this.getBBox(); - let c; - if (anchor === undefined) { + let a = anchor; + if (a === undefined) { + a = mark.previousAnchor; const fitLeft = x + w + r * 2 < width; const fitRight = x - w - r * 2 > 0; const fitTop = y + h + m + r * 2 + 7 < height; const fitBottom = y - h - m - r * 2 > 0; - const cx = (/-left$/.test(c) ? fitLeft || !fitRight : fitLeft && !fitRight) ? "left" : "right"; - const cy = (/^top-/.test(c) ? fitTop || !fitBottom : fitTop && !fitBottom) ? "top" : "bottom"; - c = `${cy}-${cx}`; + const ax = (/-left$/.test(a) ? fitLeft || !fitRight : fitLeft && !fitRight) ? "left" : "right"; + const ay = (/^top-/.test(a) ? fitTop || !fitBottom : fitTop && !fitBottom) ? "top" : "bottom"; + a = mark.previousAnchor = `${ay}-${ax}`; } const path = this.firstChild; const text = this.lastChild; - path.setAttribute("d", getPath(c, m, r, w, h)); - text.setAttribute("y", `${+getLineOffset(c, text.childNodes.length, lineHeight).toFixed(6)}em`); - text.setAttribute("transform", getTextTransform(c, m, r, w, h)); + path.setAttribute("d", getPath(a, m, r, w, h)); + text.setAttribute("y", `${+getLineOffset(a, text.childNodes.length, lineHeight).toFixed(6)}em`); + text.setAttribute("transform", getTextTransform(a, m, r, w, h)); }); } diff --git a/src/plot.js b/src/plot.js index 168c141e81..b2d6a612c6 100644 --- a/src/plot.js +++ b/src/plot.js @@ -275,7 +275,9 @@ export function plot(options = {}) { index = indexes[facetStateByMark.has(mark) ? f.i : 0]; index = mark.filter(index, channels, values); if (index.length === 0) continue; - index.fi = f.i; // TODO cleaner way of exposing the current facet index? + index.fx = f.x; + index.fy = f.y; + index.fi = f.i; } const node = mark.render(index, scales, values, subdimensions, context); if (node == null) continue; diff --git a/test/output/tipDotFacets.svg b/test/output/tipDotFacets.svg new file mode 100644 index 0000000000..8a903e5126 --- /dev/null +++ b/test/output/tipDotFacets.svg @@ -0,0 +1,11218 @@ + + + + decade of birth + + + sex + + + ↑ height + + + weight → + + + + female + + + + + + + + + + + + + + + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + + + + + + + + + + + + + 50 + 100 + 150 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1950 + + + male + + + + + + + + + + + + + + + + + + + + + + + + 1960 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1970 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1980 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1990 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2000 + + + + + + + + + + + + + + + + + + + + 50 + 100 + 150 + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 1ebb67d184..04a4a72a09 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -11,6 +11,33 @@ export async function tipDot() { }); } +export async function tipDotFacets() { + const athletes = await d3.csv("data/athletes.csv", d3.autoType); + return Plot.plot({ + grid: true, + fy: { + label: "decade of birth", + interval: "10 years" + }, + marks: [ + Plot.dot(athletes, {x: "weight", y: "height", fx: "sex", fy: "date_of_birth"}), + Plot.tip( + athletes, + Plot.pointer({ + x: "weight", + y: "height", + fx: "sex", + fy: "date_of_birth", + channels: { + name: {value: "name"}, + sport: {value: "sport"} + } + }) + ) + ] + }); +} + export async function tipLine() { const aapl = await d3.csv("data/aapl.csv", d3.autoType); return Plot.plot({ From 778b38b1b527aba53024b9c070b92d9268525634 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sun, 7 May 2023 10:12:00 -0700 Subject: [PATCH 08/56] px, py; crosshairs --- src/interactions/pointer.js | 7 +- test/output/tipCrosshairs.svg | 404 ++++++++++++++++++++++++++++++++++ test/plots/tip.ts | 16 ++ 3 files changed, 425 insertions(+), 2 deletions(-) create mode 100644 test/output/tipCrosshairs.svg diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index e275f849e9..e973b06b23 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -1,14 +1,17 @@ import {pointer as pointof} from "d3"; import {applyFrameAnchor} from "../style.js"; -function pointerK(kx, ky, {maxRadius = 40, ...options} = {}) { +function pointerK(kx, ky, {px, py, maxRadius = 40, channels, ...options} = {}) { maxRadius = +maxRadius; + if (px != null) channels = {...channels, px: {value: px, scale: "x"}}; + if (py != null) channels = {...channels, py: {value: py, scale: "y"}}; return { + channels, ...options, render(index, scales, values, dimensions, context) { const mark = this; const svg = context.ownerSVGElement; - const {x: X, y: Y, x1: X1, y1: Y1, x2: X2, y2: Y2} = values; + const {x: X0, y: Y0, x1: X1, y1: Y1, x2: X2, y2: Y2, px: X = X0, py: Y = Y0} = values; const [cx, cy] = applyFrameAnchor(this, dimensions); let sticky = false; let i; // currently focused index diff --git a/test/output/tipCrosshairs.svg b/test/output/tipCrosshairs.svg new file mode 100644 index 0000000000..a977ec5815 --- /dev/null +++ b/test/output/tipCrosshairs.svg @@ -0,0 +1,404 @@ + + + + + + + + + + + + + + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + + + ↑ culmen_depth_mm + + + + + + + + + + 35 + 40 + 45 + 50 + 55 + + + culmen_length_mm → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 04a4a72a09..d70d1aac7b 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -1,6 +1,22 @@ import * as Plot from "@observablehq/plot"; import * as d3 from "d3"; +export async function tipCrosshairs() { + const penguins = await d3.csv("data/penguins.csv", d3.autoType); + const x = "culmen_length_mm"; + const y = "culmen_depth_mm"; + const z = {fill: "currentColor", stroke: "white", strokeWidth: 5}; + return Plot.plot({ + marks: [ + Plot.dot(penguins, {x, y, stroke: "sex"}), + Plot.ruleX(penguins, Plot.pointer({x, py: y, strokeOpacity: 0.2})), + Plot.ruleY(penguins, Plot.pointer({px: x, y, strokeOpacity: 0.2})), + Plot.text(penguins, Plot.pointer({px: x, y, text: y, dx: -9, frameAnchor: "left", textAnchor: "end", ...z})), + Plot.text(penguins, Plot.pointer({x, py: y, text: x, dy: 9, frameAnchor: "bottom", lineAnchor: "top", ...z})) + ] + }); +} + export async function tipDot() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); return Plot.plot({ From a054cf44f3f50ca64779d54ee47fa97c0d23ea4a Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sun, 7 May 2023 10:26:10 -0700 Subject: [PATCH 09/56] crosshairs composite mark --- src/index.d.ts | 3 ++- src/index.js | 1 + src/marks/crosshairs.d.ts | 20 ++++++++++++++++++++ src/marks/crosshairs.js | 16 ++++++++++++++++ test/plots/tip.ts | 10 ++-------- 5 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 src/marks/crosshairs.d.ts create mode 100644 src/marks/crosshairs.js diff --git a/src/index.d.ts b/src/index.d.ts index 7832d5c1ef..62cd71a203 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -4,6 +4,7 @@ export * from "./curve.js"; export * from "./dimensions.js"; export * from "./format.js"; export * from "./inset.js"; +export * from "./interactions/pointer.js"; export * from "./interval.js"; export * from "./legends.js"; export * from "./mark.js"; @@ -16,6 +17,7 @@ export * from "./marks/bar.js"; export * from "./marks/box.js"; export * from "./marks/cell.js"; export * from "./marks/contour.js"; +export * from "./marks/crosshairs.js"; export * from "./marks/delaunay.js"; export * from "./marks/density.js"; export * from "./marks/dot.js"; @@ -52,4 +54,3 @@ export * from "./transforms/select.js"; export * from "./transforms/stack.js"; export * from "./transforms/tree.js"; export * from "./transforms/window.js"; -export * from "./interactions/pointer.js"; diff --git a/src/index.js b/src/index.js index 23f1cc4973..b005f89091 100644 --- a/src/index.js +++ b/src/index.js @@ -8,6 +8,7 @@ export {BarX, BarY, barX, barY} from "./marks/bar.js"; export {boxX, boxY} from "./marks/box.js"; export {Cell, cell, cellX, cellY} from "./marks/cell.js"; export {Contour, contour} from "./marks/contour.js"; +export {crosshairs} from "./marks/crosshairs.js"; export {delaunayLink, delaunayMesh, hull, voronoi, voronoiMesh} from "./marks/delaunay.js"; export {Density, density} from "./marks/density.js"; export {Dot, dot, dotX, dotY, circle, hexagon} from "./marks/dot.js"; diff --git a/src/marks/crosshairs.d.ts b/src/marks/crosshairs.d.ts new file mode 100644 index 0000000000..efe8527952 --- /dev/null +++ b/src/marks/crosshairs.d.ts @@ -0,0 +1,20 @@ +import type {ChannelValueSpec} from "../channel.js"; +import type {CompoundMark, Data, MarkOptions} from "../mark.js"; + +/** Options for the crosshairs mark. */ +export interface CrosshairsOptions extends MarkOptions { + /** + * The horizontal position channel specifying the crosshair’s center, + * typically bound to the *x* scale. + */ + x?: ChannelValueSpec; + + /** + * The vertical position channel specifying the crosshair’s center, typically + * bound to the *y* scale. + */ + y?: ChannelValueSpec; +} + +/** TODO */ +export function crosshairs(data?: Data, options?: CrosshairsOptions): CompoundMark; diff --git a/src/marks/crosshairs.js b/src/marks/crosshairs.js new file mode 100644 index 0000000000..1156f48b23 --- /dev/null +++ b/src/marks/crosshairs.js @@ -0,0 +1,16 @@ +import {pointer} from "../interactions/pointer.js"; +import {marks} from "../mark.js"; +import {ruleX, ruleY} from "./rule.js"; +import {text} from "./text.js"; + +export function crosshairs( + data, + {x, y, fill = "currentColor", stroke = "white", strokeOpacity = 0.2, strokeWidth = 5, dx = -9, dy = 9} = {} +) { + return marks( + ruleX(data, pointer({x, py: y, strokeOpacity})), + ruleY(data, pointer({px: x, y, strokeOpacity})), + text(data, pointer({px: x, y, text: y, dx, frameAnchor: "left", textAnchor: "end", fill, stroke, strokeWidth})), + text(data, pointer({x, py: y, text: x, dy, frameAnchor: "bottom", lineAnchor: "top", fill, stroke, strokeWidth})) + ); +} diff --git a/test/plots/tip.ts b/test/plots/tip.ts index d70d1aac7b..f2ca6e0353 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -3,16 +3,10 @@ import * as d3 from "d3"; export async function tipCrosshairs() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); - const x = "culmen_length_mm"; - const y = "culmen_depth_mm"; - const z = {fill: "currentColor", stroke: "white", strokeWidth: 5}; return Plot.plot({ marks: [ - Plot.dot(penguins, {x, y, stroke: "sex"}), - Plot.ruleX(penguins, Plot.pointer({x, py: y, strokeOpacity: 0.2})), - Plot.ruleY(penguins, Plot.pointer({px: x, y, strokeOpacity: 0.2})), - Plot.text(penguins, Plot.pointer({px: x, y, text: y, dx: -9, frameAnchor: "left", textAnchor: "end", ...z})), - Plot.text(penguins, Plot.pointer({x, py: y, text: x, dy: 9, frameAnchor: "bottom", lineAnchor: "top", ...z})) + Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm", stroke: "sex"}), + Plot.crosshairs(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"}) ] }); } From fbdc96cc51d4150a03ed9c61111752f44cd457db Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sun, 7 May 2023 13:57:32 -0700 Subject: [PATCH 10/56] crosshair singular --- src/index.d.ts | 2 +- src/index.js | 2 +- src/marks/{crosshairs.d.ts => crosshair.d.ts} | 6 +-- src/marks/crosshair.js | 39 +++++++++++++++++++ src/marks/crosshairs.js | 16 -------- .../{tipCrosshairs.svg => tipCrosshair.svg} | 0 test/plots/tip.ts | 4 +- 7 files changed, 46 insertions(+), 23 deletions(-) rename src/marks/{crosshairs.d.ts => crosshair.d.ts} (70%) create mode 100644 src/marks/crosshair.js delete mode 100644 src/marks/crosshairs.js rename test/output/{tipCrosshairs.svg => tipCrosshair.svg} (100%) diff --git a/src/index.d.ts b/src/index.d.ts index 62cd71a203..19e9442a31 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -17,7 +17,7 @@ export * from "./marks/bar.js"; export * from "./marks/box.js"; export * from "./marks/cell.js"; export * from "./marks/contour.js"; -export * from "./marks/crosshairs.js"; +export * from "./marks/crosshair.js"; export * from "./marks/delaunay.js"; export * from "./marks/density.js"; export * from "./marks/dot.js"; diff --git a/src/index.js b/src/index.js index b005f89091..8d84db05cb 100644 --- a/src/index.js +++ b/src/index.js @@ -8,7 +8,7 @@ export {BarX, BarY, barX, barY} from "./marks/bar.js"; export {boxX, boxY} from "./marks/box.js"; export {Cell, cell, cellX, cellY} from "./marks/cell.js"; export {Contour, contour} from "./marks/contour.js"; -export {crosshairs} from "./marks/crosshairs.js"; +export {crosshair} from "./marks/crosshair.js"; export {delaunayLink, delaunayMesh, hull, voronoi, voronoiMesh} from "./marks/delaunay.js"; export {Density, density} from "./marks/density.js"; export {Dot, dot, dotX, dotY, circle, hexagon} from "./marks/dot.js"; diff --git a/src/marks/crosshairs.d.ts b/src/marks/crosshair.d.ts similarity index 70% rename from src/marks/crosshairs.d.ts rename to src/marks/crosshair.d.ts index efe8527952..bad5ec02e5 100644 --- a/src/marks/crosshairs.d.ts +++ b/src/marks/crosshair.d.ts @@ -1,8 +1,8 @@ import type {ChannelValueSpec} from "../channel.js"; import type {CompoundMark, Data, MarkOptions} from "../mark.js"; -/** Options for the crosshairs mark. */ -export interface CrosshairsOptions extends MarkOptions { +/** Options for the crosshair mark. */ +export interface CrosshairOptions extends MarkOptions { /** * The horizontal position channel specifying the crosshair’s center, * typically bound to the *x* scale. @@ -17,4 +17,4 @@ export interface CrosshairsOptions extends MarkOptions { } /** TODO */ -export function crosshairs(data?: Data, options?: CrosshairsOptions): CompoundMark; +export function crosshair(data?: Data, options?: CrosshairOptions): CompoundMark; diff --git a/src/marks/crosshair.js b/src/marks/crosshair.js new file mode 100644 index 0000000000..ce59edcd91 --- /dev/null +++ b/src/marks/crosshair.js @@ -0,0 +1,39 @@ +import {pointer} from "../interactions/pointer.js"; +import {marks} from "../mark.js"; +import {ruleX, ruleY} from "./rule.js"; +import {text} from "./text.js"; + +export function crosshair(data, options = {}) { + const {x, y, dx = -9, dy = 9} = options; + return marks( + ruleX(data, ruleOptions({x, py: y}, options)), + ruleY(data, ruleOptions({px: x, y}, options)), + text(data, textOptions({px: x, y, text: y, dx, frameAnchor: "left", textAnchor: "end"}, options)), + text(data, textOptions({x, py: y, text: x, dy, frameAnchor: "bottom", lineAnchor: "top"}, options)) + ); +} + +function ruleOptions( + options, + { + color = "currentColor", + ruleStroke: stroke = color, + ruleStrokeOpacity: strokeOpacity = 0.2, + ruleStrokeWidth: strokeWidth + } +) { + return pointer({...options, stroke, strokeOpacity, strokeWidth}); +} + +function textOptions( + options, + { + color = "currentColor", + textFill: fill = color, + textStroke: stroke = "white", + textStrokeOpacity: strokeOpacity, + textStrokeWidth: strokeWidth = 5 + } +) { + return pointer({...options, fill, stroke, strokeOpacity, strokeWidth}); +} diff --git a/src/marks/crosshairs.js b/src/marks/crosshairs.js deleted file mode 100644 index 1156f48b23..0000000000 --- a/src/marks/crosshairs.js +++ /dev/null @@ -1,16 +0,0 @@ -import {pointer} from "../interactions/pointer.js"; -import {marks} from "../mark.js"; -import {ruleX, ruleY} from "./rule.js"; -import {text} from "./text.js"; - -export function crosshairs( - data, - {x, y, fill = "currentColor", stroke = "white", strokeOpacity = 0.2, strokeWidth = 5, dx = -9, dy = 9} = {} -) { - return marks( - ruleX(data, pointer({x, py: y, strokeOpacity})), - ruleY(data, pointer({px: x, y, strokeOpacity})), - text(data, pointer({px: x, y, text: y, dx, frameAnchor: "left", textAnchor: "end", fill, stroke, strokeWidth})), - text(data, pointer({x, py: y, text: x, dy, frameAnchor: "bottom", lineAnchor: "top", fill, stroke, strokeWidth})) - ); -} diff --git a/test/output/tipCrosshairs.svg b/test/output/tipCrosshair.svg similarity index 100% rename from test/output/tipCrosshairs.svg rename to test/output/tipCrosshair.svg diff --git a/test/plots/tip.ts b/test/plots/tip.ts index f2ca6e0353..b803526df2 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -1,12 +1,12 @@ import * as Plot from "@observablehq/plot"; import * as d3 from "d3"; -export async function tipCrosshairs() { +export async function tipCrosshair() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); return Plot.plot({ marks: [ Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm", stroke: "sex"}), - Plot.crosshairs(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"}) + Plot.crosshair(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"}) ] }); } From 85771cf89d76a48c75224c32d91a6dceeaff3e42 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sun, 7 May 2023 19:37:09 -0700 Subject: [PATCH 11/56] transpose facets and marks --- src/plot.js | 94 +- src/style.js | 6 +- test/output/anscombeQuartet.svg | 414 +- test/output/athletesBoxingHeight.svg | 676 +- test/output/athletesSampleFacet.svg | 1238 +- test/output/athletesSortFacet.svg | 542 +- test/output/athletesSportWeight.svg | 2708 +- test/output/autoDotFacet.svg | 858 +- test/output/autoDotFacet2.svg | 946 +- test/output/autoLineFacet.svg | 592 +- test/output/ballotStatusRace.svg | 370 +- test/output/beckerBarley.svg | 990 +- test/output/boxplotFacetInterval.svg | 1322 +- test/output/boxplotFacetNegativeInterval.svg | 1322 +- test/output/caltrainDirection.svg | 232 +- test/output/emptyFacet.svg | 80 +- test/output/footballCoverage.svg | 802 +- test/output/frameFacet.svg | 774 +- test/output/functionContourFaceted.svg | 296 +- test/output/functionContourFaceted2.svg | 296 +- test/output/futureSplom.svg | 464 +- test/output/googleTrendsRidgeline.svg | 2244 +- test/output/heatmapFaceted.svg | 210 +- test/output/hexbinR.html | 496 +- test/output/hexbinText.svg | 726 +- test/output/industryUnemploymentTrack.svg | 3796 +-- test/output/internFacetDate.svg | 22206 +++++++-------- test/output/internFacetNaN.svg | 1590 +- test/output/metroUnemploymentRidgeline.svg | 1578 +- test/output/mobyDickFaceted.svg | 556 +- test/output/moviesRatingByGenre.svg | 6614 ++--- test/output/multiplicationTable.svg | 1930 +- test/output/penguinCulmen.svg | 5960 ++-- test/output/penguinCulmenArray.svg | 6610 ++--- test/output/penguinCulmenMarkFacet.svg | 5786 ++-- test/output/penguinDensityFill.html | 248 +- test/output/penguinDensityZ.html | 284 +- test/output/penguinDodgeHexbin.svg | 1528 +- test/output/penguinFacetAnnotated.svg | 210 +- test/output/penguinFacetAnnotatedX.svg | 194 +- test/output/penguinFacetDodge.svg | 820 +- test/output/penguinFacetDodgeIdentity.svg | 820 +- test/output/penguinFacetDodgeIsland.html | 820 +- test/output/penguinMassSex.svg | 262 +- test/output/penguinMassSexSpecies.svg | 404 +- test/output/penguinSexMassCulmenSpecies.svg | 568 +- test/output/penguinSpeciesIslandRelative.svg | 154 +- test/output/penguinSpeciesIslandSex.svg | 358 +- test/output/projectionBleedEdges2.svg | 52 +- test/output/projectionFitBertin1953.svg | 38 +- test/output/projectionHeightEqualEarth.svg | 66 +- test/output/projectionHeightGeometry.svg | 38 +- test/output/projectionHeightMercator.svg | 66 +- test/output/projectionHeightOrthographic.svg | 134 +- test/output/reducerScaleOverrideFunction.svg | 160 +- .../reducerScaleOverrideImplementation.svg | 160 +- test/output/reducerScaleOverrideName.svg | 160 +- test/output/textOverflow.svg | 716 +- test/output/tipDotFacets.svg | 22400 ++++++++-------- test/output/trafficHorizon.html | 3680 +-- test/output/usPopulationStateAgeGrouped.svg | 534 +- test/output/walmartsDecades.svg | 162 +- 62 files changed, 57570 insertions(+), 52790 deletions(-) diff --git a/src/plot.js b/src/plot.js index b2d6a612c6..46098a1e3d 100644 --- a/src/plot.js +++ b/src/plot.js @@ -11,7 +11,7 @@ import {arrayify, isColor, isIterable, isNone, isScaleOptions, map, yes, maybeIn import {createScales, createScaleFunctions, autoScaleRange, exposeScales} from "./scales.js"; import {innerDimensions, outerDimensions} from "./scales.js"; import {position, registry as scaleRegistry} from "./scales/index.js"; -import {applyInlineStyles, maybeClassName} from "./style.js"; +import {applyAria, applyInlineStyles, maybeClassName} from "./style.js"; import {consumeWarnings, warn} from "./warnings.js"; export function plot(options = {}) { @@ -142,7 +142,7 @@ export function plot(options = {}) { const subdimensions = fx || fy ? innerDimensions(scaleDescriptors, dimensions) : dimensions; const superdimensions = fx || fy ? actualDimensions(scales, dimensions) : dimensions; const context = createContext(options, subdimensions, className); - const svg = context.ownerSVGElement; + const {ownerSVGElement: svg, document} = context; // Reinitialize; for deriving channels dependent on other channels. const newByScale = new Set(); @@ -198,6 +198,14 @@ export function plot(options = {}) { Object.assign(scales, newScales); } + // Sort and filter the facets to match the fx and fy domains; this is needed + // because the facets were constructed prior to the fx and fy scales. + let facetDomains; + if (facets !== undefined) { + facetDomains = {x: fx?.domain(), y: fy?.domain()}; + facets = recreateFacets(facets, facetDomains); + } + // Compute value objects, applying scales and projection as needed. for (const [mark, state] of stateByMark) { state.values = mark.scale(state.channels, scales, context); @@ -234,65 +242,51 @@ export function plot(options = {}) { ) .call(applyInlineStyles, style); - // Render non-faceted marks. + // Render marks. for (const mark of marks) { - if (facets !== undefined && mark.facet !== "super") continue; const {channels, values, facets: indexes} = stateByMark.get(mark); - let index = null; - if (indexes) { - index = indexes[0]; - index = mark.filter(index, channels, values); - if (index.length === 0) continue; - } - const node = mark.render(index, scales, values, superdimensions, context); - if (node != null) svg.appendChild(node); - } - - // Render facets. - if (facets !== undefined) { - const facetDomains = {x: fx?.domain(), y: fy?.domain()}; - // Sort and filter the facets to match the fx and fy domains; this is needed - // because the facets were constructed prior to the fx and fy scales. - facets = recreateFacets(facets, facetDomains); + // Render a non-faceted mark. + if (facets === undefined || mark.facet === "super") { + let index = null; + if (indexes) { + index = indexes[0]; + index = mark.filter(index, channels, values); + if (index.length === 0) continue; + } + const node = mark.render(index, scales, values, superdimensions, context); + if (node != null) svg.appendChild(node); + } - // Render the facets. - select(svg) - .selectAll() - .data(facets) - .enter() - .append("g") - .attr("aria-label", "facet") - .attr("transform", facetTranslate(fx, fy, dimensions)) - .each(function (f) { - let empty = true; - for (const mark of marks) { - if (mark.facet === "super") continue; // rendered below - const {channels, values, facets: indexes} = stateByMark.get(mark); - if (!(mark.facetAnchor?.(facets, facetDomains, f) ?? !f.empty)) continue; - let index = null; - if (indexes) { - index = indexes[facetStateByMark.has(mark) ? f.i : 0]; - index = mark.filter(index, channels, values); - if (index.length === 0) continue; - index.fx = f.x; - index.fy = f.y; - index.fi = f.i; - } - const node = mark.render(index, scales, values, subdimensions, context); - if (node == null) continue; - empty = false; - this.appendChild(node); + // Render a faceted mark. + else { + let g; + for (const f of facets) { + if (!(mark.facetAnchor?.(facets, facetDomains, f) ?? !f.empty)) continue; + let index = null; + if (indexes) { + index = indexes[facetStateByMark.has(mark) ? f.i : 0]; + index = mark.filter(index, channels, values); + if (index.length === 0) continue; + index.fx = f.x; + index.fy = f.y; + index.fi = f.i; } - if (empty) this.remove(); - }); + const node = mark.render(index, scales, values, subdimensions, context); + if (node == null) continue; + (g ??= select(svg).append("g").call(applyAria, mark)) + .append("g") + .datum(f) + .append(() => node); + } + g?.selectChildren().attr("transform", facetTranslate(fx, fy, dimensions)); + } } // Wrap the plot in a figure with a caption, if desired. let figure = svg; const legends = createLegends(scaleDescriptors, context, options); if (caption != null || legends.length > 0) { - const {document} = context; figure = document.createElement("figure"); figure.style.maxWidth = "initial"; for (const legend of legends) figure.appendChild(legend); diff --git a/src/style.js b/src/style.js index 5c229e192a..8224c04d03 100644 --- a/src/style.js +++ b/src/style.js @@ -350,10 +350,14 @@ function applyClip(selection, mark, dimensions, context) { // Here we’re careful to apply the ARIA attributes to the outer G element when // clipping is applied, and to apply the ARIA attributes before any other // attributes (for readability). + applyAria(selection, mark); + applyAttr(selection, "clip-path", clipUrl); +} + +export function applyAria(selection, mark) { applyAttr(selection, "aria-label", mark.ariaLabel); applyAttr(selection, "aria-description", mark.ariaDescription); applyAttr(selection, "aria-hidden", mark.ariaHidden); - applyAttr(selection, "clip-path", clipUrl); } // Note: may mutate selection.node! diff --git a/test/output/anscombeQuartet.svg b/test/output/anscombeQuartet.svg index e383ffed31..ea50b97bf4 100644 --- a/test/output/anscombeQuartet.svg +++ b/test/output/anscombeQuartet.svg @@ -13,191 +13,261 @@ white-space: pre; } + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + series + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4 + 6 + 8 + 10 + 12 + + + ↑ y - - x → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - 1 - - - - - - - - - - - - - - - - - 4 - 6 - 8 - 10 - 12 - - - - - - - - - - - - - 5 - 10 - 15 - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - 2 - - - - - - - - - - - - - - - - - - - - 5 - 10 - 15 - - - - - - - - - - - - - - + + + + 5 + 10 + 15 + + + + + 5 + 10 + 15 + + + + + 5 + 10 + 15 + + + + + 5 + 10 + 15 + - - - 3 - - - - - - - - - - - - - - - - - - - - 5 - 10 - 15 - - - - - - - - - - - - - - + + x → + + + + + + + + + + + + + - - - 4 - - - - - - - - - - - - - - - - - - - - 5 - 10 - 15 - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/athletesBoxingHeight.svg b/test/output/athletesBoxingHeight.svg index ed94fc9d80..900e2d5d63 100644 --- a/test/output/athletesBoxingHeight.svg +++ b/test/output/athletesBoxingHeight.svg @@ -13,343 +13,377 @@ white-space: pre; } + + + + Africa + + + + + Americas + + + + + Asia + + + + + Europe + + + + + Oceania + + + continent + + + + + + + + + + + + + + + + + 1.5 + 1.6 + 1.7 + 1.8 + 1.9 + 2.0 + 2.1 + + + ↑ height - - - Africa + + + - - - - - - - - + + - - 1.5 - 1.6 - 1.7 - 1.8 - 1.9 - 2.0 - 2.1 + + - - - ALG - ALG - EGY - MAR - SEY - KEN - TUN - ALG - CPV - CMR - NGR - ALG - MAR - CMR - MAR - TUN - EGY - ALG - NAM - CAF - UGA - MRI - MAR - CMR - EGY - NAM - MRI - ALG - MAR - MAR - MAR - CGO - KEN - ALG - CMR - EGY - ALG - MAR - - - - - Americas + + - - - BRA - VEN - ARG - ARG - BRA - USA - CAN - CUB - CAN - PAN - ECU - ECU - USA - COL - USA - USA - VEN - MEX - VEN - CUB - ARG - VEN - USA - DOM - ARG - COL - PUR - CUB - BRA - COL - MEX - COL - BRA - MEX - BRA - ECU - CUB - CUB - ARG - CUB - DOM - MEX - VEN - VEN - CAN - ECU - BRA - USA - MEX - USA - TTO - BRA - MEX - CUB - BRA - BRA - CUB - USA - VEN - ARG - CUB - VEN - CUB - COL + + - - - Asia + + + + ALG + ALG + EGY + MAR + SEY + KEN + TUN + ALG + CPV + CMR + NGR + ALG + MAR + CMR + MAR + TUN + EGY + ALG + NAM + CAF + UGA + MRI + MAR + CMR + EGY + NAM + MRI + ALG + MAR + MAR + MAR + CGO + KEN + ALG + CMR + EGY + ALG + MAR + - - - AZE - KAZ - KAZ - RUS - AZE - TUR - THA - RUS - RUS - TJK - ARM - JPN - TKM - RUS - ARM - UZB - TUR - UZB - KAZ - CHN - KAZ - CHN - PHI - THA - MGL - TPE - JPN - KAZ - KAZ - IRI - UZB - AZE - MGL - KGZ - RUS - UZB - CHN - MGL - QAT - UZB - ARM - UZB - JOR - RUS - KAZ - AZE - CHN - CHN - CHN - CHN - KAZ - AZE - IND - AZE - AZE - IND - TUR - CHN - RUS - UZB - ARM - TPE - JOR - KAZ - TUR - TUR - MGL - AZE - THA - RUS - CHN - CHN - PHI - AZE - UZB - KOR - THA - TUR - UZB - UZB - IND - AZE - QAT - MGL - MGL - RUS - KAZ - RUS - ARM - RUS - IRQ - CHN - THA - AZE - UZB - KAZ - KAZ + + + BRA + VEN + ARG + ARG + BRA + USA + CAN + CUB + CAN + PAN + ECU + ECU + USA + COL + USA + USA + VEN + MEX + VEN + CUB + ARG + VEN + USA + DOM + ARG + COL + PUR + CUB + BRA + COL + MEX + COL + BRA + MEX + BRA + ECU + CUB + CUB + ARG + CUB + DOM + MEX + VEN + VEN + CAN + ECU + BRA + USA + MEX + USA + TTO + BRA + MEX + CUB + BRA + BRA + CUB + USA + VEN + ARG + CUB + VEN + CUB + COL + - - - - Europe - - - - SWE - GBR - GER - GER - IRL - ITA - FRA - ITA - BUL - GER - IRL - UKR - UKR - BLR - LTU - FRA - NED - GER - FRA - LTU - CRO - GBR - ITA - GER - FRA - CRO - POL - HUN - ITA - GBR - GBR - IRL - GBR - GBR - IRL - GBR - ITA - FRA - IRL - IRL - ROU - BLR - FIN - GBR - UKR - GBR - NED - GBR - IRL - FRA - BLR - NED - GBR - ESP - FRA - GBR - GER - BUL - FRA - FRA - BUL - IRL - HON - UKR - POL - FRA - ITA - ITA - UKR - ESP - HUN + + + AZE + KAZ + KAZ + RUS + AZE + TUR + THA + RUS + RUS + TJK + ARM + JPN + TKM + RUS + ARM + UZB + TUR + UZB + KAZ + CHN + KAZ + CHN + PHI + THA + MGL + TPE + JPN + KAZ + KAZ + IRI + UZB + AZE + MGL + KGZ + RUS + UZB + CHN + MGL + QAT + UZB + ARM + UZB + JOR + RUS + KAZ + AZE + CHN + CHN + CHN + CHN + KAZ + AZE + IND + AZE + AZE + IND + TUR + CHN + RUS + UZB + ARM + TPE + JOR + KAZ + TUR + TUR + MGL + AZE + THA + RUS + CHN + CHN + PHI + AZE + UZB + KOR + THA + TUR + UZB + UZB + IND + AZE + QAT + MGL + MGL + RUS + KAZ + RUS + ARM + RUS + IRQ + CHN + THA + AZE + UZB + KAZ + KAZ + - - - - Oceania + + + SWE + GBR + GER + GER + IRL + ITA + FRA + ITA + BUL + GER + IRL + UKR + UKR + BLR + LTU + FRA + NED + GER + FRA + LTU + CRO + GBR + ITA + GER + FRA + CRO + POL + HUN + ITA + GBR + GBR + IRL + GBR + GBR + IRL + GBR + ITA + FRA + IRL + IRL + ROU + BLR + FIN + GBR + UKR + GBR + NED + GBR + IRL + FRA + BLR + NED + GBR + ESP + FRA + GBR + GER + BUL + FRA + FRA + BUL + IRL + HON + UKR + POL + FRA + ITA + ITA + UKR + ESP + HUN + - - - AUS - AUS - FSM - AUS - PNG + + + AUS + AUS + FSM + AUS + PNG + \ No newline at end of file diff --git a/test/output/athletesSampleFacet.svg b/test/output/athletesSampleFacet.svg index 782c9be797..f58d04e20f 100644 --- a/test/output/athletesSampleFacet.svg +++ b/test/output/athletesSampleFacet.svg @@ -13,577 +13,693 @@ white-space: pre; } - - sport - - - weight → - - - - aquatics - - - - - - - - - - - - Evan Van Moerkerke - Javier Garcia Gadea - Jordan Coelho - Markus Thormeyer - Mehdi Marzouki - Uvis Kalnins - Ziv Kalontarov - Aria Fischer - Farida Osman - Keesja Gofers - Makenzie Fischer - Mariia Shurochkina - Svetlana Romashina - Yekaterina Nemich - - - - - archery - - - - - - - - - - - - - - athletics - - - - - - - - - - - - A Jesus Garcia - Bachir Mahamat - Changrui Xue - Erick Barrondo - Jack Green - Joe Kovacs - Kurt Couto - Luguelin Santos - Paul Kipngetich Tanui - Theo Piniau - Tim Nedow - Yuri Floriani - Brenda Flores - Diana Martin - Hye-Song Kim - Jamile Samuel - Kamia Yousufi - Mirela Demireva - Nikkita Holder - Persis William-Mensah - Rosa Godoy - Shijie Qieyang - Vitoria Cristina Rosa - - - - - badminton - - - - - - - - - - - - Dong Keun Lee - Marc Zwiebler - Tontowi Ahmad - Birgit Michels - Liliyana Natsir - Sapsiree Taerattanachai - - - - - basketball - - - - - - - - - - - - Maryia Papova - - - - - boxing - - - - - - - - - - - - - - canoe - - - - - - - - - - - - Emanuel Silva - Filip Dvorak - Ricardas Nekriosius - Serguey Torres - Stephen Bird - Taras Mishchuk - - - - - cycling - - - - - - - - - - - - Alejandro Valverde Belmonte - Chun Hing Chan - Gregory Bauge - Hersony Canelon - Kleber da Silva Ramos - Matthew Glaetzer - Sam Webster - - - - - equestrian - - - - - - - - - - - - Jeroen Dubbeldam - Kevin Staut - - - - - fencing - - - - - - - - - - - - Gauthier Grumier - - - - - football - - - - - - - - - - - - Davie Selke - Michael Perez - Ashlyn Harris - Isabel Kerschowski - Julie Johnston - Leidy Asprilla - Olivia Schough - - - - - golf - - - - - - - - - - - - Chloe Leurquin - - - - - gymnastics - - - - - - - - - - - - Carolina Rodriguez - Danell Leyva - - - - - handball - - - - - - - - - - - - - - hockey - - - - - - - - - - - - Nic Woods - Robert van der Horst - Vicenc Ruiz - Caitlin van Sickle + + + + aquatics + + + + + archery + + + + + athletics + + + + + badminton + + + + + basketball + + + + + boxing + + + + + canoe + + + + + cycling + + + + + equestrian + + + + + fencing + + + + + football + + + + + golf + + + + + gymnastics + + + + + handball + + + + + hockey + + + + + judo + + + + + modern pentathlon + + + + + rowing + + + + + rugby sevens + + + + + sailing + + + + + shooting + + + + + table tennis + + + + + taekwondo + + + + + tennis + + + + + triathlon + + + + + volleyball + + + + + weightlifting + + + + + wrestling + - - - judo - - - - - - - - - - - - - - modern pentathlon - - - - - - - - - - - - - - rowing - - - - - - - - - - - - Alexander Sigurbjornsson - Raul Hernandez Hidalgo - Elena-Lavinia Tarlea - Ilse Paulis - Maaike Head - - - - - rugby sevens - - - - - - - - - - - - Maria Casado - Lomano Lemeki - Moises Duque - Seabelo Senatla - - - - - sailing - - - - - - - - - - - - Gil Cohen - Miho Yoshioka - Aichen Wang - Pieter-Jan Postma - - - - - shooting - - - - - - - - - - - - Alin George Moldoveanu - Will Brown - - - - - table tennis - - - - - - - - - - - - Jieni Shao - Xue Li - - - - - taekwondo - - - - - - - - - - - - Nur Tatar - Rabia Guelec - + + sport - - - tennis - - - - - - - - - - - - Angelique Kerber - Annika Beck - Daria Gavrilova + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - triathlon - - - - - - - - - - - - Ben Kanute - Ryan Bailie + + + + + + + + + + + - - - volleyball - - - - - - - - - - - - Pablo Herrera Allepuz - Simone Giannelli + + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 + - - - weightlifting - - - - - - - - - - - - Myong Hyok Kim - Yosuke Nakayama - Anastasiia Lysenko - + + weight → - - - wrestling - - - - - - - - - - - - - - - - - - - - - 40 - 60 - 80 - 100 - 120 - 140 - 160 - - - Amas Daniel - Craig Miller - Eduard Popp - Frank Chamizo Marquez - Soslan Daurov - Adela Hanzlickova - Katarzyna Krawczyk - Natalia Vorobeva + + + + Evan Van Moerkerke + Javier Garcia Gadea + Jordan Coelho + Markus Thormeyer + Mehdi Marzouki + Uvis Kalnins + Ziv Kalontarov + Aria Fischer + Farida Osman + Keesja Gofers + Makenzie Fischer + Mariia Shurochkina + Svetlana Romashina + Yekaterina Nemich + + + + + A Jesus Garcia + Bachir Mahamat + Changrui Xue + Erick Barrondo + Jack Green + Joe Kovacs + Kurt Couto + Luguelin Santos + Paul Kipngetich Tanui + Theo Piniau + Tim Nedow + Yuri Floriani + Brenda Flores + Diana Martin + Hye-Song Kim + Jamile Samuel + Kamia Yousufi + Mirela Demireva + Nikkita Holder + Persis William-Mensah + Rosa Godoy + Shijie Qieyang + Vitoria Cristina Rosa + + + + + Dong Keun Lee + Marc Zwiebler + Tontowi Ahmad + Birgit Michels + Liliyana Natsir + Sapsiree Taerattanachai + + + + + Maryia Papova + + + + + Emanuel Silva + Filip Dvorak + Ricardas Nekriosius + Serguey Torres + Stephen Bird + Taras Mishchuk + + + + + Alejandro Valverde Belmonte + Chun Hing Chan + Gregory Bauge + Hersony Canelon + Kleber da Silva Ramos + Matthew Glaetzer + Sam Webster + + + + + Jeroen Dubbeldam + Kevin Staut + + + + + Gauthier Grumier + + + + + Davie Selke + Michael Perez + Ashlyn Harris + Isabel Kerschowski + Julie Johnston + Leidy Asprilla + Olivia Schough + + + + + Chloe Leurquin + + + + + Carolina Rodriguez + Danell Leyva + + + + + Nic Woods + Robert van der Horst + Vicenc Ruiz + Caitlin van Sickle + + + + + Alexander Sigurbjornsson + Raul Hernandez Hidalgo + Elena-Lavinia Tarlea + Ilse Paulis + Maaike Head + + + + + Maria Casado + Lomano Lemeki + Moises Duque + Seabelo Senatla + + + + + Gil Cohen + Miho Yoshioka + Aichen Wang + Pieter-Jan Postma + + + + + Alin George Moldoveanu + Will Brown + + + + + Jieni Shao + Xue Li + + + + + Nur Tatar + Rabia Guelec + + + + + Angelique Kerber + Annika Beck + Daria Gavrilova + + + + + Ben Kanute + Ryan Bailie + + + + + Pablo Herrera Allepuz + Simone Giannelli + + + + + Myong Hyok Kim + Yosuke Nakayama + Anastasiia Lysenko + + + + + Amas Daniel + Craig Miller + Eduard Popp + Frank Chamizo Marquez + Soslan Daurov + Adela Hanzlickova + Katarzyna Krawczyk + Natalia Vorobeva + \ No newline at end of file diff --git a/test/output/athletesSortFacet.svg b/test/output/athletesSortFacet.svg index 0dab89ce58..352725014c 100644 --- a/test/output/athletesSortFacet.svg +++ b/test/output/athletesSortFacet.svg @@ -13,250 +13,318 @@ white-space: pre; } - - sport - - - - - boxing - - - - - - - - wrestling - - - - - - - - canoe - - - - - - - - cycling - - - - - - - - equestrian - - - - - - - - shooting - - - - - - - - judo - - - - - - - - rowing - - - - - - - - weightlifting - - - - - - - - sailing - - - - - - - - football - - - - - - - - tennis - - - - - - - - athletics - - - + + + + boxing + + + + + wrestling + + + + + canoe + + + + + cycling + + + + + equestrian + + + + + shooting + + + + + judo + + + + + rowing + + + + + weightlifting + + + + + sailing + + + + + football + + + + + tennis + + + + + athletics + + + + + golf + + + + + rugby sevens + + + + + aquatics + + + + + handball + + + + + archery + + + + + badminton + + + + + basketball + + + + + hockey + + + + + modern pentathlon + + + + + table tennis + + + + + taekwondo + + + + + triathlon + + + + + volleyball + + + + + fencing + + + + + gymnastics + - - - golf - - - - - - - - rugby sevens - - - - - - - - aquatics - - - - - - - - handball - - - - - - - - archery - - - - - - - - badminton - - - - - - - - basketball - - - - - - - - hockey - - - - - - - - modern pentathlon - - - - - - - - table tennis - - - - - - - - taekwondo - - - - - - - - triathlon - - - - + + sport - - - volleyball - - - + + + + + + + + + + + - - - fencing - - - + + + + 0.0 + 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 0.6 + - - - gymnastics - - - - - - - - - - - - 0.0 - 0.1 - 0.2 - 0.3 - 0.4 - 0.5 - 0.6 - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/athletesSportWeight.svg b/test/output/athletesSportWeight.svg index 876f8bce17..f29903d0b9 100644 --- a/test/output/athletesSportWeight.svg +++ b/test/output/athletesSportWeight.svg @@ -13,1308 +13,1436 @@ white-space: pre; } - - sport - - - weight → - - - - aquatics - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - archery - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - athletics - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - badminton - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - basketball - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - boxing - - - - - - - - - - - - - - canoe - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - cycling - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - equestrian - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - fencing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - football - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + aquatics + + + + + archery + + + + + athletics + + + + + badminton + + + + + basketball + + + + + boxing + + + + + canoe + + + + + cycling + + + + + equestrian + + + + + fencing + + + + + football + + + + + golf + + + + + gymnastics + + + + + handball + + + + + hockey + + + + + judo + + + + + modern pentathlon + + + + + rowing + + + + + rugby sevens + + + + + sailing + + + + + shooting + + + + + table tennis + + + + + taekwondo + + + + + tennis + + + + + triathlon + + + + + volleyball + + + + + weightlifting + + + + + wrestling + - - - golf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - gymnastics - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - handball - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - hockey - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - judo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - modern pentathlon - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - rowing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - rugby sevens - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - sailing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - shooting - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + sport - - - table tennis - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - taekwondo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - tennis - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 + - - - triathlon - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + weight → - - - volleyball - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - weightlifting - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - wrestling - - - - - - - - - - - - - - - - - - - - - 40 - 60 - 80 - 100 - 120 - 140 - 160 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/test/output/autoDotFacet.svg b/test/output/autoDotFacet.svg index c5cbc9c01f..b5438b7e3d 100644 --- a/test/output/autoDotFacet.svg +++ b/test/output/autoDotFacet.svg @@ -13,433 +13,475 @@ white-space: pre; } + + + + Biscoe + + + + + Dream + + + + + Torgersen + + + island + + + + + + + + + + + + + + + + + + + + + + + 34 + 36 + 38 + 40 + 42 + 44 + 46 + 48 + 50 + 52 + 54 + 56 + 58 + + + ↑ culmen_length_mm - - body_mass_g → - - - - Biscoe + + + + + + - - - - - - - - - - - - - - + + + + + - - 34 - 36 - 38 - 40 - 42 - 44 - 46 - 48 - 50 - 52 - 54 - 56 - 58 + + + + + - - - + + + + + 4,000 + 6,000 + - - 4,000 - 6,000 + + + 4,000 + 6,000 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 4,000 + 6,000 + - - - Dream - - - - + + body_mass_g → + + + + - - 4,000 - 6,000 + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - Torgersen - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 4,000 - 6,000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/autoDotFacet2.svg b/test/output/autoDotFacet2.svg index 3160af0d24..1223fde26d 100644 --- a/test/output/autoDotFacet2.svg +++ b/test/output/autoDotFacet2.svg @@ -13,479 +13,541 @@ white-space: pre; } + + + + Adelie + + + + + Chinstrap + + + + + Gentoo + + + species + + + + Biscoe + + + + + Dream + + + + + Torgersen + + + island - - ↑ culmen_length_mm - - - body_mass_g → - - - - Biscoe + + + + + + + + + - - - - - - + + + + + + + + - - 35 - 40 - 45 - 50 - 55 + + + + + + + + - - - + + + + + 35 + 40 + 45 + 50 + 55 + - - 4,000 - 6,000 + + + 35 + 40 + 45 + 50 + 55 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 35 + 40 + 45 + 50 + 55 + - - - - - - - - - - 35 - 40 - 45 - 50 - 55 + + ↑ culmen_length_mm + + + + + + + - - - + + + + + - - 4,000 - 6,000 + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - Dream + + + + 4,000 + 6,000 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 4,000 + 6,000 + - - - - - - - - + + + 4,000 + 6,000 + - - 35 - 40 - 45 - 50 - 55 + + + 4,000 + 6,000 + - - - + + + body_mass_g → + + + + - - 4,000 - 6,000 + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - Adelie + + - - Torgersen + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 4,000 - 6,000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - Chinstrap + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - Gentoo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/autoLineFacet.svg b/test/output/autoLineFacet.svg index 20f3f4ce36..57d1c314c4 100644 --- a/test/output/autoLineFacet.svg +++ b/test/output/autoLineFacet.svg @@ -13,264 +13,394 @@ white-space: pre; } - - industry - - - ↑ unemployed - - - - Agriculture - - - - - - - 1,000 - 2,000 - - - - - - - - - Business services - - - - - - - 1,000 - 2,000 - - - - - - - - - Construction - - - - - - - 1,000 - 2,000 - - - - + + + + Agriculture + + + + + Business services + + + + + Construction + + + + + Education and Health + + + + + Finance + + + + + Government + + + + + Information + + + + + Leisure and hospitality + + + + + Manufacturing + + + + + Mining and Extraction + + + + + Other + + + + + Self-employed + + + + + Transportation and Utilities + + + + + Wholesale and Retail Trade + - - - Education and Health - - - - - - - 1,000 - 2,000 - - - - - + + industry - - - Finance - - - - - - - 1,000 - 2,000 - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - Government - - - - - - - 1,000 - 2,000 - - - - + + + + 1,000 + 2,000 + + + + + 1,000 + 2,000 + + + + + 1,000 + 2,000 + + + + + 1,000 + 2,000 + + + + + 1,000 + 2,000 + + + + + 1,000 + 2,000 + + + + + 1,000 + 2,000 + + + + + 1,000 + 2,000 + + + + + 1,000 + 2,000 + + + + + 1,000 + 2,000 + + + + + 1,000 + 2,000 + + + + + 1,000 + 2,000 + + + + + 1,000 + 2,000 + + + + + 1,000 + 2,000 + - - - Information - - - - - - - 1,000 - 2,000 - - - - - + + ↑ unemployed - - - Leisure and hospitality - - - - - - - 1,000 - 2,000 - - - - + + + + + + + + + + - - - Manufacturing - - - - - - - 1,000 - 2,000 - - - - + + + + 2000 + 2002 + 2004 + 2006 + 2008 + 2010 + - - - Mining and Extraction - - - - - - - 1,000 - 2,000 + + + - - - + + - - - - Other + + - - - + + - - 1,000 - 2,000 + + - - - + + - - - - Self-employed + + - - - + + - - 1,000 - 2,000 + + - - - + + - - - - Transportation and Utilities + + - - - + + - - 1,000 - 2,000 + + - - - + + - - - Wholesale and Retail Trade - - - - - - - 1,000 - 2,000 - - - - - - - - - - - 2000 - 2002 - 2004 - 2006 - 2008 - 2010 - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/ballotStatusRace.svg b/test/output/ballotStatusRace.svg index 7650749658..d3420abeff 100644 --- a/test/output/ballotStatusRace.svg +++ b/test/output/ballotStatusRace.svg @@ -13,170 +13,234 @@ white-space: pre; } - - Frequency (%) → - - - - WHITE - - - - - - - - - 79.0% - 0.4% - 20.5% - - - + + + + WHITE + + + + + UNDESIGNATED + + + + + ASIAN + + + + + OTHER + + + + + TWO or MORE RACES + + + + + INDIAN AMERICAN or ALASKA NATIVE + + + + + BLACK or AFRICAN AMERICAN + + + + + NATIVE HAWAIIAN or PACIFIC ISLANDER + - - - UNDESIGNATED - - - - - - - - - 78.3% - 0.6% - 21.1% - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - ASIAN - - - - - - - - - 77.9% - 21.5% - 0.6% - - - + + + + + + + + - - - OTHER - - - - - - - - - 74.1% - 0.8% - 25.1% - - - + + + + 0 + 20 + 40 + 60 + - - - TWO or MORE RACES - - - - - - - - - 73.9% - 25.3% - 0.8% - - - - - - - - INDIAN AMERICAN or ALASKA NATIVE - - - - - - - - - 25.5% - 72.2% - 2.3% - - - - + + Frequency (%) → - - - BLACK or AFRICAN AMERICAN - - - - - - - - - 67.4% - 31.5% - 1.1% - - - + + + + 79.0% + 0.4% + 20.5% + + + + + 78.3% + 0.6% + 21.1% + + + + + 77.9% + 21.5% + 0.6% + + + + + 74.1% + 0.8% + 25.1% + + + + + 73.9% + 25.3% + 0.8% + + + + + 25.5% + 72.2% + 2.3% + + + + + 67.4% + 31.5% + 1.1% + + + + + 41.7% + 58.3% + - - - NATIVE HAWAIIAN or PACIFIC ISLANDER - - - - - - - - - - - - - - - 0 - 20 - 40 - 60 - - - 41.7% - 58.3% - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/beckerBarley.svg b/test/output/beckerBarley.svg index 730b6577c7..9585d7bf86 100644 --- a/test/output/beckerBarley.svg +++ b/test/output/beckerBarley.svg @@ -13,469 +13,563 @@ white-space: pre; } + + + + Waseca + + + + + Crookston + + + + + Morris + + + + + University Farm + + + + + Duluth + + + + + Grand Rapids + + + site - - variety + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - yield → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - Waseca - - - - - - - - - - - - - - - - - - - - - - - - - - - Trebi - Wisconsin No. 38 - No. 457 - Glabron - Peatland - Velvet - No. 475 - Manchuria - No. 462 - Svansota - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + Trebi + Wisconsin No. 38 + No. 457 + Glabron + Peatland + Velvet + No. 475 + Manchuria + No. 462 + Svansota + + + + + Trebi + Wisconsin No. 38 + No. 457 + Glabron + Peatland + Velvet + No. 475 + Manchuria + No. 462 + Svansota + + + + + Trebi + Wisconsin No. 38 + No. 457 + Glabron + Peatland + Velvet + No. 475 + Manchuria + No. 462 + Svansota + + + + + Trebi + Wisconsin No. 38 + No. 457 + Glabron + Peatland + Velvet + No. 475 + Manchuria + No. 462 + Svansota + + + + + Trebi + Wisconsin No. 38 + No. 457 + Glabron + Peatland + Velvet + No. 475 + Manchuria + No. 462 + Svansota + + + + + Trebi + Wisconsin No. 38 + No. 457 + Glabron + Peatland + Velvet + No. 475 + Manchuria + No. 462 + Svansota + - - - Crookston - - - - - - - - - - - - - - - - - - - - - - - - - - - Trebi - Wisconsin No. 38 - No. 457 - Glabron - Peatland - Velvet - No. 475 - Manchuria - No. 462 - Svansota - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + variety + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - Morris - - - - - - - - - - - - - - - - - - - - - - - - - - - Trebi - Wisconsin No. 38 - No. 457 - Glabron - Peatland - Velvet - No. 475 - Manchuria - No. 462 - Svansota - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - University Farm - - - - - - - - - - - - - - - - - - - - - - - - - - - Trebi - Wisconsin No. 38 - No. 457 - Glabron - Peatland - Velvet - No. 475 - Manchuria - No. 462 - Svansota - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 10 + 20 + 30 + 40 + 50 + 60 + 70 + - - - Duluth - - - - - - - - - - - - - - - - - - - - - - - - - - - Trebi - Wisconsin No. 38 - No. 457 - Glabron - Peatland - Velvet - No. 475 - Manchuria - No. 462 - Svansota - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + yield → + + + + + + + + + + + + + + + + + + + - - - Grand Rapids - - - - - - - - - - - - - - - - - - - - - - - - - - - Trebi - Wisconsin No. 38 - No. 457 - Glabron - Peatland - Velvet - No. 475 - Manchuria - No. 462 - Svansota - - - - - - - - - - - - - - - - - - - - - 10 - 20 - 30 - 40 - 50 - 60 - 70 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/boxplotFacetInterval.svg b/test/output/boxplotFacetInterval.svg index 3c5f27600d..ced273db40 100644 --- a/test/output/boxplotFacetInterval.svg +++ b/test/output/boxplotFacetInterval.svg @@ -13,623 +13,743 @@ white-space: pre; } - - height - - - weight → - - - - - - - 2.2 - - - - - - - - - - - - - - - - - 2.1 - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 2.2 + + + + + 2.1 + + + + + 2 + + + + + 1.9 + + + + + 1.8 + + + + + 1.7 + + + + + 1.6 + + + + + 1.5 + + + + + 1.4 + + + + + 1.3 + + + + + 1.2 + - - - - - - 1.9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + height - - - - - - 1.8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - 1.7 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 + - - - - - - 1.6 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + weight → - - - - - - 1.5 - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - 1.4 - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - 1.3 - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - 1.2 - - - - - - - - - - - - 40 - 60 - 80 - 100 - 120 - 140 - 160 - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/boxplotFacetNegativeInterval.svg b/test/output/boxplotFacetNegativeInterval.svg index 3c5f27600d..ced273db40 100644 --- a/test/output/boxplotFacetNegativeInterval.svg +++ b/test/output/boxplotFacetNegativeInterval.svg @@ -13,623 +13,743 @@ white-space: pre; } - - height - - - weight → - - - - - - - 2.2 - - - - - - - - - - - - - - - - - 2.1 - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 2.2 + + + + + 2.1 + + + + + 2 + + + + + 1.9 + + + + + 1.8 + + + + + 1.7 + + + + + 1.6 + + + + + 1.5 + + + + + 1.4 + + + + + 1.3 + + + + + 1.2 + - - - - - - 1.9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + height - - - - - - 1.8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - 1.7 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 + - - - - - - 1.6 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + weight → - - - - - - 1.5 - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - 1.4 - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - 1.3 - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - 1.2 - - - - - - - - - - - - 40 - 60 - 80 - 100 - 120 - 140 - 160 - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/caltrainDirection.svg b/test/output/caltrainDirection.svg index a29db0b289..00db651841 100644 --- a/test/output/caltrainDirection.svg +++ b/test/output/caltrainDirection.svg @@ -13,121 +13,139 @@ white-space: pre; } - - - B + + + + B + - - - - - - - - - - - - - - - - - + + + L + - - - - L + + + N + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - N + + + + 06 AM + 09 AM + 12 PM + 03 PM + 06 PM + 09 PM + 12 AM + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - 06 AM - 09 AM - 12 PM - 03 PM - 06 PM - 09 PM - 12 AM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/emptyFacet.svg b/test/output/emptyFacet.svg index 20359d2172..2348f8adcc 100644 --- a/test/output/emptyFacet.svg +++ b/test/output/emptyFacet.svg @@ -13,45 +13,67 @@ white-space: pre; } + + + + a + + + + + b + + + TYPE + + + + + + + + + + + 0 + + + VALUE - - PERIOD - - - - a - - - - - - 0 - - - - + + + + + + - - 1 - 2 + + + + + - - - b + + + + 1 + 2 + - - - - - - 1 - 2 + + + 1 + 2 + + + PERIOD + \ No newline at end of file diff --git a/test/output/footballCoverage.svg b/test/output/footballCoverage.svg index de6d8e03fd..4ecd7ca1ac 100644 --- a/test/output/footballCoverage.svg +++ b/test/output/footballCoverage.svg @@ -13,404 +13,462 @@ white-space: pre; } + + + + C2 + + + + + C3 + + + + + C4 + + + + + M0 + + + + + M1 + + + + + M2 + + + + + T2 + + + coverage - - - C2 + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + - - 0% - 5% - 10% - 15% - 20% - 25% - 30% - 35% - 40% - 45% - 50% + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - C3 - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - C4 + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + 0% + 5% + 10% + 15% + 20% + 25% + 30% + 35% + 40% + 45% + 50% + - - - M0 + + + - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - M1 + + + + + - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - M2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - T2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/frameFacet.svg b/test/output/frameFacet.svg index d995f68ca6..89d231a115 100644 --- a/test/output/frameFacet.svg +++ b/test/output/frameFacet.svg @@ -13,392 +13,414 @@ white-space: pre; } + + + + Adelie + + + + + Chinstrap + + + + + Gentoo + + + species - - body_mass_g → - - - - Adelie - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - Chinstrap - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 + - - - Gentoo + + body_mass_g → + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 3,000 - 3,500 - 4,000 - 4,500 - 5,000 - 5,500 - 6,000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/functionContourFaceted.svg b/test/output/functionContourFaceted.svg index e2b7f44fd5..63ebe1bddb 100644 --- a/test/output/functionContourFaceted.svg +++ b/test/output/functionContourFaceted.svg @@ -13,132 +13,180 @@ white-space: pre; } - - - lin - - - - - - - - - - - - 0 - 2 - 4 - 6 - 8 - 10 - 12 - - - - - - - - - - - - - - + + + + cos + + + + + lin + + - - - - - - - - - - - - 0 - 2 - 4 - 6 - 8 - 10 - 12 - - - - - - - - 0 - 5 - 10 - - - - - - - - - - - - - - + + + + lin + + + + + sin + + - - - cos - - - sin - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 2 + 4 + 6 + 8 + 10 + 12 + + + + + 0 + 2 + 4 + 6 + 8 + 10 + 12 + + + + + + + + + + + + + + + + + + - - - lin - - - - - - - - 0 - 5 - 10 - - - - - - - - - - - - - - + + + + 0 + 5 + 10 + + + + + 0 + 5 + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/functionContourFaceted2.svg b/test/output/functionContourFaceted2.svg index e2b7f44fd5..63ebe1bddb 100644 --- a/test/output/functionContourFaceted2.svg +++ b/test/output/functionContourFaceted2.svg @@ -13,132 +13,180 @@ white-space: pre; } - - - lin - - - - - - - - - - - - 0 - 2 - 4 - 6 - 8 - 10 - 12 - - - - - - - - - - - - - - + + + + cos + + + + + lin + + - - - - - - - - - - - - 0 - 2 - 4 - 6 - 8 - 10 - 12 - - - - - - - - 0 - 5 - 10 - - - - - - - - - - - - - - + + + + lin + + + + + sin + + - - - cos - - - sin - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 2 + 4 + 6 + 8 + 10 + 12 + + + + + 0 + 2 + 4 + 6 + 8 + 10 + 12 + + + + + + + + + + + + + + + + + + - - - lin - - - - - - - - 0 - 5 - 10 - - - - - - - - - - - - - - + + + + 0 + 5 + 10 + + + + + 0 + 5 + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/futureSplom.svg b/test/output/futureSplom.svg index 12ceb16f6c..ea41b752ea 100644 --- a/test/output/futureSplom.svg +++ b/test/output/futureSplom.svg @@ -13,220 +13,292 @@ white-space: pre; } - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - −1 - 0 - 1 - - - A - - - - - - - - - - - - - - - - - - - - - - - - - - - - −1 - 0 - 1 - - - * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - −1 - 0 - 1 - - - - - - - - −1 - 0 - 1 - - - * + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - * + + + + −1 + 0 + 1 + + + + + −1 + 0 + 1 + + + + + −1 + 0 + 1 + - - - B + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - −1 - 0 - 1 - - - * + + + + −1 + 0 + 1 + + + + + −1 + 0 + 1 + + + + + −1 + 0 + 1 + - - - - - - - - - - - - - - - - - - - - - * + + + + * + + + + + * + + + + + * + + + + + * + + + + + * + + + + + * + - - - - - - - - - - - - - - - - - - - - - * + + + + A + + + + + B + + + + + C + - - - - - + + + - - −1 - 0 - 1 + + - - C + + - \ No newline at end of file diff --git a/test/output/googleTrendsRidgeline.svg b/test/output/googleTrendsRidgeline.svg index deb225ade6..efec6a4edc 100644 --- a/test/output/googleTrendsRidgeline.svg +++ b/test/output/googleTrendsRidgeline.svg @@ -13,928 +13,1328 @@ white-space: pre; } - - - Australian bushfires - - - - - - - - - - - - - - - - - 2020 - February - March - April - May - June - July - August - September - October - November - December - - - - - - - - - - - - - - Qasem Soleimani - - - - - - - - - - - - - - Prince Harry, Meghan - - - - - - - - - - - - - - Brexit - - - - - - - - - - - - - - Impeachment - - - - - - - - - - - - - - Kobe Bryant - - - - - - - - - - - - - - Wuhan - - - - - - - - - - - - - - Nancy Pelosi - - - - - - - - - - - - - - Parasite - - - - - - - - - - - - - - Roger Stone - - - - - - - - - - - - - - Democratic primaries - - - - - - - - - - - - - - Love Is Blind - - - - - - - - - - - - - - Stock market - - - - - - - - - - - - - - Tom Hanks - - - - - - - - - - - - - - Trump coronavirus - - - - - - - - - - - - - - Locust - - - - - - - - - - - - - - Martial law - - - - - - - - - - - - - - Toilet paper - - - - - - - - - - - - - - Animal Crossing - - - - - - - - - - - - - - Anthony Fauci - - - - - - - - - - - - - - COVID-19 - - - - - - - - - - - - - - Tiger King - - - - - - - - - - - - - - Zoom Video Communications - - - - - - - - - - - - - - Masks - - - - - - - - - - - - - - Stimulus check - - - - - - - - - - - - - - Sourdough - - - - - - - - - - - - - - The Last Dance - - - - - - - - - - - - - - Kim Jong-un - - - - - - - - - - - - - - Murder hornet - - - - - - - - - - - - - - SpaceX - - - - - - - - - - - - - - Black Lives Matter - - - - - - - - - - - - - - George Floyd - - - - - - - - - - - - - - Ghislaine Maxwell - - - - - - - - - - - - - - TikTok - - - - - - - - - - - - - - Taylor Swift - - - - - - - - - - - - - - Hydroxychloroquine - - - - - - - - - - - - - - John Lewis - - - - - - - - - - - - - - Regis Philbin - - - - - - - - - - - - - - William Barr - - - - - - - - - - - - - - Beirut explosion - - - - - - - - - - - - - - Kamala Harris - - - - - - - - - - - - - - QAnon - - - - - - - - - - - - - - Chadwick Boseman - - - - - - - - - - - - - - Hurricane Laura - - - - - - - - - - - - - - Jacob Blake - - - - - - - - - - - - - - Naomi Osaka - - - - - - - - - - - - - - Wildfires - - - - - - - - - - - - - - Hurricane Teddy - - - - - - - - - - - - - - Ruth Bader Ginsburg - - - - - - - - - - - - - - Breonna Taylor - - - - - - - - - - - - - - Presidential debates - - - - - - - - - - - - - - Proud Boys - - - - - - - - - - - - - - Eddie Van Halen - - - - - - - - - - - - - - Amy Coney Barrett - - - - - - - - - - - - - - Hunter Biden - - - - - - - - - - - - - - Absentee ballot - - - - - - - - - - - - - - Joe Biden - - - - - - - - - - - - - - Voter turnout - - - - - - - - - - - - - - Alex Trebek - - - - - - - - - - - - - - Electoral fraud - - - - - - - - - - - - - - Four seasons total landscaping - - - - - - - - - - - - - - Hurricane Iota - - - - - - - - - - - - - - Rudy Giuliani - - - - - - - - - - - - - - COVID-19 vaccine - - - - - - - - - + + + + Australian bushfires + + + + + Qasem Soleimani + + + + + Prince Harry, Meghan + + + + + Brexit + + + + + Impeachment + + + + + Kobe Bryant + + + + + Wuhan + + + + + Nancy Pelosi + + + + + Parasite + + + + + Roger Stone + + + + + Democratic primaries + + + + + Love Is Blind + + + + + Stock market + + + + + Tom Hanks + + + + + Trump coronavirus + + + + + Locust + + + + + Martial law + + + + + Toilet paper + + + + + Animal Crossing + + + + + Anthony Fauci + + + + + COVID-19 + + + + + Tiger King + + + + + Zoom Video Communications + + + + + Masks + + + + + Stimulus check + + + + + Sourdough + + + + + The Last Dance + + + + + Kim Jong-un + + + + + Murder hornet + + + + + SpaceX + + + + + Black Lives Matter + + + + + George Floyd + + + + + Ghislaine Maxwell + + + + + TikTok + + + + + Taylor Swift + + + + + Hydroxychloroquine + + + + + John Lewis + + + + + Regis Philbin + + + + + William Barr + + + + + Beirut explosion + + + + + Kamala Harris + + + + + QAnon + + + + + Chadwick Boseman + + + + + Hurricane Laura + + + + + Jacob Blake + + + + + Naomi Osaka + + + + + Wildfires + + + + + Hurricane Teddy + + + + + Ruth Bader Ginsburg + + + + + Breonna Taylor + + + + + Presidential debates + + + + + Proud Boys + + + + + Eddie Van Halen + + + + + Amy Coney Barrett + + + + + Hunter Biden + + + + + Absentee ballot + + + + + Joe Biden + + + + + Voter turnout + + + + + Alex Trebek + + + + + Electoral fraud + + + + + Four seasons total landscaping + + + + + Hurricane Iota + + + + + Rudy Giuliani + + + + + COVID-19 vaccine + + + + + + + + + + + + + + + + + + + + + + + + + 2020 + February + March + April + May + June + July + August + September + October + November + December + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/heatmapFaceted.svg b/test/output/heatmapFaceted.svg index cb80d84132..b420822557 100644 --- a/test/output/heatmapFaceted.svg +++ b/test/output/heatmapFaceted.svg @@ -13,96 +13,144 @@ white-space: pre; } - - - lin - - - - - - - - - - - - 0 - 2 - 4 - 6 - 8 - 10 - 12 - - - - - + + + + cos + + + + + lin + + + + + + + lin + + + + + sin + + - - - - - - - - - - - - 0 - 2 - 4 - 6 - 8 - 10 - 12 - - - - - - - - 0 - 5 - 10 - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - cos + + + + 0 + 2 + 4 + 6 + 8 + 10 + 12 + + + + + 0 + 2 + 4 + 6 + 8 + 10 + 12 + - - sin + + + + + + + + + + + + + + + - - + + + + + 0 + 5 + 10 + + + + + 0 + 5 + 10 + + + + + + + + + + + + + + + + + + + + + + + - - - - lin + + + - - - - + + - - 0 - 5 - 10 + + - - + + - \ No newline at end of file diff --git a/test/output/hexbinR.html b/test/output/hexbinR.html index f24daf11db..4125129c89 100644 --- a/test/output/hexbinR.html +++ b/test/output/hexbinR.html @@ -48,254 +48,302 @@ white-space: pre; } + + + + FEMALE + + + + + MALE + + + sex + + + + + + + + + + + + + + + 35 + 40 + 45 + 50 + 55 + + + ↑ culmen_length_mm - - culmen_depth_mm → - - - - FEMALE - - - - - - - + + + + + + + + - - 35 - 40 - 45 - 50 - 55 + + + + + + + - - - - - + + + + + + + - - 14 - 16 - 18 - 20 + + + + + 14 + 16 + 18 + 20 + - - - - - - - + + + 14 + 16 + 18 + 20 - - 9 - 8 - 8 - 8 - 6 - 6 - 6 - 5 - 5 - 5 - 5 - 4 - 4 - 4 - 3 - 3 - 3 - 3 - 3 - 3 - 3 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 + + + 14 + 16 + 18 + 20 + - - - MALE + + culmen_depth_mm → + + + + - - - - - + + - - 14 - 16 - 18 - 20 + + - - - - - - - + + + + + + + + + + - - 11 - 9 - 8 - 7 - 5 - 5 - 5 - 4 - 4 - 4 - 4 - 4 - 4 - 4 - 4 - 3 - 3 - 3 - 3 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 + + + + + + + + + - - - - - - - + + + + + + + + + - - 14 - 16 - 18 - 20 + + + + + 9 + 8 + 8 + 8 + 6 + 6 + 6 + 5 + 5 + 5 + 5 + 4 + 4 + 4 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + - - - - - - - + + + 11 + 9 + 8 + 7 + 5 + 5 + 5 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 3 + 3 + 3 + 3 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 - - 2 - 1 - 1 - 1 - 1 - 1 - 1 - 1 + + + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + \ No newline at end of file diff --git a/test/output/hexbinText.svg b/test/output/hexbinText.svg index 354ab5a8da..94333f8cd7 100644 --- a/test/output/hexbinText.svg +++ b/test/output/hexbinText.svg @@ -13,368 +13,424 @@ white-space: pre; } + + + + FEMALE + + + + + MALE + + + sex + + + + + + + + + + + + + + + 35 + 40 + 45 + 50 + 55 + + + ↑ culmen_length_mm - - culmen_depth_mm → - - - - FEMALE - - - - - - - - - - 35 - 40 - 45 - 50 - 55 + + + + + + + + - - - - - + + + + + + + - - 14 - 16 - 18 - 20 + + + + + + + - - - - - - - + + + + + 14 + 16 + 18 + 20 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 14 + 16 + 18 + 20 + - - 4 - 5 - 2 - 6 - 1 - 7 - 3 - 2 - 4 - 6 - 3 - 8 - 1 - 7 - 4 - 3 - 1 - 2 - 1 - 2 - 1 - 1 - 5 - 1 - 2 - 2 - 1 - 5 - 1 - 3 - 2 - 1 - 2 - 1 - 2 - 2 - 1 - 1 - 1 - 1 - 4 - 7 - 7 - 3 - 1 - 10 - 3 - 1 - 2 - 4 - 6 - 2 - 3 - 1 - 1 - 1 - 1 + + + 14 + 16 + 18 + 20 + - - - MALE + + culmen_depth_mm → + + + + - - - - - + + - - 14 - 16 - 18 - 20 + + - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - 16 - 1 - 5 - 2 - 1 - 3 - 1 - 3 - 3 - 1 - 1 - 1 - 1 - 5 - 3 - 7 - 4 - 2 - 1 - 3 - 1 - 2 - 1 - 1 - 1 - 3 - 6 - 7 - 4 - 4 - 1 - 1 - 1 - 3 - 1 - 1 - 2 - 1 - 1 - 1 - 6 - 6 - 2 - 4 - 3 - 7 - 8 - 7 - 2 - 1 - 1 - 1 - 1 - 1 - 1 - 2 - 2 - 1 - 2 - 1 - 1 - 1 + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 14 - 16 - 18 - 20 + + + + + + + + + + + - - - - - - - + + + + + 4 + 5 + 2 + 6 + 1 + 7 + 3 + 2 + 4 + 6 + 3 + 8 + 1 + 7 + 4 + 3 + 1 + 2 + 1 + 2 + 1 + 1 + 5 + 1 + 2 + 2 + 1 + 5 + 1 + 3 + 2 + 1 + 2 + 1 + 2 + 2 + 1 + 1 + 1 + 1 + 4 + 7 + 7 + 3 + 1 + 10 + 3 + 1 + 2 + 4 + 6 + 2 + 3 + 1 + 1 + 1 + 1 - - - - - - - - - + + + 16 + 1 + 5 + 2 + 1 + 3 + 1 + 3 + 3 + 1 + 1 + 1 + 1 + 5 + 3 + 7 + 4 + 2 + 1 + 3 + 1 + 2 + 1 + 1 + 1 + 3 + 6 + 7 + 4 + 4 + 1 + 1 + 1 + 3 + 1 + 1 + 2 + 1 + 1 + 1 + 6 + 6 + 2 + 4 + 3 + 7 + 8 + 7 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 2 + 2 + 1 + 2 + 1 + 1 + 1 + - - 1 - 1 - 2 - 1 - 1 - 1 - 1 - 1 + + + 1 + 1 + 2 + 1 + 1 + 1 + 1 + 1 + \ No newline at end of file diff --git a/test/output/industryUnemploymentTrack.svg b/test/output/industryUnemploymentTrack.svg index 1fdb4b52c6..92912cea24 100644 --- a/test/output/industryUnemploymentTrack.svg +++ b/test/output/industryUnemploymentTrack.svg @@ -13,1913 +13,2013 @@ white-space: pre; } - - industry - - - - Construction + + + + Construction + - - 745 - 812 - 669 - 447 - 397 - 389 - 384 - 446 - 386 - 417 - 482 - 580 - 836 - 826 - 683 - 596 - 478 - 443 - 447 - 522 - 489 - 535 - 670 - 785 - 1,211 - 1,060 - 1,009 - 855 - 626 - 593 - 594 - 654 - 615 - 680 - 758 - 941 - 1,196 - 1,173 - 987 - 772 - 715 - 710 - 677 - 650 - 681 - 651 - 690 - 813 - 994 - 1,039 - 1,011 - 849 - 665 - 668 - 610 - 563 - 629 - 635 - 695 - 870 - 1,079 - 1,150 - 961 - 693 - 567 - 559 - 509 - 561 - 572 - 519 - 564 - 813 - 868 - 836 - 820 - 674 - 647 - 569 - 633 - 618 - 586 - 456 - 618 - 725 - 922 - 1,086 - 924 - 853 - 676 - 600 - 617 - 558 - 596 - 641 - 645 - 968 - 1,099 - 1,118 - 1,170 - 1,057 - 809 - 785 - 783 - 814 - 970 - 1,078 - 1,237 - 1,438 - 1,744 - 2,025 - 1,979 - 1,737 - 1,768 - 1,601 - 1,687 - 1,542 - 1,594 - 1,744 - 1,780 - 2,044 - 2,194 - 2,440 + + + Wholesale and Retail Trade + - - 2,440 + + + Manufacturing + - - 384 + + + Leisure and hospitality + - - - - Wholesale and Retail Trade + + + Business services + - - 1,000 - 1,023 - 983 - 793 - 821 - 837 - 792 - 853 - 791 - 739 - 701 - 715 - 908 - 990 - 1,037 - 820 - 875 - 955 - 833 - 928 - 936 - 941 - 1,046 - 1,074 - 1,212 - 1,264 - 1,269 - 1,222 - 1,138 - 1,240 - 1,132 - 1,170 - 1,171 - 1,212 - 1,242 - 1,150 - 1,342 - 1,238 - 1,179 - 1,201 - 1,247 - 1,434 - 1,387 - 1,161 - 1,229 - 1,189 - 1,156 - 1,081 - 1,389 - 1,369 - 1,386 - 1,248 - 1,183 - 1,182 - 1,163 - 1,079 - 1,127 - 1,138 - 1,045 - 1,058 - 1,302 - 1,301 - 1,173 - 1,131 - 1,145 - 1,197 - 1,194 - 1,130 - 1,038 - 1,050 - 1,013 - 968 - 1,203 - 1,141 - 1,022 - 972 - 1,025 - 1,085 - 1,083 - 977 - 1,008 - 972 - 1,018 - 965 - 1,166 - 1,045 - 896 - 872 - 795 - 979 - 1,089 - 1,028 - 1,027 - 907 - 893 - 1,009 - 1,120 - 1,007 - 992 - 919 - 1,049 - 1,160 - 1,329 - 1,366 - 1,277 - 1,313 - 1,397 - 1,535 - 1,794 - 1,847 - 1,852 - 1,833 - 1,835 - 1,863 - 1,854 - 1,794 - 1,809 - 1,919 - 1,879 - 1,851 - 2,154 - 2,071 + + + Education and Health + - - 2,154 + + + Government + - - 701 + + + Self-employed + - - - - Manufacturing + + + Finance + - - 734 - 694 - 739 - 736 - 685 - 621 - 708 - 685 - 667 - 693 - 672 - 653 - 911 - 902 - 954 - 855 - 903 - 956 - 1,054 - 1,023 - 996 - 1,065 - 1,108 - 1,172 - 1,377 - 1,296 - 1,367 - 1,322 - 1,194 - 1,187 - 1,185 - 1,108 - 1,076 - 1,046 - 1,115 - 1,188 - 1,302 - 1,229 - 1,222 - 1,199 - 1,150 - 1,232 - 1,193 - 1,186 - 1,175 - 1,041 - 1,034 - 1,025 - 1,110 - 1,094 - 1,083 - 1,004 - 966 - 957 - 1,019 - 840 - 852 - 884 - 905 - 872 - 889 - 889 - 879 - 793 - 743 - 743 - 883 - 767 - 775 - 800 - 823 - 757 - 778 - 821 - 701 - 745 - 680 - 635 - 736 - 680 - 632 - 618 - 702 - 660 - 752 - 774 - 742 - 749 - 651 - 653 - 621 - 596 - 673 - 729 - 762 - 772 - 837 - 820 - 831 - 796 - 879 - 862 - 908 - 960 - 984 - 1,007 - 1,144 - 1,315 - 1,711 - 1,822 - 1,912 - 1,968 - 2,010 - 2,010 - 1,988 - 1,866 - 1,876 - 1,884 - 1,882 - 1,747 - 1,918 - 1,814 + + + Transportation and Utilities + - - 2,010 + + + Other + - - 596 + + + Information + - - - - Leisure and hospitality + + + Agriculture + - - 782 - 779 - 789 - 658 - 675 - 833 - 786 - 675 - 636 - 691 - 694 - 639 - 806 - 821 - 817 - 744 - 731 - 821 - 813 - 767 - 900 - 903 - 935 - 938 - 947 - 973 - 976 - 953 - 1,022 - 1,034 - 999 - 884 - 885 - 956 - 978 - 922 - 1,049 - 1,145 - 1,035 - 986 - 955 - 1,048 - 1,020 - 1,050 - 978 - 933 - 990 - 885 - 1,097 - 987 - 1,039 - 925 - 977 - 1,189 - 965 - 1,010 - 854 - 853 - 916 - 850 - 993 - 1,008 - 967 - 882 - 944 - 950 - 929 - 844 - 842 - 796 - 966 - 930 - 910 - 1,040 - 917 - 882 - 830 - 942 - 867 - 855 - 810 - 795 - 836 - 701 - 911 - 879 - 845 - 822 - 831 - 917 - 920 - 877 - 892 - 911 - 986 - 961 - 1,176 - 1,056 - 944 - 874 - 1,074 - 1,154 - 1,172 - 1,122 - 1,029 - 1,126 - 1,283 - 1,210 - 1,487 - 1,477 - 1,484 - 1,322 - 1,599 - 1,688 - 1,600 - 1,636 - 1,469 - 1,604 - 1,524 - 1,624 - 1,804 - 1,597 + + + Mining and Extraction + - - 1,804 + + + industry + + + + + + + + + + + - - 636 + + + + + 2000 + 2002 + 2004 + 2006 + 2008 + 2010 + - - - Business services + + + + 745 + 812 + 669 + 447 + 397 + 389 + 384 + 446 + 386 + 417 + 482 + 580 + 836 + 826 + 683 + 596 + 478 + 443 + 447 + 522 + 489 + 535 + 670 + 785 + 1,211 + 1,060 + 1,009 + 855 + 626 + 593 + 594 + 654 + 615 + 680 + 758 + 941 + 1,196 + 1,173 + 987 + 772 + 715 + 710 + 677 + 650 + 681 + 651 + 690 + 813 + 994 + 1,039 + 1,011 + 849 + 665 + 668 + 610 + 563 + 629 + 635 + 695 + 870 + 1,079 + 1,150 + 961 + 693 + 567 + 559 + 509 + 561 + 572 + 519 + 564 + 813 + 868 + 836 + 820 + 674 + 647 + 569 + 633 + 618 + 586 + 456 + 618 + 725 + 922 + 1,086 + 924 + 853 + 676 + 600 + 617 + 558 + 596 + 641 + 645 + 968 + 1,099 + 1,118 + 1,170 + 1,057 + 809 + 785 + 783 + 814 + 970 + 1,078 + 1,237 + 1,438 + 1,744 + 2,025 + 1,979 + 1,737 + 1,768 + 1,601 + 1,687 + 1,542 + 1,594 + 1,744 + 1,780 + 2,044 + 2,194 + 2,440 + - - 655 - 587 - 623 - 517 - 561 - 545 - 636 - 584 - 559 - 504 - 547 - 564 - 734 - 724 - 652 - 655 - 652 - 694 - 731 - 790 - 810 - 910 - 946 - 921 - 1,120 - 973 - 964 - 951 - 983 - 1,079 - 1,075 - 926 - 1,007 - 962 - 1,029 - 1,038 - 1,112 - 1,140 - 1,190 - 1,076 - 1,105 - 1,092 - 1,021 - 881 - 975 - 1,014 - 948 - 948 - 1,070 - 964 - 999 - 752 - 819 - 814 - 790 - 845 - 750 - 781 - 872 - 875 - 958 - 916 - 807 - 714 - 730 - 743 - 804 - 728 - 862 - 748 - 711 - 788 - 825 - 841 - 824 - 644 - 695 - 753 - 735 - 681 - 736 - 768 - 658 - 791 - 885 - 825 - 775 - 689 - 743 - 722 - 743 - 683 - 655 - 675 - 679 - 803 - 893 - 866 - 876 - 736 - 829 - 890 - 866 - 961 - 951 - 1,052 - 992 - 1,147 - 1,445 - 1,512 - 1,597 - 1,448 - 1,514 - 1,580 - 1,531 - 1,560 - 1,596 - 1,488 - 1,514 - 1,486 - 1,614 - 1,740 + + + 1,000 + 1,023 + 983 + 793 + 821 + 837 + 792 + 853 + 791 + 739 + 701 + 715 + 908 + 990 + 1,037 + 820 + 875 + 955 + 833 + 928 + 936 + 941 + 1,046 + 1,074 + 1,212 + 1,264 + 1,269 + 1,222 + 1,138 + 1,240 + 1,132 + 1,170 + 1,171 + 1,212 + 1,242 + 1,150 + 1,342 + 1,238 + 1,179 + 1,201 + 1,247 + 1,434 + 1,387 + 1,161 + 1,229 + 1,189 + 1,156 + 1,081 + 1,389 + 1,369 + 1,386 + 1,248 + 1,183 + 1,182 + 1,163 + 1,079 + 1,127 + 1,138 + 1,045 + 1,058 + 1,302 + 1,301 + 1,173 + 1,131 + 1,145 + 1,197 + 1,194 + 1,130 + 1,038 + 1,050 + 1,013 + 968 + 1,203 + 1,141 + 1,022 + 972 + 1,025 + 1,085 + 1,083 + 977 + 1,008 + 972 + 1,018 + 965 + 1,166 + 1,045 + 896 + 872 + 795 + 979 + 1,089 + 1,028 + 1,027 + 907 + 893 + 1,009 + 1,120 + 1,007 + 992 + 919 + 1,049 + 1,160 + 1,329 + 1,366 + 1,277 + 1,313 + 1,397 + 1,535 + 1,794 + 1,847 + 1,852 + 1,833 + 1,835 + 1,863 + 1,854 + 1,794 + 1,809 + 1,919 + 1,879 + 1,851 + 2,154 + 2,071 + - - 1,740 + + + 734 + 694 + 739 + 736 + 685 + 621 + 708 + 685 + 667 + 693 + 672 + 653 + 911 + 902 + 954 + 855 + 903 + 956 + 1,054 + 1,023 + 996 + 1,065 + 1,108 + 1,172 + 1,377 + 1,296 + 1,367 + 1,322 + 1,194 + 1,187 + 1,185 + 1,108 + 1,076 + 1,046 + 1,115 + 1,188 + 1,302 + 1,229 + 1,222 + 1,199 + 1,150 + 1,232 + 1,193 + 1,186 + 1,175 + 1,041 + 1,034 + 1,025 + 1,110 + 1,094 + 1,083 + 1,004 + 966 + 957 + 1,019 + 840 + 852 + 884 + 905 + 872 + 889 + 889 + 879 + 793 + 743 + 743 + 883 + 767 + 775 + 800 + 823 + 757 + 778 + 821 + 701 + 745 + 680 + 635 + 736 + 680 + 632 + 618 + 702 + 660 + 752 + 774 + 742 + 749 + 651 + 653 + 621 + 596 + 673 + 729 + 762 + 772 + 837 + 820 + 831 + 796 + 879 + 862 + 908 + 960 + 984 + 1,007 + 1,144 + 1,315 + 1,711 + 1,822 + 1,912 + 1,968 + 2,010 + 2,010 + 1,988 + 1,866 + 1,876 + 1,884 + 1,882 + 1,747 + 1,918 + 1,814 + - - 504 + + + 782 + 779 + 789 + 658 + 675 + 833 + 786 + 675 + 636 + 691 + 694 + 639 + 806 + 821 + 817 + 744 + 731 + 821 + 813 + 767 + 900 + 903 + 935 + 938 + 947 + 973 + 976 + 953 + 1,022 + 1,034 + 999 + 884 + 885 + 956 + 978 + 922 + 1,049 + 1,145 + 1,035 + 986 + 955 + 1,048 + 1,020 + 1,050 + 978 + 933 + 990 + 885 + 1,097 + 987 + 1,039 + 925 + 977 + 1,189 + 965 + 1,010 + 854 + 853 + 916 + 850 + 993 + 1,008 + 967 + 882 + 944 + 950 + 929 + 844 + 842 + 796 + 966 + 930 + 910 + 1,040 + 917 + 882 + 830 + 942 + 867 + 855 + 810 + 795 + 836 + 701 + 911 + 879 + 845 + 822 + 831 + 917 + 920 + 877 + 892 + 911 + 986 + 961 + 1,176 + 1,056 + 944 + 874 + 1,074 + 1,154 + 1,172 + 1,122 + 1,029 + 1,126 + 1,283 + 1,210 + 1,487 + 1,477 + 1,484 + 1,322 + 1,599 + 1,688 + 1,600 + 1,636 + 1,469 + 1,604 + 1,524 + 1,624 + 1,804 + 1,597 + - - - - Education and Health + + + 655 + 587 + 623 + 517 + 561 + 545 + 636 + 584 + 559 + 504 + 547 + 564 + 734 + 724 + 652 + 655 + 652 + 694 + 731 + 790 + 810 + 910 + 946 + 921 + 1,120 + 973 + 964 + 951 + 983 + 1,079 + 1,075 + 926 + 1,007 + 962 + 1,029 + 1,038 + 1,112 + 1,140 + 1,190 + 1,076 + 1,105 + 1,092 + 1,021 + 881 + 975 + 1,014 + 948 + 948 + 1,070 + 964 + 999 + 752 + 819 + 814 + 790 + 845 + 750 + 781 + 872 + 875 + 958 + 916 + 807 + 714 + 730 + 743 + 804 + 728 + 862 + 748 + 711 + 788 + 825 + 841 + 824 + 644 + 695 + 753 + 735 + 681 + 736 + 768 + 658 + 791 + 885 + 825 + 775 + 689 + 743 + 722 + 743 + 683 + 655 + 675 + 679 + 803 + 893 + 866 + 876 + 736 + 829 + 890 + 866 + 961 + 951 + 1,052 + 992 + 1,147 + 1,445 + 1,512 + 1,597 + 1,448 + 1,514 + 1,580 + 1,531 + 1,560 + 1,596 + 1,488 + 1,514 + 1,486 + 1,614 + 1,740 + - - 353 - 349 - 381 - 329 - 423 - 452 - 478 - 450 - 398 - 339 - 351 - 293 - 428 - 423 - 456 - 341 - 390 - 476 - 513 - 595 - 455 - 486 - 516 - 483 - 586 - 590 - 540 - 493 - 533 - 638 - 671 - 660 - 562 - 517 - 493 - 558 - 559 - 576 - 518 - 611 - 618 - 769 - 697 - 760 - 649 - 639 - 662 - 620 - 662 - 608 - 584 - 589 - 570 - 769 - 725 - 647 - 593 - 526 - 570 - 562 - 613 - 619 - 614 - 591 - 648 - 667 - 635 - 644 - 658 - 628 - 677 - 529 - 593 - 528 - 563 - 558 - 543 - 617 - 659 - 611 - 576 - 531 - 536 - 502 - 563 - 489 - 495 - 555 - 622 - 653 - 665 - 648 - 630 - 534 - 526 - 521 - 576 - 562 - 609 - 551 - 619 - 669 - 776 - 844 - 835 - 797 - 748 - 791 - 792 - 847 - 931 - 964 - 1,005 - 1,267 - 1,269 - 1,239 - 1,257 - 1,280 - 1,168 - 1,183 - 1,175 - 1,200 + + + 353 + 349 + 381 + 329 + 423 + 452 + 478 + 450 + 398 + 339 + 351 + 293 + 428 + 423 + 456 + 341 + 390 + 476 + 513 + 595 + 455 + 486 + 516 + 483 + 586 + 590 + 540 + 493 + 533 + 638 + 671 + 660 + 562 + 517 + 493 + 558 + 559 + 576 + 518 + 611 + 618 + 769 + 697 + 760 + 649 + 639 + 662 + 620 + 662 + 608 + 584 + 589 + 570 + 769 + 725 + 647 + 593 + 526 + 570 + 562 + 613 + 619 + 614 + 591 + 648 + 667 + 635 + 644 + 658 + 628 + 677 + 529 + 593 + 528 + 563 + 558 + 543 + 617 + 659 + 611 + 576 + 531 + 536 + 502 + 563 + 489 + 495 + 555 + 622 + 653 + 665 + 648 + 630 + 534 + 526 + 521 + 576 + 562 + 609 + 551 + 619 + 669 + 776 + 844 + 835 + 797 + 748 + 791 + 792 + 847 + 931 + 964 + 1,005 + 1,267 + 1,269 + 1,239 + 1,257 + 1,280 + 1,168 + 1,183 + 1,175 + 1,200 + - - 1,280 + + + 430 + 409 + 311 + 269 + 370 + 603 + 545 + 583 + 408 + 391 + 384 + 365 + 463 + 298 + 355 + 369 + 361 + 525 + 548 + 540 + 438 + 429 + 420 + 419 + 486 + 508 + 477 + 447 + 484 + 561 + 645 + 596 + 530 + 499 + 468 + 446 + 571 + 483 + 526 + 440 + 478 + 704 + 749 + 745 + 556 + 500 + 542 + 516 + 511 + 490 + 530 + 433 + 468 + 580 + 741 + 676 + 568 + 561 + 514 + 499 + 555 + 472 + 468 + 478 + 453 + 681 + 683 + 664 + 568 + 502 + 494 + 393 + 457 + 472 + 461 + 414 + 429 + 578 + 659 + 595 + 396 + 424 + 400 + 395 + 476 + 405 + 419 + 408 + 428 + 572 + 704 + 695 + 525 + 492 + 482 + 451 + 471 + 372 + 425 + 373 + 461 + 654 + 770 + 721 + 573 + 552 + 527 + 511 + 652 + 563 + 598 + 575 + 702 + 991 + 1,129 + 1,118 + 928 + 785 + 748 + 797 + 948 + 880 + - - 293 + + + 239 + 262 + 213 + 218 + 206 + 188 + 222 + 186 + 213 + 226 + 273 + 178 + 194 + 209 + 181 + 216 + 206 + 187 + 191 + 243 + 256 + 247 + 234 + 249 + 263 + 250 + 217 + 255 + 264 + 246 + 249 + 271 + 266 + 275 + 297 + 327 + 324 + 304 + 279 + 248 + 271 + 295 + 270 + 302 + 287 + 338 + 308 + 299 + 302 + 260 + 260 + 242 + 287 + 306 + 291 + 324 + 362 + 301 + 353 + 341 + 346 + 363 + 312 + 273 + 299 + 268 + 282 + 249 + 282 + 255 + 319 + 327 + 341 + 332 + 300 + 334 + 251 + 245 + 291 + 306 + 299 + 275 + 257 + 287 + 376 + 300 + 311 + 240 + 276 + 258 + 324 + 315 + 304 + 338 + 336 + 326 + 338 + 340 + 346 + 338 + 366 + 364 + 345 + 378 + 414 + 396 + 411 + 559 + 659 + 586 + 625 + 488 + 530 + 472 + 552 + 569 + 636 + 610 + 592 + 609 + 730 + 680 + - - - - Government + + + 228 + 240 + 226 + 197 + 195 + 216 + 190 + 213 + 187 + 224 + 184 + 200 + 232 + 235 + 211 + 232 + 191 + 249 + 289 + 256 + 268 + 281 + 320 + 258 + 267 + 318 + 287 + 292 + 340 + 373 + 345 + 343 + 299 + 312 + 337 + 322 + 327 + 310 + 357 + 323 + 320 + 358 + 284 + 342 + 305 + 303 + 311 + 283 + 403 + 363 + 343 + 312 + 302 + 335 + 307 + 312 + 374 + 358 + 290 + 290 + 252 + 301 + 261 + 255 + 288 + 307 + 309 + 300 + 260 + 255 + 268 + 204 + 233 + 268 + 298 + 293 + 289 + 299 + 329 + 263 + 235 + 211 + 229 + 227 + 233 + 295 + 252 + 231 + 281 + 303 + 307 + 371 + 316 + 307 + 261 + 315 + 285 + 323 + 323 + 324 + 361 + 337 + 350 + 409 + 380 + 434 + 494 + 540 + 571 + 637 + 639 + 561 + 536 + 513 + 570 + 566 + 657 + 646 + 619 + 665 + 623 + 708 + - - 430 - 409 - 311 - 269 - 370 - 603 - 545 - 583 - 408 - 391 - 384 - 365 - 463 - 298 - 355 - 369 - 361 - 525 - 548 - 540 - 438 - 429 - 420 - 419 - 486 - 508 - 477 - 447 - 484 - 561 - 645 - 596 - 530 - 499 - 468 - 446 - 571 - 483 - 526 - 440 - 478 - 704 - 749 - 745 - 556 - 500 - 542 - 516 - 511 - 490 - 530 - 433 - 468 - 580 - 741 - 676 - 568 - 561 - 514 - 499 - 555 - 472 - 468 - 478 - 453 - 681 - 683 - 664 - 568 - 502 - 494 - 393 - 457 - 472 - 461 - 414 - 429 - 578 - 659 - 595 - 396 - 424 - 400 - 395 - 476 - 405 - 419 - 408 - 428 - 572 - 704 - 695 - 525 - 492 - 482 - 451 - 471 - 372 - 425 - 373 - 461 - 654 - 770 - 721 - 573 - 552 - 527 - 511 - 652 - 563 - 598 - 575 - 702 - 991 - 1,129 - 1,118 - 928 - 785 - 748 - 797 - 948 - 880 + + + 236 + 223 + 192 + 191 + 190 + 183 + 228 + 198 + 231 + 153 + 129 + 168 + 194 + 189 + 193 + 232 + 178 + 242 + 236 + 226 + 214 + 321 + 302 + 310 + 368 + 331 + 313 + 280 + 257 + 274 + 270 + 221 + 235 + 262 + 233 + 243 + 331 + 316 + 319 + 274 + 260 + 300 + 289 + 255 + 255 + 260 + 275 + 267 + 243 + 291 + 284 + 239 + 230 + 227 + 231 + 236 + 208 + 219 + 217 + 204 + 276 + 245 + 267 + 257 + 223 + 247 + 222 + 187 + 211 + 251 + 199 + 202 + 287 + 260 + 263 + 272 + 226 + 225 + 237 + 217 + 183 + 206 + 183 + 190 + 248 + 251 + 249 + 188 + 216 + 242 + 309 + 205 + 224 + 218 + 242 + 210 + 271 + 289 + 267 + 245 + 269 + 329 + 359 + 309 + 337 + 316 + 331 + 421 + 522 + 563 + 558 + 541 + 506 + 499 + 511 + 547 + 538 + 480 + 493 + 539 + 657 + 591 + - - 1,129 + + + 274 + 232 + 247 + 240 + 254 + 225 + 202 + 187 + 220 + 161 + 217 + 167 + 197 + 243 + 200 + 220 + 172 + 246 + 228 + 241 + 225 + 239 + 256 + 277 + 304 + 339 + 314 + 268 + 264 + 335 + 356 + 353 + 281 + 272 + 284 + 241 + 304 + 331 + 370 + 331 + 339 + 359 + 405 + 373 + 338 + 378 + 357 + 278 + 322 + 366 + 366 + 347 + 310 + 326 + 346 + 341 + 301 + 300 + 294 + 276 + 290 + 325 + 308 + 306 + 314 + 291 + 274 + 306 + 307 + 319 + 300 + 269 + 308 + 281 + 292 + 266 + 265 + 265 + 305 + 341 + 310 + 268 + 306 + 306 + 275 + 257 + 222 + 224 + 242 + 256 + 243 + 239 + 257 + 182 + 255 + 235 + 264 + 313 + 283 + 251 + 275 + 322 + 352 + 412 + 374 + 334 + 434 + 367 + 431 + 453 + 377 + 403 + 476 + 557 + 490 + 528 + 462 + 541 + 491 + 513 + 609 + 603 + - - 269 + + + 125 + 112 + 140 + 95 + 131 + 102 + 144 + 143 + 130 + 96 + 117 + 151 + 161 + 109 + 148 + 148 + 164 + 163 + 206 + 210 + 219 + 233 + 241 + 275 + 263 + 279 + 266 + 257 + 260 + 255 + 264 + 270 + 231 + 211 + 220 + 255 + 243 + 321 + 267 + 268 + 251 + 239 + 224 + 224 + 248 + 182 + 257 + 224 + 236 + 194 + 216 + 168 + 190 + 172 + 174 + 191 + 178 + 185 + 187 + 173 + 168 + 204 + 177 + 178 + 145 + 160 + 142 + 156 + 168 + 162 + 172 + 128 + 105 + 119 + 116 + 132 + 158 + 114 + 103 + 132 + 170 + 116 + 137 + 108 + 143 + 139 + 109 + 77 + 110 + 114 + 112 + 140 + 124 + 120 + 132 + 125 + 169 + 193 + 155 + 143 + 170 + 157 + 141 + 144 + 166 + 168 + 173 + 219 + 232 + 224 + 252 + 320 + 303 + 347 + 373 + 358 + 362 + 261 + 243 + 256 + 313 + 300 + - - - - Self-employed + + + 154 + 173 + 152 + 135 + 73 + 109 + 77 + 110 + 124 + 113 + 192 + 196 + 188 + 193 + 267 + 140 + 109 + 130 + 113 + 141 + 101 + 118 + 145 + 192 + 195 + 187 + 269 + 151 + 89 + 89 + 114 + 125 + 92 + 97 + 137 + 120 + 159 + 172 + 161 + 154 + 133 + 94 + 113 + 173 + 98 + 136 + 148 + 137 + 184 + 168 + 153 + 107 + 99 + 106 + 140 + 103 + 88 + 102 + 131 + 165 + 153 + 107 + 139 + 84 + 66 + 76 + 69 + 100 + 127 + 85 + 118 + 127 + 140 + 139 + 117 + 81 + 79 + 35 + 55 + 76 + 78 + 77 + 125 + 139 + 128 + 127 + 123 + 67 + 64 + 59 + 40 + 54 + 53 + 47 + 80 + 96 + 113 + 135 + 175 + 108 + 94 + 86 + 125 + 111 + 84 + 97 + 119 + 229 + 245 + 251 + 241 + 176 + 136 + 182 + 180 + 195 + 150 + 166 + 180 + 292 + 318 + 285 + - - 239 - 262 - 213 - 218 - 206 - 188 - 222 - 186 - 213 - 226 - 273 - 178 - 194 - 209 - 181 - 216 - 206 - 187 - 191 - 243 - 256 - 247 - 234 - 249 - 263 - 250 - 217 - 255 - 264 - 246 - 249 - 271 - 266 - 275 - 297 - 327 - 324 - 304 - 279 - 248 - 271 - 295 - 270 - 302 - 287 - 338 - 308 - 299 - 302 - 260 - 260 - 242 - 287 - 306 - 291 - 324 - 362 - 301 - 353 - 341 - 346 - 363 - 312 - 273 - 299 - 268 - 282 - 249 - 282 - 255 - 319 - 327 - 341 - 332 - 300 - 334 - 251 - 245 - 291 - 306 - 299 - 275 - 257 - 287 - 376 - 300 - 311 - 240 - 276 - 258 - 324 - 315 - 304 - 338 - 336 - 326 - 338 - 340 - 346 - 338 - 366 - 364 - 345 - 378 - 414 - 396 - 411 - 559 - 659 - 586 - 625 - 488 - 530 - 472 - 552 - 569 - 636 - 610 - 592 - 609 - 730 - 680 + + + 19 + 25 + 17 + 20 + 27 + 13 + 16 + 23 + 25 + 39 + 11 + 20 + 11 + 27 + 14 + 24 + 34 + 26 + 17 + 18 + 23 + 32 + 20 + 27 + 33 + 35 + 28 + 33 + 25 + 35 + 19 + 32 + 42 + 36 + 32 + 45 + 54 + 41 + 46 + 41 + 40 + 36 + 43 + 20 + 25 + 31 + 34 + 32 + 31 + 24 + 22 + 34 + 22 + 27 + 28 + 10 + 8 + 15 + 20 + 16 + 29 + 25 + 32 + 19 + 16 + 25 + 22 + 12 + 12 + 2 + 18 + 23 + 26 + 25 + 14 + 17 + 20 + 31 + 25 + 32 + 14 + 15 + 22 + 25 + 35 + 33 + 24 + 17 + 22 + 33 + 33 + 33 + 25 + 9 + 16 + 24 + 28 + 16 + 28 + 28 + 28 + 28 + 13 + 17 + 25 + 15 + 32 + 46 + 59 + 63 + 105 + 125 + 98 + 100 + 95 + 93 + 76 + 84 + 96 + 89 + 68 + 79 + - - 730 + + + + + 2,440 + - - 178 + + + 2,154 + - - - - Finance + + + 2,010 + - - 228 - 240 - 226 - 197 - 195 - 216 - 190 - 213 - 187 - 224 - 184 - 200 - 232 - 235 - 211 - 232 - 191 - 249 - 289 - 256 - 268 - 281 - 320 - 258 - 267 - 318 - 287 - 292 - 340 - 373 - 345 - 343 - 299 - 312 - 337 - 322 - 327 - 310 - 357 - 323 - 320 - 358 - 284 - 342 - 305 - 303 - 311 - 283 - 403 - 363 - 343 - 312 - 302 - 335 - 307 - 312 - 374 - 358 - 290 - 290 - 252 - 301 - 261 - 255 - 288 - 307 - 309 - 300 - 260 - 255 - 268 - 204 - 233 - 268 - 298 - 293 - 289 - 299 - 329 - 263 - 235 - 211 - 229 - 227 - 233 - 295 - 252 - 231 - 281 - 303 - 307 - 371 - 316 - 307 - 261 - 315 - 285 - 323 - 323 - 324 - 361 - 337 - 350 - 409 - 380 - 434 - 494 - 540 - 571 - 637 - 639 - 561 - 536 - 513 - 570 - 566 - 657 - 646 - 619 - 665 - 623 - 708 + + + 1,804 + - - 708 + + + 1,740 + - - 184 + + + 1,280 + - - - - Transportation and Utilities + + + 1,129 + - - 236 - 223 - 192 - 191 - 190 - 183 - 228 - 198 - 231 - 153 - 129 - 168 - 194 - 189 - 193 - 232 - 178 - 242 - 236 - 226 - 214 - 321 - 302 - 310 - 368 - 331 - 313 - 280 - 257 - 274 - 270 - 221 - 235 - 262 - 233 - 243 - 331 - 316 - 319 - 274 - 260 - 300 - 289 - 255 - 255 - 260 - 275 - 267 - 243 - 291 - 284 - 239 - 230 - 227 - 231 - 236 - 208 - 219 - 217 - 204 - 276 - 245 - 267 - 257 - 223 - 247 - 222 - 187 - 211 - 251 - 199 - 202 - 287 - 260 - 263 - 272 - 226 - 225 - 237 - 217 - 183 - 206 - 183 - 190 - 248 - 251 - 249 - 188 - 216 - 242 - 309 - 205 - 224 - 218 - 242 - 210 - 271 - 289 - 267 - 245 - 269 - 329 - 359 - 309 - 337 - 316 - 331 - 421 - 522 - 563 - 558 - 541 - 506 - 499 - 511 - 547 - 538 - 480 - 493 - 539 - 657 - 591 + + + 730 + - - 657 + + + 708 + - - 129 + + + 657 + - - - - Other + + + 609 + - - 274 - 232 - 247 - 240 - 254 - 225 - 202 - 187 - 220 - 161 - 217 - 167 - 197 - 243 - 200 - 220 - 172 - 246 - 228 - 241 - 225 - 239 - 256 - 277 - 304 - 339 - 314 - 268 - 264 - 335 - 356 - 353 - 281 - 272 - 284 - 241 - 304 - 331 - 370 - 331 - 339 - 359 - 405 - 373 - 338 - 378 - 357 - 278 - 322 - 366 - 366 - 347 - 310 - 326 - 346 - 341 - 301 - 300 - 294 - 276 - 290 - 325 - 308 - 306 - 314 - 291 - 274 - 306 - 307 - 319 - 300 - 269 - 308 - 281 - 292 - 266 - 265 - 265 - 305 - 341 - 310 - 268 - 306 - 306 - 275 - 257 - 222 - 224 - 242 - 256 - 243 - 239 - 257 - 182 - 255 - 235 - 264 - 313 - 283 - 251 - 275 - 322 - 352 - 412 - 374 - 334 - 434 - 367 - 431 - 453 - 377 - 403 - 476 - 557 - 490 - 528 - 462 - 541 - 491 - 513 - 609 - 603 + + + 373 + - - 609 + + + 318 + - - 161 + + + 125 + - - - Information + + + + 384 + - - 125 - 112 - 140 - 95 - 131 - 102 - 144 - 143 - 130 - 96 - 117 - 151 - 161 - 109 - 148 - 148 - 164 - 163 - 206 - 210 - 219 - 233 - 241 - 275 - 263 - 279 - 266 - 257 - 260 - 255 - 264 - 270 - 231 - 211 - 220 - 255 - 243 - 321 - 267 - 268 - 251 - 239 - 224 - 224 - 248 - 182 - 257 - 224 - 236 - 194 - 216 - 168 - 190 - 172 - 174 - 191 - 178 - 185 - 187 - 173 - 168 - 204 - 177 - 178 - 145 - 160 - 142 - 156 - 168 - 162 - 172 - 128 - 105 - 119 - 116 - 132 - 158 - 114 - 103 - 132 - 170 - 116 - 137 - 108 - 143 - 139 - 109 - 77 - 110 - 114 - 112 - 140 - 124 - 120 - 132 - 125 - 169 - 193 - 155 - 143 - 170 - 157 - 141 - 144 - 166 - 168 - 173 - 219 - 232 - 224 - 252 - 320 - 303 - 347 - 373 - 358 - 362 - 261 - 243 - 256 - 313 - 300 + + + 701 + - - 373 + + + 596 + - - 77 + + + 636 + - - - - Agriculture + + + 504 + - - 154 - 173 - 152 - 135 - 73 - 109 - 77 - 110 - 124 - 113 - 192 - 196 - 188 - 193 - 267 - 140 - 109 - 130 - 113 - 141 - 101 - 118 - 145 - 192 - 195 - 187 - 269 - 151 - 89 - 89 - 114 - 125 - 92 - 97 - 137 - 120 - 159 - 172 - 161 - 154 - 133 - 94 - 113 - 173 - 98 - 136 - 148 - 137 - 184 - 168 - 153 - 107 - 99 - 106 - 140 - 103 - 88 - 102 - 131 - 165 - 153 - 107 - 139 - 84 - 66 - 76 - 69 - 100 - 127 - 85 - 118 - 127 - 140 - 139 - 117 - 81 - 79 - 35 - 55 - 76 - 78 - 77 - 125 - 139 - 128 - 127 - 123 - 67 - 64 - 59 - 40 - 54 - 53 - 47 - 80 - 96 - 113 - 135 - 175 - 108 - 94 - 86 - 125 - 111 - 84 - 97 - 119 - 229 - 245 - 251 - 241 - 176 - 136 - 182 - 180 - 195 - 150 - 166 - 180 - 292 - 318 - 285 + + + 293 + - - 318 + + + 269 + - - 35 + + + 178 + - - - - Mining and Extraction + + + 184 + - - - - - - - + + + 129 + - - 2000 - 2002 - 2004 - 2006 - 2008 - 2010 + + + 161 + - - 19 - 25 - 17 - 20 - 27 - 13 - 16 - 23 - 25 - 39 - 11 - 20 - 11 - 27 - 14 - 24 - 34 - 26 - 17 - 18 - 23 - 32 - 20 - 27 - 33 - 35 - 28 - 33 - 25 - 35 - 19 - 32 - 42 - 36 - 32 - 45 - 54 - 41 - 46 - 41 - 40 - 36 - 43 - 20 - 25 - 31 - 34 - 32 - 31 - 24 - 22 - 34 - 22 - 27 - 28 - 10 - 8 - 15 - 20 - 16 - 29 - 25 - 32 - 19 - 16 - 25 - 22 - 12 - 12 - 2 - 18 - 23 - 26 - 25 - 14 - 17 - 20 - 31 - 25 - 32 - 14 - 15 - 22 - 25 - 35 - 33 - 24 - 17 - 22 - 33 - 33 - 33 - 25 - 9 - 16 - 24 - 28 - 16 - 28 - 28 - 28 - 28 - 13 - 17 - 25 - 15 - 32 - 46 - 59 - 63 - 105 - 125 - 98 - 100 - 95 - 93 - 76 - 84 - 96 - 89 - 68 - 79 + + + 77 + - - 125 + + + 35 + - - 2 + + + 2 + \ No newline at end of file diff --git a/test/output/internFacetDate.svg b/test/output/internFacetDate.svg index 93fb889a26..8cbc6a8826 100644 --- a/test/output/internFacetDate.svg +++ b/test/output/internFacetDate.svg @@ -13,11111 +13,11191 @@ white-space: pre; } - - date_of_birth - - - ↑ height - - - weight → - - - - 1950 + + + + 1950 + - - - - - - + + + 1960 + - - - - - - + + + 1970 + - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 + + + 1980 + - - - - - - - - + + + 1990 + - - - - - - - - - + + + 2000 + - - - 1960 + + date_of_birth + + + + + + + + + + - - - - - - + + + + + + + + - - - - - - + + + + + + + + - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - 1970 + + + + + + + + + - - - - - - + + + + + + + + - - - - - - + + + + + + + + - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - 1980 + + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + - - - - - - + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + - - - - - - + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + - - - - - - - - + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + - - - 1990 + + ↑ height + + + + + + + + + + + + - - - - - - + + + + + + + + + + - - - - - - + + + + + + + + + + - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 + + + + + + + + + + - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - 2000 + + + + + + + + + + + - - - - - - + + + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 + - - - - - - + + + weight → + + + + + + + + + + + + + - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 40 - 60 - 80 - 100 - 120 - 140 - 160 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/internFacetNaN.svg b/test/output/internFacetNaN.svg index ee1056d738..5888161c9b 100644 --- a/test/output/internFacetNaN.svg +++ b/test/output/internFacetNaN.svg @@ -13,743 +13,897 @@ white-space: pre; } + + + + 1.2 + + + + + 1.3 + + + + + 1.4 + + + + + 1.5 + + + + + 1.6 + + + + + 1.7 + + + + + 1.8 + + + + + 1.9 + + + + + 2 + + + + + 2.1 + + + + + 2.2 + + + height - - sex - - - weight → - - - - 1.2 - - - - - - - female - male - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - 1.3 - - - - - - - female - male - - - - - - - - - + + + + female + male + + + + + female + male + + + + + female + male + + + + + female + male + + + + + female + male + + + + + female + male + + + + + female + male + + + + + female + male + + + + + female + male + + + + + female + male + + + + + female + male + + + + + female + male + - - - 1.4 - - - - - - - female - male - - - - - - - - - - - - - - - - - 1.5 - - - - - - - female - male - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + sex - - - 1.6 - - - - - - - female - male - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - 1.7 - - - - - - - female - male - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 + - - - 1.8 - - - - - - - female - male - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + weight → - - - 1.9 - - - - - - - female - male - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - 2 - - - - - - - female - male - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - 2.1 - - - - - - - female - male - - - - - - - - - - - - - - 2.2 - - - - - - - female - male - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - female - male - - - - - - - - - - - - 40 - 60 - 80 - 100 - 120 - 140 - 160 - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/metroUnemploymentRidgeline.svg b/test/output/metroUnemploymentRidgeline.svg index 48d7415254..4a051da0b9 100644 --- a/test/output/metroUnemploymentRidgeline.svg +++ b/test/output/metroUnemploymentRidgeline.svg @@ -13,652 +13,938 @@ white-space: pre; } - - - Detroit-Livonia-Dearborn, MI Met Div - - - - - - - - - - - - - - Detroit-Warren-Livonia, MI MSA - - - - - - - - - - - - - - Warren-Troy-Farmington Hills, MI Met Div - - - - - - - - - - - - - - Lawrence-Methuen-Salem, MA-NH NECTA Div - - - - - - - - - - - - - - Los Angeles-Long Beach-Glendale, CA Met Div - - - - - - - - - - - - - - Miami-Miami Beach-Kendall, FL Met Div - - - - - - - - - - - - - - Los Angeles-Long Beach-Santa Ana, CA MSA - - - - - - - - - - - - - - Lake County-Kenosha County, IL-WI Met Div - - - - - - - - - - - - - - West Palm Beach-Boca Raton-Boynton Beach, FL Met Div - - - - - - - - - - - - - - Chicago-Joliet-Naperville, IL Met Div - - - - - - - - - - - - - - Chicago-Joliet-Naperville, IL-IN-WI MSA - - - - - - - - - - - - - - Miami-Fort Lauderdale-Pompano Beach, FL MSA - - - - - - - - - - - - - - Oakland-Fremont-Hayward, CA Met Div - - - - - - - - - - - - - - Gary, IN Met Div - - - - - - - - - - - - - - Tacoma, WA Met Div - - - - - - - - - - - - - - San Francisco-Oakland-Fremont, CA MSA - - - - - - - - - - - - - - Camden, NJ Met Div - - - - - - - - - - - - - - Brockton-Bridgewater-Easton, MA NECTA Div - - - - - - - - - - - - - - Seattle-Tacoma-Bellevue, WA MSA - - - - - - - - - - - - - - Fort Lauderdale-Pompano Beach-Deerfield Beach, FL Met Div - - - - - - - - - - - - - - New York-White Plains-Wayne, NY-NJ Met Div - - - - - - - - - - - - - - Santa Ana-Anaheim-Irvine, CA Met Div - - - - - - - - - - - - - - Seattle-Bellevue-Everett, WA Met Div - - - - - - - - - - - - - - Newark-Union, NJ-PA Met Div - - - - - - - - - - - - - - Taunton-Norton-Raynham, MA NECTA Div - - - - - - - - - - - - - - Lowell-Billerica-Chelmsford, MA-NH NECTA Div - - - - - - - - - - - - - - New York-Northern New Jersey-Long Island, NY-NJ-PA MSA - - - - - - - - - - - - - - San Francisco-San Mateo-Redwood City, CA Met Div - - - - - - - - - - - - - - Edison-New Brunswick, NJ Met Div - - - - - - - - - - - - - - Philadelphia-Camden-Wilmington, PA-NJ-DE-MD MSA - - - - - - - - - - - - - - Wilmington, DE-MD-NJ Met Div - - - - - - - - - - - - - - Peabody, MA NECTA Div - - - - - - - - - - - - - - Philadelphia, PA Met Div - - - - - - - - - - - - - - Fort Worth-Arlington, TX Met Div - - - - - - - - - - - - - - Dallas-Fort Worth-Arlington, TX MSA - - - - - - - - - - - - - - Dallas-Plano-Irving, TX Met Div - - - - - - - - - - - - - - Haverhill-North Andover-Amesbury, MA-NH NECTA Div - - - - - - - - - - - - - - Boston-Cambridge-Quincy, MA-NH Met NECTA - - - - - - - - - - - - - - Boston-Cambridge-Quincy, MA NECTA Div - - - - - - - - - - - - - - Nassau-Suffolk, NY Met Div - - - - - - - - - - - - - - Framingham, MA NECTA Div - - - - - - - - - - - - - - Nashua, NH-MA NECTA Div - - - - - - - - - - - - - - Washington-Arlington-Alexandria, DC-VA-MD-WV Met Div - - - - - - - - - - - - - - Washington-Arlington-Alexandria, DC-VA-MD-WV MSA - - - - - - - - - - - - - - Bethesda-Rockville-Frederick, MD Met Div - - - - - - - - - - - - 2000 - 2002 - 2004 - 2006 - 2008 - 2010 - 2012 - - - - - - - - - + + + + Detroit-Livonia-Dearborn, MI Met Div + + + + + Detroit-Warren-Livonia, MI MSA + + + + + Warren-Troy-Farmington Hills, MI Met Div + + + + + Lawrence-Methuen-Salem, MA-NH NECTA Div + + + + + Los Angeles-Long Beach-Glendale, CA Met Div + + + + + Miami-Miami Beach-Kendall, FL Met Div + + + + + Los Angeles-Long Beach-Santa Ana, CA MSA + + + + + Lake County-Kenosha County, IL-WI Met Div + + + + + West Palm Beach-Boca Raton-Boynton Beach, FL Met Div + + + + + Chicago-Joliet-Naperville, IL Met Div + + + + + Chicago-Joliet-Naperville, IL-IN-WI MSA + + + + + Miami-Fort Lauderdale-Pompano Beach, FL MSA + + + + + Oakland-Fremont-Hayward, CA Met Div + + + + + Gary, IN Met Div + + + + + Tacoma, WA Met Div + + + + + San Francisco-Oakland-Fremont, CA MSA + + + + + Camden, NJ Met Div + + + + + Brockton-Bridgewater-Easton, MA NECTA Div + + + + + Seattle-Tacoma-Bellevue, WA MSA + + + + + Fort Lauderdale-Pompano Beach-Deerfield Beach, FL Met Div + + + + + New York-White Plains-Wayne, NY-NJ Met Div + + + + + Santa Ana-Anaheim-Irvine, CA Met Div + + + + + Seattle-Bellevue-Everett, WA Met Div + + + + + Newark-Union, NJ-PA Met Div + + + + + Taunton-Norton-Raynham, MA NECTA Div + + + + + Lowell-Billerica-Chelmsford, MA-NH NECTA Div + + + + + New York-Northern New Jersey-Long Island, NY-NJ-PA MSA + + + + + San Francisco-San Mateo-Redwood City, CA Met Div + + + + + Edison-New Brunswick, NJ Met Div + + + + + Philadelphia-Camden-Wilmington, PA-NJ-DE-MD MSA + + + + + Wilmington, DE-MD-NJ Met Div + + + + + Peabody, MA NECTA Div + + + + + Philadelphia, PA Met Div + + + + + Fort Worth-Arlington, TX Met Div + + + + + Dallas-Fort Worth-Arlington, TX MSA + + + + + Dallas-Plano-Irving, TX Met Div + + + + + Haverhill-North Andover-Amesbury, MA-NH NECTA Div + + + + + Boston-Cambridge-Quincy, MA-NH Met NECTA + + + + + Boston-Cambridge-Quincy, MA NECTA Div + + + + + Nassau-Suffolk, NY Met Div + + + + + Framingham, MA NECTA Div + + + + + Nashua, NH-MA NECTA Div + + + + + Washington-Arlington-Alexandria, DC-VA-MD-WV Met Div + + + + + Washington-Arlington-Alexandria, DC-VA-MD-WV MSA + + + + + Bethesda-Rockville-Frederick, MD Met Div + + + + + + + + + + + + + + + + + + + + 2000 + 2002 + 2004 + 2006 + 2008 + 2010 + 2012 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/mobyDickFaceted.svg b/test/output/mobyDickFaceted.svg index 7e8899b166..e172fbb8f7 100644 --- a/test/output/mobyDickFaceted.svg +++ b/test/output/mobyDickFaceted.svg @@ -13,279 +13,337 @@ white-space: pre; } - - ↑ Frequency + + + + lower + + + + + upper + + - - - consonant + + + + consonant + - - - - - - - - + + + vowel + - - - - - - - - + + + + + + + + + + + + - - 0 - 200 - 400 - 600 - 800 - 1,000 - 1,200 + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - 0 - 200 - 400 - 600 - 800 - 1,000 - 1,200 + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + 0 + 200 + 400 + 600 + 800 + 1,000 + 1,200 + - - A - B - C - D - E - F - G - H - I - J - K - L - M - N - O - P - Q - R - S - T - U - V - W - X - Y - Z + + + 0 + 200 + 400 + 600 + 800 + 1,000 + 1,200 + - - - - - - - - - - - - - - - - - + + + ↑ Frequency + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - lower - - - vowel + + + + A + B + C + D + E + F + G + H + I + J + K + L + M + N + O + P + Q + R + S + T + U + V + W + X + Y + Z + - - - - - - - - + + + A + B + C + D + E + F + G + H + I + J + K + L + M + N + O + P + Q + R + S + T + U + V + W + X + Y + Z + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + - - - - upper + + + + + + + + + - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - A - B - C - D - E - F - G - H - I - J - K - L - M - N - O - P - Q - R - S - T - U - V - W - X - Y - Z + + + + - - - - - - - + + + + - - + + + + \ No newline at end of file diff --git a/test/output/moviesRatingByGenre.svg b/test/output/moviesRatingByGenre.svg index abd8f8594e..e3c70907dc 100644 --- a/test/output/moviesRatingByGenre.svg +++ b/test/output/moviesRatingByGenre.svg @@ -13,3320 +13,3414 @@ white-space: pre; } - - IMDB Rating → - - - - + + + + + - - Documentary + + + + - - - - - - - - - - - - + + + + - - - - - - - - - - - - + + + + - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - Black Comedy + + + + - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - + + + + - - Drama + + + + - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - + + + + Documentary + - - Musical + + + Black Comedy + - - - - - - - - - - - - + + + Drama + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + Musical + - - - - + + + Western + - - Western + + + N/A + - - - - - - - - - - - - + + + Adventure + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + Thriller/Suspense + - - - - + + + Action + + + + + Concert/Performance + - - N/A + + + Comedy + - - - - - - - - - - - - + + + Romantic Comedy + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + Horror + - - - + + + + + + + + + + + + + + + - - Adventure + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + - - Thriller/Suspense + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + - - Action + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - Concert/Performance + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - + + + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + - - - + + IMDB Rating → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - Comedy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - Romantic Comedy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - Horror + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/multiplicationTable.svg b/test/output/multiplicationTable.svg index bf541780b0..e60794cc46 100644 --- a/test/output/multiplicationTable.svg +++ b/test/output/multiplicationTable.svg @@ -13,804 +13,1138 @@ white-space: pre; } - - - - - - 2 - - - - - - 2 - - - - - - - - - 4 - - - - - - - - 3 - - - - - - - - - 6 - - - - - - - - 4 - - - - - - - - - 8 - - - - - - - - 5 - - - - - - - - - 10 - - - - - - - - 6 - - - - - - - - - 12 - - - - - - - - 7 - - - - - - - - - 14 - - - - - - - - 8 - - - - - - - - - 16 - - - - - - - - 9 - - - - - - - - - 18 - - - - - - - - 3 - - - - - - - - - 6 - - - - - - - - - - - 9 - - - - - - - - - - - 12 - - - - - - - - - - - 15 - - - - - - - - - - - 18 - - - - - - - - - - - 21 - - - - - - - - - - - 24 - - - - - - - - - - - 27 - - - - - - - - 4 - - - - - - - - - 8 - - - - - - - - - - - 12 - - - - - - - - - - - 16 - - - - - - - - - - - 20 - - - - - - - - - - - 24 - - - - - - - - - - - 28 - - - - - - - - - - - 32 - - - - - - - - - - - 36 - - - - - - - - 5 - - - - - - - - - 10 - - - - - - - - - - - 15 - - - - - - - - - - - 20 - - - - - - - - - - - 25 - - - - - - - - - - - 30 - - - - - - - - - - - 35 - - - - - - - - - - - 40 - - - - - - - - - - - 45 - - - - - - - - 6 - - - - - - - - - 12 - - - - - - - - - - - 18 - - - - - - - - - - - 24 - - - - - - - - - - - 30 - - - - - - - - - - - 36 - - - - - - - - - - - 42 - - - - - - - - - - - 48 - - - - - - - - - - - 54 - - - - - - - - 7 - - - - - - - - - 14 - - - - - - - - - - - 21 - - - - - - - - - - - 28 - - - - - - - - - - - 35 - - - - - - - - - - - 42 - - - - - - - - - - - 49 - - - - - - - - - - - 56 - - - - - - - - - - - 63 - - - - - - - - 8 - - - - - - - - - 16 - - - - - - - - - - - 24 - - - - - - - - - - - 32 - - - - - - - - - - - 40 - - - - - - - - - - - 48 - - - - - - - - - - - 56 - - - - - - - - - - - 64 - - - - - - - - - - - 72 - - - - - - - - 9 - - - - - - - - - 18 - - - - - - - - - - - 27 - - - - - - - - - - - 36 - - - - - - - - - - - 45 - - - - - - - - - - - 54 - - - - - - - - - - - 63 - - - - - - - - - - - 72 - - - - - - - - - - - 81 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4 + + + + + 6 + + + + + 8 + + + + + 10 + + + + + 12 + + + + + 14 + + + + + 16 + + + + + 18 + + + + + 6 + + + + + 9 + + + + + 12 + + + + + 15 + + + + + 18 + + + + + 21 + + + + + 24 + + + + + 27 + + + + + 8 + + + + + 12 + + + + + 16 + + + + + 20 + + + + + 24 + + + + + 28 + + + + + 32 + + + + + 36 + + + + + 10 + + + + + 15 + + + + + 20 + + + + + 25 + + + + + 30 + + + + + 35 + + + + + 40 + + + + + 45 + + + + + 12 + + + + + 18 + + + + + 24 + + + + + 30 + + + + + 36 + + + + + 42 + + + + + 48 + + + + + 54 + + + + + 14 + + + + + 21 + + + + + 28 + + + + + 35 + + + + + 42 + + + + + 49 + + + + + 56 + + + + + 63 + + + + + 16 + + + + + 24 + + + + + 32 + + + + + 40 + + + + + 48 + + + + + 56 + + + + + 64 + + + + + 72 + + + + + 18 + + + + + 27 + + + + + 36 + + + + + 45 + + + + + 54 + + + + + 63 + + + + + 72 + + + + + 81 + \ No newline at end of file diff --git a/test/output/penguinCulmen.svg b/test/output/penguinCulmen.svg index 9d633b2571..44cd44bf80 100644 --- a/test/output/penguinCulmen.svg +++ b/test/output/penguinCulmen.svg @@ -13,2987 +13,3109 @@ white-space: pre; } + + + + Adelie + + + + + Chinstrap + + + + + Gentoo + + + species + + + + FEMALE + + + + + MALE + + + sex - - ↑ culmen_length_mm - - - culmen_depth_mm → - - - - FEMALE + + + + + + + + + - - - - - - + + + + + + + + - - - - - - + + + + + + + + - - 35 - 40 - 45 - 50 - 55 + + + + + + + + - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + - - - - - - + + + + + + + + - - 35 - 40 - 45 - 50 - 55 + + + + + + + + - - - + + + + + 35 + 40 + 45 + 50 + 55 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 35 + 40 + 45 + 50 + 55 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 35 + 40 + 45 + 50 + 55 + - - - - - - - + + ↑ culmen_length_mm + + + + + + + - - - - - - + + + + + - - 35 - 40 - 45 - 50 - 55 + + + + + - - - + + + + + - - - + + + + + - - 15 - 20 + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - MALE - - - - - - - + + + + + + - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - + + + + 15 + 20 + - - - + + + 15 + 20 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 15 + 20 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 15 + 20 + - - - - - - - + + culmen_depth_mm → + + + + + + + - - - + + - - - + + - - 15 - 20 + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - Adelie + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 15 - 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - Chinstrap + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - Gentoo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 15 - 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - + + + + + + + \ No newline at end of file diff --git a/test/output/penguinCulmenArray.svg b/test/output/penguinCulmenArray.svg index 06166cc361..005a430be3 100644 --- a/test/output/penguinCulmenArray.svg +++ b/test/output/penguinCulmenArray.svg @@ -13,3315 +13,3419 @@ white-space: pre; } + + + + Adelie + + + + + Chinstrap + + + + + Gentoo + + + species + + + + FEMALE + + + + + MALE + + + sex - - - FEMALE + + + + + + + + + - - - - - - + + + + + + + + - - - - - - + + + + + + + + - - 35 - 40 - 45 - 50 - 55 + + + + + + + + - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + - - - - - - + + + + + + + + - - 35 - 40 - 45 - 50 - 55 + + + + + + + + - - - + + + + + 35 + 40 + 45 + 50 + 55 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 35 + 40 + 45 + 50 + 55 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 35 + 40 + 45 + 50 + 55 + - - - - - - - + + + + + + - - - - - - + + + + + - - 35 - 40 - 45 - 50 - 55 + + + + + - - - + + + + + - - - + + + + + - - 15 - 20 + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - MALE + + + + + + - - - - - - + + + + + - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - + + + + 15 + 20 + - - - + + + 15 + 20 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 15 + 20 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 15 + 20 + - - - - - - - - - - - - - - - - - - 15 - 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - Adelie - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 15 - 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - Chinstrap + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - Gentoo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 15 - 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - + + + + + + + \ No newline at end of file diff --git a/test/output/penguinCulmenMarkFacet.svg b/test/output/penguinCulmenMarkFacet.svg index a6d4797c7e..da39602085 100644 --- a/test/output/penguinCulmenMarkFacet.svg +++ b/test/output/penguinCulmenMarkFacet.svg @@ -13,2899 +13,2985 @@ white-space: pre; } + + + + Adelie + + + + + Chinstrap + + + + + Gentoo + + + species + + + + FEMALE + + + + + MALE + + + sex - - ↑ culmen_length_mm - - - culmen_depth_mm → - - - - FEMALE + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + - - 35 - 40 - 45 - 50 - 55 + + + + + 35 + 40 + 45 + 50 + 55 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 35 + 40 + 45 + 50 + 55 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 35 + 40 + 45 + 50 + 55 + - - - - - - - + + ↑ culmen_length_mm + + + + + + + - - 35 - 40 - 45 - 50 - 55 + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - + + + + 15 + 20 + - - 35 - 40 - 45 - 50 - 55 + + + 15 + 20 + - - - + + + 15 + 20 + - - 15 - 20 + + + 15 + 20 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + culmen_depth_mm → + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - MALE + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - + + - - 15 - 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - Adelie + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 15 - 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - Chinstrap + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - Gentoo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 15 - 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - + + + + + + + \ No newline at end of file diff --git a/test/output/penguinDensityFill.html b/test/output/penguinDensityFill.html index 16e36ef585..c781f6284d 100644 --- a/test/output/penguinDensityFill.html +++ b/test/output/penguinDensityFill.html @@ -48,123 +48,165 @@ white-space: pre; } + + + + Biscoe + + + + + Dream + + + + + Torgersen + + + island + + + + + + + + + + + + + + + 35 + 40 + 45 + 50 + 55 + + + ↑ culmen_length_mm + + + + + + + + + + + + + + + + + + + + + + + + + + + 180 + 200 + 220 + + + + + 180 + 200 + 220 + + + + + 180 + 200 + 220 + + + flipper_length_mm → - - - Biscoe - - - - - - - - - - 35 - 40 - 45 - 50 - 55 - - - - - - - - 180 - 200 - 220 - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - Dream - - - - - - - - 180 - 200 - 220 - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - Torgersen - - - - - - - - 180 - 200 - 220 - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/penguinDensityZ.html b/test/output/penguinDensityZ.html index 3aaf1d1a8c..10050a294b 100644 --- a/test/output/penguinDensityZ.html +++ b/test/output/penguinDensityZ.html @@ -46,142 +46,184 @@ white-space: pre; } + + + + Biscoe + + + + + Dream + + + + + Torgersen + + + island + + + + + + + + + + + + + + + 35 + 40 + 45 + 50 + 55 + + + ↑ culmen_length_mm + + + + + + + + + + + + + + + + + + + + + + + + + + + 180 + 200 + 220 + + + + + 180 + 200 + 220 + + + + + 180 + 200 + 220 + + + flipper_length_mm → - - - Biscoe - - - - - - - - - - 35 - 40 - 45 - 50 - 55 - - - - - - - - 180 - 200 - 220 - - - - - - - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Gentoo - Gentoo - Gentoo - Gentoo - Gentoo - Gentoo - Gentoo - Gentoo - Gentoo + + + + + + + + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Gentoo + Gentoo + Gentoo + Gentoo + Gentoo + Gentoo + Gentoo + Gentoo + Gentoo + - - - - - Dream - - - - - - - - 180 - 200 - 220 - - - - - - - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Chinstrap - Chinstrap - Chinstrap - Chinstrap - Chinstrap - Chinstrap - Chinstrap - Chinstrap - Chinstrap + + + + + + + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Chinstrap + Chinstrap + Chinstrap + Chinstrap + Chinstrap + Chinstrap + Chinstrap + Chinstrap + Chinstrap + - - - - - Torgersen - - - - - - - - 180 - 200 - 220 - - - - - - - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie + + + + + + + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + - + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/penguinDodgeHexbin.svg b/test/output/penguinDodgeHexbin.svg index b1f509e62e..a2544b014e 100644 --- a/test/output/penguinDodgeHexbin.svg +++ b/test/output/penguinDodgeHexbin.svg @@ -13,765 +13,807 @@ white-space: pre; } - - body_mass_g → + + + + Adelie + + + + + Chinstrap + + + + + Gentoo + + - - - Adelie + + + + + + + + + + + - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - Chinstrap + + + + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 + - - - - - - - - + + + body_mass_g → + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - Gentoo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 3,000 - 3,500 - 4,000 - 4,500 - 5,000 - 5,500 - 6,000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/penguinFacetAnnotated.svg b/test/output/penguinFacetAnnotated.svg index ac5a99b86c..bc70cc2186 100644 --- a/test/output/penguinFacetAnnotated.svg +++ b/test/output/penguinFacetAnnotated.svg @@ -13,101 +13,147 @@ white-space: pre; } + + + + Biscoe + + + + + Dream + + + + + Torgersen + + + island + + + + + + + + + + + + + + + + + + + + + + + + + + + Adelie + Chinstrap + Gentoo + + + + + Adelie + Chinstrap + Gentoo + + + + + Adelie + Chinstrap + Gentoo + + + species + + + + + + + + + + + + + + + + + 0 + 20 + 40 + 60 + 80 + 100 + 120 + + + Frequency → - - - Biscoe - - - - - - - - Adelie - Chinstrap - Gentoo - - - - - - - - + + + + + + + + + - - - Dream - - - - - - - - Adelie - Chinstrap - Gentoo - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - Torgersen - - - - - - - - Adelie - Chinstrap - Gentoo - - - - - - - - - - - - 0 - 20 - 40 - 60 - 80 - 100 - 120 - - - - - - - - - Torgersen Island only has Adelie penguins! + + + + Torgersen Island only has Adelie penguins! + \ No newline at end of file diff --git a/test/output/penguinFacetAnnotatedX.svg b/test/output/penguinFacetAnnotatedX.svg index 55ea3e1300..d5aab980d7 100644 --- a/test/output/penguinFacetAnnotatedX.svg +++ b/test/output/penguinFacetAnnotatedX.svg @@ -13,93 +13,139 @@ white-space: pre; } + + + + Biscoe + + + + + Dream + + + + + Torgersen + + + island + + + + + + + + + + + + + Adelie + Chinstrap + Gentoo + + + species + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 50 + 100 + + + + + 0 + 50 + 100 + + + + + 0 + 50 + 100 + + + Frequency → - - - Biscoe - - - - - - - - Adelie - Chinstrap - Gentoo - - - - - - - - 0 - 50 - 100 - - - - - - - - + + + + + + + + + - - - Dream - - - - - - - - 0 - 50 - 100 - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - Torgersen - - - - - - - - 0 - 50 - 100 - - - - - - - - - Torgersen Islandonly has Adeliepenguins! + + + + Torgersen Islandonly has Adeliepenguins! + \ No newline at end of file diff --git a/test/output/penguinFacetDodge.svg b/test/output/penguinFacetDodge.svg index 841b59bf3a..baa431cf59 100644 --- a/test/output/penguinFacetDodge.svg +++ b/test/output/penguinFacetDodge.svg @@ -13,415 +13,441 @@ white-space: pre; } - - body_mass_g → - - - - Adelie + + + + Adelie + - - - - - - - - + + + Chinstrap + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + Gentoo + - - - Chinstrap + + + + + + + + + + + - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - Gentoo + + + + + + + + + + + - - - - - - - - + + + + + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 + - - - - - - - - + + + body_mass_g → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 3,000 - 3,500 - 4,000 - 4,500 - 5,000 - 5,500 - 6,000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/penguinFacetDodgeIdentity.svg b/test/output/penguinFacetDodgeIdentity.svg index 33d966d178..0e599005d5 100644 --- a/test/output/penguinFacetDodgeIdentity.svg +++ b/test/output/penguinFacetDodgeIdentity.svg @@ -13,415 +13,441 @@ white-space: pre; } - - body_mass_g → - - - - Adelie + + + + Adelie + - - - - - - - - + + + Chinstrap + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + Gentoo + - - - Chinstrap + + + + + + + + + + + - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - Gentoo + + + + + + + + + + + - - - - - - - - + + + + + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 + - - - - - - - - + + + body_mass_g → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 3,000 - 3,500 - 4,000 - 4,500 - 5,000 - 5,500 - 6,000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/penguinFacetDodgeIsland.html b/test/output/penguinFacetDodgeIsland.html index f4e2665a69..67d51399c7 100644 --- a/test/output/penguinFacetDodgeIsland.html +++ b/test/output/penguinFacetDodgeIsland.html @@ -46,415 +46,441 @@ white-space: pre; } - - body_mass_g → - - - - Adelie + + + + Adelie + - - - - - - - - + + + Chinstrap + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + Gentoo + - - - Chinstrap + + + + + + + + + + + - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - Gentoo + + + + + + + + + + + - - - - - - - - + + + + + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 + - - - - - - - - + + + body_mass_g → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 3,000 - 3,500 - 4,000 - 4,500 - 5,000 - 5,500 - 6,000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/output/penguinMassSex.svg b/test/output/penguinMassSex.svg index 663c9bea5f..c7d0a4782d 100644 --- a/test/output/penguinMassSex.svg +++ b/test/output/penguinMassSex.svg @@ -13,128 +13,168 @@ white-space: pre; } + + + + FEMALE + + + + + MALE + + + sex + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 10 + 20 + 30 + 40 + 50 + + + + + 0 + 10 + 20 + 30 + 40 + 50 + + + + + 0 + 10 + 20 + 30 + 40 + 50 + + + ↑ Frequency - - Body mass (g) → + + + + + + + + + + + + + + - - - FEMALE - - - - - - - - - - - 0 - 10 - 20 - 30 - 40 - 50 - - - - - - - - - - - + + + + 2,500 + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 + 6,500 + - - - MALE - - - - - - - - - - - 0 - 10 - 20 - 30 - 40 - 50 - - - - - - - - - - - - + + Body mass (g) → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - 0 - 10 - 20 - 30 - 40 - 50 - - - - - - - - - - - - - - 2,500 - 3,000 - 3,500 - 4,000 - 4,500 - 5,000 - 5,500 - 6,000 - 6,500 - - - - - - - - - - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/penguinMassSexSpecies.svg b/test/output/penguinMassSexSpecies.svg index 30721c6a67..75f9ce1037 100644 --- a/test/output/penguinMassSexSpecies.svg +++ b/test/output/penguinMassSexSpecies.svg @@ -13,192 +13,260 @@ white-space: pre; } + + + + Adelie + + + + + Chinstrap + + + + + Gentoo + + + species + + + + FEMALE + + + + + MALE + + + sex - - ↑ Frequency - - - Body mass (g) → - - - - FEMALE - - - - - - - - - - 0 - 10 - 20 - 30 - 40 - - - - - - - - - - - - - - - - - - - - 0 - 10 - 20 - 30 - 40 - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - 0 - 10 - 20 - 30 - 40 - - - - - - - 4,000 - 6,000 - - - - - - - - - + + + + 0 + 10 + 20 + 30 + 40 + + + + + 0 + 10 + 20 + 30 + 40 + + + + + 0 + 10 + 20 + 30 + 40 + - - - MALE - - - - - - - - - - + + ↑ Frequency - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - 4,000 - 6,000 - - - - - - - - - + + + + 4,000 + 6,000 + + + + + 4,000 + 6,000 + + + + + 4,000 + 6,000 + + + + + 4,000 + 6,000 + - - - Adelie - - - - - - - 4,000 - 6,000 - - - - - - - - - - + + Body mass (g) → - - - Chinstrap + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - Gentoo - - - - - - - 4,000 - 6,000 - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/penguinSexMassCulmenSpecies.svg b/test/output/penguinSexMassCulmenSpecies.svg index a10962acce..c259aaf57d 100644 --- a/test/output/penguinSexMassCulmenSpecies.svg +++ b/test/output/penguinSexMassCulmenSpecies.svg @@ -13,285 +13,341 @@ white-space: pre; } + + + + FEMALE + + + + + MALE + + + sex - - ↑ culmen_length_mm - - - body_mass_g → - - - - FEMALE + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - 34 - 36 - 38 - 40 - 42 - 44 - 46 - 48 - 50 - 52 - 54 - 56 - 58 + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + 34 + 36 + 38 + 40 + 42 + 44 + 46 + 48 + 50 + 52 + 54 + 56 + 58 + - - - - - - - - + + + ↑ culmen_length_mm + + + + + + + + + + + + - - 3k - 3.5k - 4k - 4.5k - 5k - 5.5k - 6k + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - MALE + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - + + + + + + + + + + - - - - - - - - + + + + + 3k + 3.5k + 4k + 4.5k + 5k + 5.5k + 6k + - - 3k - 3.5k - 4k - 4.5k - 5k - 5.5k - 6k + + + 3k + 3.5k + 4k + 4.5k + 5k + 5.5k + 6k + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 3k + 3.5k + 4k + 4.5k + 5k + 5.5k + 6k + - - - - - - - - - - - - - - - + + body_mass_g → + + + + - - - - - - - - + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - 3k - 3.5k - 4k - 4.5k - 5k - 5.5k - 6k + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/penguinSpeciesIslandRelative.svg b/test/output/penguinSpeciesIslandRelative.svg index 1c3836bf2b..e834a1e7a2 100644 --- a/test/output/penguinSpeciesIslandRelative.svg +++ b/test/output/penguinSpeciesIslandRelative.svg @@ -13,80 +13,114 @@ white-space: pre; } - - species - - - ↑ Frequency (%) - - - - + + + + + - - Adelie + + + + - - - - - - - - - - - - + + + + - - 0 - 10 - 20 - 30 - 40 - 50 - 60 - 70 - 80 - 90 - 100 + + + + + Adelie + - - - - + + + Chinstrap + - - + + + Gentoo + - - - + + species + + + + + + + + + + + + + + + + + + + + + + 0 + 10 + 20 + 30 + 40 + 50 + 60 + 70 + 80 + 90 + 100 + - - Chinstrap + + + ↑ Frequency (%) + + + + + + + + - - + + + + - - + + + + - - - - - - Gentoo + + + + + - - + + + + - - + + + + \ No newline at end of file diff --git a/test/output/penguinSpeciesIslandSex.svg b/test/output/penguinSpeciesIslandSex.svg index f9ec7067d3..955103584c 100644 --- a/test/output/penguinSpeciesIslandSex.svg +++ b/test/output/penguinSpeciesIslandSex.svg @@ -13,171 +13,221 @@ white-space: pre; } + + + + Adelie + + + + + Chinstrap + + + + + Gentoo + + + species + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 5 + 10 + 15 + 20 + 25 + 30 + 35 + 40 + 45 + 50 + 55 + 60 + 65 + 70 + + + ↑ Frequency - - sex + + + + + + + + + + + + + + + + + + + + + + - - - Adelie - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - 5 - 10 - 15 - 20 - 25 - 30 - 35 - 40 - 45 - 50 - 55 - 60 - 65 - 70 - - - - - - - - FEMALE - MALE - N/A - - - - - - - - - - - - - + + + + FEMALE + MALE + N/A + + + + + FEMALE + MALE + N/A + + + + + FEMALE + MALE + N/A + - - - Chinstrap - - - - - - - - - - - - - - - - - - - - - - - - - FEMALE - MALE - N/A - - - - - - - + + sex + + + + + + + + + + + + + + + + + + + + + + + + + + - - - Gentoo - - - - - - - - - - - - - - - - - - - - - - - - - FEMALE - MALE - N/A - - - - - - - - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/projectionBleedEdges2.svg b/test/output/projectionBleedEdges2.svg index b1af6ad33a..bcafda14d8 100644 --- a/test/output/projectionBleedEdges2.svg +++ b/test/output/projectionBleedEdges2.svg @@ -13,28 +13,48 @@ white-space: pre; } - - - 1 + + + + 1 + - - + + + 2 + - - + + + + + + + + + + + - - - - 2 + + + + + - - + + + + + + + + + - - + + - \ No newline at end of file diff --git a/test/output/projectionFitBertin1953.svg b/test/output/projectionFitBertin1953.svg index 29200805f2..0c6ca36656 100644 --- a/test/output/projectionFitBertin1953.svg +++ b/test/output/projectionFitBertin1953.svg @@ -13,22 +13,36 @@ white-space: pre; } - - - a + + + + a + - - - + + + b + - - - b + + + - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/projectionHeightEqualEarth.svg b/test/output/projectionHeightEqualEarth.svg index 419a217896..9082a79971 100644 --- a/test/output/projectionHeightEqualEarth.svg +++ b/test/output/projectionHeightEqualEarth.svg @@ -13,34 +13,60 @@ white-space: pre; } - - - 0 + + + + 0 + - - + + + 1 + - - + + + + + + - - + + + + - - - - 1 + + + + + + + + + + - - + + + + + + - - + + + + + + + + + - - + + - \ No newline at end of file diff --git a/test/output/projectionHeightGeometry.svg b/test/output/projectionHeightGeometry.svg index 2080d79823..229e180bfe 100644 --- a/test/output/projectionHeightGeometry.svg +++ b/test/output/projectionHeightGeometry.svg @@ -13,22 +13,36 @@ white-space: pre; } - - - 0 + + + + 0 + - - + + + 1 + - - - - 1 + + + + + - - + + + + + + + + + + + + - \ No newline at end of file diff --git a/test/output/projectionHeightMercator.svg b/test/output/projectionHeightMercator.svg index b71ba12991..ec42e3b0c0 100644 --- a/test/output/projectionHeightMercator.svg +++ b/test/output/projectionHeightMercator.svg @@ -13,34 +13,60 @@ white-space: pre; } - - - 0 + + + + 0 + - - + + + 1 + - - + + + + + + - - + + + + - - - - 1 + + + + + + + + + + - - + + + + + + - - + + + + + + + + + - - + + - \ No newline at end of file diff --git a/test/output/projectionHeightOrthographic.svg b/test/output/projectionHeightOrthographic.svg index 6609f0b076..7e570fe84c 100644 --- a/test/output/projectionHeightOrthographic.svg +++ b/test/output/projectionHeightOrthographic.svg @@ -13,64 +13,108 @@ white-space: pre; } - - - 0 + + + + 0 + - - + + + 1 + - - - - - - - - - - 1 - - - 0 - - - + + + + 0 + - - + + + 1 + - - - - - - - + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + - - - - 1 + + + - - + + - - + + - - + + - \ No newline at end of file diff --git a/test/output/reducerScaleOverrideFunction.svg b/test/output/reducerScaleOverrideFunction.svg index 56beac0a77..d9528093ea 100644 --- a/test/output/reducerScaleOverrideFunction.svg +++ b/test/output/reducerScaleOverrideFunction.svg @@ -13,85 +13,117 @@ white-space: pre; } + + + + FEMALE + + + + + MALE + + + sex - - ↑ Frequency - - - species - - - - FEMALE - - - - - - + + + + + + + + - - 0 - 20 - 40 - 60 + + + + + + + - - - - + + + + + + + - - - MALE + + + + 0 + 20 + 40 + 60 + - - - - - + + + 0 + 20 + 40 + 60 + - - 0 - 20 - 40 - 60 - - - - - + + + 0 + 20 + 40 + 60 + - - - - - - + + ↑ Frequency + + + + + + + + - - 0 - 20 - 40 - 60 + + + + + Adelie + Chinstrap + Gentoo + - - - - + + + species + + + + + + + + - - Adelie - Chinstrap - Gentoo + + + + + + - - - + + + + + \ No newline at end of file diff --git a/test/output/reducerScaleOverrideImplementation.svg b/test/output/reducerScaleOverrideImplementation.svg index 56beac0a77..d9528093ea 100644 --- a/test/output/reducerScaleOverrideImplementation.svg +++ b/test/output/reducerScaleOverrideImplementation.svg @@ -13,85 +13,117 @@ white-space: pre; } + + + + FEMALE + + + + + MALE + + + sex - - ↑ Frequency - - - species - - - - FEMALE - - - - - - + + + + + + + + - - 0 - 20 - 40 - 60 + + + + + + + - - - - + + + + + + + - - - MALE + + + + 0 + 20 + 40 + 60 + - - - - - + + + 0 + 20 + 40 + 60 + - - 0 - 20 - 40 - 60 - - - - - + + + 0 + 20 + 40 + 60 + - - - - - - + + ↑ Frequency + + + + + + + + - - 0 - 20 - 40 - 60 + + + + + Adelie + Chinstrap + Gentoo + - - - - + + + species + + + + + + + + - - Adelie - Chinstrap - Gentoo + + + + + + - - - + + + + + \ No newline at end of file diff --git a/test/output/reducerScaleOverrideName.svg b/test/output/reducerScaleOverrideName.svg index 56beac0a77..d9528093ea 100644 --- a/test/output/reducerScaleOverrideName.svg +++ b/test/output/reducerScaleOverrideName.svg @@ -13,85 +13,117 @@ white-space: pre; } + + + + FEMALE + + + + + MALE + + + sex - - ↑ Frequency - - - species - - - - FEMALE - - - - - - + + + + + + + + - - 0 - 20 - 40 - 60 + + + + + + + - - - - + + + + + + + - - - MALE + + + + 0 + 20 + 40 + 60 + - - - - - + + + 0 + 20 + 40 + 60 + - - 0 - 20 - 40 - 60 - - - - - + + + 0 + 20 + 40 + 60 + - - - - - - + + ↑ Frequency + + + + + + + + - - 0 - 20 - 40 - 60 + + + + + Adelie + Chinstrap + Gentoo + - - - - + + + species + + + + + + + + - - Adelie - Chinstrap - Gentoo + + + + + + - - - + + + + + \ No newline at end of file diff --git a/test/output/textOverflow.svg b/test/output/textOverflow.svg index 5de634dc1b..04273f6997 100644 --- a/test/output/textOverflow.svg +++ b/test/output/textOverflow.svg @@ -13,358 +13,406 @@ white-space: pre; } - - - clip-start + + + + clip-start + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + clip-end + - - The Best Years of Our Lives - The Ballad of Gregorio Cortez - My Big Fat Independent Movie - Battle for the Planet of the Apes - Big Things - Bogus - Beverly Hills Cop - Beverly Hills Cop II - Beverly Hills Cop III - The Black Hole - The Big Parade - Boyz n the Hood - The Book of Mormon Movie,Volume 1: The Journey - Return to the Blue Lagoon - Bright Lights, Big City - The Blue Bird - The Blue Butterfly - Blade Runner - Bloodsport - The Blues Brothers - Blow Out - De battre mon cœur s'est arrêté - The Broadway Melody - Boom Town - Bill & Ted's Bogus Journey - The Birth of a Nation - The Ballad of Cable Hogue - The Blood of Heroes - The Blood of My Brother: A Story of Death in Iraq - Boomerang - The Bridge on the River Kwai - Born on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - 🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + + + ellipsis-start + - - ars of Our LivesThe Best Years of Our Lives - Gregorio CortezThe Ballad of Gregorio Cortez - ependent MovieMy Big Fat Independent Movie - anet of the ApesBattle for the Planet of the Apes - Big Things - Bogus - everly Hills CopBeverly Hills Cop - verly Hills Cop IIBeverly Hills Cop II - erly Hills Cop IIIBeverly Hills Cop III - The Black Hole - The Big Parade - Boyz n the Hood - Mormon Movie,e 1: The JourneyThe Book of Mormon Movie, - Volume 1: The Journey - the Blue LagoonReturn to the Blue Lagoon - Lights, Big CityBright Lights, Big City - The Blue Bird - e Blue ButterflyThe Blue Butterfly - Blade Runner - Bloodsport - e Blues BrothersThe Blues Brothers - Blow Out - cœur s'est arrêtéDe battre mon cœur s'est arrêté - roadway MelodyThe Broadway Melody - Boom Town - Bogus JourneyBill & Ted's Bogus Journey - Birth of a NationThe Birth of a Nation - of Cable HogueThe Ballad of Cable Hogue - Blood of HeroesThe Blood of Heroes - of Death in IraqThe Blood of My Brother: A Story of Death in Iraq - Boomerang - n the River KwaiThe Bridge on the River Kwai - e Fourth of JulyBorn on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - .🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + + + ellipsis-middle + + + + + ellipsis-end + + + + + monospace + - - - - clip-end + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - The Best YearsThe Best Years of Our Lives - The Ballad of GrThe Ballad of Gregorio Cortez - My Big Fat IndeMy Big Fat Independent Movie - Battle for the PlBattle for the Planet of the Apes - Big Things - Bogus - Beverly Hills CoBeverly Hills Cop - Beverly Hills CoBeverly Hills Cop II - Beverly Hills CoBeverly Hills Cop III - The Black Hole - The Big Parade - Boyz n the Hood - The Book of MorVolume 1: The JThe Book of Mormon Movie, - Volume 1: The Journey - Return to the BlReturn to the Blue Lagoon - Bright Lights, BiBright Lights, Big City - The Blue Bird - The Blue ButterfThe Blue Butterfly - Blade Runner - Bloodsport - The Blues BrothThe Blues Brothers - Blow Out - De battre mon cDe battre mon cœur s'est arrêté - The BroadwayThe Broadway Melody - Boom Town - Bill & Ted's BogBill & Ted's Bogus Journey - The Birth of a NThe Birth of a Nation - The Ballad of CaThe Ballad of Cable Hogue - The Blood of HeThe Blood of Heroes - The Blood of MyThe Blood of My Brother: A Story of Death in Iraq - Boomerang - The Bridge on tThe Bridge on the River Kwai - Born on the FouBorn on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - 🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + + + + + The Best Years of Our Lives + The Ballad of Gregorio Cortez + My Big Fat Independent Movie + Battle for the Planet of the Apes + Big Things + Bogus + Beverly Hills Cop + Beverly Hills Cop II + Beverly Hills Cop III + The Black Hole + The Big Parade + Boyz n the Hood + The Book of Mormon Movie,Volume 1: The Journey + Return to the Blue Lagoon + Bright Lights, Big City + The Blue Bird + The Blue Butterfly + Blade Runner + Bloodsport + The Blues Brothers + Blow Out + De battre mon cœur s'est arrêté + The Broadway Melody + Boom Town + Bill & Ted's Bogus Journey + The Birth of a Nation + The Ballad of Cable Hogue + The Blood of Heroes + The Blood of My Brother: A Story of Death in Iraq + Boomerang + The Bridge on the River Kwai + Born on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + 🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + - - - - ellipsis-start + + + + ars of Our LivesThe Best Years of Our Lives + Gregorio CortezThe Ballad of Gregorio Cortez + ependent MovieMy Big Fat Independent Movie + anet of the ApesBattle for the Planet of the Apes + Big Things + Bogus + everly Hills CopBeverly Hills Cop + verly Hills Cop IIBeverly Hills Cop II + erly Hills Cop IIIBeverly Hills Cop III + The Black Hole + The Big Parade + Boyz n the Hood + Mormon Movie,e 1: The JourneyThe Book of Mormon Movie, + Volume 1: The Journey + the Blue LagoonReturn to the Blue Lagoon + Lights, Big CityBright Lights, Big City + The Blue Bird + e Blue ButterflyThe Blue Butterfly + Blade Runner + Bloodsport + e Blues BrothersThe Blues Brothers + Blow Out + cœur s'est arrêtéDe battre mon cœur s'est arrêté + roadway MelodyThe Broadway Melody + Boom Town + Bogus JourneyBill & Ted's Bogus Journey + Birth of a NationThe Birth of a Nation + of Cable HogueThe Ballad of Cable Hogue + Blood of HeroesThe Blood of Heroes + of Death in IraqThe Blood of My Brother: A Story of Death in Iraq + Boomerang + n the River KwaiThe Bridge on the River Kwai + e Fourth of JulyBorn on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + .🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + - - …rs of Our LivesThe Best Years of Our Lives - …regorio CortezThe Ballad of Gregorio Cortez - …pendent MovieMy Big Fat Independent Movie - …et of the ApesBattle for the Planet of the Apes - Big Things - Bogus - …verly Hills CopBeverly Hills Cop - …rly Hills Cop IIBeverly Hills Cop II - …rly Hills Cop IIIBeverly Hills Cop III - The Black Hole - The Big Parade - Boyz n the Hood - …ormon Movie,…1: The JourneyThe Book of Mormon Movie, - Volume 1: The Journey - …e Blue LagoonReturn to the Blue Lagoon - …ights, Big CityBright Lights, Big City - The Blue Bird - …Blue ButterflyThe Blue Butterfly - Blade Runner - Bloodsport - …Blues BrothersThe Blues Brothers - Blow Out - …ur s'est arrêtéDe battre mon cœur s'est arrêté - …adway MelodyThe Broadway Melody - Boom Town - …ogus JourneyBill & Ted's Bogus Journey - …rth of a NationThe Birth of a Nation - …f Cable HogueThe Ballad of Cable Hogue - …lood of HeroesThe Blood of Heroes - …f Death in IraqThe Blood of My Brother: A Story of Death in Iraq - Boomerang - …the River KwaiThe Bridge on the River Kwai - …Fourth of JulyBorn on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - …👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - ….👨🏻.👧🏼.👦🏽.🧒🏿🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + + + + + The Best YearsThe Best Years of Our Lives + The Ballad of GrThe Ballad of Gregorio Cortez + My Big Fat IndeMy Big Fat Independent Movie + Battle for the PlBattle for the Planet of the Apes + Big Things + Bogus + Beverly Hills CoBeverly Hills Cop + Beverly Hills CoBeverly Hills Cop II + Beverly Hills CoBeverly Hills Cop III + The Black Hole + The Big Parade + Boyz n the Hood + The Book of MorVolume 1: The JThe Book of Mormon Movie, + Volume 1: The Journey + Return to the BlReturn to the Blue Lagoon + Bright Lights, BiBright Lights, Big City + The Blue Bird + The Blue ButterfThe Blue Butterfly + Blade Runner + Bloodsport + The Blues BrothThe Blues Brothers + Blow Out + De battre mon cDe battre mon cœur s'est arrêté + The BroadwayThe Broadway Melody + Boom Town + Bill & Ted's BogBill & Ted's Bogus Journey + The Birth of a NThe Birth of a Nation + The Ballad of CaThe Ballad of Cable Hogue + The Blood of HeThe Blood of Heroes + The Blood of MyThe Blood of My Brother: A Story of Death in Iraq + Boomerang + The Bridge on tThe Bridge on the River Kwai + Born on the FouBorn on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + 🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + - - - - ellipsis-middle + + + + …rs of Our LivesThe Best Years of Our Lives + …regorio CortezThe Ballad of Gregorio Cortez + …pendent MovieMy Big Fat Independent Movie + …et of the ApesBattle for the Planet of the Apes + Big Things + Bogus + …verly Hills CopBeverly Hills Cop + …rly Hills Cop IIBeverly Hills Cop II + …rly Hills Cop IIIBeverly Hills Cop III + The Black Hole + The Big Parade + Boyz n the Hood + …ormon Movie,…1: The JourneyThe Book of Mormon Movie, + Volume 1: The Journey + …e Blue LagoonReturn to the Blue Lagoon + …ights, Big CityBright Lights, Big City + The Blue Bird + …Blue ButterflyThe Blue Butterfly + Blade Runner + Bloodsport + …Blues BrothersThe Blues Brothers + Blow Out + …ur s'est arrêtéDe battre mon cœur s'est arrêté + …adway MelodyThe Broadway Melody + Boom Town + …ogus JourneyBill & Ted's Bogus Journey + …rth of a NationThe Birth of a Nation + …f Cable HogueThe Ballad of Cable Hogue + …lood of HeroesThe Blood of Heroes + …f Death in IraqThe Blood of My Brother: A Story of Death in Iraq + Boomerang + …the River KwaiThe Bridge on the River Kwai + …Fourth of JulyBorn on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + …👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + ….👨🏻.👧🏼.👦🏽.🧒🏿🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + - - The Be…ur LivesThe Best Years of Our Lives - The Ba…CortezThe Ballad of Gregorio Cortez - My Big…t MovieMy Big Fat Independent Movie - Battle f…e ApesBattle for the Planet of the Apes - Big Things - Bogus - Beverly…ills CopBeverly Hills Cop - Beverly…Cop IIBeverly Hills Cop II - Beverly…Cop IIIBeverly Hills Cop III - The Black Hole - The Big Parade - Boyz n the Hood - The Bo…Movie,Volum…JourneyThe Book of Mormon Movie, - Volume 1: The Journey - Return…LagoonReturn to the Blue Lagoon - Bright…Big CityBright Lights, Big City - The Blue Bird - The Bl…utterflyThe Blue Butterfly - Blade Runner - Bloodsport - The Bl…rothersThe Blues Brothers - Blow Out - De batt…t arrêtéDe battre mon cœur s'est arrêté - The Br…MelodyThe Broadway Melody - Boom Town - Bill & T…JourneyBill & Ted's Bogus Journey - The Bir…NationThe Birth of a Nation - The Ba…HogueThe Ballad of Cable Hogue - The Bl…f HeroesThe Blood of Heroes - The Bl…h in IraqThe Blood of My Brother: A Story of Death in Iraq - Boomerang - The Bri…er KwaiThe Bridge on the River Kwai - Born o…of JulyBorn on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - 👁️‍🗨️👩‍❤️‍💋‍👩…👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - 🧑🏾.👨🏻.….👦🏽.🧒🏿🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + + + + + The Be…ur LivesThe Best Years of Our Lives + The Ba…CortezThe Ballad of Gregorio Cortez + My Big…t MovieMy Big Fat Independent Movie + Battle f…e ApesBattle for the Planet of the Apes + Big Things + Bogus + Beverly…ills CopBeverly Hills Cop + Beverly…Cop IIBeverly Hills Cop II + Beverly…Cop IIIBeverly Hills Cop III + The Black Hole + The Big Parade + Boyz n the Hood + The Bo…Movie,Volum…JourneyThe Book of Mormon Movie, + Volume 1: The Journey + Return…LagoonReturn to the Blue Lagoon + Bright…Big CityBright Lights, Big City + The Blue Bird + The Bl…utterflyThe Blue Butterfly + Blade Runner + Bloodsport + The Bl…rothersThe Blues Brothers + Blow Out + De batt…t arrêtéDe battre mon cœur s'est arrêté + The Br…MelodyThe Broadway Melody + Boom Town + Bill & T…JourneyBill & Ted's Bogus Journey + The Bir…NationThe Birth of a Nation + The Ba…HogueThe Ballad of Cable Hogue + The Bl…f HeroesThe Blood of Heroes + The Bl…h in IraqThe Blood of My Brother: A Story of Death in Iraq + Boomerang + The Bri…er KwaiThe Bridge on the River Kwai + Born o…of JulyBorn on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + 👁️‍🗨️👩‍❤️‍💋‍👩…👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + 🧑🏾.👨🏻.….👦🏽.🧒🏿🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + - - - - ellipsis-end + + + + The Best Year…The Best Years of Our Lives + The Ballad of…The Ballad of Gregorio Cortez + My Big Fat Ind…My Big Fat Independent Movie + Battle for the…Battle for the Planet of the Apes + Big Things + Bogus + Beverly Hills C…Beverly Hills Cop + Beverly Hills C…Beverly Hills Cop II + Beverly Hills C…Beverly Hills Cop III + The Black Hole + The Big Parade + Boyz n the Hood + The Book of M…Volume 1: The…The Book of Mormon Movie, + Volume 1: The Journey + Return to the…Return to the Blue Lagoon + Bright Lights,…Bright Lights, Big City + The Blue Bird + The Blue Butte…The Blue Butterfly + Blade Runner + Bloodsport + The Blues Brot…The Blues Brothers + Blow Out + De battre mon…De battre mon cœur s'est arrêté + The Broadway…The Broadway Melody + Boom Town + Bill & Ted's Bo…Bill & Ted's Bogus Journey + The Birth of a…The Birth of a Nation + The Ballad of…The Ballad of Cable Hogue + The Blood of H…The Blood of Heroes + The Blood of…The Blood of My Brother: A Story of Death in Iraq + Boomerang + The Bridge on…The Bridge on the River Kwai + Born on the Fo…Born on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️…👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + 🧑🏾.👨🏻.👧🏼.👦🏽.…🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + - - The Best Year…The Best Years of Our Lives - The Ballad of…The Ballad of Gregorio Cortez - My Big Fat Ind…My Big Fat Independent Movie - Battle for the…Battle for the Planet of the Apes - Big Things - Bogus - Beverly Hills C…Beverly Hills Cop - Beverly Hills C…Beverly Hills Cop II - Beverly Hills C…Beverly Hills Cop III - The Black Hole - The Big Parade - Boyz n the Hood - The Book of M…Volume 1: The…The Book of Mormon Movie, - Volume 1: The Journey - Return to the…Return to the Blue Lagoon - Bright Lights,…Bright Lights, Big City - The Blue Bird - The Blue Butte…The Blue Butterfly - Blade Runner - Bloodsport - The Blues Brot…The Blues Brothers - Blow Out - De battre mon…De battre mon cœur s'est arrêté - The Broadway…The Broadway Melody - Boom Town - Bill & Ted's Bo…Bill & Ted's Bogus Journey - The Birth of a…The Birth of a Nation - The Ballad of…The Ballad of Cable Hogue - The Blood of H…The Blood of Heroes - The Blood of…The Blood of My Brother: A Story of Death in Iraq - Boomerang - The Bridge on…The Bridge on the River Kwai - Born on the Fo…Born on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️…👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - 🧑🏾.👨🏻.👧🏼.👦🏽.…🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + + + + + The Best Yea…The Best Years of Our Lives + The Ballad o…The Ballad of Gregorio Cortez + My Big Fat I…My Big Fat Independent Movie + Battle for t…Battle for the Planet of the Apes + Big Things + Bogus + Beverly Hill…Beverly Hills Cop + Beverly Hill…Beverly Hills Cop II + Beverly Hill…Beverly Hills Cop III + The Black Ho…The Black Hole + The Big Para…The Big Parade + Boyz n the H…Boyz n the Hood + The Book of…Volume 1: Th…The Book of Mormon Movie, + Volume 1: The Journey + Return to th…Return to the Blue Lagoon + Bright Light…Bright Lights, Big City + The Blue Bird + The Blue But…The Blue Butterfly + Blade Runner + Bloodsport + The Blues Br…The Blues Brothers + Blow Out + De battre mo…De battre mon cœur s'est arrêté + The Broadway…The Broadway Melody + Boom Town + Bill & Ted's…Bill & Ted's Bogus Journey + The Birth of…The Birth of a Nation + The Ballad o…The Ballad of Cable Hogue + The Blood of…The Blood of Heroes + The Blood of…The Blood of My Brother: A Story of Death in Iraq + Boomerang + The Bridge o…The Bridge on the River Kwai + Born on the…Born on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩…👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + 🧑🏾.👨🏻.👧🏼.👦🏽.…🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + - - - - monospace + + + + + + + + + + + + + + + - - The Best Yea…The Best Years of Our Lives - The Ballad o…The Ballad of Gregorio Cortez - My Big Fat I…My Big Fat Independent Movie - Battle for t…Battle for the Planet of the Apes - Big Things - Bogus - Beverly Hill…Beverly Hills Cop - Beverly Hill…Beverly Hills Cop II - Beverly Hill…Beverly Hills Cop III - The Black Ho…The Black Hole - The Big Para…The Big Parade - Boyz n the H…Boyz n the Hood - The Book of…Volume 1: Th…The Book of Mormon Movie, - Volume 1: The Journey - Return to th…Return to the Blue Lagoon - Bright Light…Bright Lights, Big City - The Blue Bird - The Blue But…The Blue Butterfly - Blade Runner - Bloodsport - The Blues Br…The Blues Brothers - Blow Out - De battre mo…De battre mon cœur s'est arrêté - The Broadway…The Broadway Melody - Boom Town - Bill & Ted's…Bill & Ted's Bogus Journey - The Birth of…The Birth of a Nation - The Ballad o…The Ballad of Cable Hogue - The Blood of…The Blood of Heroes - The Blood of…The Blood of My Brother: A Story of Death in Iraq - Boomerang - The Bridge o…The Bridge on the River Kwai - Born on the…Born on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩…👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - 🧑🏾.👨🏻.👧🏼.👦🏽.…🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 + + - \ No newline at end of file diff --git a/test/output/tipDotFacets.svg b/test/output/tipDotFacets.svg index 8a903e5126..2834b28fa6 100644 --- a/test/output/tipDotFacets.svg +++ b/test/output/tipDotFacets.svg @@ -13,11206 +13,11346 @@ white-space: pre; } + + + + 1950 + + + + + 1960 + + + + + 1970 + + + + + 1980 + + + + + 1990 + + + + + 2000 + + + decade of birth + + + + female + + + + + male + + + sex - - ↑ height - - - weight → - - - - female + + + + + + + + + - - - - - - + + + + + + + + - - - - - - + + + + + + + + - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 + + + + + + + + - - - - + + + + + + + + - - - - - + + + + + + + + - - - - - - - - - + + + + + + + + - - - - - - + + + + + + + + - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 + + + + + + + + - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 + + + + + + + + - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - + + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + + + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + - - - - - - + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + - - - - + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 + - - - - - - - - + + ↑ height + + + + + + + + - - - - - - + + + + + + - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 + + + + + + - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - + + + + + + - - - - - - + + + + + + - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 + + + + + + - - - - + + + + + + - - - - + + + + + + - - 50 - 100 - 150 + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - 1950 + + + + + + + - - male + + + + + + - - - - - - - - - - - + + + + + 50 + 100 + 150 + - - - - - + + + 50 + 100 + 150 + - - - - 1960 + + weight → + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - 1970 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - 1980 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - 1990 + + + - - - - - - + + - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - 2000 + + + + + + + + - - - - - - + + - - - - + + - - - - + + - - 50 - 100 - 150 + + - - - - - + + - \ No newline at end of file diff --git a/test/output/trafficHorizon.html b/test/output/trafficHorizon.html index 76083f4fd4..e77396629a 100644 --- a/test/output/trafficHorizon.html +++ b/test/output/trafficHorizon.html @@ -50,1743 +50,2143 @@ white-space: pre; } - - - - - - - - - - - - - - - - - Mon 04 - 12 PM - Tue 05 - 12 PM - Wed 06 - 12 PM - Thu 07 - 12 PM - Fri 08 - 12 PM - Sat 09 - 12 PM - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Von der Heydt - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Kirschheck - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Saarbrücken-Neuhaus - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Riegelsberg - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Holz - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Göttelborn - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Illingen - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AS Eppelborn - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Hasborn - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Kastel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Otzenhausen - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Bierfeld - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Nonnweiler - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Hetzerath - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Laufeld - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - Nettersheim - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Euskirchen/Bliesheim - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Hürth - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Köln-Nord - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Schloss Burg - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Hagen-Vorhalle - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Hengsen - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Unna - - - - - - - - - - - - - - - - - - - - - - - - + + + + Mon 04 + 12 PM + Tue 05 + 12 PM + Wed 06 + 12 PM + Thu 07 + 12 PM + Fri 08 + 12 PM + Sat 09 + 12 PM - - - - - - - - - - - - - - - - - - Ascheberg - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Ladbergen - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - Lotte - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - HB-Silbersee - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - HB-Weserbrücke - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - HB-Mahndorfer See - - - - - - - - + + + + Von der Heydt - - - - - - + + + Kirschheck - - - - - - + + + Saarbrücken-Neuhaus - - - - - - + + + Riegelsberg - - - - - - + + + Holz - - Groß Ippener - - - - - - - - - + + + Göttelborn - - - - - - + + + Illingen - - - - - - + + + AS Eppelborn - - - - - - + + + Hasborn - - - - - - + + + Kastel - - Uphusen - - - - - - - - - + + + Otzenhausen - - - - - - + + + Bierfeld - - - - - - + + + Nonnweiler - - - - - - + + + Hetzerath - - - - - - + + + Laufeld - - Bockel - - - - - - - - - + + + Nettersheim - - - - - - + + + Euskirchen/Bliesheim - - - - - - + + + Hürth - - - - - - + + + Köln-Nord - - - - - - + + + Schloss Burg - - Dibbersen - - - - - - - - - + + + Hagen-Vorhalle - - - - - - + + + Hengsen - - - - - - + + + Unna - - - - - - + + + Ascheberg - - - - - - + + + Ladbergen - - Glüsingen - - - - - - - - - + + + Lotte - - - - - - + + + HB-Silbersee - - - - - - + + + HB-Weserbrücke - - - - - - + + + HB-Mahndorfer See - - - - - - + + + Groß Ippener - - Barsbüttel - - - - - - - - - - - - - - - - - + + + Uphusen - - - - - - + + + Bockel - - - - - - + + + Dibbersen - - - - - - + + + Glüsingen - - Bad Schwartau - - - - - - - - - + + + Barsbüttel - - - - - - + + + Bad Schwartau - - - - - - + + + Oldenburg (Holstein) - - - - - - + + + Neustadt i. H.-Süd - - - - - - - - - - Oldenburg (Holstein) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Neustadt i. H.-Süd - \ No newline at end of file diff --git a/test/output/usPopulationStateAgeGrouped.svg b/test/output/usPopulationStateAgeGrouped.svg index 80ecaf64bb..54e4c09dc9 100644 --- a/test/output/usPopulationStateAgeGrouped.svg +++ b/test/output/usPopulationStateAgeGrouped.svg @@ -13,251 +13,317 @@ white-space: pre; } - - ↑ population + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - CA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0.0M - 0.5M - 1.0M - 1.5M - 2.0M - 2.5M - 3.0M - 3.5M - 4.0M - 4.5M - 5.0M - 5.5M - - - <10 - 10-19 - 20-29 - 30-39 - 40-49 - 50-59 - 60-69 - 70-79 - ≥80 - - - + + + + CA + + + + + TX + + + + + NY + + + + + FL + + + + + PA + + + + + IL + - - - - - - TX - - - - - - - - - - - - - - - - - <10 - 10-19 - 20-29 - 30-39 - 40-49 - 50-59 - 60-69 - 70-79 - ≥80 - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - NY - - - - - - - - - - - - - - - - - <10 - 10-19 - 20-29 - 30-39 - 40-49 - 50-59 - 60-69 - 70-79 - ≥80 - - - + + + + + + + + + + + + + + + + - - - - - - FL - - - - - - - - - - - - - - - - - <10 - 10-19 - 20-29 - 30-39 - 40-49 - 50-59 - 60-69 - 70-79 - ≥80 - - - + + + + 0.0M + 0.5M + 1.0M + 1.5M + 2.0M + 2.5M + 3.0M + 3.5M + 4.0M + 4.5M + 5.0M + 5.5M + - - - - - - PA - - - - - - - - - - - - - - - - - <10 - 10-19 - 20-29 - 30-39 - 40-49 - 50-59 - 60-69 - 70-79 - ≥80 - - - + + ↑ population + + + + + <10 + 10-19 + 20-29 + 30-39 + 40-49 + 50-59 + 60-69 + 70-79 + ≥80 + + + + + <10 + 10-19 + 20-29 + 30-39 + 40-49 + 50-59 + 60-69 + 70-79 + ≥80 + + + + + <10 + 10-19 + 20-29 + 30-39 + 40-49 + 50-59 + 60-69 + 70-79 + ≥80 + + + + + <10 + 10-19 + 20-29 + 30-39 + 40-49 + 50-59 + 60-69 + 70-79 + ≥80 + + + + + <10 + 10-19 + 20-29 + 30-39 + 40-49 + 50-59 + 60-69 + 70-79 + ≥80 + + + + + <10 + 10-19 + 20-29 + 30-39 + 40-49 + 50-59 + 60-69 + 70-79 + ≥80 + - - - - - - IL - - - - - - - - - - - - - - - - - <10 - 10-19 - 20-29 - 30-39 - 40-49 - 50-59 - 60-69 - 70-79 - ≥80 - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/walmartsDecades.svg b/test/output/walmartsDecades.svg index d2183b4cca..0a5005bb0c 100644 --- a/test/output/walmartsDecades.svg +++ b/test/output/walmartsDecades.svg @@ -13,74 +13,112 @@ white-space: pre; } - - - 1960’s - - - - - - - - - + + + + 1960’s + + + + + 1970’s + + + + + 1980’s + + + + + 1990’s + + + + + 2000’s + - - - 1970’s - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - 1980’s - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - 1990’s - - - - - - - - - - - - - - 2000’s - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 532a605e47a771335f56272b1b81ac85d42890af Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sun, 7 May 2023 19:42:28 -0700 Subject: [PATCH 12/56] prefer top-left --- src/marks/tip.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/marks/tip.js b/src/marks/tip.js index bc557bdce1..a5c7e60b76 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -49,6 +49,7 @@ export class Tip extends Mark { defaults ); this.anchor = maybeAnchor(anchor); + this.previousAnchor = this.anchor ?? "top-left"; this.frameAnchor = maybeFrameAnchor(frameAnchor); this.textAnchor = "start"; // TODO option this.lineHeight = +lineHeight; From e6c1ab313b4a05237b2748d0ec4b4c529962281e Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 08:32:29 -0700 Subject: [PATCH 13/56] only pass index.f[xyi] if faceted --- src/interactions/pointer.js | 4 +--- src/marks/tip.js | 1 + src/plot.js | 7 +++---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index e973b06b23..f73e311b82 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -21,9 +21,7 @@ function pointerK(kx, ky, {px, py, maxRadius = 40, channels, ...options} = {}) { if (i === ii) return; // the tooltip hasn’t moved i = ii; const I = i == null ? [] : [i]; - I.fx = index.fx; - I.fy = index.fy; - I.fi = index.fi; + if (index.fi != null) (I.fx = index.fx), (I.fy = index.fy), (I.fi = index.fi); const r = mark._render(I, scales, values, dimensions, context); if (g) g.replaceWith(r); return (g = r); diff --git a/src/marks/tip.js b/src/marks/tip.js index a5c7e60b76..5a10d42418 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -103,6 +103,7 @@ export class Tip extends Mark { if (!channel) continue; // e.g., dodgeY’s y renderLine(that, scales[channel.scale]?.label ?? key, formatDefault(channel.value[i])); } + if (index.fi == null) return; // not faceted if (fx) renderLine(that, labelFx, formatFx(index.fx)); if (fy) renderLine(that, labelFy, formatFy(index.fy)); }) diff --git a/src/plot.js b/src/plot.js index 46098a1e3d..af8e282ebc 100644 --- a/src/plot.js +++ b/src/plot.js @@ -265,12 +265,11 @@ export function plot(options = {}) { if (!(mark.facetAnchor?.(facets, facetDomains, f) ?? !f.empty)) continue; let index = null; if (indexes) { - index = indexes[facetStateByMark.has(mark) ? f.i : 0]; + const faceted = facetStateByMark.has(mark); + index = indexes[faceted ? f.i : 0]; index = mark.filter(index, channels, values); if (index.length === 0) continue; - index.fx = f.x; - index.fy = f.y; - index.fi = f.i; + if (faceted) (index.fx = f.x), (index.fy = f.y), (index.fi = f.i); } const node = mark.render(index, scales, values, subdimensions, context); if (node == null) continue; From 9a6923094c2195d3ba2c6e80a54ce261ae40b586 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 09:14:07 -0700 Subject: [PATCH 14/56] =?UTF-8?q?[xy][12];=20don=E2=80=99t=20apply=20strok?= =?UTF-8?q?e=20as=20text=20fill?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/marks/tip.js | 42 ++++++-- test/output/tipBin.svg | 142 +++++++++++++++++++++++++++ test/output/tipBinStack.svg | 189 ++++++++++++++++++++++++++++++++++++ test/plots/tip.ts | 20 ++++ 4 files changed, 384 insertions(+), 9 deletions(-) create mode 100644 test/output/tipBin.svg create mode 100644 test/output/tipBinStack.svg diff --git a/src/marks/tip.js b/src/marks/tip.js index 5a10d42418..eeca3b0529 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -64,10 +64,12 @@ export class Tip extends Mark { render(index, scales, channels, dimensions, context) { const mark = this; const {x, y, fx, fy} = scales; - const {x: X, y: Y, stroke: S} = channels; // TODO X1, Y1, X2, Y2 + const {x: X, y: Y, x1: X1, y1: Y1, x2: X2, y2: Y2, channels: sources} = channels; const [cx, cy] = applyFrameAnchor(this, dimensions); + const tx = X2 ? (i) => (X1[i] + X2[i]) / 2 : X ? (i) => X[i] : cx; + const ty = Y2 ? (i) => (Y1[i] + Y2[i]) / 2 : Y ? (i) => Y[i] : cy; const {ownerSVGElement: svg, document} = context; - const {stroke, anchor, monospace, lineHeight, lineWidth} = this; + const {anchor, monospace, lineHeight, lineWidth} = this; const {marginTop, marginLeft} = dimensions; const widthof = monospace ? monospaceWidth : defaultWidth; const ellipsis = "…"; @@ -89,19 +91,33 @@ export class Tip extends Mark { .data(index) .enter() .append("g") - .attr("transform", template`translate(${X ? (i) => X[i] : cx},${Y ? (i) => Y[i] : cy})`) + .attr("transform", template`translate(${tx},${ty})`) .call(applyDirectStyles, this) .call(applyChannelStyles, this, channels) .call((g) => g.append("path").attr("filter", "drop-shadow(0 3px 4px rgba(0,0,0,0.2))")) .call((g) => g.append("text").each(function (i) { const that = select(this); - this.setAttribute("fill", S ? S[i] : stroke); + this.setAttribute("fill", "currentColor"); + this.setAttribute("fill-opacity", 1); this.setAttribute("stroke", "none"); - for (const key in channels.channels) { - const channel = getSource(channels.channels, key); + for (const key in sources) { + const channel = getSource(sources, key); if (!channel) continue; // e.g., dodgeY’s y - renderLine(that, scales[channel.scale]?.label ?? key, formatDefault(channel.value[i])); + const channel1 = getSource1(sources, key); + if (channel1) continue; // already displayed + const channel2 = getSource2(sources, key); + const value1 = channel.value[i]; + const value2 = channel2?.value[i]; + renderLine( + that, + scales[channel.scale]?.label ?? key, + channel2 + ? channel2.hint?.length + ? `${formatDefault(value2 - value1)}` + : `${formatDefault(value1)}–${formatDefault(value2)}` + : formatDefault(value1) + ); } if (index.fi == null) return; // not faceted if (fx) renderLine(that, labelFx, formatFx(index.fx)); @@ -139,8 +155,8 @@ export class Tip extends Mark { const ox = fx ? fx(index.fx) - marginLeft : 0; const oy = fy ? fy(index.fy) - marginTop : 0; g.selectChildren().each(function (i) { - const x = (X ? X[i] : cx) + ox; - const y = (Y ? Y[i] : cy) + oy; + const x = tx(i) + ox; + const y = ty(i) + oy; const {width: w, height: h} = this.getBBox(); let a = anchor; if (a === undefined) { @@ -188,6 +204,14 @@ function getSource(channels, key) { return channel.source === null ? null : channel; } +function getSource1(channels, key) { + return key === "x2" ? getSource(channels, "x1") : key === "y2" ? getSource(channels, "y1") : null; +} + +function getSource2(channels, key) { + return key === "x1" ? getSource(channels, "x2") : key === "y1" ? getSource(channels, "y2") : null; +} + function getLineOffset(anchor, length, lineHeight) { return /^top-/.test(anchor) ? 0.94 - lineHeight : -0.29 - length * lineHeight; } diff --git a/test/output/tipBin.svg b/test/output/tipBin.svg new file mode 100644 index 0000000000..5a315ad72c --- /dev/null +++ b/test/output/tipBin.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + 0 + 50 + 100 + 150 + 200 + 250 + 300 + 350 + 400 + 450 + 500 + 550 + 600 + + + ↑ Frequency + + + + + + + + + + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 + + + weight → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/tipBinStack.svg b/test/output/tipBinStack.svg new file mode 100644 index 0000000000..8b4c61cd58 --- /dev/null +++ b/test/output/tipBinStack.svg @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + 0 + 50 + 100 + 150 + 200 + 250 + 300 + 350 + 400 + 450 + 500 + 550 + 600 + + + ↑ Frequency + + + + + + + + + + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 + + + weight → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index b803526df2..6e91af766f 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -1,6 +1,26 @@ import * as Plot from "@observablehq/plot"; import * as d3 from "d3"; +export async function tipBin() { + const olympians = await d3.csv("data/athletes.csv", d3.autoType); + return Plot.plot({ + marks: [ + Plot.rectY(olympians, Plot.binX({y: "count"}, {x: "weight"})), + Plot.tip(olympians, Plot.pointerX(Plot.binX({y: "count"}, {x: "weight"}))) + ] + }); +} + +export async function tipBinStack() { + const olympians = await d3.csv("data/athletes.csv", d3.autoType); + return Plot.plot({ + marks: [ + Plot.rectY(olympians, Plot.stackY({}, Plot.binX({y: "count"}, {x: "weight", fill: "sex"}))), + Plot.tip(olympians, Plot.pointerX(Plot.stackY({}, Plot.binX({y: "count"}, {x: "weight", stroke: "sex"})))) + ] + }); +} + export async function tipCrosshair() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); return Plot.plot({ From 56455011f62c855b65deeb429bc14b9d64870807 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 09:30:52 -0700 Subject: [PATCH 15/56] tip + hexbin test --- src/transforms/hexbin.js | 11 +- test/output/tipHexbin.svg | 306 ++++++++++++++++++++++++++++++++++++++ test/plots/tip.ts | 10 ++ 3 files changed, 324 insertions(+), 3 deletions(-) create mode 100644 test/output/tipHexbin.svg diff --git a/src/transforms/hexbin.js b/src/transforms/hexbin.js index ec06624bef..5ef514e63d 100644 --- a/src/transforms/hexbin.js +++ b/src/transforms/hexbin.js @@ -79,8 +79,8 @@ export function hexbin(outputs = {fill: "count"}, {binWidth, ...options} = {}) { // Construct the output channels, and populate the radius scale hint. const binChannels = { - x: {value: BX}, - y: {value: BY}, + x: {value: BX, source: null}, // or {value: map(BX, scales.x.invert), scale: "x"}? + y: {value: BY, source: null}, // or {value: map(BY, scales.y.invert), scale: "y"}? ...(Z && {z: {value: GZ}}), ...(F && {fill: {value: GF, scale: "auto"}}), ...(S && {stroke: {value: GS, scale: "auto"}}), @@ -88,7 +88,12 @@ export function hexbin(outputs = {fill: "count"}, {binWidth, ...options} = {}) { ...Object.fromEntries( outputs.map(({name, output}) => [ name, - {scale: "auto", radius: name === "r" ? binWidth / 2 : undefined, value: output.transform()} + { + scale: "auto", + label: output.label, + radius: name === "r" ? binWidth / 2 : undefined, + value: output.transform() + } ]) ) }; diff --git a/test/output/tipHexbin.svg b/test/output/tipHexbin.svg new file mode 100644 index 0000000000..2e6d1ea5f5 --- /dev/null +++ b/test/output/tipHexbin.svg @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + 1.3 + 1.4 + 1.5 + 1.6 + 1.7 + 1.8 + 1.9 + 2.0 + 2.1 + 2.2 + + + ↑ height + + + + + + + + + + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 + + + weight → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 6e91af766f..73f2e2972c 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -68,6 +68,16 @@ export async function tipDotFacets() { }); } +export async function tipHexbin() { + const olympians = await d3.csv("data/athletes.csv", d3.autoType); + return Plot.plot({ + marks: [ + Plot.hexagon(olympians, Plot.hexbin({r: "count"}, {x: "weight", y: "height"})), + Plot.tip(olympians, Plot.pointer(Plot.hexbin({r: "count"}, {x: "weight", y: "height"}))) + ] + }); +} + export async function tipLine() { const aapl = await d3.csv("data/aapl.csv", d3.autoType); return Plot.plot({ From 383fcb955843ef81204cab4c41f6725988baf1ff Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 10:27:44 -0700 Subject: [PATCH 16/56] optimize faceting by swapping transforms --- src/facet.js | 2 +- src/interactions/pointer.js | 14 +- src/plot.js | 24 +- test/output/anscombeQuartet.svg | 388 +- test/output/athletesBoxingHeight.svg | 646 +- test/output/athletesSampleFacet.svg | 1040 +- test/output/athletesSortFacet.svg | 322 +- test/output/athletesSportWeight.svg | 2496 +- test/output/autoDotFacet.svg | 842 +- test/output/autoDotFacet2.svg | 918 +- test/output/autoLineFacet.svg | 574 +- test/output/ballotStatusRace.svg | 302 +- test/output/beckerBarley.svg | 978 +- test/output/boxplotFacetInterval.svg | 1306 +- test/output/boxplotFacetNegativeInterval.svg | 1306 +- test/output/caltrainDirection.svg | 230 +- test/output/emptyFacet.svg | 58 +- test/output/footballCoverage.svg | 778 +- test/output/frameFacet.svg | 764 +- test/output/functionContourFaceted.svg | 256 +- test/output/functionContourFaceted2.svg | 256 +- test/output/futureSplom.svg | 438 +- test/output/googleTrendsRidgeline.svg | 2106 +- test/output/heatmapFaceted.svg | 184 +- test/output/hexbinR.html | 480 +- test/output/hexbinText.svg | 710 +- test/output/industryUnemploymentTrack.svg | 3738 ++- test/output/internFacetDate.svg | 22188 ++++++++------- test/output/internFacetNaN.svg | 1416 +- test/output/metroUnemploymentRidgeline.svg | 1478 +- test/output/mobyDickFaceted.svg | 528 +- test/output/moviesRatingByGenre.svg | 6586 +++-- test/output/multiplicationTable.svg | 1212 +- test/output/penguinCulmen.svg | 5940 ++-- test/output/penguinCulmenArray.svg | 6590 +++-- test/output/penguinCulmenMarkFacet.svg | 5760 ++-- test/output/penguinDensityFill.html | 222 +- test/output/penguinDensityZ.html | 258 +- test/output/penguinDodgeHexbin.svg | 1524 +- test/output/penguinFacetAnnotated.svg | 186 +- test/output/penguinFacetAnnotatedX.svg | 164 +- test/output/penguinFacetDodge.svg | 814 +- test/output/penguinFacetDodgeIdentity.svg | 814 +- test/output/penguinFacetDodgeIsland.html | 808 +- test/output/penguinMassSex.svg | 232 +- test/output/penguinMassSexSpecies.svg | 318 +- test/output/penguinSexMassCulmenSpecies.svg | 552 +- test/output/penguinSpeciesIslandRelative.svg | 126 +- test/output/penguinSpeciesIslandSex.svg | 308 +- test/output/projectionBleedEdges2.svg | 48 +- test/output/projectionFitBertin1953.svg | 30 +- test/output/projectionHeightEqualEarth.svg | 58 +- test/output/projectionHeightGeometry.svg | 38 +- test/output/projectionHeightMercator.svg | 62 +- test/output/projectionHeightOrthographic.svg | 112 +- test/output/reducerScaleOverrideFunction.svg | 134 +- .../reducerScaleOverrideImplementation.svg | 134 +- test/output/reducerScaleOverrideName.svg | 134 +- test/output/textOverflow.svg | 702 +- test/output/tipDotFacets.svg | 22372 ++++++++-------- test/output/trafficHorizon.html | 3620 ++- test/output/usPopulationStateAgeGrouped.svg | 462 +- test/output/walmartsDecades.svg | 118 +- 63 files changed, 51053 insertions(+), 56151 deletions(-) diff --git a/src/facet.js b/src/facet.js index 91ec69d8cf..5398b344e7 100644 --- a/src/facet.js +++ b/src/facet.js @@ -62,7 +62,7 @@ export function facetGroups(data, {fx, fy}) { ); } -export function facetTranslate(fx, fy, {marginTop, marginLeft}) { +export function facetTranslator(fx, fy, {marginTop, marginLeft}) { return fx && fy ? ({x, y}) => `translate(${fx(x) - marginLeft},${fy(y) - marginTop})` : fx diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index f73e311b82..b5064c6bd8 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -23,13 +23,23 @@ function pointerK(kx, ky, {px, py, maxRadius = 40, channels, ...options} = {}) { const I = i == null ? [] : [i]; if (index.fi != null) (I.fx = index.fx), (I.fy = index.fy), (I.fi = index.fi); const r = mark._render(I, scales, values, dimensions, context); - if (g) g.replaceWith(r); + if (g) { + const p = g.parentNode; + if (p !== svg) { + // when faceting, preserve swapped mark and facet transforms + const ft = g.getAttribute("transform"); + const mt = r.getAttribute("transform"); + ft ? r.setAttribute("transform", ft) : r.removeAttribute("transform"); + mt ? p.setAttribute("transform", mt) : p.removeAttribute("transform"); + } + g.replaceWith(r); + } return (g = r); } function pointermove(event) { if (sticky || (event.pointerType === "mouse" && event.buttons === 1)) return; // dragging - const [xp, yp] = pointof(event, g.parentNode); + const [xp, yp] = pointof(event, g.parentNode === svg ? g.parentNode : g); // detect faceting let ii = null; let ri = maxRadius * maxRadius; for (const j of index) { diff --git a/src/plot.js b/src/plot.js index af8e282ebc..d32dfebfb1 100644 --- a/src/plot.js +++ b/src/plot.js @@ -2,7 +2,7 @@ import {select} from "d3"; import {createChannel, inferChannelScale} from "./channel.js"; import {createContext} from "./context.js"; import {createDimensions} from "./dimensions.js"; -import {createFacets, recreateFacets, facetExclude, facetGroups, facetTranslate, facetFilter} from "./facet.js"; +import {createFacets, recreateFacets, facetExclude, facetGroups, facetTranslator, facetFilter} from "./facet.js"; import {createLegends, exposeLegends} from "./legends.js"; import {Mark} from "./mark.js"; import {axisFx, axisFy, axisX, axisY, gridFx, gridFy, gridX, gridY} from "./marks/axis.js"; @@ -11,7 +11,7 @@ import {arrayify, isColor, isIterable, isNone, isScaleOptions, map, yes, maybeIn import {createScales, createScaleFunctions, autoScaleRange, exposeScales} from "./scales.js"; import {innerDimensions, outerDimensions} from "./scales.js"; import {position, registry as scaleRegistry} from "./scales/index.js"; -import {applyAria, applyInlineStyles, maybeClassName} from "./style.js"; +import {applyInlineStyles, maybeClassName} from "./style.js"; import {consumeWarnings, warn} from "./warnings.js"; export function plot(options = {}) { @@ -200,10 +200,11 @@ export function plot(options = {}) { // Sort and filter the facets to match the fx and fy domains; this is needed // because the facets were constructed prior to the fx and fy scales. - let facetDomains; + let facetDomains, facetTranslate; if (facets !== undefined) { facetDomains = {x: fx?.domain(), y: fy?.domain()}; facets = recreateFacets(facets, facetDomains); + facetTranslate = facetTranslator(fx, fy, dimensions); } // Compute value objects, applying scales and projection as needed. @@ -273,12 +274,19 @@ export function plot(options = {}) { } const node = mark.render(index, scales, values, subdimensions, context); if (node == null) continue; - (g ??= select(svg).append("g").call(applyAria, mark)) - .append("g") - .datum(f) - .append(() => node); + // Lazily construct the shared group (to drop empty marks). + (g ??= select(svg).append("g")).append(() => node).datum(f); + // Promote ARIA attributes and mark transform to avoid repetition on + // each facet; this assumes that these attributes are consistent across + // facets, but that should be the case! + for (const name of ["aria-label", "aria-description", "aria-hidden", "transform"]) { + if (node.hasAttribute(name)) { + g.attr(name, node.getAttribute(name)); + node.removeAttribute(name); + } + } } - g?.selectChildren().attr("transform", facetTranslate(fx, fy, dimensions)); + g?.selectChildren().attr("transform", facetTranslate); } } diff --git a/test/output/anscombeQuartet.svg b/test/output/anscombeQuartet.svg index ea50b97bf4..4f38c24c3e 100644 --- a/test/output/anscombeQuartet.svg +++ b/test/output/anscombeQuartet.svg @@ -13,261 +13,201 @@ white-space: pre; } - + - - 1 - + 1 - - 2 - + 2 - - 3 - + 3 - - 4 - + 4 series - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + - - - - 4 - 6 - 8 - 10 - 12 - + + + 4 + 6 + 8 + 10 + 12 ↑ y - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - 5 - 10 - 15 - - - - - 5 - 10 - 15 - - - - - 5 - 10 - 15 - - - - - 5 - 10 - 15 - + + + 5 + 10 + 15 + + + 5 + 10 + 15 + + + 5 + 10 + 15 + + + 5 + 10 + 15 x → - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/athletesBoxingHeight.svg b/test/output/athletesBoxingHeight.svg index 900e2d5d63..abc004d7b3 100644 --- a/test/output/athletesBoxingHeight.svg +++ b/test/output/athletesBoxingHeight.svg @@ -13,377 +13,343 @@ white-space: pre; } - + - - Africa - + Africa - - Americas - + Americas - - Asia - + Asia - - Europe - + Europe - - Oceania - + Oceania continent - - - - - - - - - - - + + + + + + + + + - - - - 1.5 - 1.6 - 1.7 - 1.8 - 1.9 - 2.0 - 2.1 - + + + 1.5 + 1.6 + 1.7 + 1.8 + 1.9 + 2.0 + 2.1 ↑ height - - - - - - - - - - - - - - - - + + + + + + - + - - ALG - ALG - EGY - MAR - SEY - KEN - TUN - ALG - CPV - CMR - NGR - ALG - MAR - CMR - MAR - TUN - EGY - ALG - NAM - CAF - UGA - MRI - MAR - CMR - EGY - NAM - MRI - ALG - MAR - MAR - MAR - CGO - KEN - ALG - CMR - EGY - ALG - MAR - + ALG + ALG + EGY + MAR + SEY + KEN + TUN + ALG + CPV + CMR + NGR + ALG + MAR + CMR + MAR + TUN + EGY + ALG + NAM + CAF + UGA + MRI + MAR + CMR + EGY + NAM + MRI + ALG + MAR + MAR + MAR + CGO + KEN + ALG + CMR + EGY + ALG + MAR - - BRA - VEN - ARG - ARG - BRA - USA - CAN - CUB - CAN - PAN - ECU - ECU - USA - COL - USA - USA - VEN - MEX - VEN - CUB - ARG - VEN - USA - DOM - ARG - COL - PUR - CUB - BRA - COL - MEX - COL - BRA - MEX - BRA - ECU - CUB - CUB - ARG - CUB - DOM - MEX - VEN - VEN - CAN - ECU - BRA - USA - MEX - USA - TTO - BRA - MEX - CUB - BRA - BRA - CUB - USA - VEN - ARG - CUB - VEN - CUB - COL - + BRA + VEN + ARG + ARG + BRA + USA + CAN + CUB + CAN + PAN + ECU + ECU + USA + COL + USA + USA + VEN + MEX + VEN + CUB + ARG + VEN + USA + DOM + ARG + COL + PUR + CUB + BRA + COL + MEX + COL + BRA + MEX + BRA + ECU + CUB + CUB + ARG + CUB + DOM + MEX + VEN + VEN + CAN + ECU + BRA + USA + MEX + USA + TTO + BRA + MEX + CUB + BRA + BRA + CUB + USA + VEN + ARG + CUB + VEN + CUB + COL - - AZE - KAZ - KAZ - RUS - AZE - TUR - THA - RUS - RUS - TJK - ARM - JPN - TKM - RUS - ARM - UZB - TUR - UZB - KAZ - CHN - KAZ - CHN - PHI - THA - MGL - TPE - JPN - KAZ - KAZ - IRI - UZB - AZE - MGL - KGZ - RUS - UZB - CHN - MGL - QAT - UZB - ARM - UZB - JOR - RUS - KAZ - AZE - CHN - CHN - CHN - CHN - KAZ - AZE - IND - AZE - AZE - IND - TUR - CHN - RUS - UZB - ARM - TPE - JOR - KAZ - TUR - TUR - MGL - AZE - THA - RUS - CHN - CHN - PHI - AZE - UZB - KOR - THA - TUR - UZB - UZB - IND - AZE - QAT - MGL - MGL - RUS - KAZ - RUS - ARM - RUS - IRQ - CHN - THA - AZE - UZB - KAZ - KAZ - + AZE + KAZ + KAZ + RUS + AZE + TUR + THA + RUS + RUS + TJK + ARM + JPN + TKM + RUS + ARM + UZB + TUR + UZB + KAZ + CHN + KAZ + CHN + PHI + THA + MGL + TPE + JPN + KAZ + KAZ + IRI + UZB + AZE + MGL + KGZ + RUS + UZB + CHN + MGL + QAT + UZB + ARM + UZB + JOR + RUS + KAZ + AZE + CHN + CHN + CHN + CHN + KAZ + AZE + IND + AZE + AZE + IND + TUR + CHN + RUS + UZB + ARM + TPE + JOR + KAZ + TUR + TUR + MGL + AZE + THA + RUS + CHN + CHN + PHI + AZE + UZB + KOR + THA + TUR + UZB + UZB + IND + AZE + QAT + MGL + MGL + RUS + KAZ + RUS + ARM + RUS + IRQ + CHN + THA + AZE + UZB + KAZ + KAZ - - SWE - GBR - GER - GER - IRL - ITA - FRA - ITA - BUL - GER - IRL - UKR - UKR - BLR - LTU - FRA - NED - GER - FRA - LTU - CRO - GBR - ITA - GER - FRA - CRO - POL - HUN - ITA - GBR - GBR - IRL - GBR - GBR - IRL - GBR - ITA - FRA - IRL - IRL - ROU - BLR - FIN - GBR - UKR - GBR - NED - GBR - IRL - FRA - BLR - NED - GBR - ESP - FRA - GBR - GER - BUL - FRA - FRA - BUL - IRL - HON - UKR - POL - FRA - ITA - ITA - UKR - ESP - HUN - + SWE + GBR + GER + GER + IRL + ITA + FRA + ITA + BUL + GER + IRL + UKR + UKR + BLR + LTU + FRA + NED + GER + FRA + LTU + CRO + GBR + ITA + GER + FRA + CRO + POL + HUN + ITA + GBR + GBR + IRL + GBR + GBR + IRL + GBR + ITA + FRA + IRL + IRL + ROU + BLR + FIN + GBR + UKR + GBR + NED + GBR + IRL + FRA + BLR + NED + GBR + ESP + FRA + GBR + GER + BUL + FRA + FRA + BUL + IRL + HON + UKR + POL + FRA + ITA + ITA + UKR + ESP + HUN - - AUS - AUS - FSM - AUS - PNG - + AUS + AUS + FSM + AUS + PNG \ No newline at end of file diff --git a/test/output/athletesSampleFacet.svg b/test/output/athletesSampleFacet.svg index f58d04e20f..b4a9a7a225 100644 --- a/test/output/athletesSampleFacet.svg +++ b/test/output/athletesSampleFacet.svg @@ -13,693 +13,531 @@ white-space: pre; } - - - - aquatics - + + + aquatics - - - archery - + + archery - - - athletics - + + athletics - - - badminton - + + badminton - - - basketball - + + basketball - - - boxing - + + boxing - - - canoe - + + canoe - - - cycling - + + cycling - - - equestrian - + + equestrian - - - fencing - + + fencing - - - football - + + football - - - golf - + + golf - - - gymnastics - + + gymnastics - - - handball - + + handball - - - hockey - + + hockey - - - judo - + + judo - - - modern pentathlon - + + modern pentathlon - - - rowing - + + rowing - - - rugby sevens - + + rugby sevens - - - sailing - + + sailing - - - shooting - + + shooting - - - table tennis - + + table tennis - - - taekwondo - + + taekwondo - - - tennis - + + tennis - - - triathlon - + + triathlon - - - volleyball - + + volleyball - - - weightlifting - + + weightlifting - - - wrestling - + + wrestling sport - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + - - - - 40 - 60 - 80 - 100 - 120 - 140 - 160 - + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 weight → - + - - Evan Van Moerkerke - Javier Garcia Gadea - Jordan Coelho - Markus Thormeyer - Mehdi Marzouki - Uvis Kalnins - Ziv Kalontarov - Aria Fischer - Farida Osman - Keesja Gofers - Makenzie Fischer - Mariia Shurochkina - Svetlana Romashina - Yekaterina Nemich - + Evan Van Moerkerke + Javier Garcia Gadea + Jordan Coelho + Markus Thormeyer + Mehdi Marzouki + Uvis Kalnins + Ziv Kalontarov + Aria Fischer + Farida Osman + Keesja Gofers + Makenzie Fischer + Mariia Shurochkina + Svetlana Romashina + Yekaterina Nemich - - A Jesus Garcia - Bachir Mahamat - Changrui Xue - Erick Barrondo - Jack Green - Joe Kovacs - Kurt Couto - Luguelin Santos - Paul Kipngetich Tanui - Theo Piniau - Tim Nedow - Yuri Floriani - Brenda Flores - Diana Martin - Hye-Song Kim - Jamile Samuel - Kamia Yousufi - Mirela Demireva - Nikkita Holder - Persis William-Mensah - Rosa Godoy - Shijie Qieyang - Vitoria Cristina Rosa - + A Jesus Garcia + Bachir Mahamat + Changrui Xue + Erick Barrondo + Jack Green + Joe Kovacs + Kurt Couto + Luguelin Santos + Paul Kipngetich Tanui + Theo Piniau + Tim Nedow + Yuri Floriani + Brenda Flores + Diana Martin + Hye-Song Kim + Jamile Samuel + Kamia Yousufi + Mirela Demireva + Nikkita Holder + Persis William-Mensah + Rosa Godoy + Shijie Qieyang + Vitoria Cristina Rosa - - Dong Keun Lee - Marc Zwiebler - Tontowi Ahmad - Birgit Michels - Liliyana Natsir - Sapsiree Taerattanachai - + Dong Keun Lee + Marc Zwiebler + Tontowi Ahmad + Birgit Michels + Liliyana Natsir + Sapsiree Taerattanachai - - Maryia Papova - + Maryia Papova - - Emanuel Silva - Filip Dvorak - Ricardas Nekriosius - Serguey Torres - Stephen Bird - Taras Mishchuk - + Emanuel Silva + Filip Dvorak + Ricardas Nekriosius + Serguey Torres + Stephen Bird + Taras Mishchuk - - Alejandro Valverde Belmonte - Chun Hing Chan - Gregory Bauge - Hersony Canelon - Kleber da Silva Ramos - Matthew Glaetzer - Sam Webster - + Alejandro Valverde Belmonte + Chun Hing Chan + Gregory Bauge + Hersony Canelon + Kleber da Silva Ramos + Matthew Glaetzer + Sam Webster - - Jeroen Dubbeldam - Kevin Staut - + Jeroen Dubbeldam + Kevin Staut - - Gauthier Grumier - + Gauthier Grumier - - Davie Selke - Michael Perez - Ashlyn Harris - Isabel Kerschowski - Julie Johnston - Leidy Asprilla - Olivia Schough - + Davie Selke + Michael Perez + Ashlyn Harris + Isabel Kerschowski + Julie Johnston + Leidy Asprilla + Olivia Schough - - Chloe Leurquin - + Chloe Leurquin - - Carolina Rodriguez - Danell Leyva - + Carolina Rodriguez + Danell Leyva - - Nic Woods - Robert van der Horst - Vicenc Ruiz - Caitlin van Sickle - + Nic Woods + Robert van der Horst + Vicenc Ruiz + Caitlin van Sickle - - Alexander Sigurbjornsson - Raul Hernandez Hidalgo - Elena-Lavinia Tarlea - Ilse Paulis - Maaike Head - + Alexander Sigurbjornsson + Raul Hernandez Hidalgo + Elena-Lavinia Tarlea + Ilse Paulis + Maaike Head - - Maria Casado - Lomano Lemeki - Moises Duque - Seabelo Senatla - + Maria Casado + Lomano Lemeki + Moises Duque + Seabelo Senatla - - Gil Cohen - Miho Yoshioka - Aichen Wang - Pieter-Jan Postma - + Gil Cohen + Miho Yoshioka + Aichen Wang + Pieter-Jan Postma - - Alin George Moldoveanu - Will Brown - + Alin George Moldoveanu + Will Brown - - Jieni Shao - Xue Li - + Jieni Shao + Xue Li - - Nur Tatar - Rabia Guelec - + Nur Tatar + Rabia Guelec - - Angelique Kerber - Annika Beck - Daria Gavrilova - + Angelique Kerber + Annika Beck + Daria Gavrilova - - Ben Kanute - Ryan Bailie - + Ben Kanute + Ryan Bailie - - Pablo Herrera Allepuz - Simone Giannelli - + Pablo Herrera Allepuz + Simone Giannelli - - Myong Hyok Kim - Yosuke Nakayama - Anastasiia Lysenko - + Myong Hyok Kim + Yosuke Nakayama + Anastasiia Lysenko - - Amas Daniel - Craig Miller - Eduard Popp - Frank Chamizo Marquez - Soslan Daurov - Adela Hanzlickova - Katarzyna Krawczyk - Natalia Vorobeva - + Amas Daniel + Craig Miller + Eduard Popp + Frank Chamizo Marquez + Soslan Daurov + Adela Hanzlickova + Katarzyna Krawczyk + Natalia Vorobeva \ No newline at end of file diff --git a/test/output/athletesSortFacet.svg b/test/output/athletesSortFacet.svg index 352725014c..523ab0e56b 100644 --- a/test/output/athletesSortFacet.svg +++ b/test/output/athletesSortFacet.svg @@ -13,317 +13,201 @@ white-space: pre; } - - - - boxing - + + + boxing - - - wrestling - + + wrestling - - - canoe - + + canoe - - - cycling - + + cycling - - - equestrian - + + equestrian - - - shooting - + + shooting - - - judo - + + judo - - - rowing - + + rowing - - - weightlifting - + + weightlifting - - - sailing - + + sailing - - - football - + + football - - - tennis - + + tennis - - - athletics - + + athletics - - - golf - + + golf - - - rugby sevens - + + rugby sevens - - - aquatics - + + aquatics - - - handball - + + handball - - - archery - + + archery - - - badminton - + + badminton - - - basketball - + + basketball - - - hockey - + + hockey - - - modern pentathlon - + + modern pentathlon - - - table tennis - + + table tennis - - - taekwondo - + + taekwondo - - - triathlon - + + triathlon - - - volleyball - + + volleyball - - - fencing - + + fencing - - - gymnastics - + + gymnastics sport - - - - - - - - - - - + + + + + + + + + - - - - 0.0 - 0.1 - 0.2 - 0.3 - 0.4 - 0.5 - 0.6 - + + + 0.0 + 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 0.6 - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + diff --git a/test/output/athletesSportWeight.svg b/test/output/athletesSportWeight.svg index f29903d0b9..2e03b72b90 100644 --- a/test/output/athletesSportWeight.svg +++ b/test/output/athletesSportWeight.svg @@ -13,485 +13,369 @@ white-space: pre; } - - - - aquatics - + + + aquatics - - - archery - + + archery - - - athletics - + + athletics - - - badminton - + + badminton - - - basketball - + + basketball - - - boxing - + + boxing - - - canoe - + + canoe - - - cycling - + + cycling - - - equestrian - + + equestrian - - - fencing - + + fencing - - - football - + + football - - - golf - + + golf - - - gymnastics - + + gymnastics - - - handball - + + handball - - - hockey - + + hockey - - - judo - + + judo - - - modern pentathlon - + + modern pentathlon - - - rowing - + + rowing - - - rugby sevens - + + rugby sevens - - - sailing - + + sailing - - - shooting - + + shooting - - - table tennis - + + table tennis - - - taekwondo - + + taekwondo - - - tennis - + + tennis - - - triathlon - + + triathlon - - - volleyball - + + volleyball - - - weightlifting - + + weightlifting - - - wrestling - + + wrestling sport - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + - - - - 40 - 60 - 80 - 100 - 120 - 140 - 160 - + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 @@ -499,950 +383,894 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + \ No newline at end of file diff --git a/test/output/autoDotFacet.svg b/test/output/autoDotFacet.svg index b5438b7e3d..b1380b90f9 100644 --- a/test/output/autoDotFacet.svg +++ b/test/output/autoDotFacet.svg @@ -13,475 +13,441 @@ white-space: pre; } - + - - Biscoe - + Biscoe - - Dream - + Dream - - Torgersen - + Torgersen island - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - 34 - 36 - 38 - 40 - 42 - 44 - 46 - 48 - 50 - 52 - 54 - 56 - 58 - + + + 34 + 36 + 38 + 40 + 42 + 44 + 46 + 48 + 50 + 52 + 54 + 56 + 58 ↑ culmen_length_mm - - - - - - + + + + - - - - - + + + - - - - - + + + - - - - 4,000 - 6,000 - + + + 4,000 + 6,000 - - - 4,000 - 6,000 - + + 4,000 + 6,000 - - - 4,000 - 6,000 - + + 4,000 + 6,000 body_mass_g → - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/autoDotFacet2.svg b/test/output/autoDotFacet2.svg index 1223fde26d..4d3c4c0116 100644 --- a/test/output/autoDotFacet2.svg +++ b/test/output/autoDotFacet2.svg @@ -13,541 +13,481 @@ white-space: pre; } - - - - Adelie - + + + Adelie - - - Chinstrap - + + Chinstrap - - - Gentoo - + + Gentoo species - + - - Biscoe - + Biscoe - - Dream - + Dream - - Torgersen - + Torgersen island - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - 35 - 40 - 45 - 50 - 55 - + + + 35 + 40 + 45 + 50 + 55 - - - 35 - 40 - 45 - 50 - 55 - + + 35 + 40 + 45 + 50 + 55 - - - 35 - 40 - 45 - 50 - 55 - + + 35 + 40 + 45 + 50 + 55 ↑ culmen_length_mm - - - - - - + + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - 4,000 - 6,000 - + + + 4,000 + 6,000 - - - 4,000 - 6,000 - + + 4,000 + 6,000 - - - 4,000 - 6,000 - + + 4,000 + 6,000 - - - 4,000 - 6,000 - + + 4,000 + 6,000 body_mass_g → - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/autoLineFacet.svg b/test/output/autoLineFacet.svg index 57d1c314c4..1066a9f09e 100644 --- a/test/output/autoLineFacet.svg +++ b/test/output/autoLineFacet.svg @@ -13,394 +13,250 @@ white-space: pre; } - - - - Agriculture - - - - - Business services - - - - - Construction - - - - - Education and Health - - - - - Finance - - - - - Government - - - - - Information - - - - - Leisure and hospitality - - - - - Manufacturing - - - - - Mining and Extraction - - - - - Other - - - - - Self-employed - - - - - Transportation and Utilities - - - - - Wholesale and Retail Trade - + + + Agriculture + + + Business services + + + Construction + + + Education and Health + + + Finance + + + Government + + + Information + + + Leisure and hospitality + + + Manufacturing + + + Mining and Extraction + + + Other + + + Self-employed + + + Transportation and Utilities + + + Wholesale and Retail Trade industry - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - 1,000 - 2,000 - - - - - 1,000 - 2,000 - - - - - 1,000 - 2,000 - - - - - 1,000 - 2,000 - - - - - 1,000 - 2,000 - - - - - 1,000 - 2,000 - - - - - 1,000 - 2,000 - - - - - 1,000 - 2,000 - - - - - 1,000 - 2,000 - - - - - 1,000 - 2,000 - - - - - 1,000 - 2,000 - - - - - 1,000 - 2,000 - - - - - 1,000 - 2,000 - - - - - 1,000 - 2,000 - + + + 1,000 + 2,000 + + + 1,000 + 2,000 + + + 1,000 + 2,000 + + + 1,000 + 2,000 + + + 1,000 + 2,000 + + + 1,000 + 2,000 + + + 1,000 + 2,000 + + + 1,000 + 2,000 + + + 1,000 + 2,000 + + + 1,000 + 2,000 + + + 1,000 + 2,000 + + + 1,000 + 2,000 + + + 1,000 + 2,000 + + + 1,000 + 2,000 ↑ unemployed - - - - - - - - - - + + + + + + + + - - - - 2000 - 2002 - 2004 - 2006 - 2008 - 2010 - + + + 2000 + 2002 + 2004 + 2006 + 2008 + 2010 - - - - - - + + + + + + + + + + + + + + + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/test/output/ballotStatusRace.svg b/test/output/ballotStatusRace.svg index d3420abeff..c89c4f45f3 100644 --- a/test/output/ballotStatusRace.svg +++ b/test/output/ballotStatusRace.svg @@ -13,132 +13,96 @@ white-space: pre; } - - - - WHITE - + + + WHITE - - - UNDESIGNATED - + + UNDESIGNATED - - - ASIAN - + + ASIAN - - - OTHER - + + OTHER - - - TWO or MORE RACES - + + TWO or MORE RACES - - - INDIAN AMERICAN or ALASKA NATIVE - + + INDIAN AMERICAN or ALASKA NATIVE - - - BLACK or AFRICAN AMERICAN - + + BLACK or AFRICAN AMERICAN - - - NATIVE HAWAIIAN or PACIFIC ISLANDER - + + NATIVE HAWAIIAN or PACIFIC ISLANDER - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + - - - - 0 - 20 - 40 - 60 - + + + 0 + 20 + 40 + 60 @@ -146,101 +110,69 @@ - - 79.0% - 0.4% - 20.5% - + 79.0% + 0.4% + 20.5% - - 78.3% - 0.6% - 21.1% - + 78.3% + 0.6% + 21.1% - - 77.9% - 21.5% - 0.6% - + 77.9% + 21.5% + 0.6% - - 74.1% - 0.8% - 25.1% - + 74.1% + 0.8% + 25.1% - - 73.9% - 25.3% - 0.8% - + 73.9% + 25.3% + 0.8% - - 25.5% - 72.2% - 2.3% - + 25.5% + 72.2% + 2.3% - - 67.4% - 31.5% - 1.1% - + 67.4% + 31.5% + 1.1% - - 41.7% - 58.3% - + 41.7% + 58.3% - - - - - + + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + \ No newline at end of file diff --git a/test/output/beckerBarley.svg b/test/output/beckerBarley.svg index 9585d7bf86..484b671b98 100644 --- a/test/output/beckerBarley.svg +++ b/test/output/beckerBarley.svg @@ -13,563 +13,475 @@ white-space: pre; } - - - - Waseca - - - - - Crookston - - - - - Morris - - - - - University Farm - - - - - Duluth - - - - - Grand Rapids - + + + Waseca + + + Crookston + + + Morris + + + University Farm + + + Duluth + + + Grand Rapids site - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - Trebi - Wisconsin No. 38 - No. 457 - Glabron - Peatland - Velvet - No. 475 - Manchuria - No. 462 - Svansota - - - - - Trebi - Wisconsin No. 38 - No. 457 - Glabron - Peatland - Velvet - No. 475 - Manchuria - No. 462 - Svansota - - - - - Trebi - Wisconsin No. 38 - No. 457 - Glabron - Peatland - Velvet - No. 475 - Manchuria - No. 462 - Svansota - - - - - Trebi - Wisconsin No. 38 - No. 457 - Glabron - Peatland - Velvet - No. 475 - Manchuria - No. 462 - Svansota - - - - - Trebi - Wisconsin No. 38 - No. 457 - Glabron - Peatland - Velvet - No. 475 - Manchuria - No. 462 - Svansota - - - - - Trebi - Wisconsin No. 38 - No. 457 - Glabron - Peatland - Velvet - No. 475 - Manchuria - No. 462 - Svansota - + + + Trebi + Wisconsin No. 38 + No. 457 + Glabron + Peatland + Velvet + No. 475 + Manchuria + No. 462 + Svansota + + + Trebi + Wisconsin No. 38 + No. 457 + Glabron + Peatland + Velvet + No. 475 + Manchuria + No. 462 + Svansota + + + Trebi + Wisconsin No. 38 + No. 457 + Glabron + Peatland + Velvet + No. 475 + Manchuria + No. 462 + Svansota + + + Trebi + Wisconsin No. 38 + No. 457 + Glabron + Peatland + Velvet + No. 475 + Manchuria + No. 462 + Svansota + + + Trebi + Wisconsin No. 38 + No. 457 + Glabron + Peatland + Velvet + No. 475 + Manchuria + No. 462 + Svansota + + + Trebi + Wisconsin No. 38 + No. 457 + Glabron + Peatland + Velvet + No. 475 + Manchuria + No. 462 + Svansota variety - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + - - - - 10 - 20 - 30 - 40 - 50 - 60 - 70 - + + + 10 + 20 + 30 + 40 + 50 + 60 + 70 yield → - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/boxplotFacetInterval.svg b/test/output/boxplotFacetInterval.svg index ced273db40..f1f99b9a77 100644 --- a/test/output/boxplotFacetInterval.svg +++ b/test/output/boxplotFacetInterval.svg @@ -13,743 +13,617 @@ white-space: pre; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - 2.2 - - - - - 2.1 - - - - - 2 - - - - - 1.9 - - - - - 1.8 - - - - - 1.7 - - - - - 1.6 - - - - - 1.5 - - - - - 1.4 - - - - - 1.3 - - - - - 1.2 - + + + 2.2 + + + 2.1 + + + 2 + + + 1.9 + + + 1.8 + + + 1.7 + + + 1.6 + + + 1.5 + + + 1.4 + + + 1.3 + + + 1.2 height - - - - - - - - - - - + + + + + + + + + - - - - 40 - 60 - 80 - 100 - 120 - 140 - 160 - + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 weight → - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/boxplotFacetNegativeInterval.svg b/test/output/boxplotFacetNegativeInterval.svg index ced273db40..f1f99b9a77 100644 --- a/test/output/boxplotFacetNegativeInterval.svg +++ b/test/output/boxplotFacetNegativeInterval.svg @@ -13,743 +13,617 @@ white-space: pre; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - 2.2 - - - - - 2.1 - - - - - 2 - - - - - 1.9 - - - - - 1.8 - - - - - 1.7 - - - - - 1.6 - - - - - 1.5 - - - - - 1.4 - - - - - 1.3 - - - - - 1.2 - + + + 2.2 + + + 2.1 + + + 2 + + + 1.9 + + + 1.8 + + + 1.7 + + + 1.6 + + + 1.5 + + + 1.4 + + + 1.3 + + + 1.2 height - - - - - - - - - - - + + + + + + + + + - - - - 40 - 60 - 80 - 100 - 120 - 140 - 160 - + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 weight → - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/caltrainDirection.svg b/test/output/caltrainDirection.svg index 00db651841..ec66bc81d8 100644 --- a/test/output/caltrainDirection.svg +++ b/test/output/caltrainDirection.svg @@ -13,139 +13,123 @@ white-space: pre; } - - - - B - + + + B - - - L - + + L - - - N - + + N - - - - - - - - - - - + + + + + + + + + - - - - 06 AM - 09 AM - 12 PM - 03 PM - 06 PM - 09 PM - 12 AM - + + + 06 AM + 09 AM + 12 PM + 03 PM + 06 PM + 09 PM + 12 AM - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/emptyFacet.svg b/test/output/emptyFacet.svg index 2348f8adcc..747ce7357f 100644 --- a/test/output/emptyFacet.svg +++ b/test/output/emptyFacet.svg @@ -13,64 +13,48 @@ white-space: pre; } - + - - a - + a - - b - + b TYPE - - - - - + + + - - - - 0 - + + + 0 VALUE - - - - - - + + + + - - - - - + + + - + - - 1 - 2 - + 1 + 2 - - 1 - 2 - + 1 + 2 diff --git a/test/output/footballCoverage.svg b/test/output/footballCoverage.svg index 4ecd7ca1ac..6e845f8dbd 100644 --- a/test/output/footballCoverage.svg +++ b/test/output/footballCoverage.svg @@ -13,462 +13,402 @@ white-space: pre; } - + - - C2 - + C2 - - C3 - + C3 - - C4 - + C4 - - M0 - + M0 - - M1 - + M1 - - M2 - + M2 - - T2 - + T2 coverage - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - 0% - 5% - 10% - 15% - 20% - 25% - 30% - 35% - 40% - 45% - 50% - + + + 0% + 5% + 10% + 15% + 20% + 25% + 30% + 35% + 40% + 45% + 50% - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/frameFacet.svg b/test/output/frameFacet.svg index 89d231a115..382578446d 100644 --- a/test/output/frameFacet.svg +++ b/test/output/frameFacet.svg @@ -13,414 +13,396 @@ white-space: pre; } - - - - Adelie - + + + Adelie - - - Chinstrap - + + Chinstrap - - - Gentoo - + + Gentoo species - - - - - - - - - - - + + + + + + + + + - - - - 3,000 - 3,500 - 4,000 - 4,500 - 5,000 - 5,500 - 6,000 - + + + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 body_mass_g → - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/functionContourFaceted.svg b/test/output/functionContourFaceted.svg index 63ebe1bddb..bbc1e4a29a 100644 --- a/test/output/functionContourFaceted.svg +++ b/test/output/functionContourFaceted.svg @@ -13,180 +13,140 @@ white-space: pre; } - - - - cos - + + + cos - - - lin - + + lin - + - - lin - + lin - - sin - + sin - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - 0 - 2 - 4 - 6 - 8 - 10 - 12 - - - - - 0 - 2 - 4 - 6 - 8 - 10 - 12 - + + + 0 + 2 + 4 + 6 + 8 + 10 + 12 + + + 0 + 2 + 4 + 6 + 8 + 10 + 12 - - - - - - - + + + + + - - - - - - + + + + - - - - 0 - 5 - 10 - + + + 0 + 5 + 10 - - - 0 - 5 - 10 - + + 0 + 5 + 10 - + - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - + + + + + \ No newline at end of file diff --git a/test/output/functionContourFaceted2.svg b/test/output/functionContourFaceted2.svg index 63ebe1bddb..bbc1e4a29a 100644 --- a/test/output/functionContourFaceted2.svg +++ b/test/output/functionContourFaceted2.svg @@ -13,180 +13,140 @@ white-space: pre; } - - - - cos - + + + cos - - - lin - + + lin - + - - lin - + lin - - sin - + sin - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - 0 - 2 - 4 - 6 - 8 - 10 - 12 - - - - - 0 - 2 - 4 - 6 - 8 - 10 - 12 - + + + 0 + 2 + 4 + 6 + 8 + 10 + 12 + + + 0 + 2 + 4 + 6 + 8 + 10 + 12 - - - - - - - + + + + + - - - - - - + + + + - - - - 0 - 5 - 10 - + + + 0 + 5 + 10 - - - 0 - 5 - 10 - + + 0 + 5 + 10 - + - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - + + + + + \ No newline at end of file diff --git a/test/output/futureSplom.svg b/test/output/futureSplom.svg index ea41b752ea..80da5e457a 100644 --- a/test/output/futureSplom.svg +++ b/test/output/futureSplom.svg @@ -13,292 +13,220 @@ white-space: pre; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - −1 - 0 - 1 - - - - - −1 - 0 - 1 - - - - - −1 - 0 - 1 - + + + −1 + 0 + 1 + + + −1 + 0 + 1 + + + −1 + 0 + 1 - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - −1 - 0 - 1 - - - - - −1 - 0 - 1 - - - - - −1 - 0 - 1 - + + + −1 + 0 + 1 + + + −1 + 0 + 1 + + + −1 + 0 + 1 - + - - * - + * - - * - + * - - * - + * - - * - + * - - * - + * - - * - + * - + - - A - + A - - B - + B - - C - + C - - - - - - - - - - + + + + \ No newline at end of file diff --git a/test/output/googleTrendsRidgeline.svg b/test/output/googleTrendsRidgeline.svg index efec6a4edc..c8cee5c6e2 100644 --- a/test/output/googleTrendsRidgeline.svg +++ b/test/output/googleTrendsRidgeline.svg @@ -13,1328 +13,812 @@ white-space: pre; } - - - - Australian bushfires - - - - - Qasem Soleimani - - - - - Prince Harry, Meghan - - - - - Brexit - - - - - Impeachment - - - - - Kobe Bryant - - - - - Wuhan - - - - - Nancy Pelosi - - - - - Parasite - - - - - Roger Stone - - - - - Democratic primaries - - - - - Love Is Blind - - - - - Stock market - - - - - Tom Hanks - - - - - Trump coronavirus - - - - - Locust - - - - - Martial law - - - - - Toilet paper - - - - - Animal Crossing - - - - - Anthony Fauci - - - - - COVID-19 - - - - - Tiger King - - - - - Zoom Video Communications - - - - - Masks - - - - - Stimulus check - - - - - Sourdough - - - - - The Last Dance - - - - - Kim Jong-un - - - - - Murder hornet - - - - - SpaceX - - - - - Black Lives Matter - - - - - George Floyd - - - - - Ghislaine Maxwell - - - - - TikTok - - - - - Taylor Swift - - - - - Hydroxychloroquine - - - - - John Lewis - - - - - Regis Philbin - - - - - William Barr - - - - - Beirut explosion - - - - - Kamala Harris - - - - - QAnon - - - - - Chadwick Boseman - - - - - Hurricane Laura - - - - - Jacob Blake - - - - - Naomi Osaka - - - - - Wildfires - - - - - Hurricane Teddy - - - - - Ruth Bader Ginsburg - - - - - Breonna Taylor - - - - - Presidential debates - - - - - Proud Boys - - - - - Eddie Van Halen - - - - - Amy Coney Barrett - - - - - Hunter Biden - - - - - Absentee ballot - - - - - Joe Biden - - - - - Voter turnout - - - - - Alex Trebek - - - - - Electoral fraud - - - - - Four seasons total landscaping - - - - - Hurricane Iota - - - - - Rudy Giuliani - - - - - COVID-19 vaccine - + + + Australian bushfires + + + Qasem Soleimani + + + Prince Harry, Meghan + + + Brexit + + + Impeachment + + + Kobe Bryant + + + Wuhan + + + Nancy Pelosi + + + Parasite + + + Roger Stone + + + Democratic primaries + + + Love Is Blind + + + Stock market + + + Tom Hanks + + + Trump coronavirus + + + Locust + + + Martial law + + + Toilet paper + + + Animal Crossing + + + Anthony Fauci + + + COVID-19 + + + Tiger King + + + Zoom Video Communications + + + Masks + + + Stimulus check + + + Sourdough + + + The Last Dance + + + Kim Jong-un + + + Murder hornet + + + SpaceX + + + Black Lives Matter + + + George Floyd + + + Ghislaine Maxwell + + + TikTok + + + Taylor Swift + + + Hydroxychloroquine + + + John Lewis + + + Regis Philbin + + + William Barr + + + Beirut explosion + + + Kamala Harris + + + QAnon + + + Chadwick Boseman + + + Hurricane Laura + + + Jacob Blake + + + Naomi Osaka + + + Wildfires + + + Hurricane Teddy + + + Ruth Bader Ginsburg + + + Breonna Taylor + + + Presidential debates + + + Proud Boys + + + Eddie Van Halen + + + Amy Coney Barrett + + + Hunter Biden + + + Absentee ballot + + + Joe Biden + + + Voter turnout + + + Alex Trebek + + + Electoral fraud + + + Four seasons total landscaping + + + Hurricane Iota + + + Rudy Giuliani + + + COVID-19 vaccine - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - 2020 - February - March - April - May - June - July - August - September - October - November - December - + + + 2020 + February + March + April + May + June + July + August + September + October + November + December - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/heatmapFaceted.svg b/test/output/heatmapFaceted.svg index b420822557..f56f816e99 100644 --- a/test/output/heatmapFaceted.svg +++ b/test/output/heatmapFaceted.svg @@ -13,144 +13,104 @@ white-space: pre; } - - - - cos - + + + cos - - - lin - + + lin - + - - lin - + lin - - sin - + sin - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - 0 - 2 - 4 - 6 - 8 - 10 - 12 - - - - - 0 - 2 - 4 - 6 - 8 - 10 - 12 - + + + 0 + 2 + 4 + 6 + 8 + 10 + 12 + + + 0 + 2 + 4 + 6 + 8 + 10 + 12 - - - - - - - + + + + + - - - - - - + + + + - - - - 0 - 5 - 10 - + + + 0 + 5 + 10 - - - 0 - 5 - 10 - + + 0 + 5 + 10 - + - - - + - - - + - - - + - - - + - - - - - - - - - - - - - + + + + + \ No newline at end of file diff --git a/test/output/hexbinR.html b/test/output/hexbinR.html index 4125129c89..3f7144b913 100644 --- a/test/output/hexbinR.html +++ b/test/output/hexbinR.html @@ -48,302 +48,264 @@ white-space: pre; } - + - - FEMALE - + FEMALE - - MALE - + MALE sex - - - - - - - - - + + + + + + + - - - - 35 - 40 - 45 - 50 - 55 - + + + 35 + 40 + 45 + 50 + 55 ↑ culmen_length_mm - - - - - - - - + + + + + + - - - - - - - + + + + + - - - - - - - + + + + + - - - - 14 - 16 - 18 - 20 - + + + 14 + 16 + 18 + 20 - - - 14 - 16 - 18 - 20 - + + 14 + 16 + 18 + 20 - - - 14 - 16 - 18 - 20 - + + 14 + 16 + 18 + 20 culmen_depth_mm → - - - - - - - - - - + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - 9 - 8 - 8 - 8 - 6 - 6 - 6 - 5 - 5 - 5 - 5 - 4 - 4 - 4 - 3 - 3 - 3 - 3 - 3 - 3 - 3 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - + + + 9 + 8 + 8 + 8 + 6 + 6 + 6 + 5 + 5 + 5 + 5 + 4 + 4 + 4 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 - - - 11 - 9 - 8 - 7 - 5 - 5 - 5 - 4 - 4 - 4 - 4 - 4 - 4 - 4 - 4 - 3 - 3 - 3 - 3 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - + + 11 + 9 + 8 + 7 + 5 + 5 + 5 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 3 + 3 + 3 + 3 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 - - - 2 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - + + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 \ No newline at end of file diff --git a/test/output/hexbinText.svg b/test/output/hexbinText.svg index 94333f8cd7..d0a0bb0721 100644 --- a/test/output/hexbinText.svg +++ b/test/output/hexbinText.svg @@ -13,424 +13,380 @@ white-space: pre; } - + - - FEMALE - + FEMALE - - MALE - + MALE sex - - - - - - - - - + + + + + + + - - - - 35 - 40 - 45 - 50 - 55 - + + + 35 + 40 + 45 + 50 + 55 ↑ culmen_length_mm - - - - - - - - + + + + + + - - - - - - - + + + + + - - - - - - - + + + + + - - - - 14 - 16 - 18 - 20 - + + + 14 + 16 + 18 + 20 - - - 14 - 16 - 18 - 20 - + + 14 + 16 + 18 + 20 - - - 14 - 16 - 18 - 20 - + + 14 + 16 + 18 + 20 culmen_depth_mm → - - - - - - - - - - + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + - - - - 4 - 5 - 2 - 6 - 1 - 7 - 3 - 2 - 4 - 6 - 3 - 8 - 1 - 7 - 4 - 3 - 1 - 2 - 1 - 2 - 1 - 1 - 5 - 1 - 2 - 2 - 1 - 5 - 1 - 3 - 2 - 1 - 2 - 1 - 2 - 2 - 1 - 1 - 1 - 1 - 4 - 7 - 7 - 3 - 1 - 10 - 3 - 1 - 2 - 4 - 6 - 2 - 3 - 1 - 1 - 1 - 1 - + + + 4 + 5 + 2 + 6 + 1 + 7 + 3 + 2 + 4 + 6 + 3 + 8 + 1 + 7 + 4 + 3 + 1 + 2 + 1 + 2 + 1 + 1 + 5 + 1 + 2 + 2 + 1 + 5 + 1 + 3 + 2 + 1 + 2 + 1 + 2 + 2 + 1 + 1 + 1 + 1 + 4 + 7 + 7 + 3 + 1 + 10 + 3 + 1 + 2 + 4 + 6 + 2 + 3 + 1 + 1 + 1 + 1 - - - 16 - 1 - 5 - 2 - 1 - 3 - 1 - 3 - 3 - 1 - 1 - 1 - 1 - 5 - 3 - 7 - 4 - 2 - 1 - 3 - 1 - 2 - 1 - 1 - 1 - 3 - 6 - 7 - 4 - 4 - 1 - 1 - 1 - 3 - 1 - 1 - 2 - 1 - 1 - 1 - 6 - 6 - 2 - 4 - 3 - 7 - 8 - 7 - 2 - 1 - 1 - 1 - 1 - 1 - 1 - 2 - 2 - 1 - 2 - 1 - 1 - 1 - + + 16 + 1 + 5 + 2 + 1 + 3 + 1 + 3 + 3 + 1 + 1 + 1 + 1 + 5 + 3 + 7 + 4 + 2 + 1 + 3 + 1 + 2 + 1 + 1 + 1 + 3 + 6 + 7 + 4 + 4 + 1 + 1 + 1 + 3 + 1 + 1 + 2 + 1 + 1 + 1 + 6 + 6 + 2 + 4 + 3 + 7 + 8 + 7 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 2 + 2 + 1 + 2 + 1 + 1 + 1 - - - 1 - 1 - 2 - 1 - 1 - 1 - 1 - 1 - + + 1 + 1 + 2 + 1 + 1 + 1 + 1 + 1 \ No newline at end of file diff --git a/test/output/industryUnemploymentTrack.svg b/test/output/industryUnemploymentTrack.svg index 92912cea24..be40bdb238 100644 --- a/test/output/industryUnemploymentTrack.svg +++ b/test/output/industryUnemploymentTrack.svg @@ -13,2013 +13,1897 @@ white-space: pre; } - - - - Construction - + + + Construction - - - Wholesale and Retail Trade - + + Wholesale and Retail Trade - - - Manufacturing - + + Manufacturing - - - Leisure and hospitality - + + Leisure and hospitality - - - Business services - + + Business services - - - Education and Health - + + Education and Health - - - Government - + + Government - - - Self-employed - + + Self-employed - - - Finance - + + Finance - - - Transportation and Utilities - + + Transportation and Utilities - - - Other - + + Other - - - Information - + + Information - - - Agriculture - + + Agriculture - - - Mining and Extraction - + + Mining and Extraction industry - - - - - - - - - - + + + + + + + + - - - - 2000 - 2002 - 2004 - 2006 - 2008 - 2010 - + + + 2000 + 2002 + 2004 + 2006 + 2008 + 2010 - - 745 - 812 - 669 - 447 - 397 - 389 - 384 - 446 - 386 - 417 - 482 - 580 - 836 - 826 - 683 - 596 - 478 - 443 - 447 - 522 - 489 - 535 - 670 - 785 - 1,211 - 1,060 - 1,009 - 855 - 626 - 593 - 594 - 654 - 615 - 680 - 758 - 941 - 1,196 - 1,173 - 987 - 772 - 715 - 710 - 677 - 650 - 681 - 651 - 690 - 813 - 994 - 1,039 - 1,011 - 849 - 665 - 668 - 610 - 563 - 629 - 635 - 695 - 870 - 1,079 - 1,150 - 961 - 693 - 567 - 559 - 509 - 561 - 572 - 519 - 564 - 813 - 868 - 836 - 820 - 674 - 647 - 569 - 633 - 618 - 586 - 456 - 618 - 725 - 922 - 1,086 - 924 - 853 - 676 - 600 - 617 - 558 - 596 - 641 - 645 - 968 - 1,099 - 1,118 - 1,170 - 1,057 - 809 - 785 - 783 - 814 - 970 - 1,078 - 1,237 - 1,438 - 1,744 - 2,025 - 1,979 - 1,737 - 1,768 - 1,601 - 1,687 - 1,542 - 1,594 - 1,744 - 1,780 - 2,044 - 2,194 - 2,440 - + 745 + 812 + 669 + 447 + 397 + 389 + 384 + 446 + 386 + 417 + 482 + 580 + 836 + 826 + 683 + 596 + 478 + 443 + 447 + 522 + 489 + 535 + 670 + 785 + 1,211 + 1,060 + 1,009 + 855 + 626 + 593 + 594 + 654 + 615 + 680 + 758 + 941 + 1,196 + 1,173 + 987 + 772 + 715 + 710 + 677 + 650 + 681 + 651 + 690 + 813 + 994 + 1,039 + 1,011 + 849 + 665 + 668 + 610 + 563 + 629 + 635 + 695 + 870 + 1,079 + 1,150 + 961 + 693 + 567 + 559 + 509 + 561 + 572 + 519 + 564 + 813 + 868 + 836 + 820 + 674 + 647 + 569 + 633 + 618 + 586 + 456 + 618 + 725 + 922 + 1,086 + 924 + 853 + 676 + 600 + 617 + 558 + 596 + 641 + 645 + 968 + 1,099 + 1,118 + 1,170 + 1,057 + 809 + 785 + 783 + 814 + 970 + 1,078 + 1,237 + 1,438 + 1,744 + 2,025 + 1,979 + 1,737 + 1,768 + 1,601 + 1,687 + 1,542 + 1,594 + 1,744 + 1,780 + 2,044 + 2,194 + 2,440 - - 1,000 - 1,023 - 983 - 793 - 821 - 837 - 792 - 853 - 791 - 739 - 701 - 715 - 908 - 990 - 1,037 - 820 - 875 - 955 - 833 - 928 - 936 - 941 - 1,046 - 1,074 - 1,212 - 1,264 - 1,269 - 1,222 - 1,138 - 1,240 - 1,132 - 1,170 - 1,171 - 1,212 - 1,242 - 1,150 - 1,342 - 1,238 - 1,179 - 1,201 - 1,247 - 1,434 - 1,387 - 1,161 - 1,229 - 1,189 - 1,156 - 1,081 - 1,389 - 1,369 - 1,386 - 1,248 - 1,183 - 1,182 - 1,163 - 1,079 - 1,127 - 1,138 - 1,045 - 1,058 - 1,302 - 1,301 - 1,173 - 1,131 - 1,145 - 1,197 - 1,194 - 1,130 - 1,038 - 1,050 - 1,013 - 968 - 1,203 - 1,141 - 1,022 - 972 - 1,025 - 1,085 - 1,083 - 977 - 1,008 - 972 - 1,018 - 965 - 1,166 - 1,045 - 896 - 872 - 795 - 979 - 1,089 - 1,028 - 1,027 - 907 - 893 - 1,009 - 1,120 - 1,007 - 992 - 919 - 1,049 - 1,160 - 1,329 - 1,366 - 1,277 - 1,313 - 1,397 - 1,535 - 1,794 - 1,847 - 1,852 - 1,833 - 1,835 - 1,863 - 1,854 - 1,794 - 1,809 - 1,919 - 1,879 - 1,851 - 2,154 - 2,071 - + 1,000 + 1,023 + 983 + 793 + 821 + 837 + 792 + 853 + 791 + 739 + 701 + 715 + 908 + 990 + 1,037 + 820 + 875 + 955 + 833 + 928 + 936 + 941 + 1,046 + 1,074 + 1,212 + 1,264 + 1,269 + 1,222 + 1,138 + 1,240 + 1,132 + 1,170 + 1,171 + 1,212 + 1,242 + 1,150 + 1,342 + 1,238 + 1,179 + 1,201 + 1,247 + 1,434 + 1,387 + 1,161 + 1,229 + 1,189 + 1,156 + 1,081 + 1,389 + 1,369 + 1,386 + 1,248 + 1,183 + 1,182 + 1,163 + 1,079 + 1,127 + 1,138 + 1,045 + 1,058 + 1,302 + 1,301 + 1,173 + 1,131 + 1,145 + 1,197 + 1,194 + 1,130 + 1,038 + 1,050 + 1,013 + 968 + 1,203 + 1,141 + 1,022 + 972 + 1,025 + 1,085 + 1,083 + 977 + 1,008 + 972 + 1,018 + 965 + 1,166 + 1,045 + 896 + 872 + 795 + 979 + 1,089 + 1,028 + 1,027 + 907 + 893 + 1,009 + 1,120 + 1,007 + 992 + 919 + 1,049 + 1,160 + 1,329 + 1,366 + 1,277 + 1,313 + 1,397 + 1,535 + 1,794 + 1,847 + 1,852 + 1,833 + 1,835 + 1,863 + 1,854 + 1,794 + 1,809 + 1,919 + 1,879 + 1,851 + 2,154 + 2,071 - - 734 - 694 - 739 - 736 - 685 - 621 - 708 - 685 - 667 - 693 - 672 - 653 - 911 - 902 - 954 - 855 - 903 - 956 - 1,054 - 1,023 - 996 - 1,065 - 1,108 - 1,172 - 1,377 - 1,296 - 1,367 - 1,322 - 1,194 - 1,187 - 1,185 - 1,108 - 1,076 - 1,046 - 1,115 - 1,188 - 1,302 - 1,229 - 1,222 - 1,199 - 1,150 - 1,232 - 1,193 - 1,186 - 1,175 - 1,041 - 1,034 - 1,025 - 1,110 - 1,094 - 1,083 - 1,004 - 966 - 957 - 1,019 - 840 - 852 - 884 - 905 - 872 - 889 - 889 - 879 - 793 - 743 - 743 - 883 - 767 - 775 - 800 - 823 - 757 - 778 - 821 - 701 - 745 - 680 - 635 - 736 - 680 - 632 - 618 - 702 - 660 - 752 - 774 - 742 - 749 - 651 - 653 - 621 - 596 - 673 - 729 - 762 - 772 - 837 - 820 - 831 - 796 - 879 - 862 - 908 - 960 - 984 - 1,007 - 1,144 - 1,315 - 1,711 - 1,822 - 1,912 - 1,968 - 2,010 - 2,010 - 1,988 - 1,866 - 1,876 - 1,884 - 1,882 - 1,747 - 1,918 - 1,814 - + 734 + 694 + 739 + 736 + 685 + 621 + 708 + 685 + 667 + 693 + 672 + 653 + 911 + 902 + 954 + 855 + 903 + 956 + 1,054 + 1,023 + 996 + 1,065 + 1,108 + 1,172 + 1,377 + 1,296 + 1,367 + 1,322 + 1,194 + 1,187 + 1,185 + 1,108 + 1,076 + 1,046 + 1,115 + 1,188 + 1,302 + 1,229 + 1,222 + 1,199 + 1,150 + 1,232 + 1,193 + 1,186 + 1,175 + 1,041 + 1,034 + 1,025 + 1,110 + 1,094 + 1,083 + 1,004 + 966 + 957 + 1,019 + 840 + 852 + 884 + 905 + 872 + 889 + 889 + 879 + 793 + 743 + 743 + 883 + 767 + 775 + 800 + 823 + 757 + 778 + 821 + 701 + 745 + 680 + 635 + 736 + 680 + 632 + 618 + 702 + 660 + 752 + 774 + 742 + 749 + 651 + 653 + 621 + 596 + 673 + 729 + 762 + 772 + 837 + 820 + 831 + 796 + 879 + 862 + 908 + 960 + 984 + 1,007 + 1,144 + 1,315 + 1,711 + 1,822 + 1,912 + 1,968 + 2,010 + 2,010 + 1,988 + 1,866 + 1,876 + 1,884 + 1,882 + 1,747 + 1,918 + 1,814 - - 782 - 779 - 789 - 658 - 675 - 833 - 786 - 675 - 636 - 691 - 694 - 639 - 806 - 821 - 817 - 744 - 731 - 821 - 813 - 767 - 900 - 903 - 935 - 938 - 947 - 973 - 976 - 953 - 1,022 - 1,034 - 999 - 884 - 885 - 956 - 978 - 922 - 1,049 - 1,145 - 1,035 - 986 - 955 - 1,048 - 1,020 - 1,050 - 978 - 933 - 990 - 885 - 1,097 - 987 - 1,039 - 925 - 977 - 1,189 - 965 - 1,010 - 854 - 853 - 916 - 850 - 993 - 1,008 - 967 - 882 - 944 - 950 - 929 - 844 - 842 - 796 - 966 - 930 - 910 - 1,040 - 917 - 882 - 830 - 942 - 867 - 855 - 810 - 795 - 836 - 701 - 911 - 879 - 845 - 822 - 831 - 917 - 920 - 877 - 892 - 911 - 986 - 961 - 1,176 - 1,056 - 944 - 874 - 1,074 - 1,154 - 1,172 - 1,122 - 1,029 - 1,126 - 1,283 - 1,210 - 1,487 - 1,477 - 1,484 - 1,322 - 1,599 - 1,688 - 1,600 - 1,636 - 1,469 - 1,604 - 1,524 - 1,624 - 1,804 - 1,597 - + 782 + 779 + 789 + 658 + 675 + 833 + 786 + 675 + 636 + 691 + 694 + 639 + 806 + 821 + 817 + 744 + 731 + 821 + 813 + 767 + 900 + 903 + 935 + 938 + 947 + 973 + 976 + 953 + 1,022 + 1,034 + 999 + 884 + 885 + 956 + 978 + 922 + 1,049 + 1,145 + 1,035 + 986 + 955 + 1,048 + 1,020 + 1,050 + 978 + 933 + 990 + 885 + 1,097 + 987 + 1,039 + 925 + 977 + 1,189 + 965 + 1,010 + 854 + 853 + 916 + 850 + 993 + 1,008 + 967 + 882 + 944 + 950 + 929 + 844 + 842 + 796 + 966 + 930 + 910 + 1,040 + 917 + 882 + 830 + 942 + 867 + 855 + 810 + 795 + 836 + 701 + 911 + 879 + 845 + 822 + 831 + 917 + 920 + 877 + 892 + 911 + 986 + 961 + 1,176 + 1,056 + 944 + 874 + 1,074 + 1,154 + 1,172 + 1,122 + 1,029 + 1,126 + 1,283 + 1,210 + 1,487 + 1,477 + 1,484 + 1,322 + 1,599 + 1,688 + 1,600 + 1,636 + 1,469 + 1,604 + 1,524 + 1,624 + 1,804 + 1,597 - - 655 - 587 - 623 - 517 - 561 - 545 - 636 - 584 - 559 - 504 - 547 - 564 - 734 - 724 - 652 - 655 - 652 - 694 - 731 - 790 - 810 - 910 - 946 - 921 - 1,120 - 973 - 964 - 951 - 983 - 1,079 - 1,075 - 926 - 1,007 - 962 - 1,029 - 1,038 - 1,112 - 1,140 - 1,190 - 1,076 - 1,105 - 1,092 - 1,021 - 881 - 975 - 1,014 - 948 - 948 - 1,070 - 964 - 999 - 752 - 819 - 814 - 790 - 845 - 750 - 781 - 872 - 875 - 958 - 916 - 807 - 714 - 730 - 743 - 804 - 728 - 862 - 748 - 711 - 788 - 825 - 841 - 824 - 644 - 695 - 753 - 735 - 681 - 736 - 768 - 658 - 791 - 885 - 825 - 775 - 689 - 743 - 722 - 743 - 683 - 655 - 675 - 679 - 803 - 893 - 866 - 876 - 736 - 829 - 890 - 866 - 961 - 951 - 1,052 - 992 - 1,147 - 1,445 - 1,512 - 1,597 - 1,448 - 1,514 - 1,580 - 1,531 - 1,560 - 1,596 - 1,488 - 1,514 - 1,486 - 1,614 - 1,740 - + 655 + 587 + 623 + 517 + 561 + 545 + 636 + 584 + 559 + 504 + 547 + 564 + 734 + 724 + 652 + 655 + 652 + 694 + 731 + 790 + 810 + 910 + 946 + 921 + 1,120 + 973 + 964 + 951 + 983 + 1,079 + 1,075 + 926 + 1,007 + 962 + 1,029 + 1,038 + 1,112 + 1,140 + 1,190 + 1,076 + 1,105 + 1,092 + 1,021 + 881 + 975 + 1,014 + 948 + 948 + 1,070 + 964 + 999 + 752 + 819 + 814 + 790 + 845 + 750 + 781 + 872 + 875 + 958 + 916 + 807 + 714 + 730 + 743 + 804 + 728 + 862 + 748 + 711 + 788 + 825 + 841 + 824 + 644 + 695 + 753 + 735 + 681 + 736 + 768 + 658 + 791 + 885 + 825 + 775 + 689 + 743 + 722 + 743 + 683 + 655 + 675 + 679 + 803 + 893 + 866 + 876 + 736 + 829 + 890 + 866 + 961 + 951 + 1,052 + 992 + 1,147 + 1,445 + 1,512 + 1,597 + 1,448 + 1,514 + 1,580 + 1,531 + 1,560 + 1,596 + 1,488 + 1,514 + 1,486 + 1,614 + 1,740 - - 353 - 349 - 381 - 329 - 423 - 452 - 478 - 450 - 398 - 339 - 351 - 293 - 428 - 423 - 456 - 341 - 390 - 476 - 513 - 595 - 455 - 486 - 516 - 483 - 586 - 590 - 540 - 493 - 533 - 638 - 671 - 660 - 562 - 517 - 493 - 558 - 559 - 576 - 518 - 611 - 618 - 769 - 697 - 760 - 649 - 639 - 662 - 620 - 662 - 608 - 584 - 589 - 570 - 769 - 725 - 647 - 593 - 526 - 570 - 562 - 613 - 619 - 614 - 591 - 648 - 667 - 635 - 644 - 658 - 628 - 677 - 529 - 593 - 528 - 563 - 558 - 543 - 617 - 659 - 611 - 576 - 531 - 536 - 502 - 563 - 489 - 495 - 555 - 622 - 653 - 665 - 648 - 630 - 534 - 526 - 521 - 576 - 562 - 609 - 551 - 619 - 669 - 776 - 844 - 835 - 797 - 748 - 791 - 792 - 847 - 931 - 964 - 1,005 - 1,267 - 1,269 - 1,239 - 1,257 - 1,280 - 1,168 - 1,183 - 1,175 - 1,200 - + 353 + 349 + 381 + 329 + 423 + 452 + 478 + 450 + 398 + 339 + 351 + 293 + 428 + 423 + 456 + 341 + 390 + 476 + 513 + 595 + 455 + 486 + 516 + 483 + 586 + 590 + 540 + 493 + 533 + 638 + 671 + 660 + 562 + 517 + 493 + 558 + 559 + 576 + 518 + 611 + 618 + 769 + 697 + 760 + 649 + 639 + 662 + 620 + 662 + 608 + 584 + 589 + 570 + 769 + 725 + 647 + 593 + 526 + 570 + 562 + 613 + 619 + 614 + 591 + 648 + 667 + 635 + 644 + 658 + 628 + 677 + 529 + 593 + 528 + 563 + 558 + 543 + 617 + 659 + 611 + 576 + 531 + 536 + 502 + 563 + 489 + 495 + 555 + 622 + 653 + 665 + 648 + 630 + 534 + 526 + 521 + 576 + 562 + 609 + 551 + 619 + 669 + 776 + 844 + 835 + 797 + 748 + 791 + 792 + 847 + 931 + 964 + 1,005 + 1,267 + 1,269 + 1,239 + 1,257 + 1,280 + 1,168 + 1,183 + 1,175 + 1,200 - - 430 - 409 - 311 - 269 - 370 - 603 - 545 - 583 - 408 - 391 - 384 - 365 - 463 - 298 - 355 - 369 - 361 - 525 - 548 - 540 - 438 - 429 - 420 - 419 - 486 - 508 - 477 - 447 - 484 - 561 - 645 - 596 - 530 - 499 - 468 - 446 - 571 - 483 - 526 - 440 - 478 - 704 - 749 - 745 - 556 - 500 - 542 - 516 - 511 - 490 - 530 - 433 - 468 - 580 - 741 - 676 - 568 - 561 - 514 - 499 - 555 - 472 - 468 - 478 - 453 - 681 - 683 - 664 - 568 - 502 - 494 - 393 - 457 - 472 - 461 - 414 - 429 - 578 - 659 - 595 - 396 - 424 - 400 - 395 - 476 - 405 - 419 - 408 - 428 - 572 - 704 - 695 - 525 - 492 - 482 - 451 - 471 - 372 - 425 - 373 - 461 - 654 - 770 - 721 - 573 - 552 - 527 - 511 - 652 - 563 - 598 - 575 - 702 - 991 - 1,129 - 1,118 - 928 - 785 - 748 - 797 - 948 - 880 - + 430 + 409 + 311 + 269 + 370 + 603 + 545 + 583 + 408 + 391 + 384 + 365 + 463 + 298 + 355 + 369 + 361 + 525 + 548 + 540 + 438 + 429 + 420 + 419 + 486 + 508 + 477 + 447 + 484 + 561 + 645 + 596 + 530 + 499 + 468 + 446 + 571 + 483 + 526 + 440 + 478 + 704 + 749 + 745 + 556 + 500 + 542 + 516 + 511 + 490 + 530 + 433 + 468 + 580 + 741 + 676 + 568 + 561 + 514 + 499 + 555 + 472 + 468 + 478 + 453 + 681 + 683 + 664 + 568 + 502 + 494 + 393 + 457 + 472 + 461 + 414 + 429 + 578 + 659 + 595 + 396 + 424 + 400 + 395 + 476 + 405 + 419 + 408 + 428 + 572 + 704 + 695 + 525 + 492 + 482 + 451 + 471 + 372 + 425 + 373 + 461 + 654 + 770 + 721 + 573 + 552 + 527 + 511 + 652 + 563 + 598 + 575 + 702 + 991 + 1,129 + 1,118 + 928 + 785 + 748 + 797 + 948 + 880 - - 239 - 262 - 213 - 218 - 206 - 188 - 222 - 186 - 213 - 226 - 273 - 178 - 194 - 209 - 181 - 216 - 206 - 187 - 191 - 243 - 256 - 247 - 234 - 249 - 263 - 250 - 217 - 255 - 264 - 246 - 249 - 271 - 266 - 275 - 297 - 327 - 324 - 304 - 279 - 248 - 271 - 295 - 270 - 302 - 287 - 338 - 308 - 299 - 302 - 260 - 260 - 242 - 287 - 306 - 291 - 324 - 362 - 301 - 353 - 341 - 346 - 363 - 312 - 273 - 299 - 268 - 282 - 249 - 282 - 255 - 319 - 327 - 341 - 332 - 300 - 334 - 251 - 245 - 291 - 306 - 299 - 275 - 257 - 287 - 376 - 300 - 311 - 240 - 276 - 258 - 324 - 315 - 304 - 338 - 336 - 326 - 338 - 340 - 346 - 338 - 366 - 364 - 345 - 378 - 414 - 396 - 411 - 559 - 659 - 586 - 625 - 488 - 530 - 472 - 552 - 569 - 636 - 610 - 592 - 609 - 730 - 680 - + 239 + 262 + 213 + 218 + 206 + 188 + 222 + 186 + 213 + 226 + 273 + 178 + 194 + 209 + 181 + 216 + 206 + 187 + 191 + 243 + 256 + 247 + 234 + 249 + 263 + 250 + 217 + 255 + 264 + 246 + 249 + 271 + 266 + 275 + 297 + 327 + 324 + 304 + 279 + 248 + 271 + 295 + 270 + 302 + 287 + 338 + 308 + 299 + 302 + 260 + 260 + 242 + 287 + 306 + 291 + 324 + 362 + 301 + 353 + 341 + 346 + 363 + 312 + 273 + 299 + 268 + 282 + 249 + 282 + 255 + 319 + 327 + 341 + 332 + 300 + 334 + 251 + 245 + 291 + 306 + 299 + 275 + 257 + 287 + 376 + 300 + 311 + 240 + 276 + 258 + 324 + 315 + 304 + 338 + 336 + 326 + 338 + 340 + 346 + 338 + 366 + 364 + 345 + 378 + 414 + 396 + 411 + 559 + 659 + 586 + 625 + 488 + 530 + 472 + 552 + 569 + 636 + 610 + 592 + 609 + 730 + 680 - - 228 - 240 - 226 - 197 - 195 - 216 - 190 - 213 - 187 - 224 - 184 - 200 - 232 - 235 - 211 - 232 - 191 - 249 - 289 - 256 - 268 - 281 - 320 - 258 - 267 - 318 - 287 - 292 - 340 - 373 - 345 - 343 - 299 - 312 - 337 - 322 - 327 - 310 - 357 - 323 - 320 - 358 - 284 - 342 - 305 - 303 - 311 - 283 - 403 - 363 - 343 - 312 - 302 - 335 - 307 - 312 - 374 - 358 - 290 - 290 - 252 - 301 - 261 - 255 - 288 - 307 - 309 - 300 - 260 - 255 - 268 - 204 - 233 - 268 - 298 - 293 - 289 - 299 - 329 - 263 - 235 - 211 - 229 - 227 - 233 - 295 - 252 - 231 - 281 - 303 - 307 - 371 - 316 - 307 - 261 - 315 - 285 - 323 - 323 - 324 - 361 - 337 - 350 - 409 - 380 - 434 - 494 - 540 - 571 - 637 - 639 - 561 - 536 - 513 - 570 - 566 - 657 - 646 - 619 - 665 - 623 - 708 - + 228 + 240 + 226 + 197 + 195 + 216 + 190 + 213 + 187 + 224 + 184 + 200 + 232 + 235 + 211 + 232 + 191 + 249 + 289 + 256 + 268 + 281 + 320 + 258 + 267 + 318 + 287 + 292 + 340 + 373 + 345 + 343 + 299 + 312 + 337 + 322 + 327 + 310 + 357 + 323 + 320 + 358 + 284 + 342 + 305 + 303 + 311 + 283 + 403 + 363 + 343 + 312 + 302 + 335 + 307 + 312 + 374 + 358 + 290 + 290 + 252 + 301 + 261 + 255 + 288 + 307 + 309 + 300 + 260 + 255 + 268 + 204 + 233 + 268 + 298 + 293 + 289 + 299 + 329 + 263 + 235 + 211 + 229 + 227 + 233 + 295 + 252 + 231 + 281 + 303 + 307 + 371 + 316 + 307 + 261 + 315 + 285 + 323 + 323 + 324 + 361 + 337 + 350 + 409 + 380 + 434 + 494 + 540 + 571 + 637 + 639 + 561 + 536 + 513 + 570 + 566 + 657 + 646 + 619 + 665 + 623 + 708 - - 236 - 223 - 192 - 191 - 190 - 183 - 228 - 198 - 231 - 153 - 129 - 168 - 194 - 189 - 193 - 232 - 178 - 242 - 236 - 226 - 214 - 321 - 302 - 310 - 368 - 331 - 313 - 280 - 257 - 274 - 270 - 221 - 235 - 262 - 233 - 243 - 331 - 316 - 319 - 274 - 260 - 300 - 289 - 255 - 255 - 260 - 275 - 267 - 243 - 291 - 284 - 239 - 230 - 227 - 231 - 236 - 208 - 219 - 217 - 204 - 276 - 245 - 267 - 257 - 223 - 247 - 222 - 187 - 211 - 251 - 199 - 202 - 287 - 260 - 263 - 272 - 226 - 225 - 237 - 217 - 183 - 206 - 183 - 190 - 248 - 251 - 249 - 188 - 216 - 242 - 309 - 205 - 224 - 218 - 242 - 210 - 271 - 289 - 267 - 245 - 269 - 329 - 359 - 309 - 337 - 316 - 331 - 421 - 522 - 563 - 558 - 541 - 506 - 499 - 511 - 547 - 538 - 480 - 493 - 539 - 657 - 591 - + 236 + 223 + 192 + 191 + 190 + 183 + 228 + 198 + 231 + 153 + 129 + 168 + 194 + 189 + 193 + 232 + 178 + 242 + 236 + 226 + 214 + 321 + 302 + 310 + 368 + 331 + 313 + 280 + 257 + 274 + 270 + 221 + 235 + 262 + 233 + 243 + 331 + 316 + 319 + 274 + 260 + 300 + 289 + 255 + 255 + 260 + 275 + 267 + 243 + 291 + 284 + 239 + 230 + 227 + 231 + 236 + 208 + 219 + 217 + 204 + 276 + 245 + 267 + 257 + 223 + 247 + 222 + 187 + 211 + 251 + 199 + 202 + 287 + 260 + 263 + 272 + 226 + 225 + 237 + 217 + 183 + 206 + 183 + 190 + 248 + 251 + 249 + 188 + 216 + 242 + 309 + 205 + 224 + 218 + 242 + 210 + 271 + 289 + 267 + 245 + 269 + 329 + 359 + 309 + 337 + 316 + 331 + 421 + 522 + 563 + 558 + 541 + 506 + 499 + 511 + 547 + 538 + 480 + 493 + 539 + 657 + 591 - - 274 - 232 - 247 - 240 - 254 - 225 - 202 - 187 - 220 - 161 - 217 - 167 - 197 - 243 - 200 - 220 - 172 - 246 - 228 - 241 - 225 - 239 - 256 - 277 - 304 - 339 - 314 - 268 - 264 - 335 - 356 - 353 - 281 - 272 - 284 - 241 - 304 - 331 - 370 - 331 - 339 - 359 - 405 - 373 - 338 - 378 - 357 - 278 - 322 - 366 - 366 - 347 - 310 - 326 - 346 - 341 - 301 - 300 - 294 - 276 - 290 - 325 - 308 - 306 - 314 - 291 - 274 - 306 - 307 - 319 - 300 - 269 - 308 - 281 - 292 - 266 - 265 - 265 - 305 - 341 - 310 - 268 - 306 - 306 - 275 - 257 - 222 - 224 - 242 - 256 - 243 - 239 - 257 - 182 - 255 - 235 - 264 - 313 - 283 - 251 - 275 - 322 - 352 - 412 - 374 - 334 - 434 - 367 - 431 - 453 - 377 - 403 - 476 - 557 - 490 - 528 - 462 - 541 - 491 - 513 - 609 - 603 - + 274 + 232 + 247 + 240 + 254 + 225 + 202 + 187 + 220 + 161 + 217 + 167 + 197 + 243 + 200 + 220 + 172 + 246 + 228 + 241 + 225 + 239 + 256 + 277 + 304 + 339 + 314 + 268 + 264 + 335 + 356 + 353 + 281 + 272 + 284 + 241 + 304 + 331 + 370 + 331 + 339 + 359 + 405 + 373 + 338 + 378 + 357 + 278 + 322 + 366 + 366 + 347 + 310 + 326 + 346 + 341 + 301 + 300 + 294 + 276 + 290 + 325 + 308 + 306 + 314 + 291 + 274 + 306 + 307 + 319 + 300 + 269 + 308 + 281 + 292 + 266 + 265 + 265 + 305 + 341 + 310 + 268 + 306 + 306 + 275 + 257 + 222 + 224 + 242 + 256 + 243 + 239 + 257 + 182 + 255 + 235 + 264 + 313 + 283 + 251 + 275 + 322 + 352 + 412 + 374 + 334 + 434 + 367 + 431 + 453 + 377 + 403 + 476 + 557 + 490 + 528 + 462 + 541 + 491 + 513 + 609 + 603 - - 125 - 112 - 140 - 95 - 131 - 102 - 144 - 143 - 130 - 96 - 117 - 151 - 161 - 109 - 148 - 148 - 164 - 163 - 206 - 210 - 219 - 233 - 241 - 275 - 263 - 279 - 266 - 257 - 260 - 255 - 264 - 270 - 231 - 211 - 220 - 255 - 243 - 321 - 267 - 268 - 251 - 239 - 224 - 224 - 248 - 182 - 257 - 224 - 236 - 194 - 216 - 168 - 190 - 172 - 174 - 191 - 178 - 185 - 187 - 173 - 168 - 204 - 177 - 178 - 145 - 160 - 142 - 156 - 168 - 162 - 172 - 128 - 105 - 119 - 116 - 132 - 158 - 114 - 103 - 132 - 170 - 116 - 137 - 108 - 143 - 139 - 109 - 77 - 110 - 114 - 112 - 140 - 124 - 120 - 132 - 125 - 169 - 193 - 155 - 143 - 170 - 157 - 141 - 144 - 166 - 168 - 173 - 219 - 232 - 224 - 252 - 320 - 303 - 347 - 373 - 358 - 362 - 261 - 243 - 256 - 313 - 300 - + 125 + 112 + 140 + 95 + 131 + 102 + 144 + 143 + 130 + 96 + 117 + 151 + 161 + 109 + 148 + 148 + 164 + 163 + 206 + 210 + 219 + 233 + 241 + 275 + 263 + 279 + 266 + 257 + 260 + 255 + 264 + 270 + 231 + 211 + 220 + 255 + 243 + 321 + 267 + 268 + 251 + 239 + 224 + 224 + 248 + 182 + 257 + 224 + 236 + 194 + 216 + 168 + 190 + 172 + 174 + 191 + 178 + 185 + 187 + 173 + 168 + 204 + 177 + 178 + 145 + 160 + 142 + 156 + 168 + 162 + 172 + 128 + 105 + 119 + 116 + 132 + 158 + 114 + 103 + 132 + 170 + 116 + 137 + 108 + 143 + 139 + 109 + 77 + 110 + 114 + 112 + 140 + 124 + 120 + 132 + 125 + 169 + 193 + 155 + 143 + 170 + 157 + 141 + 144 + 166 + 168 + 173 + 219 + 232 + 224 + 252 + 320 + 303 + 347 + 373 + 358 + 362 + 261 + 243 + 256 + 313 + 300 - - 154 - 173 - 152 - 135 - 73 - 109 - 77 - 110 - 124 - 113 - 192 - 196 - 188 - 193 - 267 - 140 - 109 - 130 - 113 - 141 - 101 - 118 - 145 - 192 - 195 - 187 - 269 - 151 - 89 - 89 - 114 - 125 - 92 - 97 - 137 - 120 - 159 - 172 - 161 - 154 - 133 - 94 - 113 - 173 - 98 - 136 - 148 - 137 - 184 - 168 - 153 - 107 - 99 - 106 - 140 - 103 - 88 - 102 - 131 - 165 - 153 - 107 - 139 - 84 - 66 - 76 - 69 - 100 - 127 - 85 - 118 - 127 - 140 - 139 - 117 - 81 - 79 - 35 - 55 - 76 - 78 - 77 - 125 - 139 - 128 - 127 - 123 - 67 - 64 - 59 - 40 - 54 - 53 - 47 - 80 - 96 - 113 - 135 - 175 - 108 - 94 - 86 - 125 - 111 - 84 - 97 - 119 - 229 - 245 - 251 - 241 - 176 - 136 - 182 - 180 - 195 - 150 - 166 - 180 - 292 - 318 - 285 - + 154 + 173 + 152 + 135 + 73 + 109 + 77 + 110 + 124 + 113 + 192 + 196 + 188 + 193 + 267 + 140 + 109 + 130 + 113 + 141 + 101 + 118 + 145 + 192 + 195 + 187 + 269 + 151 + 89 + 89 + 114 + 125 + 92 + 97 + 137 + 120 + 159 + 172 + 161 + 154 + 133 + 94 + 113 + 173 + 98 + 136 + 148 + 137 + 184 + 168 + 153 + 107 + 99 + 106 + 140 + 103 + 88 + 102 + 131 + 165 + 153 + 107 + 139 + 84 + 66 + 76 + 69 + 100 + 127 + 85 + 118 + 127 + 140 + 139 + 117 + 81 + 79 + 35 + 55 + 76 + 78 + 77 + 125 + 139 + 128 + 127 + 123 + 67 + 64 + 59 + 40 + 54 + 53 + 47 + 80 + 96 + 113 + 135 + 175 + 108 + 94 + 86 + 125 + 111 + 84 + 97 + 119 + 229 + 245 + 251 + 241 + 176 + 136 + 182 + 180 + 195 + 150 + 166 + 180 + 292 + 318 + 285 - - 19 - 25 - 17 - 20 - 27 - 13 - 16 - 23 - 25 - 39 - 11 - 20 - 11 - 27 - 14 - 24 - 34 - 26 - 17 - 18 - 23 - 32 - 20 - 27 - 33 - 35 - 28 - 33 - 25 - 35 - 19 - 32 - 42 - 36 - 32 - 45 - 54 - 41 - 46 - 41 - 40 - 36 - 43 - 20 - 25 - 31 - 34 - 32 - 31 - 24 - 22 - 34 - 22 - 27 - 28 - 10 - 8 - 15 - 20 - 16 - 29 - 25 - 32 - 19 - 16 - 25 - 22 - 12 - 12 - 2 - 18 - 23 - 26 - 25 - 14 - 17 - 20 - 31 - 25 - 32 - 14 - 15 - 22 - 25 - 35 - 33 - 24 - 17 - 22 - 33 - 33 - 33 - 25 - 9 - 16 - 24 - 28 - 16 - 28 - 28 - 28 - 28 - 13 - 17 - 25 - 15 - 32 - 46 - 59 - 63 - 105 - 125 - 98 - 100 - 95 - 93 - 76 - 84 - 96 - 89 - 68 - 79 - + 19 + 25 + 17 + 20 + 27 + 13 + 16 + 23 + 25 + 39 + 11 + 20 + 11 + 27 + 14 + 24 + 34 + 26 + 17 + 18 + 23 + 32 + 20 + 27 + 33 + 35 + 28 + 33 + 25 + 35 + 19 + 32 + 42 + 36 + 32 + 45 + 54 + 41 + 46 + 41 + 40 + 36 + 43 + 20 + 25 + 31 + 34 + 32 + 31 + 24 + 22 + 34 + 22 + 27 + 28 + 10 + 8 + 15 + 20 + 16 + 29 + 25 + 32 + 19 + 16 + 25 + 22 + 12 + 12 + 2 + 18 + 23 + 26 + 25 + 14 + 17 + 20 + 31 + 25 + 32 + 14 + 15 + 22 + 25 + 35 + 33 + 24 + 17 + 22 + 33 + 33 + 33 + 25 + 9 + 16 + 24 + 28 + 16 + 28 + 28 + 28 + 28 + 13 + 17 + 25 + 15 + 32 + 46 + 59 + 63 + 105 + 125 + 98 + 100 + 95 + 93 + 76 + 84 + 96 + 89 + 68 + 79 - - - - 2,440 - + + + 2,440 - - - 2,154 - + + 2,154 - - - 2,010 - + + 2,010 - - - 1,804 - + + 1,804 - - - 1,740 - + + 1,740 - - - 1,280 - + + 1,280 - - - 1,129 - + + 1,129 - - - 730 - + + 730 - - - 708 - + + 708 - - - 657 - + + 657 - - - 609 - + + 609 - - - 373 - + + 373 - - - 318 - + + 318 - - - 125 - + + 125 - - - - 384 - + + + 384 - - - 701 - + + 701 - - - 596 - + + 596 - - - 636 - + + 636 - - - 504 - + + 504 - - - 293 - + + 293 - - - 269 - + + 269 - - - 178 - + + 178 - - - 184 - + + 184 - - - 129 - + + 129 - - - 161 - + + 161 - - - 77 - + + 77 - - - 35 - + + 35 - - - 2 - + + 2 \ No newline at end of file diff --git a/test/output/internFacetDate.svg b/test/output/internFacetDate.svg index 8cbc6a8826..d5cd69f212 100644 --- a/test/output/internFacetDate.svg +++ b/test/output/internFacetDate.svg @@ -13,11191 +13,11115 @@ white-space: pre; } - - - - 1950 - + + + 1950 - - - 1960 - + + 1960 - - - 1970 - + + 1970 - - - 1980 - + + 1980 - - - 1990 - + + 1990 - - - 2000 - + + 2000 date_of_birth - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 - + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 - - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 - + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 - - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 - + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 - - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 - + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 - - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 - + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 - - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 - + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 ↑ height - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - - + + + + + + + + + - - - - 40 - 60 - 80 - 100 - 120 - 140 - 160 - + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 weight → - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/internFacetNaN.svg b/test/output/internFacetNaN.svg index 5888161c9b..8a70c3402c 100644 --- a/test/output/internFacetNaN.svg +++ b/test/output/internFacetNaN.svg @@ -13,897 +13,737 @@ white-space: pre; } - - - - 1.2 - + + + 1.2 - - - 1.3 - + + 1.3 - - - 1.4 - + + 1.4 - - - 1.5 - + + 1.5 - - - 1.6 - + + 1.6 - - - 1.7 - + + 1.7 - - - 1.8 - + + 1.8 - - - 1.9 - + + 1.9 - - - 2 - + + 2 - - - 2.1 - + + 2.1 - - - 2.2 - + + 2.2 height - - - - - - + + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - female - male - + + + female + male - - - female - male - + + female + male - - - female - male - + + female + male - - - female - male - + + female + male - - - female - male - + + female + male - - - female - male - + + female + male - - - female - male - + + female + male - - - female - male - + + female + male - - - female - male - + + female + male - - - female - male - + + female + male - - - female - male - + + female + male - - - female - male - + + female + male sex - - - - - - - - - - - + + + + + + + + + - - - - 40 - 60 - 80 - 100 - 120 - 140 - 160 - + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 weight → - + - - - + - - - + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - + - - - + - - - - + + - - - - + + - - - - + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - + + - - - - + + - - - - - + + + - - - - - + + + - - - - + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - + + - - - - + + - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/metroUnemploymentRidgeline.svg b/test/output/metroUnemploymentRidgeline.svg index 4a051da0b9..a917bf624c 100644 --- a/test/output/metroUnemploymentRidgeline.svg +++ b/test/output/metroUnemploymentRidgeline.svg @@ -13,938 +13,574 @@ white-space: pre; } - - - - Detroit-Livonia-Dearborn, MI Met Div - - - - - Detroit-Warren-Livonia, MI MSA - - - - - Warren-Troy-Farmington Hills, MI Met Div - - - - - Lawrence-Methuen-Salem, MA-NH NECTA Div - - - - - Los Angeles-Long Beach-Glendale, CA Met Div - - - - - Miami-Miami Beach-Kendall, FL Met Div - - - - - Los Angeles-Long Beach-Santa Ana, CA MSA - - - - - Lake County-Kenosha County, IL-WI Met Div - - - - - West Palm Beach-Boca Raton-Boynton Beach, FL Met Div - - - - - Chicago-Joliet-Naperville, IL Met Div - - - - - Chicago-Joliet-Naperville, IL-IN-WI MSA - - - - - Miami-Fort Lauderdale-Pompano Beach, FL MSA - - - - - Oakland-Fremont-Hayward, CA Met Div - - - - - Gary, IN Met Div - - - - - Tacoma, WA Met Div - - - - - San Francisco-Oakland-Fremont, CA MSA - - - - - Camden, NJ Met Div - - - - - Brockton-Bridgewater-Easton, MA NECTA Div - - - - - Seattle-Tacoma-Bellevue, WA MSA - - - - - Fort Lauderdale-Pompano Beach-Deerfield Beach, FL Met Div - - - - - New York-White Plains-Wayne, NY-NJ Met Div - - - - - Santa Ana-Anaheim-Irvine, CA Met Div - - - - - Seattle-Bellevue-Everett, WA Met Div - - - - - Newark-Union, NJ-PA Met Div - - - - - Taunton-Norton-Raynham, MA NECTA Div - - - - - Lowell-Billerica-Chelmsford, MA-NH NECTA Div - - - - - New York-Northern New Jersey-Long Island, NY-NJ-PA MSA - - - - - San Francisco-San Mateo-Redwood City, CA Met Div - - - - - Edison-New Brunswick, NJ Met Div - - - - - Philadelphia-Camden-Wilmington, PA-NJ-DE-MD MSA - - - - - Wilmington, DE-MD-NJ Met Div - - - - - Peabody, MA NECTA Div - - - - - Philadelphia, PA Met Div - - - - - Fort Worth-Arlington, TX Met Div - - - - - Dallas-Fort Worth-Arlington, TX MSA - - - - - Dallas-Plano-Irving, TX Met Div - - - - - Haverhill-North Andover-Amesbury, MA-NH NECTA Div - - - - - Boston-Cambridge-Quincy, MA-NH Met NECTA - - - - - Boston-Cambridge-Quincy, MA NECTA Div - - - - - Nassau-Suffolk, NY Met Div - - - - - Framingham, MA NECTA Div - - - - - Nashua, NH-MA NECTA Div - - - - - Washington-Arlington-Alexandria, DC-VA-MD-WV Met Div - - - - - Washington-Arlington-Alexandria, DC-VA-MD-WV MSA - - - - - Bethesda-Rockville-Frederick, MD Met Div - + + + Detroit-Livonia-Dearborn, MI Met Div + + + Detroit-Warren-Livonia, MI MSA + + + Warren-Troy-Farmington Hills, MI Met Div + + + Lawrence-Methuen-Salem, MA-NH NECTA Div + + + Los Angeles-Long Beach-Glendale, CA Met Div + + + Miami-Miami Beach-Kendall, FL Met Div + + + Los Angeles-Long Beach-Santa Ana, CA MSA + + + Lake County-Kenosha County, IL-WI Met Div + + + West Palm Beach-Boca Raton-Boynton Beach, FL Met Div + + + Chicago-Joliet-Naperville, IL Met Div + + + Chicago-Joliet-Naperville, IL-IN-WI MSA + + + Miami-Fort Lauderdale-Pompano Beach, FL MSA + + + Oakland-Fremont-Hayward, CA Met Div + + + Gary, IN Met Div + + + Tacoma, WA Met Div + + + San Francisco-Oakland-Fremont, CA MSA + + + Camden, NJ Met Div + + + Brockton-Bridgewater-Easton, MA NECTA Div + + + Seattle-Tacoma-Bellevue, WA MSA + + + Fort Lauderdale-Pompano Beach-Deerfield Beach, FL Met Div + + + New York-White Plains-Wayne, NY-NJ Met Div + + + Santa Ana-Anaheim-Irvine, CA Met Div + + + Seattle-Bellevue-Everett, WA Met Div + + + Newark-Union, NJ-PA Met Div + + + Taunton-Norton-Raynham, MA NECTA Div + + + Lowell-Billerica-Chelmsford, MA-NH NECTA Div + + + New York-Northern New Jersey-Long Island, NY-NJ-PA MSA + + + San Francisco-San Mateo-Redwood City, CA Met Div + + + Edison-New Brunswick, NJ Met Div + + + Philadelphia-Camden-Wilmington, PA-NJ-DE-MD MSA + + + Wilmington, DE-MD-NJ Met Div + + + Peabody, MA NECTA Div + + + Philadelphia, PA Met Div + + + Fort Worth-Arlington, TX Met Div + + + Dallas-Fort Worth-Arlington, TX MSA + + + Dallas-Plano-Irving, TX Met Div + + + Haverhill-North Andover-Amesbury, MA-NH NECTA Div + + + Boston-Cambridge-Quincy, MA-NH Met NECTA + + + Boston-Cambridge-Quincy, MA NECTA Div + + + Nassau-Suffolk, NY Met Div + + + Framingham, MA NECTA Div + + + Nashua, NH-MA NECTA Div + + + Washington-Arlington-Alexandria, DC-VA-MD-WV Met Div + + + Washington-Arlington-Alexandria, DC-VA-MD-WV MSA + + + Bethesda-Rockville-Frederick, MD Met Div - - - - - - - - - - - + + + + + + + + + - - - - 2000 - 2002 - 2004 - 2006 - 2008 - 2010 - 2012 - + + + 2000 + 2002 + 2004 + 2006 + 2008 + 2010 + 2012 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/mobyDickFaceted.svg b/test/output/mobyDickFaceted.svg index e172fbb8f7..f6172d5e69 100644 --- a/test/output/mobyDickFaceted.svg +++ b/test/output/mobyDickFaceted.svg @@ -13,337 +13,289 @@ white-space: pre; } - - - - lower - + + + lower - - - upper - + + upper - + - - consonant - + consonant - - vowel - + vowel - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - 0 - 200 - 400 - 600 - 800 - 1,000 - 1,200 - + + + 0 + 200 + 400 + 600 + 800 + 1,000 + 1,200 - - - 0 - 200 - 400 - 600 - 800 - 1,000 - 1,200 - + + 0 + 200 + 400 + 600 + 800 + 1,000 + 1,200 ↑ Frequency - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - A - B - C - D - E - F - G - H - I - J - K - L - M - N - O - P - Q - R - S - T - U - V - W - X - Y - Z - + A + B + C + D + E + F + G + H + I + J + K + L + M + N + O + P + Q + R + S + T + U + V + W + X + Y + Z - - A - B - C - D - E - F - G - H - I - J - K - L - M - N - O - P - Q - R - S - T - U - V - W - X - Y - Z - + A + B + C + D + E + F + G + H + I + J + K + L + M + N + O + P + Q + R + S + T + U + V + W + X + Y + Z - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - + + + - - - - + + - - - - + + - - - - + + \ No newline at end of file diff --git a/test/output/moviesRatingByGenre.svg b/test/output/moviesRatingByGenre.svg index e3c70907dc..a25990176e 100644 --- a/test/output/moviesRatingByGenre.svg +++ b/test/output/moviesRatingByGenre.svg @@ -13,3414 +13,3306 @@ white-space: pre; } - - - - - + + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - Documentary - + + + Documentary - - - Black Comedy - + + Black Comedy - - - Drama - + + Drama - - - Musical - + + Musical - - - Western - + + Western - - - N/A - + + N/A - - - Adventure - + + Adventure - - - Thriller/Suspense - + + Thriller/Suspense - - - Action - + + Action - - - Concert/Performance - + + Concert/Performance - - - Comedy - + + Comedy - - - Romantic Comedy - + + Romantic Comedy - - - Horror - + + Horror - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 IMDB Rating → - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/multiplicationTable.svg b/test/output/multiplicationTable.svg index e60794cc46..26ecedd248 100644 --- a/test/output/multiplicationTable.svg +++ b/test/output/multiplicationTable.svg @@ -13,1138 +13,690 @@ white-space: pre; } - - - - - + + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - 2 - + + + 2 - - - 3 - + + 3 - - - 4 - + + 4 - - - 5 - + + 5 - - - 6 - + + 6 - - - 7 - + + 7 - - - 8 - + + 8 - - - 9 - + + 9 - - - - - + + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - + - - 2 - + 2 - - 3 - + 3 - - 4 - + 4 - - 5 - + 5 - - 6 - + 6 - - 7 - + 7 - - 8 - + 8 - - 9 - + 9 - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - - - + + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - 4 - + + + 4 - - - 6 - + + 6 - - - 8 - + + 8 - - - 10 - + + 10 - - - 12 - + + 12 - - - 14 - + + 14 - - - 16 - + + 16 - - - 18 - + + 18 - - - 6 - + + 6 - - - 9 - + + 9 - - - 12 - + + 12 - - - 15 - + + 15 - - - 18 - + + 18 - - - 21 - + + 21 - - - 24 - + + 24 - - - 27 - + + 27 - - - 8 - + + 8 - - - 12 - + + 12 - - - 16 - + + 16 - - - 20 - + + 20 - - - 24 - + + 24 - - - 28 - + + 28 - - - 32 - + + 32 - - - 36 - + + 36 - - - 10 - + + 10 - - - 15 - + + 15 - - - 20 - + + 20 - - - 25 - + + 25 - - - 30 - + + 30 - - - 35 - + + 35 - - - 40 - + + 40 - - - 45 - + + 45 - - - 12 - + + 12 - - - 18 - + + 18 - - - 24 - + + 24 - - - 30 - + + 30 - - - 36 - + + 36 - - - 42 - + + 42 - - - 48 - + + 48 - - - 54 - + + 54 - - - 14 - + + 14 - - - 21 - + + 21 - - - 28 - + + 28 - - - 35 - + + 35 - - - 42 - + + 42 - - - 49 - + + 49 - - - 56 - + + 56 - - - 63 - + + 63 - - - 16 - + + 16 - - - 24 - + + 24 - - - 32 - + + 32 - - - 40 - + + 40 - - - 48 - + + 48 - - - 56 - + + 56 - - - 64 - + + 64 - - - 72 - + + 72 - - - 18 - + + 18 - - - 27 - + + 27 - - - 36 - + + 36 - - - 45 - + + 45 - - - 54 - + + 54 - - - 63 - + + 63 - - - 72 - + + 72 - - - 81 - + + 81 \ No newline at end of file diff --git a/test/output/penguinCulmen.svg b/test/output/penguinCulmen.svg index 44cd44bf80..7f5d472c71 100644 --- a/test/output/penguinCulmen.svg +++ b/test/output/penguinCulmen.svg @@ -13,3109 +13,2991 @@ white-space: pre; } - - - - Adelie - + + + Adelie - - - Chinstrap - + + Chinstrap - - - Gentoo - + + Gentoo species - + - - FEMALE - + FEMALE - - MALE - + MALE sex - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - 35 - 40 - 45 - 50 - 55 - + + + 35 + 40 + 45 + 50 + 55 - - - 35 - 40 - 45 - 50 - 55 - + + 35 + 40 + 45 + 50 + 55 - - - 35 - 40 - 45 - 50 - 55 - + + 35 + 40 + 45 + 50 + 55 ↑ culmen_length_mm - - - - - - + + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - - + + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - 15 - 20 - + + + 15 + 20 - - - 15 - 20 - + + 15 + 20 - - - 15 - 20 - + + 15 + 20 - - - 15 - 20 - + + 15 + 20 culmen_depth_mm → - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + - - - - - - - + + + + + \ No newline at end of file diff --git a/test/output/penguinCulmenArray.svg b/test/output/penguinCulmenArray.svg index 005a430be3..bdc90ba8ba 100644 --- a/test/output/penguinCulmenArray.svg +++ b/test/output/penguinCulmenArray.svg @@ -13,3419 +13,3317 @@ white-space: pre; } - - - - Adelie - + + + Adelie - - - Chinstrap - + + Chinstrap - - - Gentoo - + + Gentoo species - + - - FEMALE - + FEMALE - - MALE - + MALE sex - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - 35 - 40 - 45 - 50 - 55 - + + + 35 + 40 + 45 + 50 + 55 - - - 35 - 40 - 45 - 50 - 55 - + + 35 + 40 + 45 + 50 + 55 - - - 35 - 40 - 45 - 50 - 55 - + + 35 + 40 + 45 + 50 + 55 - - - - - - + + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - - + + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - 15 - 20 - + + + 15 + 20 - - - 15 - 20 - + + 15 + 20 - - - 15 - 20 - + + 15 + 20 - - - 15 - 20 - + + 15 + 20 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + - - - - - - - + + + + + \ No newline at end of file diff --git a/test/output/penguinCulmenMarkFacet.svg b/test/output/penguinCulmenMarkFacet.svg index da39602085..1ef8750daa 100644 --- a/test/output/penguinCulmenMarkFacet.svg +++ b/test/output/penguinCulmenMarkFacet.svg @@ -13,2985 +13,2899 @@ white-space: pre; } - - - - Adelie - + + + Adelie - - - Chinstrap - + + Chinstrap - - - Gentoo - + + Gentoo species - + - - FEMALE - + FEMALE - - MALE - + MALE sex - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - 35 - 40 - 45 - 50 - 55 - + + + 35 + 40 + 45 + 50 + 55 - - - 35 - 40 - 45 - 50 - 55 - + + 35 + 40 + 45 + 50 + 55 - - - 35 - 40 - 45 - 50 - 55 - + + 35 + 40 + 45 + 50 + 55 ↑ culmen_length_mm - - - - - - + + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - 15 - 20 - + + + 15 + 20 - - - 15 - 20 - + + 15 + 20 - - - 15 - 20 - + + 15 + 20 - - - 15 - 20 - + + 15 + 20 culmen_depth_mm → - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + - - - - - - - + + + + + \ No newline at end of file diff --git a/test/output/penguinDensityFill.html b/test/output/penguinDensityFill.html index c781f6284d..fdbb5e2e35 100644 --- a/test/output/penguinDensityFill.html +++ b/test/output/penguinDensityFill.html @@ -48,165 +48,131 @@ white-space: pre; } - + - - Biscoe - + Biscoe - - Dream - + Dream - - Torgersen - + Torgersen island - - - - - - - - - + + + + + + + - - - - 35 - 40 - 45 - 50 - 55 - + + + 35 + 40 + 45 + 50 + 55 ↑ culmen_length_mm - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - 180 - 200 - 220 - - - - - 180 - 200 - 220 - - - - - 180 - 200 - 220 - + + + 180 + 200 + 220 + + + 180 + 200 + 220 + + + 180 + 200 + 220 flipper_length_mm → - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - + + + + \ No newline at end of file diff --git a/test/output/penguinDensityZ.html b/test/output/penguinDensityZ.html index 10050a294b..fc1ed9a03b 100644 --- a/test/output/penguinDensityZ.html +++ b/test/output/penguinDensityZ.html @@ -46,184 +46,150 @@ white-space: pre; } - + - - Biscoe - + Biscoe - - Dream - + Dream - - Torgersen - + Torgersen island - - - - - - - - - + + + + + + + - - - - 35 - 40 - 45 - 50 - 55 - + + + 35 + 40 + 45 + 50 + 55 ↑ culmen_length_mm - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - 180 - 200 - 220 - - - - - 180 - 200 - 220 - - - - - 180 - 200 - 220 - + + + 180 + 200 + 220 + + + 180 + 200 + 220 + + + 180 + 200 + 220 flipper_length_mm → - - - - - - - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Gentoo - Gentoo - Gentoo - Gentoo - Gentoo - Gentoo - Gentoo - Gentoo - Gentoo - + + + + + + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Gentoo + Gentoo + Gentoo + Gentoo + Gentoo + Gentoo + Gentoo + Gentoo + Gentoo - - - - - - - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Chinstrap - Chinstrap - Chinstrap - Chinstrap - Chinstrap - Chinstrap - Chinstrap - Chinstrap - Chinstrap - + + + + + + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Chinstrap + Chinstrap + Chinstrap + Chinstrap + Chinstrap + Chinstrap + Chinstrap + Chinstrap + Chinstrap - - - - - - - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - Adelie - + + + + + + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie + Adelie - - - - - - - - - - + + + + \ No newline at end of file diff --git a/test/output/penguinDodgeHexbin.svg b/test/output/penguinDodgeHexbin.svg index a2544b014e..bb85609357 100644 --- a/test/output/penguinDodgeHexbin.svg +++ b/test/output/penguinDodgeHexbin.svg @@ -13,807 +13,773 @@ white-space: pre; } - - - - Adelie - + + + Adelie - - - Chinstrap - + + Chinstrap - - - Gentoo - + + Gentoo - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - - + + + + + + + + + - - - - 3,000 - 3,500 - 4,000 - 4,500 - 5,000 - 5,500 - 6,000 - + + + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 body_mass_g → - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/penguinFacetAnnotated.svg b/test/output/penguinFacetAnnotated.svg index bc70cc2186..15761c8856 100644 --- a/test/output/penguinFacetAnnotated.svg +++ b/test/output/penguinFacetAnnotated.svg @@ -13,147 +13,111 @@ white-space: pre; } - - - - Biscoe - + + + Biscoe - - - Dream - + + Dream - - - Torgersen - + + Torgersen island - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - Adelie - Chinstrap - Gentoo - - - - - Adelie - Chinstrap - Gentoo - - - - - Adelie - Chinstrap - Gentoo - + + + Adelie + Chinstrap + Gentoo + + + Adelie + Chinstrap + Gentoo + + + Adelie + Chinstrap + Gentoo species - - - - - - - - - - - + + + + + + + + + - - - - 0 - 20 - 40 - 60 - 80 - 100 - 120 - + + + 0 + 20 + 40 + 60 + 80 + 100 + 120 Frequency → - - - - - - - - - - + + + + - - - - - - - + + + + + - - - - - - - + + + + + - - - - - + + + - - - - Torgersen Island only has Adelie penguins! - + + + Torgersen Island only has Adelie penguins! \ No newline at end of file diff --git a/test/output/penguinFacetAnnotatedX.svg b/test/output/penguinFacetAnnotatedX.svg index d5aab980d7..3b1c380543 100644 --- a/test/output/penguinFacetAnnotatedX.svg +++ b/test/output/penguinFacetAnnotatedX.svg @@ -13,139 +13,103 @@ white-space: pre; } - + - - Biscoe - + Biscoe - - Dream - + Dream - - Torgersen - + Torgersen island - - - - - - - + + + + + - - - - Adelie - Chinstrap - Gentoo - + + + Adelie + Chinstrap + Gentoo species - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - 0 - 50 - 100 - - - - - 0 - 50 - 100 - - - - - 0 - 50 - 100 - + + + 0 + 50 + 100 + + + 0 + 50 + 100 + + + 0 + 50 + 100 Frequency → - - - - - - - - - - + + + + - - - - - - - + + + + + - - - - - - - + + + + + - - - - - + + + - - - - Torgersen Islandonly has Adeliepenguins! - + + + Torgersen Islandonly has Adeliepenguins! \ No newline at end of file diff --git a/test/output/penguinFacetDodge.svg b/test/output/penguinFacetDodge.svg index baa431cf59..3cd648a002 100644 --- a/test/output/penguinFacetDodge.svg +++ b/test/output/penguinFacetDodge.svg @@ -13,441 +13,419 @@ white-space: pre; } - - - - Adelie - + + + Adelie - - - Chinstrap - + + Chinstrap - - - Gentoo - + + Gentoo - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - - + + + + + + + + + - - - - 3,000 - 3,500 - 4,000 - 4,500 - 5,000 - 5,500 - 6,000 - + + + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 body_mass_g → - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/penguinFacetDodgeIdentity.svg b/test/output/penguinFacetDodgeIdentity.svg index 0e599005d5..b53dae2ae0 100644 --- a/test/output/penguinFacetDodgeIdentity.svg +++ b/test/output/penguinFacetDodgeIdentity.svg @@ -13,441 +13,419 @@ white-space: pre; } - - - - Adelie - + + + Adelie - - - Chinstrap - + + Chinstrap - - - Gentoo - + + Gentoo - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - - + + + + + + + + + - - - - 3,000 - 3,500 - 4,000 - 4,500 - 5,000 - 5,500 - 6,000 - + + + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 body_mass_g → - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/penguinFacetDodgeIsland.html b/test/output/penguinFacetDodgeIsland.html index 67d51399c7..165676cae9 100644 --- a/test/output/penguinFacetDodgeIsland.html +++ b/test/output/penguinFacetDodgeIsland.html @@ -46,441 +46,419 @@ white-space: pre; } - - - - Adelie - + + + Adelie - - - Chinstrap - + + Chinstrap - - - Gentoo - + + Gentoo - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - - + + + + + + + + + - - - - 3,000 - 3,500 - 4,000 - 4,500 - 5,000 - 5,500 - 6,000 - + + + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 body_mass_g → - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/output/penguinMassSex.svg b/test/output/penguinMassSex.svg index c7d0a4782d..8c26390e62 100644 --- a/test/output/penguinMassSex.svg +++ b/test/output/penguinMassSex.svg @@ -13,116 +13,96 @@ white-space: pre; } - - - - FEMALE - + + + FEMALE - - - MALE - + + MALE sex - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - 0 - 10 - 20 - 30 - 40 - 50 - - - - - 0 - 10 - 20 - 30 - 40 - 50 - - - - - 0 - 10 - 20 - 30 - 40 - 50 - + + + 0 + 10 + 20 + 30 + 40 + 50 + + + 0 + 10 + 20 + 30 + 40 + 50 + + + 0 + 10 + 20 + 30 + 40 + 50 ↑ Frequency - - - - - - - - - - - - - + + + + + + + + + + + - - - - 2,500 - 3,000 - 3,500 - 4,000 - 4,500 - 5,000 - 5,500 - 6,000 - 6,500 - + + + 2,500 + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 + 6,500 @@ -130,51 +110,39 @@ - - - - - - - - + + + + + + - - - - - - - - - + + + + + + + - - - - - - - + + + + + - - - - - + + + - - - - + + - - - - + + \ No newline at end of file diff --git a/test/output/penguinMassSexSpecies.svg b/test/output/penguinMassSexSpecies.svg index 75f9ce1037..4f1ba5d920 100644 --- a/test/output/penguinMassSexSpecies.svg +++ b/test/output/penguinMassSexSpecies.svg @@ -13,152 +13,114 @@ white-space: pre; } - - - - Adelie - + + + Adelie - - - Chinstrap - + + Chinstrap - - - Gentoo - + + Gentoo species - + - - FEMALE - + FEMALE - - MALE - + MALE sex - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - 0 - 10 - 20 - 30 - 40 - - - - - 0 - 10 - 20 - 30 - 40 - - - - - 0 - 10 - 20 - 30 - 40 - + + + 0 + 10 + 20 + 30 + 40 + + + 0 + 10 + 20 + 30 + 40 + + + 0 + 10 + 20 + 30 + 40 ↑ Frequency - - - - - - + + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - 4,000 - 6,000 - + + + 4,000 + 6,000 - - - 4,000 - 6,000 - + + 4,000 + 6,000 - - - 4,000 - 6,000 - + + 4,000 + 6,000 - - - 4,000 - 6,000 - + + 4,000 + 6,000 @@ -166,107 +128,75 @@ - - - - - + + + - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - - - - + + - - - - - + + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + \ No newline at end of file diff --git a/test/output/penguinSexMassCulmenSpecies.svg b/test/output/penguinSexMassCulmenSpecies.svg index c259aaf57d..2fbe4e8e3b 100644 --- a/test/output/penguinSexMassCulmenSpecies.svg +++ b/test/output/penguinSexMassCulmenSpecies.svg @@ -13,341 +13,297 @@ white-space: pre; } - + - - FEMALE - + FEMALE - - MALE - + MALE sex - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - 34 - 36 - 38 - 40 - 42 - 44 - 46 - 48 - 50 - 52 - 54 - 56 - 58 - + + + 34 + 36 + 38 + 40 + 42 + 44 + 46 + 48 + 50 + 52 + 54 + 56 + 58 ↑ culmen_length_mm - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - 3k - 3.5k - 4k - 4.5k - 5k - 5.5k - 6k - + + + 3k + 3.5k + 4k + 4.5k + 5k + 5.5k + 6k - - - 3k - 3.5k - 4k - 4.5k - 5k - 5.5k - 6k - + + 3k + 3.5k + 4k + 4.5k + 5k + 5.5k + 6k - - - 3k - 3.5k - 4k - 4.5k - 5k - 5.5k - 6k - + + 3k + 3.5k + 4k + 4.5k + 5k + 5.5k + 6k body_mass_g → - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/test/output/penguinSpeciesIslandRelative.svg b/test/output/penguinSpeciesIslandRelative.svg index e834a1e7a2..186534e203 100644 --- a/test/output/penguinSpeciesIslandRelative.svg +++ b/test/output/penguinSpeciesIslandRelative.svg @@ -13,75 +13,59 @@ white-space: pre; } - - - - - + + + - - - - + + - - - - + + - + - - Adelie - + Adelie - - Chinstrap - + Chinstrap - - Gentoo - + Gentoo species - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - 0 - 10 - 20 - 30 - 40 - 50 - 60 - 70 - 80 - 90 - 100 - + + + 0 + 10 + 20 + 30 + 40 + 50 + 60 + 70 + 80 + 90 + 100 @@ -89,38 +73,26 @@ - - - - - + + + - - - + - - - + - - - - - + + + - - - - + + - - - - + + \ No newline at end of file diff --git a/test/output/penguinSpeciesIslandSex.svg b/test/output/penguinSpeciesIslandSex.svg index 955103584c..507726a790 100644 --- a/test/output/penguinSpeciesIslandSex.svg +++ b/test/output/penguinSpeciesIslandSex.svg @@ -13,174 +13,146 @@ white-space: pre; } - + - - Adelie - + Adelie - - Chinstrap - + Chinstrap - - Gentoo - + Gentoo species - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - 0 - 5 - 10 - 15 - 20 - 25 - 30 - 35 - 40 - 45 - 50 - 55 - 60 - 65 - 70 - + + + 0 + 5 + 10 + 15 + 20 + 25 + 30 + 35 + 40 + 45 + 50 + 55 + 60 + 65 + 70 ↑ Frequency - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - + - - FEMALE - MALE - N/A - + FEMALE + MALE + N/A - - FEMALE - MALE - N/A - + FEMALE + MALE + N/A - - FEMALE - MALE - N/A - + FEMALE + MALE + N/A @@ -188,46 +160,34 @@ - - - - - - - - - - + + + + + + + + - - - - + + - - - - - + + + - - - - - + + + - - - - + + - - - - + + \ No newline at end of file diff --git a/test/output/projectionBleedEdges2.svg b/test/output/projectionBleedEdges2.svg index bcafda14d8..2b2fdb67b7 100644 --- a/test/output/projectionBleedEdges2.svg +++ b/test/output/projectionBleedEdges2.svg @@ -13,48 +13,32 @@ white-space: pre; } - + - - 1 - + 1 - - 2 - + 2 - - - - - + + + - - - - + + - - - - - + + + - - - - + + - - - - - - - + + + \ No newline at end of file diff --git a/test/output/projectionFitBertin1953.svg b/test/output/projectionFitBertin1953.svg index 0c6ca36656..cd2a461f69 100644 --- a/test/output/projectionFitBertin1953.svg +++ b/test/output/projectionFitBertin1953.svg @@ -13,36 +13,24 @@ white-space: pre; } - + - - a - + a - - b - + b - - - - - - - + + + - + - - - + - - - + \ No newline at end of file diff --git a/test/output/projectionHeightEqualEarth.svg b/test/output/projectionHeightEqualEarth.svg index 9082a79971..7de650c6e6 100644 --- a/test/output/projectionHeightEqualEarth.svg +++ b/test/output/projectionHeightEqualEarth.svg @@ -13,60 +13,40 @@ white-space: pre; } - + - - 0 - + 0 - - 1 - + 1 - + - - - + - - - + - - - - - + + + - - - - + + - - - - - + + + - - - - + + - - - - - - - + + + \ No newline at end of file diff --git a/test/output/projectionHeightGeometry.svg b/test/output/projectionHeightGeometry.svg index 229e180bfe..24ad13d9ee 100644 --- a/test/output/projectionHeightGeometry.svg +++ b/test/output/projectionHeightGeometry.svg @@ -13,36 +13,24 @@ white-space: pre; } - - - - 0 - + + + 0 - - - 1 - + + 1 - - - - - + + + - - - - + + - - - - - - - + + + \ No newline at end of file diff --git a/test/output/projectionHeightMercator.svg b/test/output/projectionHeightMercator.svg index ec42e3b0c0..85432e47ec 100644 --- a/test/output/projectionHeightMercator.svg +++ b/test/output/projectionHeightMercator.svg @@ -13,60 +13,40 @@ white-space: pre; } - - - - 0 - + + + 0 - - - 1 - + + 1 - + - - - + - - - + - - - - - + + + - - - - + + - - - - - + + + - - - - + + - - - - - - - + + + \ No newline at end of file diff --git a/test/output/projectionHeightOrthographic.svg b/test/output/projectionHeightOrthographic.svg index 7e570fe84c..bd0f04ba43 100644 --- a/test/output/projectionHeightOrthographic.svg +++ b/test/output/projectionHeightOrthographic.svg @@ -13,108 +13,68 @@ white-space: pre; } - - - - 0 - + + + 0 - - - 1 - + + 1 - + - - 0 - + 0 - - 1 - + 1 - + - - - + - - - + - - - + - - - + - - - - - + + + - - - - + + - - - - + + - - - - + + - - - - - + + + - - - - + + - - - - + + - - - - + + - - - - - - - - - - - - - + + + + + \ No newline at end of file diff --git a/test/output/reducerScaleOverrideFunction.svg b/test/output/reducerScaleOverrideFunction.svg index d9528093ea..a2dd006780 100644 --- a/test/output/reducerScaleOverrideFunction.svg +++ b/test/output/reducerScaleOverrideFunction.svg @@ -13,92 +13,72 @@ white-space: pre; } - - - - FEMALE - + + + FEMALE - - - MALE - + + MALE sex - - - - - - - - + + + + + + - - - - - - - + + + + + - - - - - - - + + + + + - - - - 0 - 20 - 40 - 60 - + + + 0 + 20 + 40 + 60 - - - 0 - 20 - 40 - 60 - + + 0 + 20 + 40 + 60 - - - 0 - 20 - 40 - 60 - + + 0 + 20 + 40 + 60 ↑ Frequency - - - - - - - + + + + + - + - - Adelie - Chinstrap - Gentoo - + Adelie + Chinstrap + Gentoo @@ -106,24 +86,18 @@ - - - - - + + + - - - - - + + + - - - - + + \ No newline at end of file diff --git a/test/output/reducerScaleOverrideImplementation.svg b/test/output/reducerScaleOverrideImplementation.svg index d9528093ea..a2dd006780 100644 --- a/test/output/reducerScaleOverrideImplementation.svg +++ b/test/output/reducerScaleOverrideImplementation.svg @@ -13,92 +13,72 @@ white-space: pre; } - - - - FEMALE - + + + FEMALE - - - MALE - + + MALE sex - - - - - - - - + + + + + + - - - - - - - + + + + + - - - - - - - + + + + + - - - - 0 - 20 - 40 - 60 - + + + 0 + 20 + 40 + 60 - - - 0 - 20 - 40 - 60 - + + 0 + 20 + 40 + 60 - - - 0 - 20 - 40 - 60 - + + 0 + 20 + 40 + 60 ↑ Frequency - - - - - - - + + + + + - + - - Adelie - Chinstrap - Gentoo - + Adelie + Chinstrap + Gentoo @@ -106,24 +86,18 @@ - - - - - + + + - - - - - + + + - - - - + + \ No newline at end of file diff --git a/test/output/reducerScaleOverrideName.svg b/test/output/reducerScaleOverrideName.svg index d9528093ea..a2dd006780 100644 --- a/test/output/reducerScaleOverrideName.svg +++ b/test/output/reducerScaleOverrideName.svg @@ -13,92 +13,72 @@ white-space: pre; } - - - - FEMALE - + + + FEMALE - - - MALE - + + MALE sex - - - - - - - - + + + + + + - - - - - - - + + + + + - - - - - - - + + + + + - - - - 0 - 20 - 40 - 60 - + + + 0 + 20 + 40 + 60 - - - 0 - 20 - 40 - 60 - + + 0 + 20 + 40 + 60 - - - 0 - 20 - 40 - 60 - + + 0 + 20 + 40 + 60 ↑ Frequency - - - - - - - + + + + + - + - - Adelie - Chinstrap - Gentoo - + Adelie + Chinstrap + Gentoo @@ -106,24 +86,18 @@ - - - - - + + + - - - - - + + + - - - - + + \ No newline at end of file diff --git a/test/output/textOverflow.svg b/test/output/textOverflow.svg index 04273f6997..d22f0aea12 100644 --- a/test/output/textOverflow.svg +++ b/test/output/textOverflow.svg @@ -13,406 +13,366 @@ white-space: pre; } - + - - clip-start - + clip-start - - clip-end - + clip-end - - ellipsis-start - + ellipsis-start - - ellipsis-middle - + ellipsis-middle - - ellipsis-end - + ellipsis-end - - monospace - + monospace - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - The Best Years of Our Lives - The Ballad of Gregorio Cortez - My Big Fat Independent Movie - Battle for the Planet of the Apes - Big Things - Bogus - Beverly Hills Cop - Beverly Hills Cop II - Beverly Hills Cop III - The Black Hole - The Big Parade - Boyz n the Hood - The Book of Mormon Movie,Volume 1: The Journey - Return to the Blue Lagoon - Bright Lights, Big City - The Blue Bird - The Blue Butterfly - Blade Runner - Bloodsport - The Blues Brothers - Blow Out - De battre mon cœur s'est arrêté - The Broadway Melody - Boom Town - Bill & Ted's Bogus Journey - The Birth of a Nation - The Ballad of Cable Hogue - The Blood of Heroes - The Blood of My Brother: A Story of Death in Iraq - Boomerang - The Bridge on the River Kwai - Born on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - 🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - + + + The Best Years of Our Lives + The Ballad of Gregorio Cortez + My Big Fat Independent Movie + Battle for the Planet of the Apes + Big Things + Bogus + Beverly Hills Cop + Beverly Hills Cop II + Beverly Hills Cop III + The Black Hole + The Big Parade + Boyz n the Hood + The Book of Mormon Movie,Volume 1: The Journey + Return to the Blue Lagoon + Bright Lights, Big City + The Blue Bird + The Blue Butterfly + Blade Runner + Bloodsport + The Blues Brothers + Blow Out + De battre mon cœur s'est arrêté + The Broadway Melody + Boom Town + Bill & Ted's Bogus Journey + The Birth of a Nation + The Ballad of Cable Hogue + The Blood of Heroes + The Blood of My Brother: A Story of Death in Iraq + Boomerang + The Bridge on the River Kwai + Born on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + 🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - - - - ars of Our LivesThe Best Years of Our Lives - Gregorio CortezThe Ballad of Gregorio Cortez - ependent MovieMy Big Fat Independent Movie - anet of the ApesBattle for the Planet of the Apes - Big Things - Bogus - everly Hills CopBeverly Hills Cop - verly Hills Cop IIBeverly Hills Cop II - erly Hills Cop IIIBeverly Hills Cop III - The Black Hole - The Big Parade - Boyz n the Hood - Mormon Movie,e 1: The JourneyThe Book of Mormon Movie, - Volume 1: The Journey - the Blue LagoonReturn to the Blue Lagoon - Lights, Big CityBright Lights, Big City - The Blue Bird - e Blue ButterflyThe Blue Butterfly - Blade Runner - Bloodsport - e Blues BrothersThe Blues Brothers - Blow Out - cœur s'est arrêtéDe battre mon cœur s'est arrêté - roadway MelodyThe Broadway Melody - Boom Town - Bogus JourneyBill & Ted's Bogus Journey - Birth of a NationThe Birth of a Nation - of Cable HogueThe Ballad of Cable Hogue - Blood of HeroesThe Blood of Heroes - of Death in IraqThe Blood of My Brother: A Story of Death in Iraq - Boomerang - n the River KwaiThe Bridge on the River Kwai - e Fourth of JulyBorn on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - .🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - + + + ars of Our LivesThe Best Years of Our Lives + Gregorio CortezThe Ballad of Gregorio Cortez + ependent MovieMy Big Fat Independent Movie + anet of the ApesBattle for the Planet of the Apes + Big Things + Bogus + everly Hills CopBeverly Hills Cop + verly Hills Cop IIBeverly Hills Cop II + erly Hills Cop IIIBeverly Hills Cop III + The Black Hole + The Big Parade + Boyz n the Hood + Mormon Movie,e 1: The JourneyThe Book of Mormon Movie, + Volume 1: The Journey + the Blue LagoonReturn to the Blue Lagoon + Lights, Big CityBright Lights, Big City + The Blue Bird + e Blue ButterflyThe Blue Butterfly + Blade Runner + Bloodsport + e Blues BrothersThe Blues Brothers + Blow Out + cœur s'est arrêtéDe battre mon cœur s'est arrêté + roadway MelodyThe Broadway Melody + Boom Town + Bogus JourneyBill & Ted's Bogus Journey + Birth of a NationThe Birth of a Nation + of Cable HogueThe Ballad of Cable Hogue + Blood of HeroesThe Blood of Heroes + of Death in IraqThe Blood of My Brother: A Story of Death in Iraq + Boomerang + n the River KwaiThe Bridge on the River Kwai + e Fourth of JulyBorn on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + .🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - - - - The Best YearsThe Best Years of Our Lives - The Ballad of GrThe Ballad of Gregorio Cortez - My Big Fat IndeMy Big Fat Independent Movie - Battle for the PlBattle for the Planet of the Apes - Big Things - Bogus - Beverly Hills CoBeverly Hills Cop - Beverly Hills CoBeverly Hills Cop II - Beverly Hills CoBeverly Hills Cop III - The Black Hole - The Big Parade - Boyz n the Hood - The Book of MorVolume 1: The JThe Book of Mormon Movie, - Volume 1: The Journey - Return to the BlReturn to the Blue Lagoon - Bright Lights, BiBright Lights, Big City - The Blue Bird - The Blue ButterfThe Blue Butterfly - Blade Runner - Bloodsport - The Blues BrothThe Blues Brothers - Blow Out - De battre mon cDe battre mon cœur s'est arrêté - The BroadwayThe Broadway Melody - Boom Town - Bill & Ted's BogBill & Ted's Bogus Journey - The Birth of a NThe Birth of a Nation - The Ballad of CaThe Ballad of Cable Hogue - The Blood of HeThe Blood of Heroes - The Blood of MyThe Blood of My Brother: A Story of Death in Iraq - Boomerang - The Bridge on tThe Bridge on the River Kwai - Born on the FouBorn on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - 🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - + + + The Best YearsThe Best Years of Our Lives + The Ballad of GrThe Ballad of Gregorio Cortez + My Big Fat IndeMy Big Fat Independent Movie + Battle for the PlBattle for the Planet of the Apes + Big Things + Bogus + Beverly Hills CoBeverly Hills Cop + Beverly Hills CoBeverly Hills Cop II + Beverly Hills CoBeverly Hills Cop III + The Black Hole + The Big Parade + Boyz n the Hood + The Book of MorVolume 1: The JThe Book of Mormon Movie, + Volume 1: The Journey + Return to the BlReturn to the Blue Lagoon + Bright Lights, BiBright Lights, Big City + The Blue Bird + The Blue ButterfThe Blue Butterfly + Blade Runner + Bloodsport + The Blues BrothThe Blues Brothers + Blow Out + De battre mon cDe battre mon cœur s'est arrêté + The BroadwayThe Broadway Melody + Boom Town + Bill & Ted's BogBill & Ted's Bogus Journey + The Birth of a NThe Birth of a Nation + The Ballad of CaThe Ballad of Cable Hogue + The Blood of HeThe Blood of Heroes + The Blood of MyThe Blood of My Brother: A Story of Death in Iraq + Boomerang + The Bridge on tThe Bridge on the River Kwai + Born on the FouBorn on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + 🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - - - - …rs of Our LivesThe Best Years of Our Lives - …regorio CortezThe Ballad of Gregorio Cortez - …pendent MovieMy Big Fat Independent Movie - …et of the ApesBattle for the Planet of the Apes - Big Things - Bogus - …verly Hills CopBeverly Hills Cop - …rly Hills Cop IIBeverly Hills Cop II - …rly Hills Cop IIIBeverly Hills Cop III - The Black Hole - The Big Parade - Boyz n the Hood - …ormon Movie,…1: The JourneyThe Book of Mormon Movie, - Volume 1: The Journey - …e Blue LagoonReturn to the Blue Lagoon - …ights, Big CityBright Lights, Big City - The Blue Bird - …Blue ButterflyThe Blue Butterfly - Blade Runner - Bloodsport - …Blues BrothersThe Blues Brothers - Blow Out - …ur s'est arrêtéDe battre mon cœur s'est arrêté - …adway MelodyThe Broadway Melody - Boom Town - …ogus JourneyBill & Ted's Bogus Journey - …rth of a NationThe Birth of a Nation - …f Cable HogueThe Ballad of Cable Hogue - …lood of HeroesThe Blood of Heroes - …f Death in IraqThe Blood of My Brother: A Story of Death in Iraq - Boomerang - …the River KwaiThe Bridge on the River Kwai - …Fourth of JulyBorn on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - …👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - ….👨🏻.👧🏼.👦🏽.🧒🏿🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - + + + …rs of Our LivesThe Best Years of Our Lives + …regorio CortezThe Ballad of Gregorio Cortez + …pendent MovieMy Big Fat Independent Movie + …et of the ApesBattle for the Planet of the Apes + Big Things + Bogus + …verly Hills CopBeverly Hills Cop + …rly Hills Cop IIBeverly Hills Cop II + …rly Hills Cop IIIBeverly Hills Cop III + The Black Hole + The Big Parade + Boyz n the Hood + …ormon Movie,…1: The JourneyThe Book of Mormon Movie, + Volume 1: The Journey + …e Blue LagoonReturn to the Blue Lagoon + …ights, Big CityBright Lights, Big City + The Blue Bird + …Blue ButterflyThe Blue Butterfly + Blade Runner + Bloodsport + …Blues BrothersThe Blues Brothers + Blow Out + …ur s'est arrêtéDe battre mon cœur s'est arrêté + …adway MelodyThe Broadway Melody + Boom Town + …ogus JourneyBill & Ted's Bogus Journey + …rth of a NationThe Birth of a Nation + …f Cable HogueThe Ballad of Cable Hogue + …lood of HeroesThe Blood of Heroes + …f Death in IraqThe Blood of My Brother: A Story of Death in Iraq + Boomerang + …the River KwaiThe Bridge on the River Kwai + …Fourth of JulyBorn on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + …👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + ….👨🏻.👧🏼.👦🏽.🧒🏿🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - + - - The Be…ur LivesThe Best Years of Our Lives - The Ba…CortezThe Ballad of Gregorio Cortez - My Big…t MovieMy Big Fat Independent Movie - Battle f…e ApesBattle for the Planet of the Apes - Big Things - Bogus - Beverly…ills CopBeverly Hills Cop - Beverly…Cop IIBeverly Hills Cop II - Beverly…Cop IIIBeverly Hills Cop III - The Black Hole - The Big Parade - Boyz n the Hood - The Bo…Movie,Volum…JourneyThe Book of Mormon Movie, - Volume 1: The Journey - Return…LagoonReturn to the Blue Lagoon - Bright…Big CityBright Lights, Big City - The Blue Bird - The Bl…utterflyThe Blue Butterfly - Blade Runner - Bloodsport - The Bl…rothersThe Blues Brothers - Blow Out - De batt…t arrêtéDe battre mon cœur s'est arrêté - The Br…MelodyThe Broadway Melody - Boom Town - Bill & T…JourneyBill & Ted's Bogus Journey - The Bir…NationThe Birth of a Nation - The Ba…HogueThe Ballad of Cable Hogue - The Bl…f HeroesThe Blood of Heroes - The Bl…h in IraqThe Blood of My Brother: A Story of Death in Iraq - Boomerang - The Bri…er KwaiThe Bridge on the River Kwai - Born o…of JulyBorn on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - 👁️‍🗨️👩‍❤️‍💋‍👩…👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - 🧑🏾.👨🏻.….👦🏽.🧒🏿🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - + The Be…ur LivesThe Best Years of Our Lives + The Ba…CortezThe Ballad of Gregorio Cortez + My Big…t MovieMy Big Fat Independent Movie + Battle f…e ApesBattle for the Planet of the Apes + Big Things + Bogus + Beverly…ills CopBeverly Hills Cop + Beverly…Cop IIBeverly Hills Cop II + Beverly…Cop IIIBeverly Hills Cop III + The Black Hole + The Big Parade + Boyz n the Hood + The Bo…Movie,Volum…JourneyThe Book of Mormon Movie, + Volume 1: The Journey + Return…LagoonReturn to the Blue Lagoon + Bright…Big CityBright Lights, Big City + The Blue Bird + The Bl…utterflyThe Blue Butterfly + Blade Runner + Bloodsport + The Bl…rothersThe Blues Brothers + Blow Out + De batt…t arrêtéDe battre mon cœur s'est arrêté + The Br…MelodyThe Broadway Melody + Boom Town + Bill & T…JourneyBill & Ted's Bogus Journey + The Bir…NationThe Birth of a Nation + The Ba…HogueThe Ballad of Cable Hogue + The Bl…f HeroesThe Blood of Heroes + The Bl…h in IraqThe Blood of My Brother: A Story of Death in Iraq + Boomerang + The Bri…er KwaiThe Bridge on the River Kwai + Born o…of JulyBorn on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + 👁️‍🗨️👩‍❤️‍💋‍👩…👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + 🧑🏾.👨🏻.….👦🏽.🧒🏿🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - - - - The Best Year…The Best Years of Our Lives - The Ballad of…The Ballad of Gregorio Cortez - My Big Fat Ind…My Big Fat Independent Movie - Battle for the…Battle for the Planet of the Apes - Big Things - Bogus - Beverly Hills C…Beverly Hills Cop - Beverly Hills C…Beverly Hills Cop II - Beverly Hills C…Beverly Hills Cop III - The Black Hole - The Big Parade - Boyz n the Hood - The Book of M…Volume 1: The…The Book of Mormon Movie, - Volume 1: The Journey - Return to the…Return to the Blue Lagoon - Bright Lights,…Bright Lights, Big City - The Blue Bird - The Blue Butte…The Blue Butterfly - Blade Runner - Bloodsport - The Blues Brot…The Blues Brothers - Blow Out - De battre mon…De battre mon cœur s'est arrêté - The Broadway…The Broadway Melody - Boom Town - Bill & Ted's Bo…Bill & Ted's Bogus Journey - The Birth of a…The Birth of a Nation - The Ballad of…The Ballad of Cable Hogue - The Blood of H…The Blood of Heroes - The Blood of…The Blood of My Brother: A Story of Death in Iraq - Boomerang - The Bridge on…The Bridge on the River Kwai - Born on the Fo…Born on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️…👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - 🧑🏾.👨🏻.👧🏼.👦🏽.…🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - + + + The Best Year…The Best Years of Our Lives + The Ballad of…The Ballad of Gregorio Cortez + My Big Fat Ind…My Big Fat Independent Movie + Battle for the…Battle for the Planet of the Apes + Big Things + Bogus + Beverly Hills C…Beverly Hills Cop + Beverly Hills C…Beverly Hills Cop II + Beverly Hills C…Beverly Hills Cop III + The Black Hole + The Big Parade + Boyz n the Hood + The Book of M…Volume 1: The…The Book of Mormon Movie, + Volume 1: The Journey + Return to the…Return to the Blue Lagoon + Bright Lights,…Bright Lights, Big City + The Blue Bird + The Blue Butte…The Blue Butterfly + Blade Runner + Bloodsport + The Blues Brot…The Blues Brothers + Blow Out + De battre mon…De battre mon cœur s'est arrêté + The Broadway…The Broadway Melody + Boom Town + Bill & Ted's Bo…Bill & Ted's Bogus Journey + The Birth of a…The Birth of a Nation + The Ballad of…The Ballad of Cable Hogue + The Blood of H…The Blood of Heroes + The Blood of…The Blood of My Brother: A Story of Death in Iraq + Boomerang + The Bridge on…The Bridge on the River Kwai + Born on the Fo…Born on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️…👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + 🧑🏾.👨🏻.👧🏼.👦🏽.…🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - - - - The Best Yea…The Best Years of Our Lives - The Ballad o…The Ballad of Gregorio Cortez - My Big Fat I…My Big Fat Independent Movie - Battle for t…Battle for the Planet of the Apes - Big Things - Bogus - Beverly Hill…Beverly Hills Cop - Beverly Hill…Beverly Hills Cop II - Beverly Hill…Beverly Hills Cop III - The Black Ho…The Black Hole - The Big Para…The Big Parade - Boyz n the H…Boyz n the Hood - The Book of…Volume 1: Th…The Book of Mormon Movie, - Volume 1: The Journey - Return to th…Return to the Blue Lagoon - Bright Light…Bright Lights, Big City - The Blue Bird - The Blue But…The Blue Butterfly - Blade Runner - Bloodsport - The Blues Br…The Blues Brothers - Blow Out - De battre mo…De battre mon cœur s'est arrêté - The Broadway…The Broadway Melody - Boom Town - Bill & Ted's…Bill & Ted's Bogus Journey - The Birth of…The Birth of a Nation - The Ballad o…The Ballad of Cable Hogue - The Blood of…The Blood of Heroes - The Blood of…The Blood of My Brother: A Story of Death in Iraq - Boomerang - The Bridge o…The Bridge on the River Kwai - Born on the…Born on the Fourth of July - Basquiat - Black Rain - Bottle Rocket - 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩…👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 - 🧑🏾.👨🏻.👧🏼.👦🏽.…🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - + + + The Best Yea…The Best Years of Our Lives + The Ballad o…The Ballad of Gregorio Cortez + My Big Fat I…My Big Fat Independent Movie + Battle for t…Battle for the Planet of the Apes + Big Things + Bogus + Beverly Hill…Beverly Hills Cop + Beverly Hill…Beverly Hills Cop II + Beverly Hill…Beverly Hills Cop III + The Black Ho…The Black Hole + The Big Para…The Big Parade + Boyz n the H…Boyz n the Hood + The Book of…Volume 1: Th…The Book of Mormon Movie, + Volume 1: The Journey + Return to th…Return to the Blue Lagoon + Bright Light…Bright Lights, Big City + The Blue Bird + The Blue But…The Blue Butterfly + Blade Runner + Bloodsport + The Blues Br…The Blues Brothers + Blow Out + De battre mo…De battre mon cœur s'est arrêté + The Broadway…The Broadway Melody + Boom Town + Bill & Ted's…Bill & Ted's Bogus Journey + The Birth of…The Birth of a Nation + The Ballad o…The Ballad of Cable Hogue + The Blood of…The Blood of Heroes + The Blood of…The Blood of My Brother: A Story of Death in Iraq + Boomerang + The Bridge o…The Bridge on the River Kwai + Born on the…Born on the Fourth of July + Basquiat + Black Rain + Bottle Rocket + 👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩…👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩 + 🧑🏾.👨🏻.👧🏼.👦🏽.…🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿 - - - - - - - - - - - - - - - - - - - + + + + + + + \ No newline at end of file diff --git a/test/output/tipDotFacets.svg b/test/output/tipDotFacets.svg index 2834b28fa6..da6e98dfea 100644 --- a/test/output/tipDotFacets.svg +++ b/test/output/tipDotFacets.svg @@ -13,11346 +13,11202 @@ white-space: pre; } - - - - 1950 - + + + 1950 - - - 1960 - + + 1960 - - - 1970 - + + 1970 - - - 1980 - + + 1980 - - - 1990 - + + 1990 - - - 2000 - + + 2000 decade of birth - + - - female - + female - - male - + male sex - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - - - - - + + + + + + - - - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 - + + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 - - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 - + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 - - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 - + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 - - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 - + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 - - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 - + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 - - - 1.4 - 1.6 - 1.8 - 2.0 - 2.2 - + + 1.4 + 1.6 + 1.8 + 2.0 + 2.2 ↑ height - - - - - - - + + + + + - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - - - - - - + + + + - - - - - - - + + + + + - - - - - - + + + + - - - - 50 - 100 - 150 - + + + 50 + 100 + 150 - - - 50 - 100 - 150 - + + 50 + 100 + 150 weight → - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/trafficHorizon.html b/test/output/trafficHorizon.html index e77396629a..bb11d9b198 100644 --- a/test/output/trafficHorizon.html +++ b/test/output/trafficHorizon.html @@ -50,2143 +50,1683 @@ white-space: pre; } - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - Mon 04 - 12 PM - Tue 05 - 12 PM - Wed 06 - 12 PM - Thu 07 - 12 PM - Fri 08 - 12 PM - Sat 09 - 12 PM - + + + Mon 04 + 12 PM + Tue 05 + 12 PM + Wed 06 + 12 PM + Thu 07 + 12 PM + Fri 08 + 12 PM + Sat 09 + 12 PM - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - Von der Heydt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - Kirschheck + + + + + + - - - Saarbrücken-Neuhaus + + + + + + - - - Riegelsberg + + + + + + - - - Holz + + + + + + - - - Göttelborn + + + + + + - - - Illingen + + + + + + - - - AS Eppelborn + + + + + + - - - Hasborn + + + + + + - - - Kastel + + + + + + - - - Otzenhausen + + + + + + - - - Bierfeld + + + + + + - - - Nonnweiler + + + + + + - - - Hetzerath + + + + + + - - - Laufeld + + + + + + - - - Nettersheim + + + + + + - - - Euskirchen/Bliesheim + + + + + + - - - Hürth + + + + + + - - - Köln-Nord + + + + + + - - - Schloss Burg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - Hagen-Vorhalle + + + + + + - - - Hengsen + + + + + + - - - Unna + + + + + + - - - Ascheberg + + + + + + - - - Ladbergen + + + + + + - - - Lotte + + + + + + - - - HB-Silbersee + + + + + + - - - HB-Weserbrücke + + + + + + - - - HB-Mahndorfer See + + + + + + - - - Groß Ippener + + + + + + - - - Uphusen + + + + + + - - - Bockel + + + + + + - - - Dibbersen + + + + + + - - - Glüsingen + + + + + + - - - Barsbüttel + + + + + + - - - Bad Schwartau + + + + + + - - - Oldenburg (Holstein) + + + + + + - - - Neustadt i. H.-Süd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Von der Heydt + + + Kirschheck + + + Saarbrücken-Neuhaus + + + Riegelsberg + + + Holz + + + Göttelborn + + + Illingen + + + AS Eppelborn + + + Hasborn + + + Kastel + + + Otzenhausen + + + Bierfeld + + + Nonnweiler + + + Hetzerath + + + Laufeld + + + Nettersheim + + + Euskirchen/Bliesheim + + + Hürth + + + Köln-Nord + + + Schloss Burg + + + Hagen-Vorhalle + + + Hengsen + + + Unna + + + Ascheberg + + + Ladbergen + + + Lotte + + + HB-Silbersee + + + HB-Weserbrücke + + + HB-Mahndorfer See + + + Groß Ippener + + + Uphusen + + + Bockel + + + Dibbersen + + + Glüsingen + + + Barsbüttel + + + Bad Schwartau + + + Oldenburg (Holstein) + + + Neustadt i. H.-Süd + \ No newline at end of file diff --git a/test/output/usPopulationStateAgeGrouped.svg b/test/output/usPopulationStateAgeGrouped.svg index 54e4c09dc9..79e337cfa7 100644 --- a/test/output/usPopulationStateAgeGrouped.svg +++ b/test/output/usPopulationStateAgeGrouped.svg @@ -13,202 +13,162 @@ white-space: pre; } - - - - - + + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - + - - CA - + CA - - TX - + TX - - NY - + NY - - FL - + FL - - PA - + PA - - IL - + IL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - 0.0M - 0.5M - 1.0M - 1.5M - 2.0M - 2.5M - 3.0M - 3.5M - 4.0M - 4.5M - 5.0M - 5.5M - + + + 0.0M + 0.5M + 1.0M + 1.5M + 2.0M + 2.5M + 3.0M + 3.5M + 4.0M + 4.5M + 5.0M + 5.5M @@ -216,114 +176,90 @@ - - <10 - 10-19 - 20-29 - 30-39 - 40-49 - 50-59 - 60-69 - 70-79 - ≥80 - + <10 + 10-19 + 20-29 + 30-39 + 40-49 + 50-59 + 60-69 + 70-79 + ≥80 - - <10 - 10-19 - 20-29 - 30-39 - 40-49 - 50-59 - 60-69 - 70-79 - ≥80 - + <10 + 10-19 + 20-29 + 30-39 + 40-49 + 50-59 + 60-69 + 70-79 + ≥80 - - <10 - 10-19 - 20-29 - 30-39 - 40-49 - 50-59 - 60-69 - 70-79 - ≥80 - + <10 + 10-19 + 20-29 + 30-39 + 40-49 + 50-59 + 60-69 + 70-79 + ≥80 - - <10 - 10-19 - 20-29 - 30-39 - 40-49 - 50-59 - 60-69 - 70-79 - ≥80 - + <10 + 10-19 + 20-29 + 30-39 + 40-49 + 50-59 + 60-69 + 70-79 + ≥80 - - <10 - 10-19 - 20-29 - 30-39 - 40-49 - 50-59 - 60-69 - 70-79 - ≥80 - + <10 + 10-19 + 20-29 + 30-39 + 40-49 + 50-59 + 60-69 + 70-79 + ≥80 - - <10 - 10-19 - 20-29 - 30-39 - 40-49 - 50-59 - 60-69 - 70-79 - ≥80 - + <10 + 10-19 + 20-29 + 30-39 + 40-49 + 50-59 + 60-69 + 70-79 + ≥80 - - - - - + + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + \ No newline at end of file diff --git a/test/output/walmartsDecades.svg b/test/output/walmartsDecades.svg index 0a5005bb0c..ad0b6ccffb 100644 --- a/test/output/walmartsDecades.svg +++ b/test/output/walmartsDecades.svg @@ -13,112 +13,72 @@ white-space: pre; } - + - - 1960’s - + 1960’s - - 1970’s - + 1970’s - - 1980’s - + 1980’s - - 1990’s - + 1990’s - - 2000’s - + 2000’s - - - - - + + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - - + + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - - + + + - - - - + + - - - - + + - - - - + + - - - - + + \ No newline at end of file From 992ad5463ce8fc70f75463ba13c35990006d599d Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 10:38:48 -0700 Subject: [PATCH 17/56] renderTransform instead of _render --- src/interactions/pointer.js | 2 +- src/mark.js | 3 +-- src/plot.js | 11 ++++++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index b5064c6bd8..a4a0df9057 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -22,7 +22,7 @@ function pointerK(kx, ky, {px, py, maxRadius = 40, channels, ...options} = {}) { i = ii; const I = i == null ? [] : [i]; if (index.fi != null) (I.fx = index.fx), (I.fy = index.fy), (I.fi = index.fi); - const r = mark._render(I, scales, values, dimensions, context); + const r = mark.render(I, scales, values, dimensions, context); if (g) { const p = g.parentNode; if (p !== svg) { diff --git a/src/mark.js b/src/mark.js index 81f7a88054..873ee2704d 100644 --- a/src/mark.js +++ b/src/mark.js @@ -81,8 +81,7 @@ export class Mark { } if (render != null) { if (typeof render !== "function") throw new TypeError(`invalid render transform: ${render}`); - this._render = this.render; - this.render = render; + this.renderTransform = render; } } initialize(facets, facetChannels, plotOptions) { diff --git a/src/plot.js b/src/plot.js index d32dfebfb1..e662ee61f9 100644 --- a/src/plot.js +++ b/src/plot.js @@ -255,8 +255,9 @@ export function plot(options = {}) { index = mark.filter(index, channels, values); if (index.length === 0) continue; } - const node = mark.render(index, scales, values, superdimensions, context); - if (node != null) svg.appendChild(node); + const node = render(mark, index, scales, values, superdimensions, context); + if (node == null) continue; + svg.appendChild(node); } // Render a faceted mark. @@ -272,7 +273,7 @@ export function plot(options = {}) { if (index.length === 0) continue; if (faceted) (index.fx = f.x), (index.fy = f.y), (index.fi = f.i); } - const node = mark.render(index, scales, values, subdimensions, context); + const node = render(mark, index, scales, values, subdimensions, context); if (node == null) continue; // Lazily construct the shared group (to drop empty marks). (g ??= select(svg).append("g")).append(() => node).datum(f); @@ -352,6 +353,10 @@ class Render extends Mark { render() {} } +function render(mark, ...args) { + return (mark.renderTransform ?? mark.render).apply(mark, args); +} + // Note: mutates channel.value to apply the scale transform, if any. function applyScaleTransforms(channels, options) { for (const name in channels) applyScaleTransform(channels[name], options); From 57bd084f739c639a8cebdd154e49c8986b6471b1 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 11:27:23 -0700 Subject: [PATCH 18/56] only one pointer across facets --- src/interactions/pointer.js | 45 ++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index a4a0df9057..fc489af990 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -11,22 +11,42 @@ function pointerK(kx, ky, {px, py, maxRadius = 40, channels, ...options} = {}) { render(index, scales, values, dimensions, context) { const mark = this; const svg = context.ownerSVGElement; + const faceted = index.fi != null; + const facetState = faceted ? getFacetState(mark, svg) : null; const {x: X0, y: Y0, x1: X1, y1: Y1, x2: X2, y2: Y2, px: X = X0, py: Y = Y0} = values; const [cx, cy] = applyFrameAnchor(this, dimensions); let sticky = false; let i; // currently focused index let g; // currently rendered mark - function render(ii) { + function render(ii, ri) { + // When faceting, if more than one pointer would be visible, only show + // this one if it is the closest. This is a simple linear scan because + // we don’t expect many facets with simultaneously-visible pointers. + if (faceted) { + if (ii == null) { + facetState.delete(index.fi); + } else { + facetState.set(index.fi, ri); + if (facetState.size > 1) { + for (const [fi, r] of facetState) { + if (fi !== index.fi && r < ri) { + ii = null; + break; + } + } + } + } + } if (i === ii) return; // the tooltip hasn’t moved i = ii; const I = i == null ? [] : [i]; - if (index.fi != null) (I.fx = index.fx), (I.fy = index.fy), (I.fi = index.fi); + if (faceted) (I.fx = index.fx), (I.fy = index.fy), (I.fi = index.fi); const r = mark.render(I, scales, values, dimensions, context); if (g) { - const p = g.parentNode; - if (p !== svg) { + if (faceted) { // when faceting, preserve swapped mark and facet transforms + const p = g.parentNode; const ft = g.getAttribute("transform"); const mt = r.getAttribute("transform"); ft ? r.setAttribute("transform", ft) : r.removeAttribute("transform"); @@ -39,7 +59,7 @@ function pointerK(kx, ky, {px, py, maxRadius = 40, channels, ...options} = {}) { function pointermove(event) { if (sticky || (event.pointerType === "mouse" && event.buttons === 1)) return; // dragging - const [xp, yp] = pointof(event, g.parentNode === svg ? g.parentNode : g); // detect faceting + const [xp, yp] = pointof(event, faceted ? g : g.parentNode); let ii = null; let ri = maxRadius * maxRadius; for (const j of index) { @@ -50,7 +70,7 @@ function pointerK(kx, ky, {px, py, maxRadius = 40, channels, ...options} = {}) { const rj = dx * dx + dy * dy; if (rj <= ri) (ii = j), (ri = rj); } - render(ii); + render(ii, ri); } function pointerdown(event) { @@ -90,3 +110,16 @@ export function pointerX(options) { export function pointerY(options) { return pointerK(0.01, 1, options); } + +const facetStateByMark = new WeakMap(); + +// This isolates facet state per-mark, per-plot. Most of the time a separate +// pointer will be instantiated per mark, but it’s possible to reuse the same +// pointer instance with multiple marks so we protect against it. +function getFacetState(mark, svg) { + let stateBySvg = facetStateByMark.get(mark); + if (!stateBySvg) facetStateByMark.set(mark, (stateBySvg = new WeakMap())); + let state = stateBySvg.get(svg); + if (!state) stateBySvg.set(svg, (state = new Map())); + return state; +} From 72a0d4092db74c220fc794a5b2e0888caa61137c Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 11:32:20 -0700 Subject: [PATCH 19/56] suppress other facets when sticky --- src/interactions/pointer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index fc489af990..96b9afdac0 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -77,7 +77,7 @@ function pointerK(kx, ky, {px, py, maxRadius = 40, channels, ...options} = {}) { if (event.pointerType !== "mouse") return; if (sticky && g.contains(event.target)) return; // stay sticky if (sticky) (sticky = false), render(null); - else if (i != null) sticky = true; + else if (i != null) (sticky = true), facetState?.set(index.fi, -1); // suppress other facets } function pointerleave(event) { From da1df9178b9eec77f38cedd8889496f75637529b Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 12:38:54 -0700 Subject: [PATCH 20/56] prevent duplicate ARIA when faceting --- src/interactions/pointer.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index 96b9afdac0..da0ecb5286 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -51,6 +51,10 @@ function pointerK(kx, ky, {px, py, maxRadius = 40, channels, ...options} = {}) { const mt = r.getAttribute("transform"); ft ? r.setAttribute("transform", ft) : r.removeAttribute("transform"); mt ? p.setAttribute("transform", mt) : p.removeAttribute("transform"); + // also remove ARIA attributes since these are promoted to the parent + r.removeAttribute("aria-label"); + r.removeAttribute("aria-description"); + r.removeAttribute("aria-hidden"); } g.replaceWith(r); } From 8174cfa3116031f427ca08c4168d72e9dd82010c Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 13:36:29 -0700 Subject: [PATCH 21/56] isolate state per-pointer --- src/interactions/pointer.js | 37 +++++++++++++++++-------------------- src/marks/crosshair.js | 15 +++++++++------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index da0ecb5286..1770a37cec 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -5,17 +5,24 @@ function pointerK(kx, ky, {px, py, maxRadius = 40, channels, ...options} = {}) { maxRadius = +maxRadius; if (px != null) channels = {...channels, px: {value: px, scale: "x"}}; if (py != null) channels = {...channels, py: {value: py, scale: "y"}}; + const stateBySvg = new WeakMap(); return { channels, ...options, render(index, scales, values, dimensions, context) { const mark = this; const svg = context.ownerSVGElement; + + // Isolate state per-pointer, per-plot; if the pointer is reused by + // multiple marks, they will share the same state (e.g., sticky modality). + let state = stateBySvg.get(svg); + if (!state) stateBySvg.set(svg, (state = {sticky: false, roots: [], renders: []})); + let renderIndex = state.renders.push(render) - 1; + const faceted = index.fi != null; - const facetState = faceted ? getFacetState(mark, svg) : null; + const facetState = faceted ? (state.facetState ??= new Map()) : null; const {x: X0, y: Y0, x1: X1, y1: Y1, x2: X2, y2: Y2, px: X = X0, py: Y = Y0} = values; const [cx, cy] = applyFrameAnchor(this, dimensions); - let sticky = false; let i; // currently focused index let g; // currently rendered mark @@ -58,11 +65,12 @@ function pointerK(kx, ky, {px, py, maxRadius = 40, channels, ...options} = {}) { } g.replaceWith(r); } + state.roots[renderIndex] = r; return (g = r); } function pointermove(event) { - if (sticky || (event.pointerType === "mouse" && event.buttons === 1)) return; // dragging + if (state.sticky || (event.pointerType === "mouse" && event.buttons === 1)) return; // dragging const [xp, yp] = pointof(event, faceted ? g : g.parentNode); let ii = null; let ri = maxRadius * maxRadius; @@ -79,14 +87,16 @@ function pointerK(kx, ky, {px, py, maxRadius = 40, channels, ...options} = {}) { function pointerdown(event) { if (event.pointerType !== "mouse") return; - if (sticky && g.contains(event.target)) return; // stay sticky - if (sticky) (sticky = false), render(null); - else if (i != null) (sticky = true), facetState?.set(index.fi, -1); // suppress other facets + if (i == null) return; // not pointing + if (state.sticky && state.roots.some((r) => r?.contains(event.target))) return; // stay sticky + if (state.sticky) (state.sticky = false), state.renders.forEach((r) => r(null)); // clear all pointers + else state.sticky = true; + event.stopImmediatePropagation(); // suppress other pointers } function pointerleave(event) { if (event.pointerType !== "mouse") return; - if (!sticky) render(null); + if (!state.sticky) render(null); } // We listen to the svg element; listening to the window instead would let @@ -114,16 +124,3 @@ export function pointerX(options) { export function pointerY(options) { return pointerK(0.01, 1, options); } - -const facetStateByMark = new WeakMap(); - -// This isolates facet state per-mark, per-plot. Most of the time a separate -// pointer will be instantiated per mark, but it’s possible to reuse the same -// pointer instance with multiple marks so we protect against it. -function getFacetState(mark, svg) { - let stateBySvg = facetStateByMark.get(mark); - if (!stateBySvg) facetStateByMark.set(mark, (stateBySvg = new WeakMap())); - let state = stateBySvg.get(svg); - if (!state) stateBySvg.set(svg, (state = new Map())); - return state; -} diff --git a/src/marks/crosshair.js b/src/marks/crosshair.js index ce59edcd91..1e4665cad3 100644 --- a/src/marks/crosshair.js +++ b/src/marks/crosshair.js @@ -5,15 +5,17 @@ import {text} from "./text.js"; export function crosshair(data, options = {}) { const {x, y, dx = -9, dy = 9} = options; + const p = pointer({px: x, py: y}); return marks( - ruleX(data, ruleOptions({x, py: y}, options)), - ruleY(data, ruleOptions({px: x, y}, options)), - text(data, textOptions({px: x, y, text: y, dx, frameAnchor: "left", textAnchor: "end"}, options)), - text(data, textOptions({x, py: y, text: x, dy, frameAnchor: "bottom", lineAnchor: "top"}, options)) + ruleX(data, ruleOptions(p, {x}, options)), + ruleY(data, ruleOptions(p, {y}, options)), + text(data, textOptions(p, {y, text: y, dx, frameAnchor: "left", textAnchor: "end"}, options)), + text(data, textOptions(p, {x, text: x, dy, frameAnchor: "bottom", lineAnchor: "top"}, options)) ); } function ruleOptions( + pointer, options, { color = "currentColor", @@ -22,10 +24,11 @@ function ruleOptions( ruleStrokeWidth: strokeWidth } ) { - return pointer({...options, stroke, strokeOpacity, strokeWidth}); + return {...pointer, ...options, stroke, strokeOpacity, strokeWidth}; } function textOptions( + pointer, options, { color = "currentColor", @@ -35,5 +38,5 @@ function textOptions( textStrokeWidth: strokeWidth = 5 } ) { - return pointer({...options, fill, stroke, strokeOpacity, strokeWidth}); + return {...pointer, ...options, fill, stroke, strokeOpacity, strokeWidth}; } From e0ac0e088b54d8bf2bc1f41032b4767555ef3e9e Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 13:47:30 -0700 Subject: [PATCH 22/56] fix crash with one-dimensional tip --- src/marks/tip.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/marks/tip.js b/src/marks/tip.js index eeca3b0529..33bf7a4056 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -5,7 +5,6 @@ import {Mark} from "../mark.js"; import {maybeFrameAnchor, maybeKeyword, maybeTuple, number, string} from "../options.js"; import {applyChannelStyles, applyDirectStyles, applyIndirectStyles} from "../style.js"; import {applyFrameAnchor, applyTransform} from "../style.js"; -import {template} from "../template.js"; import {inferTickFormat} from "./axis.js"; import {applyIndirectTextStyles, cut, defaultWidth, monospaceWidth} from "./text.js"; @@ -66,8 +65,8 @@ export class Tip extends Mark { const {x, y, fx, fy} = scales; const {x: X, y: Y, x1: X1, y1: Y1, x2: X2, y2: Y2, channels: sources} = channels; const [cx, cy] = applyFrameAnchor(this, dimensions); - const tx = X2 ? (i) => (X1[i] + X2[i]) / 2 : X ? (i) => X[i] : cx; - const ty = Y2 ? (i) => (Y1[i] + Y2[i]) / 2 : Y ? (i) => Y[i] : cy; + const tx = X2 ? (i) => (X1[i] + X2[i]) / 2 : X ? (i) => X[i] : () => cx; + const ty = Y2 ? (i) => (Y1[i] + Y2[i]) / 2 : Y ? (i) => Y[i] : () => cy; const {ownerSVGElement: svg, document} = context; const {anchor, monospace, lineHeight, lineWidth} = this; const {marginTop, marginLeft} = dimensions; @@ -91,7 +90,7 @@ export class Tip extends Mark { .data(index) .enter() .append("g") - .attr("transform", template`translate(${tx},${ty})`) + .attr("transform", (i) => `translate(${tx(i)},${ty(i)})`) .call(applyDirectStyles, this) .call(applyChannelStyles, this, channels) .call((g) => g.append("path").attr("filter", "drop-shadow(0 3px 4px rgba(0,0,0,0.2))")) From c01a775e8d1ff9e79e8a9dee248797ebaec0f754 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 13:47:52 -0700 Subject: [PATCH 23/56] if px, default x to null; same for py --- src/interactions/pointer.js | 8 +- src/marks/rule.js | 2 +- test/output/tipRule.svg | 382 ++++++++++++++++++++++++++++++++++++ test/plots/tip.ts | 7 + 4 files changed, 395 insertions(+), 4 deletions(-) create mode 100644 test/output/tipRule.svg diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index 1770a37cec..5da0ba5232 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -1,12 +1,14 @@ import {pointer as pointof} from "d3"; import {applyFrameAnchor} from "../style.js"; -function pointerK(kx, ky, {px, py, maxRadius = 40, channels, ...options} = {}) { +function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = {}) { maxRadius = +maxRadius; - if (px != null) channels = {...channels, px: {value: px, scale: "x"}}; - if (py != null) channels = {...channels, py: {value: py, scale: "y"}}; + if (px != null) (x ??= null), (channels = {...channels, px: {value: px, scale: "x"}}); + if (py != null) (y ??= null), (channels = {...channels, py: {value: py, scale: "y"}}); const stateBySvg = new WeakMap(); return { + x, + y, channels, ...options, render(index, scales, values, dimensions, context) { diff --git a/src/marks/rule.js b/src/marks/rule.js index e47ed93723..3efaf1a34f 100644 --- a/src/marks/rule.js +++ b/src/marks/rule.js @@ -121,7 +121,7 @@ export function ruleY(data, options) { // For marks specified either as [0, x] or [x1, x2], or nothing. function maybeOptionalZero(x, x1, x2) { - if (x === undefined) { + if (x == null) { if (x1 === undefined) { if (x2 !== undefined) return [0, x2]; } else { diff --git a/test/output/tipRule.svg b/test/output/tipRule.svg new file mode 100644 index 0000000000..99b687131f --- /dev/null +++ b/test/output/tipRule.svg @@ -0,0 +1,382 @@ + + + + + + + + + + + + + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 + + + body_mass_g → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 73f2e2972c..048b27f8a1 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -84,3 +84,10 @@ export async function tipLine() { marks: [Plot.lineY(aapl, {x: "Date", y: "Close"}), Plot.tip(aapl, Plot.pointerX({x: "Date", y: "Close"}))] }); } + +export async function tipRule() { + const penguins = await d3.csv("data/penguins.csv", d3.autoType); + return Plot.plot({ + marks: [Plot.ruleX(penguins, {x: "body_mass_g"}), Plot.tip(penguins, Plot.pointerX({x: "body_mass_g"}))] + }); +} From 9282918cb5402f7ef8ea952755db27039b3a5d14 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 13:56:41 -0700 Subject: [PATCH 24/56] tidier crosshair options --- src/marks/crosshair.js | 46 +++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/src/marks/crosshair.js b/src/marks/crosshair.js index 1e4665cad3..0b6bbc4514 100644 --- a/src/marks/crosshair.js +++ b/src/marks/crosshair.js @@ -7,36 +7,28 @@ export function crosshair(data, options = {}) { const {x, y, dx = -9, dy = 9} = options; const p = pointer({px: x, py: y}); return marks( - ruleX(data, ruleOptions(p, {x}, options)), - ruleY(data, ruleOptions(p, {y}, options)), - text(data, textOptions(p, {y, text: y, dx, frameAnchor: "left", textAnchor: "end"}, options)), - text(data, textOptions(p, {x, text: x, dy, frameAnchor: "bottom", lineAnchor: "top"}, options)) + ruleX(data, {...p, x, ...ruleOptions(options)}), + ruleY(data, {...p, y, ...ruleOptions(options)}), + text(data, {...p, y, text: y, dx, frameAnchor: "left", textAnchor: "end", ...textOptions(options)}), + text(data, {...p, x, text: x, dy, frameAnchor: "bottom", lineAnchor: "top", ...textOptions(options)}) ); } -function ruleOptions( - pointer, - options, - { - color = "currentColor", - ruleStroke: stroke = color, - ruleStrokeOpacity: strokeOpacity = 0.2, - ruleStrokeWidth: strokeWidth - } -) { - return {...pointer, ...options, stroke, strokeOpacity, strokeWidth}; +function ruleOptions({ + color = "currentColor", + ruleStroke: stroke = color, + ruleStrokeOpacity: strokeOpacity = 0.2, + ruleStrokeWidth: strokeWidth +}) { + return {stroke, strokeOpacity, strokeWidth}; } -function textOptions( - pointer, - options, - { - color = "currentColor", - textFill: fill = color, - textStroke: stroke = "white", - textStrokeOpacity: strokeOpacity, - textStrokeWidth: strokeWidth = 5 - } -) { - return {...pointer, ...options, fill, stroke, strokeOpacity, strokeWidth}; +function textOptions({ + color = "currentColor", + textFill: fill = color, + textStroke: stroke = "white", + textStrokeOpacity: strokeOpacity, + textStrokeWidth: strokeWidth = 5 +}) { + return {fill, stroke, strokeOpacity, strokeWidth}; } From 0ede4921eebf1c3810f633381bad59871c4807f7 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 14:25:57 -0700 Subject: [PATCH 25/56] use channel label if available --- src/marks/tip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/marks/tip.js b/src/marks/tip.js index 33bf7a4056..c4a2fe0b8c 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -110,7 +110,7 @@ export class Tip extends Mark { const value2 = channel2?.value[i]; renderLine( that, - scales[channel.scale]?.label ?? key, + scales[channel.scale]?.label ?? channel.label ?? key, channel2 ? channel2.hint?.length ? `${formatDefault(value2 - value1)}` From 42a6d7865cc9ac05a7950b863230d3e5da73c49c Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 14:28:35 -0700 Subject: [PATCH 26/56] only separating space if named --- src/marks/tip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/marks/tip.js b/src/marks/tip.js index c4a2fe0b8c..70dab4d800 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -135,7 +135,7 @@ export class Tip extends Mark { value = ""; title = value.trim(); } else { - value = ` ${value}\u200b`; // zwsp for double-click + value = `${name ? " " : ""}${value}\u200b`; // zwsp for double-click const [k] = cut(value, w - widthof(name), widthof, ee); if (k >= 0) { // value is truncated From 57599457b668bd3751239b57ecba009d20378ab1 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 19:36:39 -0700 Subject: [PATCH 27/56] crosshair initializer fixes --- src/index.js | 2 +- src/interactions/pointer.js | 8 +- src/marks/crosshair.d.ts | 6 + src/marks/crosshair.js | 91 +++- test/output/crosshairDodge.svg | 379 ++++++++++++++ .../{tipCrosshair.svg => crosshairDot.svg} | 2 +- test/output/crosshairDotFacet.svg | 464 ++++++++++++++++++ test/output/crosshairHexbin.svg | 309 ++++++++++++ test/plots/crosshair.ts | 43 ++ test/plots/index.ts | 3 +- test/plots/tip.ts | 10 - 11 files changed, 1283 insertions(+), 34 deletions(-) create mode 100644 test/output/crosshairDodge.svg rename test/output/{tipCrosshair.svg => crosshairDot.svg} (100%) create mode 100644 test/output/crosshairDotFacet.svg create mode 100644 test/output/crosshairHexbin.svg create mode 100644 test/plots/crosshair.ts diff --git a/src/index.js b/src/index.js index 8d84db05cb..fec7e243ec 100644 --- a/src/index.js +++ b/src/index.js @@ -8,7 +8,7 @@ export {BarX, BarY, barX, barY} from "./marks/bar.js"; export {boxX, boxY} from "./marks/box.js"; export {Cell, cell, cellX, cellY} from "./marks/cell.js"; export {Contour, contour} from "./marks/contour.js"; -export {crosshair} from "./marks/crosshair.js"; +export {crosshair, crosshairX, crosshairY} from "./marks/crosshair.js"; export {delaunayLink, delaunayMesh, hull, voronoi, voronoiMesh} from "./marks/delaunay.js"; export {Density, density} from "./marks/density.js"; export {Dot, dot, dotX, dotY, circle, hexagon} from "./marks/dot.js"; diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index 5da0ba5232..32a014bb9f 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -73,7 +73,13 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = function pointermove(event) { if (state.sticky || (event.pointerType === "mouse" && event.buttons === 1)) return; // dragging - const [xp, yp] = pointof(event, faceted ? g : g.parentNode); + let [xp, yp] = pointof(event); + // TODO use facetTranslate instead? + if (faceted) { + const matrix = g.transform.baseVal[0].matrix; + xp -= matrix.e; + yp -= matrix.f; + } let ii = null; let ri = maxRadius * maxRadius; for (const j of index) { diff --git a/src/marks/crosshair.d.ts b/src/marks/crosshair.d.ts index bad5ec02e5..c0860584e5 100644 --- a/src/marks/crosshair.d.ts +++ b/src/marks/crosshair.d.ts @@ -18,3 +18,9 @@ export interface CrosshairOptions extends MarkOptions { /** TODO */ export function crosshair(data?: Data, options?: CrosshairOptions): CompoundMark; + +/** TODO */ +export function crosshairX(data?: Data, options?: Omit): CompoundMark; + +/** TODO */ +export function crosshairY(data?: Data, options?: Omit): CompoundMark; diff --git a/src/marks/crosshair.js b/src/marks/crosshair.js index 0b6bbc4514..69067614de 100644 --- a/src/marks/crosshair.js +++ b/src/marks/crosshair.js @@ -1,4 +1,4 @@ -import {pointer} from "../interactions/pointer.js"; +import {pointer, pointerX, pointerY} from "../interactions/pointer.js"; import {marks} from "../mark.js"; import {ruleX, ruleY} from "./rule.js"; import {text} from "./text.js"; @@ -7,28 +7,79 @@ export function crosshair(data, options = {}) { const {x, y, dx = -9, dy = 9} = options; const p = pointer({px: x, py: y}); return marks( - ruleX(data, {...p, x, ...ruleOptions(options)}), - ruleY(data, {...p, y, ...ruleOptions(options)}), - text(data, {...p, y, text: y, dx, frameAnchor: "left", textAnchor: "end", ...textOptions(options)}), - text(data, {...p, x, text: x, dy, frameAnchor: "bottom", lineAnchor: "top", ...textOptions(options)}) + ruleX(data, ruleOptions(p, options, x, null)), + ruleY(data, ruleOptions(p, options, null, y)), + text(data, textOptions({...p, text: x, dy, frameAnchor: "bottom", lineAnchor: "top"}, options, x, null)), + text(data, textOptions({...p, text: y, dx, frameAnchor: "left", textAnchor: "end"}, options, null, y)) ); } -function ruleOptions({ - color = "currentColor", - ruleStroke: stroke = color, - ruleStrokeOpacity: strokeOpacity = 0.2, - ruleStrokeWidth: strokeWidth -}) { - return {stroke, strokeOpacity, strokeWidth}; +export function crosshairX(data, options = {}) { + const {x, dy = 9} = options; + const p = pointerX({px: x}); + return marks( + ruleX(data, ruleOptions(p, options, x, null)), + text(data, textOptions({...p, text: x, dy, frameAnchor: "bottom", lineAnchor: "top"}, options, x, null)) + ); +} + +export function crosshairY(data, options = {}) { + const {y, dx = -9} = options; + const p = pointerY({py: y}); + return marks( + ruleY(data, ruleOptions(p, options, null, y)), + text(data, textOptions({...p, text: y, dx, frameAnchor: "left", textAnchor: "end"}, options, null, y)) + ); +} + +// TODO pass all options? +function markOptions( + {channels: pointerChannels, ...pointerOptions}, + {facet, facetAnchor, fx, fy, channels, transform, initializer}, + x, + y +) { + return { + ...pointerOptions, + facet, + facetAnchor, + fx, + fy, + x, + y, + channels: {...pointerChannels, ...channels}, + transform, + initializer: pxpy(initializer, x, y) + }; +} + +// Wrap the initializer, if any, mapping px and py to x and y temporarily (e.g., +// for hexbin) then mapping back to px and py for rendering. +function pxpy(i, ox, oy) { + if (i == null) return i; + return function (data, facets, {x: x1, y: y1, px, py, ...c1}, ...args) { + const {channels: {x, y, ...c} = {}, ...r} = i.call(this, data, facets, {...c1, x: px, y: py}, ...args); + return {channels: {...c, px: x, py: y, ...(ox !== null && {x}), ...(oy !== null && {y})}, ...r}; + }; +} + +function ruleOptions(pointerOptions, options, x, y) { + const { + color = "currentColor", + ruleStroke: stroke = color, + ruleStrokeOpacity: strokeOpacity = 0.2, + ruleStrokeWidth: strokeWidth + } = options; + return {...markOptions(pointerOptions, options, x, y), stroke, strokeOpacity, strokeWidth}; } -function textOptions({ - color = "currentColor", - textFill: fill = color, - textStroke: stroke = "white", - textStrokeOpacity: strokeOpacity, - textStrokeWidth: strokeWidth = 5 -}) { - return {fill, stroke, strokeOpacity, strokeWidth}; +function textOptions(pointerOptions, options, x, y) { + const { + color = "currentColor", + textFill: fill = color, + textStroke: stroke = "white", + textStrokeOpacity: strokeOpacity, + textStrokeWidth: strokeWidth = 5 + } = options; + return {...markOptions(pointerOptions, options, x, y), fill, stroke, strokeOpacity, strokeWidth}; } diff --git a/test/output/crosshairDodge.svg b/test/output/crosshairDodge.svg new file mode 100644 index 0000000000..c238fbb923 --- /dev/null +++ b/test/output/crosshairDodge.svg @@ -0,0 +1,379 @@ + + + + + + + + + + + 35 + 40 + 45 + 50 + 55 + + + culmen_length_mm → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/tipCrosshair.svg b/test/output/crosshairDot.svg similarity index 100% rename from test/output/tipCrosshair.svg rename to test/output/crosshairDot.svg index a977ec5815..aa1b7aca4b 100644 --- a/test/output/tipCrosshair.svg +++ b/test/output/crosshairDot.svg @@ -399,6 +399,6 @@ - + \ No newline at end of file diff --git a/test/output/crosshairDotFacet.svg b/test/output/crosshairDotFacet.svg new file mode 100644 index 0000000000..c78f6dee37 --- /dev/null +++ b/test/output/crosshairDotFacet.svg @@ -0,0 +1,464 @@ + + + + + Adelie + + + Chinstrap + + + Gentoo + + + + species + + + + + + + + + + + + + + + + + + + + + + + + 14 + 16 + 18 + 20 + + + 14 + 16 + 18 + 20 + + + 14 + 16 + 18 + 20 + + + + ↑ culmen_depth_mm + + + + + + + + + + + + + 35 + 40 + 45 + 50 + 55 + + + + culmen_length_mm → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/crosshairHexbin.svg b/test/output/crosshairHexbin.svg new file mode 100644 index 0000000000..d545460ce1 --- /dev/null +++ b/test/output/crosshairHexbin.svg @@ -0,0 +1,309 @@ + + + + + + + + + + + + + + + + 1.3 + 1.4 + 1.5 + 1.6 + 1.7 + 1.8 + 1.9 + 2.0 + 2.1 + 2.2 + + + ↑ height + + + + + + + + + + + + 40 + 60 + 80 + 100 + 120 + 140 + 160 + + + weight → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/crosshair.ts b/test/plots/crosshair.ts new file mode 100644 index 0000000000..806808bd6b --- /dev/null +++ b/test/plots/crosshair.ts @@ -0,0 +1,43 @@ +import * as Plot from "@observablehq/plot"; +import * as d3 from "d3"; + +export async function crosshairDodge() { + const penguins = await d3.csv("data/penguins.csv", d3.autoType); + return Plot.plot({ + height: 160, + marks: [ + Plot.dot(penguins, Plot.dodgeY({x: "culmen_length_mm", r: "body_mass_g"})), + Plot.crosshairX(penguins, Plot.dodgeY({x: "culmen_length_mm", r: "body_mass_g"})) + ] + }); +} + +export async function crosshairDot() { + const penguins = await d3.csv("data/penguins.csv", d3.autoType); + return Plot.plot({ + marks: [ + Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm", stroke: "sex"}), + Plot.crosshair(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"}) + ] + }); +} + +export async function crosshairDotFacet() { + const penguins = await d3.csv("data/penguins.csv", d3.autoType); + return Plot.plot({ + marks: [ + Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm", fy: "species", stroke: "sex"}), + Plot.crosshair(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm", fy: "species"}) + ] + }); +} + +export async function crosshairHexbin() { + const olympians = await d3.csv("data/athletes.csv", d3.autoType); + return Plot.plot({ + marks: [ + Plot.hexagon(olympians, Plot.hexbin({r: "count"}, {x: "weight", y: "height"})), + Plot.crosshair(olympians, Plot.hexbin({r: "count"}, {x: "weight", y: "height"})) + ] + }); +} diff --git a/test/plots/index.ts b/test/plots/index.ts index 63442ad28a..fd35318b1b 100644 --- a/test/plots/index.ts +++ b/test/plots/index.ts @@ -54,6 +54,7 @@ export * from "./crimean-war-arrow.js"; export * from "./crimean-war-line.js"; export * from "./crimean-war-overlapped.js"; export * from "./crimean-war-stacked.js"; +export * from "./crosshair.js"; export * from "./d3-survey-2015-comfort.js"; export * from "./d3-survey-2015-why.js"; export * from "./darker-dodge.js"; @@ -271,8 +272,8 @@ export * from "./stargazers-hourly.js"; export * from "./stargazers.js"; export * from "./stocks-index.js"; export * from "./text-overflow.js"; -export * from "./tip.js"; export * from "./this-is-just-to-say.js"; +export * from "./tip.js"; export * from "./traffic-horizon.js"; export * from "./travelers-covid-drop.js"; export * from "./travelers-year-over-year.js"; diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 048b27f8a1..d29155e1e1 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -21,16 +21,6 @@ export async function tipBinStack() { }); } -export async function tipCrosshair() { - const penguins = await d3.csv("data/penguins.csv", d3.autoType); - return Plot.plot({ - marks: [ - Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm", stroke: "sex"}), - Plot.crosshair(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"}) - ] - }); -} - export async function tipDot() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); return Plot.plot({ From 50a136a9f2ea8a300f2c06c842f11ab758710cc9 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 20:22:39 -0700 Subject: [PATCH 28/56] tidier crosshair options --- src/marks/crosshair.js | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/marks/crosshair.js b/src/marks/crosshair.js index 69067614de..ab51f98e02 100644 --- a/src/marks/crosshair.js +++ b/src/marks/crosshair.js @@ -4,32 +4,26 @@ import {ruleX, ruleY} from "./rule.js"; import {text} from "./text.js"; export function crosshair(data, options = {}) { - const {x, y, dx = -9, dy = 9} = options; + const {x, y} = options; const p = pointer({px: x, py: y}); return marks( - ruleX(data, ruleOptions(p, options, x, null)), - ruleY(data, ruleOptions(p, options, null, y)), - text(data, textOptions({...p, text: x, dy, frameAnchor: "bottom", lineAnchor: "top"}, options, x, null)), - text(data, textOptions({...p, text: y, dx, frameAnchor: "left", textAnchor: "end"}, options, null, y)) + ruleX(data, ruleXOptions(p, options, x)), + ruleY(data, ruleYOptions(p, options, y)), + text(data, textXOptions(p, options, x)), + text(data, textYOptions(p, options, y)) ); } export function crosshairX(data, options = {}) { - const {x, dy = 9} = options; + const {x} = options; const p = pointerX({px: x}); - return marks( - ruleX(data, ruleOptions(p, options, x, null)), - text(data, textOptions({...p, text: x, dy, frameAnchor: "bottom", lineAnchor: "top"}, options, x, null)) - ); + return marks(ruleX(data, ruleXOptions(p, options, x)), text(data, textXOptions(p, options, x))); } export function crosshairY(data, options = {}) { - const {y, dx = -9} = options; + const {y} = options; const p = pointerY({py: y}); - return marks( - ruleY(data, ruleOptions(p, options, null, y)), - text(data, textOptions({...p, text: y, dx, frameAnchor: "left", textAnchor: "end"}, options, null, y)) - ); + return marks(ruleY(data, ruleYOptions(p, options, y)), text(data, textYOptions(p, options, y))); } // TODO pass all options? @@ -63,6 +57,14 @@ function pxpy(i, ox, oy) { }; } +function ruleXOptions(pointerOptions, options, x) { + return ruleOptions(pointerOptions, options, x, null); +} + +function ruleYOptions(pointerOptions, options, y) { + return ruleOptions(pointerOptions, options, null, y); +} + function ruleOptions(pointerOptions, options, x, y) { const { color = "currentColor", @@ -73,6 +75,14 @@ function ruleOptions(pointerOptions, options, x, y) { return {...markOptions(pointerOptions, options, x, y), stroke, strokeOpacity, strokeWidth}; } +function textXOptions(pointerOptions, options, x) { + return textOptions({...pointerOptions, text: x, dy: 9, frameAnchor: "bottom", lineAnchor: "top"}, options, x, null); +} + +function textYOptions(pointerOptions, options, y) { + return textOptions({...pointerOptions, text: y, dx: -9, frameAnchor: "left", textAnchor: "end"}, options, null, y); +} + function textOptions(pointerOptions, options, x, y) { const { color = "currentColor", From 0d15771fb9048654e3c39870a78da2ebfecc7303 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 20:23:24 -0700 Subject: [PATCH 29/56] remove to-do --- src/marks/crosshair.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/marks/crosshair.js b/src/marks/crosshair.js index ab51f98e02..c6bcffa805 100644 --- a/src/marks/crosshair.js +++ b/src/marks/crosshair.js @@ -26,7 +26,6 @@ export function crosshairY(data, options = {}) { return marks(ruleY(data, ruleYOptions(p, options, y)), text(data, textYOptions(p, options, y))); } -// TODO pass all options? function markOptions( {channels: pointerChannels, ...pointerOptions}, {facet, facetAnchor, fx, fy, channels, transform, initializer}, From 8ec7a317eddf8d5b01dd0d858c5cab649fcd58af Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 20:30:43 -0700 Subject: [PATCH 30/56] tip + dodge test --- test/output/tipDodge.svg | 378 +++++++++++++++++++++++++++++++++++++++ test/plots/tip.ts | 11 ++ 2 files changed, 389 insertions(+) create mode 100644 test/output/tipDodge.svg diff --git a/test/output/tipDodge.svg b/test/output/tipDodge.svg new file mode 100644 index 0000000000..3127891ebb --- /dev/null +++ b/test/output/tipDodge.svg @@ -0,0 +1,378 @@ + + + + + + + + + + + 35 + 40 + 45 + 50 + 55 + + + culmen_length_mm → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index d29155e1e1..2b08368c62 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -21,6 +21,17 @@ export async function tipBinStack() { }); } +export async function tipDodge() { + const penguins = await d3.csv("data/penguins.csv", d3.autoType); + return Plot.plot({ + height: 160, + marks: [ + Plot.dot(penguins, Plot.dodgeY({x: "culmen_length_mm", r: "body_mass_g"})), + Plot.tip(penguins, Plot.pointer(Plot.dodgeY({x: "culmen_length_mm", r: "body_mass_g"}))) + ] + }); +} + export async function tipDot() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); return Plot.plot({ From 8b6f84e58795ff6449ca256fd2f96be951f36008 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 22:10:07 -0700 Subject: [PATCH 31/56] cleaner facet translate --- src/interactions/pointer.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index 32a014bb9f..5aaa4d1582 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -23,6 +23,8 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = const faceted = index.fi != null; const facetState = faceted ? (state.facetState ??= new Map()) : null; + const tx = scales.fx ? scales.fx(index.fx) - dimensions.marginLeft : 0; + const ty = scales.fy ? scales.fy(index.fy) - dimensions.marginTop : 0; const {x: X0, y: Y0, x1: X1, y1: Y1, x2: X2, y2: Y2, px: X = X0, py: Y = Y0} = values; const [cx, cy] = applyFrameAnchor(this, dimensions); let i; // currently focused index @@ -74,12 +76,7 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = function pointermove(event) { if (state.sticky || (event.pointerType === "mouse" && event.buttons === 1)) return; // dragging let [xp, yp] = pointof(event); - // TODO use facetTranslate instead? - if (faceted) { - const matrix = g.transform.baseVal[0].matrix; - xp -= matrix.e; - yp -= matrix.f; - } + if (faceted) (xp -= tx), (yp -= ty); let ii = null; let ri = maxRadius * maxRadius; for (const j of index) { From c385d6b909e9837ae5426e67ad389db62d72211d Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 8 May 2023 23:17:12 -0700 Subject: [PATCH 32/56] crosshair text using channel alias --- src/channel.js | 7 +++++++ src/marks/crosshair.js | 28 ++++++++++++++++++++++++---- src/marks/tip.js | 11 ++--------- src/transforms/hexbin.js | 10 ++++++---- 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/channel.js b/src/channel.js index 2f6ab38509..314861599c 100644 --- a/src/channel.js +++ b/src/channel.js @@ -160,3 +160,10 @@ function ascendingGroup([ak, av], [bk, bv]) { function descendingGroup([ak, av], [bk, bv]) { return descendingDefined(av, bv) || ascendingDefined(ak, bk); } + +export function getSource(channels, key) { + let channel = channels[key]; + if (!channel) return; + while (channel.source) channel = channel.source; + return channel.source === null ? null : channel; +} diff --git a/src/marks/crosshair.js b/src/marks/crosshair.js index c6bcffa805..1cab5899be 100644 --- a/src/marks/crosshair.js +++ b/src/marks/crosshair.js @@ -1,5 +1,7 @@ +import {getSource} from "../channel.js"; import {pointer, pointerX, pointerY} from "../interactions/pointer.js"; import {marks} from "../mark.js"; +import {initializer} from "../transforms/basic.js"; import {ruleX, ruleY} from "./rule.js"; import {text} from "./text.js"; @@ -51,8 +53,15 @@ function markOptions( function pxpy(i, ox, oy) { if (i == null) return i; return function (data, facets, {x: x1, y: y1, px, py, ...c1}, ...args) { - const {channels: {x, y, ...c} = {}, ...r} = i.call(this, data, facets, {...c1, x: px, y: py}, ...args); - return {channels: {...c, px: x, py: y, ...(ox !== null && {x}), ...(oy !== null && {y})}, ...r}; + const {channels: {x, y, ...c} = {}, ...rest} = i.call(this, data, facets, {...c1, x: px, y: py}, ...args); + return { + channels: { + ...c, + ...(x && {px: x, ...(ox !== null && {x})}), + ...(y && {py: y, ...(oy !== null && {y})}) + }, + ...rest + }; }; } @@ -75,11 +84,13 @@ function ruleOptions(pointerOptions, options, x, y) { } function textXOptions(pointerOptions, options, x) { - return textOptions({...pointerOptions, text: x, dy: 9, frameAnchor: "bottom", lineAnchor: "top"}, options, x, null); + options = textChannel("x", options); + return textOptions({...pointerOptions, dy: 9, frameAnchor: "bottom", lineAnchor: "top"}, options, x, null); } function textYOptions(pointerOptions, options, y) { - return textOptions({...pointerOptions, text: y, dx: -9, frameAnchor: "left", textAnchor: "end"}, options, null, y); + options = textChannel("y", options); + return textOptions({...pointerOptions, dx: -9, frameAnchor: "left", textAnchor: "end"}, options, null, y); } function textOptions(pointerOptions, options, x, y) { @@ -92,3 +103,12 @@ function textOptions(pointerOptions, options, x, y) { } = options; return {...markOptions(pointerOptions, options, x, y), fill, stroke, strokeOpacity, strokeWidth}; } + +// Rather than aliasing text to have the same definition as x and y, we use an +// initializer to alias the channel values, such that the text channel can be +// derived by an initializer such as hexbin. +function textChannel(source, options) { + return initializer(options, (data, facets, channels) => { + return {channels: {text: {value: getSource(channels, source)?.value}}}; + }); +} diff --git a/src/marks/tip.js b/src/marks/tip.js index 70dab4d800..4d9f4ea7fd 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -1,10 +1,10 @@ import {select} from "d3"; +import {getSource} from "../channel.js"; import {create} from "../context.js"; import {formatDefault} from "../format.js"; import {Mark} from "../mark.js"; import {maybeFrameAnchor, maybeKeyword, maybeTuple, number, string} from "../options.js"; -import {applyChannelStyles, applyDirectStyles, applyIndirectStyles} from "../style.js"; -import {applyFrameAnchor, applyTransform} from "../style.js"; +import {applyChannelStyles, applyDirectStyles, applyFrameAnchor, applyIndirectStyles, applyTransform} from "../style.js"; import {inferTickFormat} from "./axis.js"; import {applyIndirectTextStyles, cut, defaultWidth, monospaceWidth} from "./text.js"; @@ -196,13 +196,6 @@ function maybeAnchor(value) { return maybeKeyword(value, "anchor", ["top-left", "top-right", "bottom-right", "bottom-left"]); } -function getSource(channels, key) { - let channel = channels[key]; - if (!channel) return; - while (channel.source) channel = channel.source; - return channel.source === null ? null : channel; -} - function getSource1(channels, key) { return key === "x2" ? getSource(channels, "x1") : key === "y2" ? getSource(channels, "y1") : null; } diff --git a/src/transforms/hexbin.js b/src/transforms/hexbin.js index 5ef514e63d..d2ff05e4e1 100644 --- a/src/transforms/hexbin.js +++ b/src/transforms/hexbin.js @@ -1,8 +1,8 @@ +import {isNoneish, map, number, valueof} from "../options.js"; +import {applyPosition} from "../projection.js"; import {sqrt3} from "../symbol.js"; -import {isNoneish, number, valueof} from "../options.js"; import {initializer} from "./basic.js"; import {hasOutput, maybeGroup, maybeOutputs, maybeSubgroup} from "./group.js"; -import {applyPosition} from "../projection.js"; // We don’t want the hexagons to align with the edges of the plot frame, as that // would cause extreme x-values (the upper bound of the default x-scale domain) @@ -78,9 +78,11 @@ export function hexbin(outputs = {fill: "count"}, {binWidth, ...options} = {}) { } // Construct the output channels, and populate the radius scale hint. + const sx = channels.x.scale; + const sy = channels.y.scale; const binChannels = { - x: {value: BX, source: null}, // or {value: map(BX, scales.x.invert), scale: "x"}? - y: {value: BY, source: null}, // or {value: map(BY, scales.y.invert), scale: "y"}? + x: {value: BX, source: scales[sx] ? {value: map(BX, scales[sx].invert), scale: sx} : null}, + y: {value: BY, source: scales[sy] ? {value: map(BY, scales[sy].invert), scale: sy} : null}, ...(Z && {z: {value: GZ}}), ...(F && {fill: {value: GF, scale: "auto"}}), ...(S && {stroke: {value: GS, scale: "auto"}}), From 736b45deed0e69fee70f7a249ddc8fae3b7077a7 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Tue, 9 May 2023 07:06:21 -0700 Subject: [PATCH 33/56] preTtier --- src/marks/tip.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/marks/tip.js b/src/marks/tip.js index 4d9f4ea7fd..c9fb334384 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -4,7 +4,8 @@ import {create} from "../context.js"; import {formatDefault} from "../format.js"; import {Mark} from "../mark.js"; import {maybeFrameAnchor, maybeKeyword, maybeTuple, number, string} from "../options.js"; -import {applyChannelStyles, applyDirectStyles, applyFrameAnchor, applyIndirectStyles, applyTransform} from "../style.js"; +import {applyChannelStyles, applyDirectStyles, applyIndirectStyles} from "../style.js"; +import {applyFrameAnchor, applyTransform} from "../style.js"; import {inferTickFormat} from "./axis.js"; import {applyIndirectTextStyles, cut, defaultWidth, monospaceWidth} from "./text.js"; From 99d4554a59c349e38676131d98267578171131c0 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Tue, 9 May 2023 09:18:44 -0700 Subject: [PATCH 34/56] fix transform for [xy][12] --- src/marks/tip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/marks/tip.js b/src/marks/tip.js index c9fb334384..c2e5256f74 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -84,7 +84,7 @@ export class Tip extends Mark { const g = create("svg:g", context) .call(applyIndirectStyles, this, dimensions, context) .call(applyIndirectTextStyles, this) - .call(applyTransform, this, {x: X && x, y: Y && y}) + .call(applyTransform, this, {x: (X || X2) && x, y: (Y || Y2) && y}) .call((g) => g .selectAll() From 0521e704a731c26cd89df35d42931aaf2a8afca6 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Tue, 9 May 2023 09:38:53 -0700 Subject: [PATCH 35/56] p[xy] precedence --- src/interactions/pointer.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index 5aaa4d1582..ba5e5c8297 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -25,8 +25,10 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = const facetState = faceted ? (state.facetState ??= new Map()) : null; const tx = scales.fx ? scales.fx(index.fx) - dimensions.marginLeft : 0; const ty = scales.fy ? scales.fy(index.fy) - dimensions.marginTop : 0; - const {x: X0, y: Y0, x1: X1, y1: Y1, x2: X2, y2: Y2, px: X = X0, py: Y = Y0} = values; + const {x: X, y: Y, x1: X1, y1: Y1, x2: X2, y2: Y2, px: PX, py: PY} = values; const [cx, cy] = applyFrameAnchor(this, dimensions); + const px = PX ? (i) => PX[i] : X2 ? (i) => (X1[i] + X2[i]) / 2 : X ? (i) => X[i] : () => cx; + const py = PY ? (i) => PY[i] : Y2 ? (i) => (Y1[i] + Y2[i]) / 2 : Y ? (i) => Y[i] : () => cy; let i; // currently focused index let g; // currently rendered mark @@ -80,10 +82,8 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = let ii = null; let ri = maxRadius * maxRadius; for (const j of index) { - const xj = X2 ? (X1[j] + X2[j]) / 2 : X ? X[j] : cx; - const yj = Y2 ? (Y1[j] + Y2[j]) / 2 : Y ? Y[j] : cy; - const dx = kx * (xj - xp); - const dy = ky * (yj - yp); + const dx = kx * (px(j) - xp); + const dy = ky * (py(j) - yp); const rj = dx * dx + dy * dy; if (rj <= ri) (ii = j), (ri = rj); } From f6e68dd2e28897c94a93526b10f0d30a46d9d6de Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Tue, 9 May 2023 09:52:24 -0700 Subject: [PATCH 36/56] pointer comments --- src/interactions/pointer.js | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index ba5e5c8297..22cd299ba0 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -3,9 +3,13 @@ import {applyFrameAnchor} from "../style.js"; function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = {}) { maxRadius = +maxRadius; + // When px or py is used, register an extra channel that the pointer + // interaction can use to control which point is focused; this allows pointing + // to function independently of where the downstream mark (e.g., a tip) is + // displayed. Also default x or y to null to disable maybeTuple etc. if (px != null) (x ??= null), (channels = {...channels, px: {value: px, scale: "x"}}); if (py != null) (y ??= null), (channels = {...channels, py: {value: py, scale: "y"}}); - const stateBySvg = new WeakMap(); + const states = new WeakMap(); return { x, y, @@ -17,18 +21,35 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = // Isolate state per-pointer, per-plot; if the pointer is reused by // multiple marks, they will share the same state (e.g., sticky modality). - let state = stateBySvg.get(svg); - if (!state) stateBySvg.set(svg, (state = {sticky: false, roots: [], renders: []})); + let state = states.get(svg); + if (!state) states.set(svg, (state = {sticky: false, roots: [], renders: []})); + + // This serves as a unique identifier of the rendered mark per-plot; it is + // used to record the currently-rendered elements (state.roots) so that we + // can tell when a rendered element is clicked on. let renderIndex = state.renders.push(render) - 1; - const faceted = index.fi != null; - const facetState = faceted ? (state.facetState ??= new Map()) : null; + // For faceting, we want to compute the local coordinates of each point, + // which means subtracting out the facet translation, if any. (It’s + // tempting to do this using the local coordinates in SVG, but that’s + // complicated by mark-specific transforms such as dx and dy.) const tx = scales.fx ? scales.fx(index.fx) - dimensions.marginLeft : 0; const ty = scales.fy ? scales.fy(index.fy) - dimensions.marginTop : 0; + + // For faceting, we also need to record the closest point per facet, since + // each facet has its own pointer event listeners; we only want the + // closest point across facets to be visible. + const faceted = index.fi != null; + const facetState = faceted ? (state.facetState ??= new Map()) : null; + + // The order of precedence when determining the point position is: px & + // py; the middle of x1 & y1 and x2 & y2; or lastly x & y. If any + // dimension is unspecified, we fallback to the frame anchor. const {x: X, y: Y, x1: X1, y1: Y1, x2: X2, y2: Y2, px: PX, py: PY} = values; const [cx, cy] = applyFrameAnchor(this, dimensions); const px = PX ? (i) => PX[i] : X2 ? (i) => (X1[i] + X2[i]) / 2 : X ? (i) => X[i] : () => cx; const py = PY ? (i) => PY[i] : Y2 ? (i) => (Y1[i] + Y2[i]) / 2 : Y ? (i) => Y[i] : () => cy; + let i; // currently focused index let g; // currently rendered mark @@ -57,14 +78,16 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = if (faceted) (I.fx = index.fx), (I.fy = index.fy), (I.fi = index.fi); const r = mark.render(I, scales, values, dimensions, context); if (g) { + // When faceting, preserve swapped mark and facet transforms; also + // remove ARIA attributes since these are promoted to the parent. This + // is perhaps brittle in that it depends on how Plot renders facets, + // but it produces a cleaner and more accessible SVG structure. if (faceted) { - // when faceting, preserve swapped mark and facet transforms const p = g.parentNode; const ft = g.getAttribute("transform"); const mt = r.getAttribute("transform"); ft ? r.setAttribute("transform", ft) : r.removeAttribute("transform"); mt ? p.setAttribute("transform", mt) : p.removeAttribute("transform"); - // also remove ARIA attributes since these are promoted to the parent r.removeAttribute("aria-label"); r.removeAttribute("aria-description"); r.removeAttribute("aria-hidden"); From 98ad85b370e28efe835050de66a0c032dd6c84a4 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Tue, 9 May 2023 10:03:16 -0700 Subject: [PATCH 37/56] tip textAnchor --- src/marks/tip.js | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/marks/tip.js b/src/marks/tip.js index c2e5256f74..6f4ab873c4 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -33,7 +33,8 @@ export class Tip extends Mark { fontWeight, lineHeight = 1, lineWidth = 20, - frameAnchor + frameAnchor, + textAnchor = "start" } = options; super( data, @@ -51,7 +52,7 @@ export class Tip extends Mark { this.anchor = maybeAnchor(anchor); this.previousAnchor = this.anchor ?? "top-left"; this.frameAnchor = maybeFrameAnchor(frameAnchor); - this.textAnchor = "start"; // TODO option + this.textAnchor = string(textAnchor); this.lineHeight = +lineHeight; this.lineWidth = +lineWidth; this.monospace = !!monospace; @@ -66,8 +67,8 @@ export class Tip extends Mark { const {x, y, fx, fy} = scales; const {x: X, y: Y, x1: X1, y1: Y1, x2: X2, y2: Y2, channels: sources} = channels; const [cx, cy] = applyFrameAnchor(this, dimensions); - const tx = X2 ? (i) => (X1[i] + X2[i]) / 2 : X ? (i) => X[i] : () => cx; - const ty = Y2 ? (i) => (Y1[i] + Y2[i]) / 2 : Y ? (i) => Y[i] : () => cy; + const px = X2 ? (i) => (X1[i] + X2[i]) / 2 : X ? (i) => X[i] : () => cx; + const py = Y2 ? (i) => (Y1[i] + Y2[i]) / 2 : Y ? (i) => Y[i] : () => cy; const {ownerSVGElement: svg, document} = context; const {anchor, monospace, lineHeight, lineWidth} = this; const {marginTop, marginLeft} = dimensions; @@ -91,7 +92,7 @@ export class Tip extends Mark { .data(index) .enter() .append("g") - .attr("transform", (i) => `translate(${tx(i)},${ty(i)})`) + .attr("transform", (i) => `translate(${px(i)},${py(i)})`) .call(applyDirectStyles, this) .call(applyChannelStyles, this, channels) .call((g) => g.append("path").attr("filter", "drop-shadow(0 3px 4px rgba(0,0,0,0.2))")) @@ -155,9 +156,9 @@ export class Tip extends Mark { const ox = fx ? fx(index.fx) - marginLeft : 0; const oy = fy ? fy(index.fy) - marginTop : 0; g.selectChildren().each(function (i) { - const x = tx(i) + ox; - const y = ty(i) + oy; - const {width: w, height: h} = this.getBBox(); + const x = px(i) + ox; + const y = py(i) + oy; + const {x: tx, width: w, height: h} = this.getBBox(); let a = anchor; if (a === undefined) { a = mark.previousAnchor; @@ -172,15 +173,16 @@ export class Tip extends Mark { const path = this.firstChild; const text = this.lastChild; path.setAttribute("d", getPath(a, m, r, w, h)); + if (tx) for (const t of text.childNodes) t.setAttribute("x", -tx); text.setAttribute("y", `${+getLineOffset(a, text.childNodes.length, lineHeight).toFixed(6)}em`); text.setAttribute("transform", getTextTransform(a, m, r, w, h)); }); } - // Wait until the Plot is inserted into the page, so that we can use getBBox - // to compute the text dimensions. Perhaps this could be done synchronously; - // getting the dimensions of the SVG is easy, and although accurate text - // metrics are hard, we could use approximate heuristics. + // Wait until the Plot is inserted into the page so that we can use getBBox + // to compute the exact text dimensions. Perhaps this could be done + // synchronously; getting the dimensions of the SVG is easy, and although + // accurate text metrics are hard, we could use approximate heuristics. if (svg.isConnected) Promise.resolve().then(postrender); else if (typeof requestAnimationFrame !== "undefined") requestAnimationFrame(postrender); From d24bb0ab3c257a435dcb0847fd487ac387c3e184 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Tue, 9 May 2023 10:27:09 -0700 Subject: [PATCH 38/56] more tip options --- src/marks/text.js | 8 +++++--- src/marks/tip.js | 38 ++++++++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/marks/text.js b/src/marks/text.js index 087c91b052..3ac6679c88 100644 --- a/src/marks/text.js +++ b/src/marks/text.js @@ -430,14 +430,16 @@ function clipper({monospace, lineWidth, textOverflow}) { case "clip-end": return (text) => clipEnd(text, maxWidth, widthof, ""); case "ellipsis-start": - return (text) => clipStart(text, maxWidth, widthof, "…"); + return (text) => clipStart(text, maxWidth, widthof, ellipsis); case "ellipsis-middle": - return (text) => clipMiddle(text, maxWidth, widthof, "…"); + return (text) => clipMiddle(text, maxWidth, widthof, ellipsis); case "ellipsis-end": - return (text) => clipEnd(text, maxWidth, widthof, "…"); + return (text) => clipEnd(text, maxWidth, widthof, ellipsis); } } +export const ellipsis = "…"; + // Cuts the given text to the given width, using the specified widthof function; // the returned [index, error] guarantees text.slice(0, index) fits within the // specified width with the given error. If the text fits naturally within the diff --git a/src/marks/tip.js b/src/marks/tip.js index 6f4ab873c4..f504ebabde 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -5,9 +5,9 @@ import {formatDefault} from "../format.js"; import {Mark} from "../mark.js"; import {maybeFrameAnchor, maybeKeyword, maybeTuple, number, string} from "../options.js"; import {applyChannelStyles, applyDirectStyles, applyIndirectStyles} from "../style.js"; -import {applyFrameAnchor, applyTransform} from "../style.js"; +import {applyFrameAnchor, applyTransform, impliedString} from "../style.js"; import {inferTickFormat} from "./axis.js"; -import {applyIndirectTextStyles, cut, defaultWidth, monospaceWidth} from "./text.js"; +import {applyIndirectTextStyles, cut, defaultWidth, ellipsis, monospaceWidth} from "./text.js"; const defaults = { ariaLabel: "tip", @@ -52,7 +52,9 @@ export class Tip extends Mark { this.anchor = maybeAnchor(anchor); this.previousAnchor = this.anchor ?? "top-left"; this.frameAnchor = maybeFrameAnchor(frameAnchor); - this.textAnchor = string(textAnchor); + this.textAnchor = impliedString(textAnchor, "middle"); + this.textPadding = 8; // TODO option + this.pointerSize = 12; // TODO option this.lineHeight = +lineHeight; this.lineWidth = +lineWidth; this.monospace = !!monospace; @@ -61,24 +63,32 @@ export class Tip extends Mark { this.fontStyle = string(fontStyle); this.fontVariant = string(fontVariant); this.fontWeight = string(fontWeight); + this.imageFilter = "drop-shadow(0 3px 4px rgba(0,0,0,0.2))"; // TODO option } render(index, scales, channels, dimensions, context) { const mark = this; const {x, y, fx, fy} = scales; + const {ownerSVGElement: svg, document} = context; + const {anchor, monospace, lineHeight, lineWidth, textPadding: r, pointerSize: m} = this; + const {marginTop, marginLeft} = dimensions; + + // The anchor position is the middle of x1 & y1 and x2 & y2, if available, + // or x & y; the former is considered more specific because it’s how we + // disable the implicit stack and interval transforms. If any dimension is + // unspecified, we fallback to the frame anchor. const {x: X, y: Y, x1: X1, y1: Y1, x2: X2, y2: Y2, channels: sources} = channels; const [cx, cy] = applyFrameAnchor(this, dimensions); const px = X2 ? (i) => (X1[i] + X2[i]) / 2 : X ? (i) => X[i] : () => cx; const py = Y2 ? (i) => (Y1[i] + Y2[i]) / 2 : Y ? (i) => Y[i] : () => cy; - const {ownerSVGElement: svg, document} = context; - const {anchor, monospace, lineHeight, lineWidth} = this; - const {marginTop, marginLeft} = dimensions; + + // Resolve the text metric implementation. We may need an ellipsis for text + // truncation, so we optimistically compute the ellipsis width. const widthof = monospace ? monospaceWidth : defaultWidth; - const ellipsis = "…"; const ee = widthof(ellipsis); - const r = 8; // “padding” - const m = 12; // “margin” (flag size) - const labelFx = fx && (fx.label === undefined ? "fx" : fx.label); - const labelFy = fy && (fy.label === undefined ? "fy" : fy.label); + + // We borrow the scale’s tick format for facet channels; this is safe for + // ordinal scales (but not continuous scales where the display value may + // need higher precision), and generally better than the default format. const formatFx = fx && inferTickFormat(fx); const formatFy = fy && inferTickFormat(fy); @@ -95,7 +105,7 @@ export class Tip extends Mark { .attr("transform", (i) => `translate(${px(i)},${py(i)})`) .call(applyDirectStyles, this) .call(applyChannelStyles, this, channels) - .call((g) => g.append("path").attr("filter", "drop-shadow(0 3px 4px rgba(0,0,0,0.2))")) + .call((g) => g.append("path")) .call((g) => g.append("text").each(function (i) { const that = select(this); @@ -121,8 +131,8 @@ export class Tip extends Mark { ); } if (index.fi == null) return; // not faceted - if (fx) renderLine(that, labelFx, formatFx(index.fx)); - if (fy) renderLine(that, labelFy, formatFy(index.fy)); + if (fx) renderLine(that, fx.label ?? "fx", formatFx(index.fx)); + if (fy) renderLine(that, fy.label ?? "fy", formatFy(index.fy)); }) ) ); From 6512367a51868b7b016f24a4a522ee14a4e97340 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Tue, 9 May 2023 10:53:14 -0700 Subject: [PATCH 39/56] more tip options, comments --- src/marks/tip.js | 64 +++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/src/marks/tip.js b/src/marks/tip.js index f504ebabde..8ab7115902 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -34,7 +34,10 @@ export class Tip extends Mark { lineHeight = 1, lineWidth = 20, frameAnchor, - textAnchor = "start" + textAnchor = "start", + textPadding = 8, + pointerSize = 12, + pathFilter = "drop-shadow(0 3px 4px rgba(0,0,0,0.2))" } = options; super( data, @@ -53,8 +56,9 @@ export class Tip extends Mark { this.previousAnchor = this.anchor ?? "top-left"; this.frameAnchor = maybeFrameAnchor(frameAnchor); this.textAnchor = impliedString(textAnchor, "middle"); - this.textPadding = 8; // TODO option - this.pointerSize = 12; // TODO option + this.textPadding = +textPadding; + this.pointerSize = +pointerSize; + this.pathFilter = string(pathFilter); this.lineHeight = +lineHeight; this.lineWidth = +lineWidth; this.monospace = !!monospace; @@ -63,21 +67,25 @@ export class Tip extends Mark { this.fontStyle = string(fontStyle); this.fontVariant = string(fontVariant); this.fontWeight = string(fontWeight); - this.imageFilter = "drop-shadow(0 3px 4px rgba(0,0,0,0.2))"; // TODO option } render(index, scales, channels, dimensions, context) { const mark = this; const {x, y, fx, fy} = scales; const {ownerSVGElement: svg, document} = context; - const {anchor, monospace, lineHeight, lineWidth, textPadding: r, pointerSize: m} = this; + const {anchor, monospace, lineHeight, lineWidth} = this; + const {textPadding: r, pointerSize: m, pathFilter} = this; const {marginTop, marginLeft} = dimensions; // The anchor position is the middle of x1 & y1 and x2 & y2, if available, // or x & y; the former is considered more specific because it’s how we // disable the implicit stack and interval transforms. If any dimension is - // unspecified, we fallback to the frame anchor. + // unspecified, we fallback to the frame anchor. We also need to know the + // facet offsets to detect when the tip would draw outside the plot, and + // thus we need to change the orientation. const {x: X, y: Y, x1: X1, y1: Y1, x2: X2, y2: Y2, channels: sources} = channels; const [cx, cy] = applyFrameAnchor(this, dimensions); + const ox = fx ? fx(index.fx) - marginLeft : 0; + const oy = fy ? fy(index.fy) - marginTop : 0; const px = X2 ? (i) => (X1[i] + X2[i]) / 2 : X ? (i) => X[i] : () => cx; const py = Y2 ? (i) => (Y1[i] + Y2[i]) / 2 : Y ? (i) => Y[i] : () => cy; @@ -105,13 +113,15 @@ export class Tip extends Mark { .attr("transform", (i) => `translate(${px(i)},${py(i)})`) .call(applyDirectStyles, this) .call(applyChannelStyles, this, channels) - .call((g) => g.append("path")) + .call((g) => g.append("path").attr("filter", pathFilter)) .call((g) => g.append("text").each(function (i) { const that = select(this); + // prevent style inheritance (from path) this.setAttribute("fill", "currentColor"); this.setAttribute("fill-opacity", 1); this.setAttribute("stroke", "none"); + // iteratively render each channel value for (const key in sources) { const channel = getSource(sources, key); if (!channel) continue; // e.g., dodgeY’s y @@ -123,8 +133,8 @@ export class Tip extends Mark { renderLine( that, scales[channel.scale]?.label ?? channel.label ?? key, - channel2 - ? channel2.hint?.length + channel2 // e.g., binX’s x1 and x2 + ? channel2.hint?.length // e.g., stackY’s y1 and y2 ? `${formatDefault(value2 - value1)}` : `${formatDefault(value1)}–${formatDefault(value2)}` : formatDefault(value1) @@ -137,7 +147,12 @@ export class Tip extends Mark { ) ); - function renderLine(that, name, value) { + // Renders a single line (a name-value pair) to the tip, truncating the text + // as needed, and adding a title if the text is truncated. Note that this is + // just the initial layout of the text; in postrender we will compute the + // exact text metrics and translate the text as needed once we know the + // tip’s orientation (anchor). + function renderLine(selection, name, value) { let title; let w = lineWidth * 100; const [j] = cut(name, w, widthof, ee); @@ -155,23 +170,23 @@ export class Tip extends Mark { title = value.trim(); } } - const line = that.append("tspan").attr("x", 0).attr("dy", `${lineHeight}em`); + const line = selection.append("tspan").attr("x", 0).attr("dy", `${lineHeight}em`); line.append("tspan").attr("font-weight", "bold").text(name); if (value) line.append(() => document.createTextNode(value)); if (title) line.append("title").text(title); } + // Only after the plot is attached to the page can we compute the exact text + // metrics needed to determine the tip size and orientation (anchor). function postrender() { const {width, height} = svg.getBBox(); - const ox = fx ? fx(index.fx) - marginLeft : 0; - const oy = fy ? fy(index.fy) - marginTop : 0; g.selectChildren().each(function (i) { - const x = px(i) + ox; - const y = py(i) + oy; const {x: tx, width: w, height: h} = this.getBBox(); - let a = anchor; + let a = anchor; // use the specified anchor, if any if (a === undefined) { - a = mark.previousAnchor; + a = mark.previousAnchor; // favor the previous anchor, if it fits + const x = px(i) + ox; + const y = py(i) + oy; const fitLeft = x + w + r * 2 < width; const fitRight = x - w - r * 2 > 0; const fitTop = y + h + m + r * 2 + 7 < height; @@ -180,8 +195,8 @@ export class Tip extends Mark { const ay = (/^top-/.test(a) ? fitTop || !fitBottom : fitTop && !fitBottom) ? "top" : "bottom"; a = mark.previousAnchor = `${ay}-${ax}`; } - const path = this.firstChild; - const text = this.lastChild; + const path = this.firstChild; // note: assumes exactly two children! + const text = this.lastChild; // note: assumes exactly two children! path.setAttribute("d", getPath(a, m, r, w, h)); if (tx) for (const t of text.childNodes) t.setAttribute("x", -tx); text.setAttribute("y", `${+getLineOffset(a, text.childNodes.length, lineHeight).toFixed(6)}em`); @@ -189,10 +204,13 @@ export class Tip extends Mark { }); } - // Wait until the Plot is inserted into the page so that we can use getBBox - // to compute the exact text dimensions. Perhaps this could be done - // synchronously; getting the dimensions of the SVG is easy, and although - // accurate text metrics are hard, we could use approximate heuristics. + // Wait until the plot is inserted into the page so that we can use getBBox + // to compute the exact text dimensions. If the SVG is already connected, as + // when the pointer interaction triggers the re-render, use a faster + // microtask instead of an animation frame; if this SSR (e.g., JSDOM), skip + // this step. Perhaps this could be done synchronously; getting the + // dimensions of the SVG is easy, and although accurate text metrics are + // hard, we could use approximate heuristics. if (svg.isConnected) Promise.resolve().then(postrender); else if (typeof requestAnimationFrame !== "undefined") requestAnimationFrame(postrender); From f40792f8f24cff82758766848db48dfad66f67c0 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Tue, 9 May 2023 11:56:25 -0700 Subject: [PATCH 40/56] bandwidth offset --- src/interactions/pointer.js | 11 ++- test/output/tipCell.svg | 149 ++++++++++++++++++++++++++++++++++++ test/plots/tip.ts | 13 ++++ 3 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 test/output/tipCell.svg diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index 22cd299ba0..bab3f5e752 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -32,9 +32,14 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = // For faceting, we want to compute the local coordinates of each point, // which means subtracting out the facet translation, if any. (It’s // tempting to do this using the local coordinates in SVG, but that’s - // complicated by mark-specific transforms such as dx and dy.) - const tx = scales.fx ? scales.fx(index.fx) - dimensions.marginLeft : 0; - const ty = scales.fy ? scales.fy(index.fy) - dimensions.marginTop : 0; + // complicated by mark-specific transforms such as dx and dy.) Also, since + // band scales return the upper bound of the band, we have to offset by + // half the bandwidth. + const {x, y, fx, fy} = scales; + let tx = fx ? fx(index.fx) - dimensions.marginLeft : 0; + let ty = fy ? fy(index.fy) - dimensions.marginTop : 0; + if (x?.bandwidth) tx += x.bandwidth() / 2; + if (y?.bandwidth) ty += y.bandwidth() / 2; // For faceting, we also need to record the closest point per facet, since // each facet has its own pointer event listeners; we only want the diff --git a/test/output/tipCell.svg b/test/output/tipCell.svg new file mode 100644 index 0000000000..dfd8412195 --- /dev/null +++ b/test/output/tipCell.svg @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + aquatics + archery + athletics + badminton + basketball + boxing + canoe + cycling + equestrian + fencing + football + golf + gymnastics + handball + hockey + judo + modern pentathlon + rowing + rugby sevens + sailing + shooting + table tennis + taekwondo + tennis + triathlon + volleyball + weightlifting + wrestling + + + sport + + + + + + + female + male + + + sex + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 2b08368c62..0a7fa5e69a 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -21,6 +21,19 @@ export async function tipBinStack() { }); } +export async function tipCell() { + const olympians = await d3.csv("data/athletes.csv", d3.autoType); + return Plot.plot({ + height: 400, + marginLeft: 100, + color: {scheme: "blues"}, + marks: [ + Plot.cell(olympians, Plot.group({fill: "count"}, {x: "sex", y: "sport"})), + Plot.tip(olympians, Plot.pointerY(Plot.group({stroke: "count"}, {x: "sex", y: "sport"}))) + ] + }); +} + export async function tipDodge() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); return Plot.plot({ From 45d1d43bbb2df2ecd20e36fd99c6f2f54e5fc04b Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Tue, 9 May 2023 14:52:52 -0700 Subject: [PATCH 41/56] fix for multi-facet, multi-pointer --- src/interactions/pointer.js | 51 +++++++---- src/mark.js | 2 +- test/output/tipCellFacet.svg | 160 +++++++++++++++++++++++++++++++++++ test/plots/tip.ts | 13 +++ 4 files changed, 207 insertions(+), 19 deletions(-) create mode 100644 test/output/tipCellFacet.svg diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index bab3f5e752..7289e14bdb 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -41,11 +41,17 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = if (x?.bandwidth) tx += x.bandwidth() / 2; if (y?.bandwidth) ty += y.bandwidth() / 2; - // For faceting, we also need to record the closest point per facet, since - // each facet has its own pointer event listeners; we only want the - // closest point across facets to be visible. + // For faceting, we also need to record the closest point per facet per + // mark (!), since each facet has its own pointer event listeners; we only + // want the closest point across facets to be visible. const faceted = index.fi != null; - const facetState = faceted ? (state.facetState ??= new Map()) : null; + let facetState; + if (faceted) { + let facetStates = state.facetStates; + if (!facetStates) state.facetStates = facetStates = new Map(); + facetState = facetStates.get(mark); + if (!facetState) facetStates.set(mark, (facetState = new Map())); + } // The order of precedence when determining the point position is: px & // py; the middle of x1 & y1 and x2 & y2; or lastly x & y. If any @@ -57,26 +63,35 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = let i; // currently focused index let g; // currently rendered mark + let f; // current animation frame - function render(ii, ri) { - // When faceting, if more than one pointer would be visible, only show - // this one if it is the closest. This is a simple linear scan because - // we don’t expect many facets with simultaneously-visible pointers. + // When faceting, if more than one pointer would be visible, only show + // this one if it is the closest. We defer rendering using an animation + // frame to allow all pointer events to be received before deciding which + // mark to render; although when hiding, we render immediately. + function update(ii, ri) { if (faceted) { - if (ii == null) { - facetState.delete(index.fi); - } else { + if (f) f = cancelAnimationFrame(f); + if (ii == null) facetState.delete(index.fi); + else { facetState.set(index.fi, ri); - if (facetState.size > 1) { - for (const [fi, r] of facetState) { - if (fi !== index.fi && r < ri) { + f = requestAnimationFrame(() => { + f = null; + for (const r of facetState.values()) { + if (r < ri) { ii = null; break; } } - } + render(ii); + }); + return; } } + render(ii); + } + + function render(ii) { if (i === ii) return; // the tooltip hasn’t moved i = ii; const I = i == null ? [] : [i]; @@ -106,7 +121,7 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = function pointermove(event) { if (state.sticky || (event.pointerType === "mouse" && event.buttons === 1)) return; // dragging let [xp, yp] = pointof(event); - if (faceted) (xp -= tx), (yp -= ty); + (xp -= tx), (yp -= ty); // correct for facets and band scales let ii = null; let ri = maxRadius * maxRadius; for (const j of index) { @@ -115,7 +130,7 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = const rj = dx * dx + dy * dy; if (rj <= ri) (ii = j), (ri = rj); } - render(ii, ri); + update(ii, ri); } function pointerdown(event) { @@ -129,7 +144,7 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = function pointerleave(event) { if (event.pointerType !== "mouse") return; - if (!state.sticky) render(null); + if (!state.sticky) update(null); } // We listen to the svg element; listening to the window instead would let diff --git a/src/mark.js b/src/mark.js index 873ee2704d..74e6ed72c9 100644 --- a/src/mark.js +++ b/src/mark.js @@ -89,7 +89,7 @@ export class Mark { if (facets === undefined && data != null) facets = [range(data)]; const originalFacets = facets; if (this.transform != null) ({facets, data} = this.transform(data, facets, plotOptions)), (data = arrayify(data)); - if (facets !== undefined) facets.original = originalFacets; // needed up read facetChannels + if (facets !== undefined) facets.original = originalFacets; // needed to read facetChannels const channels = createChannels(this.channels, data); if (this.sort != null) channelDomain(data, facets, channels, facetChannels, this.sort); // mutates facetChannels! return {data, facets, channels}; diff --git a/test/output/tipCellFacet.svg b/test/output/tipCellFacet.svg new file mode 100644 index 0000000000..c7d9d318fb --- /dev/null +++ b/test/output/tipCellFacet.svg @@ -0,0 +1,160 @@ + + + + + female + + + male + + + + sex + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + aquatics + archery + athletics + badminton + basketball + boxing + canoe + cycling + equestrian + fencing + football + golf + gymnastics + handball + hockey + judo + modern pentathlon + rowing + rugby sevens + sailing + shooting + table tennis + taekwondo + tennis + triathlon + volleyball + weightlifting + wrestling + + + + sport + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 0a7fa5e69a..821f445af4 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -34,6 +34,19 @@ export async function tipCell() { }); } +export async function tipCellFacet() { + const olympians = await d3.csv("data/athletes.csv", d3.autoType); + return Plot.plot({ + height: 400, + marginLeft: 100, + color: {scheme: "blues"}, + marks: [ + Plot.cell(olympians, Plot.groupY({fill: "count"}, {fx: "sex", y: "sport"})), + Plot.tip(olympians, Plot.pointerY(Plot.groupY({stroke: "count"}, {fx: "sex", y: "sport"}))) + ] + }); +} + export async function tipDodge() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); return Plot.plot({ From 00be81497bc48e93eef5b0d09bd70d4dc8dad740 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Tue, 9 May 2023 17:43:12 -0700 Subject: [PATCH 42/56] fix dimensions --- src/marks/tip.js | 2 +- src/scales.js | 3 +- test/output/tipBar.svg | 127 +++++++++++++++++++++++++++++++++++++++++ test/plots/tip.ts | 11 ++++ 4 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 test/output/tipBar.svg diff --git a/src/marks/tip.js b/src/marks/tip.js index 8ab7115902..641e6d2063 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -179,7 +179,7 @@ export class Tip extends Mark { // Only after the plot is attached to the page can we compute the exact text // metrics needed to determine the tip size and orientation (anchor). function postrender() { - const {width, height} = svg.getBBox(); + const {width, height} = dimensions.facet ?? dimensions; g.selectChildren().each(function (i) { const {x: tx, width: w, height: h} = this.getBBox(); let a = anchor; // use the specified anchor, if any diff --git a/src/scales.js b/src/scales.js index 0e0de399fa..a768865410 100644 --- a/src/scales.js +++ b/src/scales.js @@ -176,7 +176,8 @@ export function innerDimensions({fx, fy}, dimensions) { marginBottom, marginLeft, width: fx ? fx.scale.bandwidth() + marginLeft + marginRight : width, - height: fy ? fy.scale.bandwidth() + marginTop + marginBottom : height + height: fy ? fy.scale.bandwidth() + marginTop + marginBottom : height, + facet: {width, height} }; } diff --git a/test/output/tipBar.svg b/test/output/tipBar.svg new file mode 100644 index 0000000000..89403a504b --- /dev/null +++ b/test/output/tipBar.svg @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + modern pentathlon + triathlon + golf + archery + taekwondo + badminton + table tennis + tennis + equestrian + fencing + weightlifting + boxing + basketball + rugby sevens + gymnastics + canoe + wrestling + handball + sailing + volleyball + shooting + judo + hockey + cycling + rowing + football + aquatics + athletics + + + sport + + + + + + + + + + 0 + 500 + 1,000 + 1,500 + 2,000 + + + Frequency → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 821f445af4..fe0f89fdac 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -1,6 +1,17 @@ import * as Plot from "@observablehq/plot"; import * as d3 from "d3"; +export async function tipBar() { + const olympians = await d3.csv("data/athletes.csv", d3.autoType); + return Plot.plot({ + marginLeft: 100, + marks: [ + Plot.barX(olympians, Plot.groupY({x: "count"}, {y: "sport", sort: {y: "x"}})), + Plot.tip(olympians, Plot.pointerY(Plot.groupY({x: "count"}, {y: "sport"}))) + ] + }); +} + export async function tipBin() { const olympians = await d3.csv("data/athletes.csv", d3.autoType); return Plot.plot({ From c8417e3114a40322b22ebdda3c8cfbb6f1b8378a Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Tue, 9 May 2023 18:21:44 -0700 Subject: [PATCH 43/56] tip side anchors --- src/marks/tip.d.ts | 2 +- src/marks/tip.js | 51 +++++++++++++++++++++++++++++++++++----------- src/options.js | 8 ++++++-- test/plots/tip.ts | 2 +- 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/marks/tip.d.ts b/src/marks/tip.d.ts index e1beae1496..38a14b4a39 100644 --- a/src/marks/tip.d.ts +++ b/src/marks/tip.d.ts @@ -35,7 +35,7 @@ export interface TipOptions extends MarkOptions, TextStyles { frameAnchor?: FrameAnchor; /** TODO */ - anchor?: "top-left" | "top-right" | "bottom-right" | "bottom-left"; + anchor?: FrameAnchor; } /** diff --git a/src/marks/tip.js b/src/marks/tip.js index 641e6d2063..704f6cd00d 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -3,7 +3,7 @@ import {getSource} from "../channel.js"; import {create} from "../context.js"; import {formatDefault} from "../format.js"; import {Mark} from "../mark.js"; -import {maybeFrameAnchor, maybeKeyword, maybeTuple, number, string} from "../options.js"; +import {maybeAnchor, maybeFrameAnchor, maybeTuple, number, string} from "../options.js"; import {applyChannelStyles, applyDirectStyles, applyIndirectStyles} from "../style.js"; import {applyFrameAnchor, applyTransform, impliedString} from "../style.js"; import {inferTickFormat} from "./axis.js"; @@ -52,7 +52,7 @@ export class Tip extends Mark { options, defaults ); - this.anchor = maybeAnchor(anchor); + this.anchor = maybeAnchor(anchor, "anchor"); this.previousAnchor = this.anchor ?? "top-left"; this.frameAnchor = maybeFrameAnchor(frameAnchor); this.textAnchor = impliedString(textAnchor, "middle"); @@ -200,7 +200,7 @@ export class Tip extends Mark { path.setAttribute("d", getPath(a, m, r, w, h)); if (tx) for (const t of text.childNodes) t.setAttribute("x", -tx); text.setAttribute("y", `${+getLineOffset(a, text.childNodes.length, lineHeight).toFixed(6)}em`); - text.setAttribute("transform", getTextTransform(a, m, r, w, h)); + text.setAttribute("transform", `translate(${getTextTranslate(a, m, r, w, h)})`); }); } @@ -223,10 +223,6 @@ export function tip(data, {x, y, ...options} = {}) { return new Tip(data, {...options, x, y}); } -function maybeAnchor(value) { - return maybeKeyword(value, "anchor", ["top-left", "top-right", "bottom-right", "bottom-left"]); -} - function getSource1(channels, key) { return key === "x2" ? getSource(channels, "x1") : key === "y2" ? getSource(channels, "y1") : null; } @@ -236,26 +232,57 @@ function getSource2(channels, key) { } function getLineOffset(anchor, length, lineHeight) { - return /^top-/.test(anchor) ? 0.94 - lineHeight : -0.29 - length * lineHeight; + return /^top(?:-|$)/.test(anchor) + ? 0.94 - lineHeight + : /^bottom(?:-|$)/ + ? -0.29 - length * lineHeight + : (length / 2) * lineHeight; } -function getTextTransform(anchor, m, r, width) { - const x = /-left$/.test(anchor) ? r : -width - r; - const y = /^top-/.test(anchor) ? m + r : -m - r; - return `translate(${x},${y})`; +function getTextTranslate(anchor, m, r, width, height) { + switch (anchor) { + case "middle": + return [-width / 2, height / 2]; + case "top-left": + return [r, m + r]; + case "top": + return [-width / 2, m / 2 + r]; + case "top-right": + return [-width - r, m + r]; + case "right": + return [-m / 2 - width - r, height / 2]; + case "bottom-left": + return [r, -m - r]; + case "bottom": + return [-width / 2, -m / 2 - r]; + case "bottom-right": + return [-width - r, -m - r]; + case "left": + return [r + m / 2, height / 2]; + } } function getPath(anchor, m, r, width, height) { const w = width + r * 2; const h = height + r * 2; switch (anchor) { + case "middle": + return `M${-w / 2},${-h / 2}h${w}v${h}h${-w}z`; case "top-left": return `M0,0l${m},${m}h${w - m}v${h}h${-w}z`; + case "top": + return `M0,0l${m / 2},${m / 2}h${(w - m) / 2}v${h}h${-w}v${-h}h${(w - m) / 2}z`; case "top-right": return `M0,0l${-m},${m}h${m - w}v${h}h${w}z`; + case "right": + return `M0,0l${-m / 2},${-m / 2}v${m / 2 - h / 2}h${-w}v${h}h${w}v${m / 2 - h / 2}z`; case "bottom-left": return `M0,0l${m},${-m}h${w - m}v${-h}h${-w}z`; + case "bottom": + return `M0,0l${m / 2},${-m / 2}h${(w - m) / 2}v${-h}h${-w}v${h}h${(w - m) / 2}z`; case "bottom-right": return `M0,0l${-m},${-m}h${m - w}v${-h}h${w}z`; + case "left": + return `M0,0l${m / 2},${-m / 2}v${m / 2 - h / 2}h${w}v${h}h${-w}v${m / 2 - h / 2}z`; } } diff --git a/src/options.js b/src/options.js index 294903dc55..e05a6e2c5b 100644 --- a/src/options.js +++ b/src/options.js @@ -450,8 +450,8 @@ export function isRound(value) { return /^\s*round\s*$/i.test(value); } -export function maybeFrameAnchor(value = "middle") { - return keyword(value, "frameAnchor", [ +export function maybeAnchor(value, name) { + return maybeKeyword(value, name, [ "middle", "top-left", "top", @@ -464,6 +464,10 @@ export function maybeFrameAnchor(value = "middle") { ]); } +export function maybeFrameAnchor(value = "middle") { + return maybeAnchor(value, "frameAnchor"); +} + // Like a sort comparator, returns a positive value if the given array of values // is in ascending order, a negative value if the values are in descending // order. Assumes monotonicity; only tests the first and last values. diff --git a/test/plots/tip.ts b/test/plots/tip.ts index fe0f89fdac..6853ad36c0 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -7,7 +7,7 @@ export async function tipBar() { marginLeft: 100, marks: [ Plot.barX(olympians, Plot.groupY({x: "count"}, {y: "sport", sort: {y: "x"}})), - Plot.tip(olympians, Plot.pointerY(Plot.groupY({x: "count"}, {y: "sport"}))) + Plot.tip(olympians, Plot.pointerY(Plot.groupY({x: "count"}, {y: "sport", anchor: "left"}))) ] }); } From 5b5242869ea6191e6ec68c244c4a8028db97d0b2 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Wed, 10 May 2023 11:04:21 -0700 Subject: [PATCH 44/56] tipped helper --- src/context.js | 7 ++----- src/marks/axis.js | 18 +++++++++--------- src/plot.js | 37 ++++++++++++++++++++++++++----------- test/output/tipRaster.svg | 20 ++++++++++++++++++++ test/plots/tip.ts | 32 ++++++++++++++++++++++++++++---- 5 files changed, 85 insertions(+), 29 deletions(-) create mode 100644 test/output/tipRaster.svg diff --git a/src/context.js b/src/context.js index 5a270f3f03..c1911f9118 100644 --- a/src/context.js +++ b/src/context.js @@ -1,11 +1,8 @@ import {creator, select} from "d3"; -import {createProjection} from "./projection.js"; -export function createContext(options = {}, dimensions, className) { +export function createContext(options = {}) { const {document = typeof window !== "undefined" ? window.document : undefined} = options; - const ownerSVGElement = creator("svg").call(document.documentElement); - const projection = createProjection(options, dimensions); - return {document, ownerSVGElement, className, projection}; + return {document}; } export function create(name, {document}) { diff --git a/src/marks/axis.js b/src/marks/axis.js index b124724275..9cfa89c4b4 100644 --- a/src/marks/axis.js +++ b/src/marks/axis.js @@ -513,7 +513,8 @@ function axisMark(mark, k, ariaLabel, data, options, initialize) { let channels; const m = mark( data, - initializer(options, function (data, facets, _channels, scales) { + initializer(options, function (data, facets, _channels, scales, dimensions, context) { + const initializeFacets = data == null && (k === "fx" || k === "fy"); const {[k]: scale} = scales; if (!scale) throw new Error(`missing scale: ${k}`); let {ticks, tickSpacing, interval} = options; @@ -546,17 +547,16 @@ function axisMark(mark, k, ariaLabel, data, options, initialize) { facets = [range(data)]; } else { channels[k] = {scale: k, value: identity}; - facets = undefined; // computed automatically by plot } } initialize?.call(this, scale, ticks, channels); - return { - data, - facets, - channels: Object.fromEntries( - Object.entries(channels).map(([name, channel]) => [name, {...channel, value: valueof(data, channel.value)}]) - ) - }; + const initializedChannels = Object.fromEntries( + Object.entries(channels).map(([name, channel]) => { + return [name, {...channel, value: valueof(data, channel.value)}]; + }) + ); + if (initializeFacets) facets = context.filterFacets(data, initializedChannels); + return {data, facets, channels: initializedChannels}; }) ); if (data == null) { diff --git a/src/plot.js b/src/plot.js index e662ee61f9..9601e1d378 100644 --- a/src/plot.js +++ b/src/plot.js @@ -1,4 +1,4 @@ -import {select} from "d3"; +import {creator, select} from "d3"; import {createChannel, inferChannelScale} from "./channel.js"; import {createContext} from "./context.js"; import {createDimensions} from "./dimensions.js"; @@ -8,6 +8,7 @@ import {Mark} from "./mark.js"; import {axisFx, axisFy, axisX, axisY, gridFx, gridFy, gridX, gridY} from "./marks/axis.js"; import {frame} from "./marks/frame.js"; import {arrayify, isColor, isIterable, isNone, isScaleOptions, map, yes, maybeIntervalTransform} from "./options.js"; +import {createProjection} from "./projection.js"; import {createScales, createScaleFunctions, autoScaleRange, exposeScales} from "./scales.js"; import {innerDimensions, outerDimensions} from "./scales.js"; import {position, registry as scaleRegistry} from "./scales/index.js"; @@ -141,8 +142,26 @@ export function plot(options = {}) { const {fx, fy} = scales; const subdimensions = fx || fy ? innerDimensions(scaleDescriptors, dimensions) : dimensions; const superdimensions = fx || fy ? actualDimensions(scales, dimensions) : dimensions; - const context = createContext(options, subdimensions, className); - const {ownerSVGElement: svg, document} = context; + + // Initialize the context. + const context = createContext(options); + const document = context.document; + const svg = creator("svg").call(document.documentElement); + context.ownerSVGElement = svg; + context.className = className; + context.projection = createProjection(options, subdimensions); + + // Allows e.g. the axis mark to determine faceting lazily. + context.filterFacets = (data, channels) => { + return facetFilter(facets, {channels, groups: facetGroups(data, channels)}); + }; + + // Allows e.g. the tip mark to reference channels and data on other marks. + context.getMarkState = (mark) => { + const state = stateByMark.get(mark); + const facetState = facetStateByMark.get(mark); + return {...state, channels: {...state.channels, ...facetState?.channels}}; + }; // Reinitialize; for deriving channels dependent on other channels. const newByScale = new Set(); @@ -172,15 +191,11 @@ export function plot(options = {}) { } } // If the initializer returns new mark-level facet channels, we must - // also recompute the facet state. + // record that the mark is now faceted. Note: we aren’t actually + // populating the facet state, but subsequently we won’t need it. const {fx, fy} = update.channels; - if (fx != null || fy != null) { - const facetState = facetStateByMark.get(mark) ?? {channels: {}}; - if (fx != null) facetState.channels.fx = fx; - if (fy != null) facetState.channels.fy = fy; - facetState.groups = facetGroups(state.data, facetState.channels); - facetState.facetsIndex = state.facets = facetFilter(facets, facetState); - facetStateByMark.set(mark, facetState); + if ((fx != null || fy != null) && !facetStateByMark.has(mark)) { + facetStateByMark.set(mark, true); } } } diff --git a/test/output/tipRaster.svg b/test/output/tipRaster.svg new file mode 100644 index 0000000000..b480a97cef --- /dev/null +++ b/test/output/tipRaster.svg @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 6853ad36c0..7022ddf26c 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -1,14 +1,24 @@ import * as Plot from "@observablehq/plot"; import * as d3 from "d3"; +function tipped(mark, options = {}) { + return Plot.marks(mark, Plot.tip(mark.data, Plot.pointer(anchor(mark, options)))); +} + +function anchor(mark, options = {}) { + return Plot.initializer({...options, x: null, y: null}, (data, facets, channels, scales, dimensions, context) => { + const xy = {}; + const state = (context as any).getMarkState(mark); + for (const k of ["fx", "fy", "x", "x1", "x2", "y", "y1", "y2"]) if (state.channels[k]) xy[k] = state.channels[k]; + return {data: state.data, facets: state.facets, channels: xy}; + }); +} + export async function tipBar() { const olympians = await d3.csv("data/athletes.csv", d3.autoType); return Plot.plot({ marginLeft: 100, - marks: [ - Plot.barX(olympians, Plot.groupY({x: "count"}, {y: "sport", sort: {y: "x"}})), - Plot.tip(olympians, Plot.pointerY(Plot.groupY({x: "count"}, {y: "sport", anchor: "left"}))) - ] + marks: [tipped(Plot.barX(olympians, Plot.groupY({x: "count"}, {y: "sport", sort: {y: "x"}})))] }); } @@ -123,6 +133,20 @@ export async function tipLine() { }); } +export async function tipRaster() { + const ca55 = await d3.csv("data/ca55-south.csv", d3.autoType); + const domain = {type: "MultiPoint", coordinates: ca55.map((d) => [d.GRID_EAST, d.GRID_NORTH])} as const; + return Plot.plot({ + width: 640, + height: 484, + projection: {type: "reflect-y", inset: 3, domain}, + color: {type: "diverging"}, + marks: [ + tipped(Plot.raster(ca55, {x: "GRID_EAST", y: "GRID_NORTH", fill: "MAG_IGRF90", interpolate: "random-walk"})) + ] + }); +} + export async function tipRule() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); return Plot.plot({ From c394c6e06780743ef3c0dfafb599a2812a6dc80b Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Wed, 10 May 2023 11:09:29 -0700 Subject: [PATCH 45/56] raster nearest --- test/plots/tip.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 7022ddf26c..b49b11de08 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -142,7 +142,7 @@ export async function tipRaster() { projection: {type: "reflect-y", inset: 3, domain}, color: {type: "diverging"}, marks: [ - tipped(Plot.raster(ca55, {x: "GRID_EAST", y: "GRID_NORTH", fill: "MAG_IGRF90", interpolate: "random-walk"})) + tipped(Plot.raster(ca55, {x: "GRID_EAST", y: "GRID_NORTH", fill: "MAG_IGRF90", interpolate: "nearest"})) ] }); } From 3365727bbb831b0c8cbcb9c13c2eaae2444ba9e5 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Wed, 10 May 2023 12:12:12 -0700 Subject: [PATCH 46/56] color swatch; fix f[xy]; no tip aesthetic channels --- src/marks/tip.js | 16 ++++--- src/plot.js | 12 ++--- test/output/tipBinStack.svg | 2 +- test/output/tipCell.svg | 2 +- test/output/tipCellFacet.svg | 4 +- test/output/tipRaster.svg | 2 +- test/plots/tip.ts | 88 ++++++++++-------------------------- 7 files changed, 45 insertions(+), 81 deletions(-) diff --git a/src/marks/tip.js b/src/marks/tip.js index 704f6cd00d..c56dd89286 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -4,8 +4,7 @@ import {create} from "../context.js"; import {formatDefault} from "../format.js"; import {Mark} from "../mark.js"; import {maybeAnchor, maybeFrameAnchor, maybeTuple, number, string} from "../options.js"; -import {applyChannelStyles, applyDirectStyles, applyIndirectStyles} from "../style.js"; -import {applyFrameAnchor, applyTransform, impliedString} from "../style.js"; +import {applyDirectStyles, applyFrameAnchor, applyIndirectStyles, applyTransform, impliedString} from "../style.js"; import {inferTickFormat} from "./axis.js"; import {applyIndirectTextStyles, cut, defaultWidth, ellipsis, monospaceWidth} from "./text.js"; @@ -67,6 +66,7 @@ export class Tip extends Mark { this.fontStyle = string(fontStyle); this.fontVariant = string(fontVariant); this.fontWeight = string(fontWeight); + for (const key in defaults) if (key in this.channels) this[key] = defaults[key]; // apply default even if channel } render(index, scales, channels, dimensions, context) { const mark = this; @@ -100,6 +100,8 @@ export class Tip extends Mark { const formatFx = fx && inferTickFormat(fx); const formatFy = fy && inferTickFormat(fy); + // We don’t call applyChannelStyles because we only use the channels to + // derive the content of the tip, not its aesthetics. const g = create("svg:g", context) .call(applyIndirectStyles, this, dimensions, context) .call(applyIndirectTextStyles, this) @@ -112,7 +114,6 @@ export class Tip extends Mark { .append("g") .attr("transform", (i) => `translate(${px(i)},${py(i)})`) .call(applyDirectStyles, this) - .call(applyChannelStyles, this, channels) .call((g) => g.append("path").attr("filter", pathFilter)) .call((g) => g.append("text").each(function (i) { @@ -137,7 +138,8 @@ export class Tip extends Mark { ? channel2.hint?.length // e.g., stackY’s y1 and y2 ? `${formatDefault(value2 - value1)}` : `${formatDefault(value1)}–${formatDefault(value2)}` - : formatDefault(value1) + : formatDefault(value1), + channel.scale === "color" ? scales.color(value1) : undefined ); } if (index.fi == null) return; // not faceted @@ -152,7 +154,8 @@ export class Tip extends Mark { // just the initial layout of the text; in postrender we will compute the // exact text metrics and translate the text as needed once we know the // tip’s orientation (anchor). - function renderLine(selection, name, value) { + function renderLine(selection, name, value, color) { + name = "\u200b" + name; // zwsp for double-click let title; let w = lineWidth * 100; const [j] = cut(name, w, widthof, ee); @@ -162,7 +165,7 @@ export class Tip extends Mark { value = ""; title = value.trim(); } else { - value = `${name ? " " : ""}${value}\u200b`; // zwsp for double-click + if (name) value = " " + value; const [k] = cut(value, w - widthof(name), widthof, ee); if (k >= 0) { // value is truncated @@ -173,6 +176,7 @@ export class Tip extends Mark { const line = selection.append("tspan").attr("x", 0).attr("dy", `${lineHeight}em`); line.append("tspan").attr("font-weight", "bold").text(name); if (value) line.append(() => document.createTextNode(value)); + if (color) line.append("tspan").text(" ■").attr("fill", color).style("user-select", "none"); if (title) line.append("title").text(title); } diff --git a/src/plot.js b/src/plot.js index 9601e1d378..2ae56ee066 100644 --- a/src/plot.js +++ b/src/plot.js @@ -176,9 +176,10 @@ export function plot(options = {}) { state.facets = update.facets; } if (update.channels !== undefined) { - inferChannelScales(update.channels); - Object.assign(state.channels, update.channels); - for (const channel of Object.values(update.channels)) { + const {fx, fy, ...channels} = update.channels; // separate facet channels + inferChannelScales(channels); + Object.assign(state.channels, channels); + for (const channel of Object.values(channels)) { const {scale} = channel; // Initializers aren’t allowed to redefine position scales as this // would introduce a circular dependency; so simply scale these @@ -193,10 +194,7 @@ export function plot(options = {}) { // If the initializer returns new mark-level facet channels, we must // record that the mark is now faceted. Note: we aren’t actually // populating the facet state, but subsequently we won’t need it. - const {fx, fy} = update.channels; - if ((fx != null || fy != null) && !facetStateByMark.has(mark)) { - facetStateByMark.set(mark, true); - } + if (fx != null || fy != null) facetStateByMark.set(mark, true); } } } diff --git a/test/output/tipBinStack.svg b/test/output/tipBinStack.svg index 8b4c61cd58..9d96f3d16d 100644 --- a/test/output/tipBinStack.svg +++ b/test/output/tipBinStack.svg @@ -185,5 +185,5 @@ - + \ No newline at end of file diff --git a/test/output/tipCell.svg b/test/output/tipCell.svg index dfd8412195..5c72903d12 100644 --- a/test/output/tipCell.svg +++ b/test/output/tipCell.svg @@ -145,5 +145,5 @@ - + \ No newline at end of file diff --git a/test/output/tipCellFacet.svg b/test/output/tipCellFacet.svg index c7d9d318fb..06b40c5f6f 100644 --- a/test/output/tipCellFacet.svg +++ b/test/output/tipCellFacet.svg @@ -154,7 +154,7 @@ - - + + \ No newline at end of file diff --git a/test/output/tipRaster.svg b/test/output/tipRaster.svg index b480a97cef..66a9e730af 100644 --- a/test/output/tipRaster.svg +++ b/test/output/tipRaster.svg @@ -14,7 +14,7 @@ } - + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index b49b11de08..fb0b5286d2 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -1,45 +1,37 @@ import * as Plot from "@observablehq/plot"; import * as d3 from "d3"; -function tipped(mark, options = {}) { - return Plot.marks(mark, Plot.tip(mark.data, Plot.pointer(anchor(mark, options)))); +function tipped(mark, options = {}, pointer = Plot.pointer) { + return Plot.marks(mark, Plot.tip(mark.data, pointer(derive(mark, options)))); } -function anchor(mark, options = {}) { +function tippedX(mark, options = {}) { + return tipped(mark, options, Plot.pointerX); +} + +function tippedY(mark, options = {}) { + return tipped(mark, options, Plot.pointerY); +} + +function derive(mark, options = {}) { return Plot.initializer({...options, x: null, y: null}, (data, facets, channels, scales, dimensions, context) => { - const xy = {}; - const state = (context as any).getMarkState(mark); - for (const k of ["fx", "fy", "x", "x1", "x2", "y", "y1", "y2"]) if (state.channels[k]) xy[k] = state.channels[k]; - return {data: state.data, facets: state.facets, channels: xy}; + return (context as any).getMarkState(mark); }); } export async function tipBar() { const olympians = await d3.csv("data/athletes.csv", d3.autoType); - return Plot.plot({ - marginLeft: 100, - marks: [tipped(Plot.barX(olympians, Plot.groupY({x: "count"}, {y: "sport", sort: {y: "x"}})))] - }); + return tippedY(Plot.barX(olympians, Plot.groupY({x: "count"}, {y: "sport", sort: {y: "x"}}))).plot({marginLeft: 100}); } export async function tipBin() { const olympians = await d3.csv("data/athletes.csv", d3.autoType); - return Plot.plot({ - marks: [ - Plot.rectY(olympians, Plot.binX({y: "count"}, {x: "weight"})), - Plot.tip(olympians, Plot.pointerX(Plot.binX({y: "count"}, {x: "weight"}))) - ] - }); + return tippedX(Plot.rectY(olympians, Plot.binX({y: "count"}, {x: "weight"}))).plot(); } export async function tipBinStack() { const olympians = await d3.csv("data/athletes.csv", d3.autoType); - return Plot.plot({ - marks: [ - Plot.rectY(olympians, Plot.stackY({}, Plot.binX({y: "count"}, {x: "weight", fill: "sex"}))), - Plot.tip(olympians, Plot.pointerX(Plot.stackY({}, Plot.binX({y: "count"}, {x: "weight", stroke: "sex"})))) - ] - }); + return tippedX(Plot.rectY(olympians, Plot.binX({y: "count"}, {x: "weight", fill: "sex"}))).plot(); } export async function tipCell() { @@ -48,10 +40,7 @@ export async function tipCell() { height: 400, marginLeft: 100, color: {scheme: "blues"}, - marks: [ - Plot.cell(olympians, Plot.group({fill: "count"}, {x: "sex", y: "sport"})), - Plot.tip(olympians, Plot.pointerY(Plot.group({stroke: "count"}, {x: "sex", y: "sport"}))) - ] + marks: [tippedY(Plot.cell(olympians, Plot.group({fill: "count"}, {x: "sex", y: "sport"})))] }); } @@ -61,32 +50,18 @@ export async function tipCellFacet() { height: 400, marginLeft: 100, color: {scheme: "blues"}, - marks: [ - Plot.cell(olympians, Plot.groupY({fill: "count"}, {fx: "sex", y: "sport"})), - Plot.tip(olympians, Plot.pointerY(Plot.groupY({stroke: "count"}, {fx: "sex", y: "sport"}))) - ] + marks: [tippedY(Plot.cell(olympians, Plot.groupY({fill: "count"}, {fx: "sex", y: "sport"})))] }); } export async function tipDodge() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); - return Plot.plot({ - height: 160, - marks: [ - Plot.dot(penguins, Plot.dodgeY({x: "culmen_length_mm", r: "body_mass_g"})), - Plot.tip(penguins, Plot.pointer(Plot.dodgeY({x: "culmen_length_mm", r: "body_mass_g"}))) - ] - }); + return tipped(Plot.dot(penguins, Plot.dodgeY({x: "culmen_length_mm", r: "body_mass_g"}))).plot({height: 160}); } export async function tipDot() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); - return Plot.plot({ - marks: [ - Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm", stroke: "sex"}), - Plot.tip(penguins, Plot.pointer({x: "culmen_length_mm", y: "culmen_depth_mm"})) - ] - }); + return tipped(Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm", stroke: "sex"})).plot(); } export async function tipDotFacets() { @@ -98,10 +73,8 @@ export async function tipDotFacets() { interval: "10 years" }, marks: [ - Plot.dot(athletes, {x: "weight", y: "height", fx: "sex", fy: "date_of_birth"}), - Plot.tip( - athletes, - Plot.pointer({ + tipped( + Plot.dot(athletes, { x: "weight", y: "height", fx: "sex", @@ -118,19 +91,12 @@ export async function tipDotFacets() { export async function tipHexbin() { const olympians = await d3.csv("data/athletes.csv", d3.autoType); - return Plot.plot({ - marks: [ - Plot.hexagon(olympians, Plot.hexbin({r: "count"}, {x: "weight", y: "height"})), - Plot.tip(olympians, Plot.pointer(Plot.hexbin({r: "count"}, {x: "weight", y: "height"}))) - ] - }); + return tipped(Plot.hexagon(olympians, Plot.hexbin({r: "count"}, {x: "weight", y: "height"}))).plot(); } export async function tipLine() { const aapl = await d3.csv("data/aapl.csv", d3.autoType); - return Plot.plot({ - marks: [Plot.lineY(aapl, {x: "Date", y: "Close"}), Plot.tip(aapl, Plot.pointerX({x: "Date", y: "Close"}))] - }); + return tippedX(Plot.lineY(aapl, {x: "Date", y: "Close"})).plot(); } export async function tipRaster() { @@ -141,15 +107,11 @@ export async function tipRaster() { height: 484, projection: {type: "reflect-y", inset: 3, domain}, color: {type: "diverging"}, - marks: [ - tipped(Plot.raster(ca55, {x: "GRID_EAST", y: "GRID_NORTH", fill: "MAG_IGRF90", interpolate: "nearest"})) - ] + marks: [tipped(Plot.raster(ca55, {x: "GRID_EAST", y: "GRID_NORTH", fill: "MAG_IGRF90", interpolate: "nearest"}))] }); } export async function tipRule() { const penguins = await d3.csv("data/penguins.csv", d3.autoType); - return Plot.plot({ - marks: [Plot.ruleX(penguins, {x: "body_mass_g"}), Plot.tip(penguins, Plot.pointerX({x: "body_mass_g"}))] - }); + return tippedX(Plot.ruleX(penguins, {x: "body_mass_g"})).plot(); } From 4570bb9b5b5160bd193f772e550866286372dbe0 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Wed, 10 May 2023 13:37:45 -0700 Subject: [PATCH 47/56] multi-line, summary ariaLabel --- src/marks/tip.js | 10 ++++++---- src/transforms/group.js | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/marks/tip.js b/src/marks/tip.js index c56dd89286..d1dec0c2cb 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -124,6 +124,7 @@ export class Tip extends Mark { this.setAttribute("stroke", "none"); // iteratively render each channel value for (const key in sources) { + if (key === "ariaLabel") continue; // see below const channel = getSource(sources, key); if (!channel) continue; // e.g., dodgeY’s y const channel1 = getSource1(sources, key); @@ -142,9 +143,10 @@ export class Tip extends Mark { channel.scale === "color" ? scales.color(value1) : undefined ); } - if (index.fi == null) return; // not faceted - if (fx) renderLine(that, fx.label ?? "fx", formatFx(index.fx)); - if (fy) renderLine(that, fy.label ?? "fy", formatFy(index.fy)); + if (index.fi != null && fx) renderLine(that, fx.label ?? "fx", formatFx(index.fx)); + if (index.fi != null && fy) renderLine(that, fy.label ?? "fy", formatFy(index.fy)); + const ariaLabel = String(getSource(sources, "ariaLabel")?.value[i] ?? ""); + if (ariaLabel) for (const value of ariaLabel.split(/\r\n?|\n/g)) renderLine(that, "", value); }) ) ); @@ -155,7 +157,7 @@ export class Tip extends Mark { // exact text metrics and translate the text as needed once we know the // tip’s orientation (anchor). function renderLine(selection, name, value, color) { - name = "\u200b" + name; // zwsp for double-click + if (name) name = "\u200b" + name; // zwsp for double-click let title; let w = lineWidth * 100; const [j] = cut(name, w, widthof, ee); diff --git a/src/transforms/group.js b/src/transforms/group.js index 390a711620..f1aae17d0d 100644 --- a/src/transforms/group.js +++ b/src/transforms/group.js @@ -170,7 +170,8 @@ export function hasOutput(outputs, ...names) { export function maybeOutputs(outputs, inputs, asOutput = maybeOutput) { const entries = Object.entries(outputs); // Propagate standard mark channels by default. - if (inputs.title != null && outputs.title === undefined) entries.push(["title", reduceTitle]); + if (inputs.ariaLabel != null && outputs.ariaLabel === undefined) entries.push(["ariaLabel", reduceTop]); + if (inputs.title != null && outputs.title === undefined) entries.push(["title", reduceTop]); if (inputs.href != null && outputs.href === undefined) entries.push(["href", reduceFirst]); return entries .filter(([, reduce]) => reduce !== undefined) @@ -346,7 +347,7 @@ export const reduceFirst = { } }; -const reduceTitle = { +const reduceTop = { reduceIndex(I, X) { const n = 5; const groups = sort( From 36aa6b1b29aa89e29d6bcad1cb56fdee5cb9901b Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Wed, 10 May 2023 16:09:51 -0700 Subject: [PATCH 48/56] tidier formatting --- src/marks/tip.js | 77 ++++++++++++++++++++++++----------------- src/transforms/group.js | 5 ++- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/marks/tip.js b/src/marks/tip.js index d1dec0c2cb..ed53e6d8ed 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -14,6 +14,9 @@ const defaults = { stroke: "currentColor" }; +// These channels are not displayed in the tip; TODO allow customization. +const ignoreChannels = new Set(["geometry", "title", "href", "src", "ariaLabel"]); + export class Tip extends Mark { constructor(data, options = {}) { const { @@ -75,6 +78,7 @@ export class Tip extends Mark { const {anchor, monospace, lineHeight, lineWidth} = this; const {textPadding: r, pointerSize: m, pathFilter} = this; const {marginTop, marginLeft} = dimensions; + const sources = getSources(channels); // The anchor position is the middle of x1 & y1 and x2 & y2, if available, // or x & y; the former is considered more specific because it’s how we @@ -82,7 +86,7 @@ export class Tip extends Mark { // unspecified, we fallback to the frame anchor. We also need to know the // facet offsets to detect when the tip would draw outside the plot, and // thus we need to change the orientation. - const {x: X, y: Y, x1: X1, y1: Y1, x2: X2, y2: Y2, channels: sources} = channels; + const {x: X, y: Y, x1: X1, y1: Y1, x2: X2, y2: Y2} = channels; const [cx, cy] = applyFrameAnchor(this, dimensions); const ox = fx ? fx(index.fx) - marginLeft : 0; const oy = fy ? fy(index.fy) - marginTop : 0; @@ -100,6 +104,24 @@ export class Tip extends Mark { const formatFx = fx && inferTickFormat(fx); const formatFy = fy && inferTickFormat(fy); + function* format(sources, i) { + for (const key in sources) { + if (key === "x1" && "x2" in sources) continue; + if (key === "y1" && "y2" in sources) continue; + const channel = sources[key]; + const color = channel.scale === "color" ? channels[key][i] : undefined; + if (key === "x2" && "x1" in sources) { + yield [formatLabel(scales, channel) ?? "x", formatPair(sources.x1, channel, i)]; + } else if (key === "y2" && "y1" in sources) { + yield [formatLabel(scales, channel) ?? "y", formatPair(sources.y1, channel, i)]; + } else { + yield [formatLabel(scales, channel) ?? key, formatDefault(channel.value[i]), color]; + } + } + if (index.fi != null && fx) yield [fx.label ?? "fx", formatFx(index.fx)]; + if (index.fi != null && fy) yield [fy.label ?? "fy", formatFy(index.fy)]; + } + // We don’t call applyChannelStyles because we only use the channels to // derive the content of the tip, not its aesthetics. const g = create("svg:g", context) @@ -123,30 +145,9 @@ export class Tip extends Mark { this.setAttribute("fill-opacity", 1); this.setAttribute("stroke", "none"); // iteratively render each channel value - for (const key in sources) { - if (key === "ariaLabel") continue; // see below - const channel = getSource(sources, key); - if (!channel) continue; // e.g., dodgeY’s y - const channel1 = getSource1(sources, key); - if (channel1) continue; // already displayed - const channel2 = getSource2(sources, key); - const value1 = channel.value[i]; - const value2 = channel2?.value[i]; - renderLine( - that, - scales[channel.scale]?.label ?? channel.label ?? key, - channel2 // e.g., binX’s x1 and x2 - ? channel2.hint?.length // e.g., stackY’s y1 and y2 - ? `${formatDefault(value2 - value1)}` - : `${formatDefault(value1)}–${formatDefault(value2)}` - : formatDefault(value1), - channel.scale === "color" ? scales.color(value1) : undefined - ); + for (const [name, value, color] of format(sources, i)) { + renderLine(that, name, value, color); } - if (index.fi != null && fx) renderLine(that, fx.label ?? "fx", formatFx(index.fx)); - if (index.fi != null && fy) renderLine(that, fy.label ?? "fy", formatFy(index.fy)); - const ariaLabel = String(getSource(sources, "ariaLabel")?.value[i] ?? ""); - if (ariaLabel) for (const value of ariaLabel.split(/\r\n?|\n/g)) renderLine(that, "", value); }) ) ); @@ -229,14 +230,6 @@ export function tip(data, {x, y, ...options} = {}) { return new Tip(data, {...options, x, y}); } -function getSource1(channels, key) { - return key === "x2" ? getSource(channels, "x1") : key === "y2" ? getSource(channels, "y1") : null; -} - -function getSource2(channels, key) { - return key === "x1" ? getSource(channels, "x2") : key === "y1" ? getSource(channels, "y2") : null; -} - function getLineOffset(anchor, length, lineHeight) { return /^top(?:-|$)/.test(anchor) ? 0.94 - lineHeight @@ -292,3 +285,23 @@ function getPath(anchor, m, r, width, height) { return `M0,0l${m / 2},${-m / 2}v${m / 2 - h / 2}h${w}v${h}h${-w}v${m / 2 - h / 2}z`; } } + +function getSources({channels}) { + const sources = {}; + for (const key in channels) { + if (ignoreChannels.has(key)) continue; + const source = getSource(channels, key); + if (source) sources[key] = source; + } + return sources; +} + +function formatPair(c1, c2, i) { + return c2.hint?.length // e.g., stackY’s y1 and y2 + ? `${formatDefault(c2.value[i] - c1.value[i])}` + : `${formatDefault(c1.value[i])}–${formatDefault(c2.value[i])}`; +} + +function formatLabel(scales, c) { + return scales[c.scale]?.label ?? c?.label; +} diff --git a/src/transforms/group.js b/src/transforms/group.js index f1aae17d0d..390a711620 100644 --- a/src/transforms/group.js +++ b/src/transforms/group.js @@ -170,8 +170,7 @@ export function hasOutput(outputs, ...names) { export function maybeOutputs(outputs, inputs, asOutput = maybeOutput) { const entries = Object.entries(outputs); // Propagate standard mark channels by default. - if (inputs.ariaLabel != null && outputs.ariaLabel === undefined) entries.push(["ariaLabel", reduceTop]); - if (inputs.title != null && outputs.title === undefined) entries.push(["title", reduceTop]); + if (inputs.title != null && outputs.title === undefined) entries.push(["title", reduceTitle]); if (inputs.href != null && outputs.href === undefined) entries.push(["href", reduceFirst]); return entries .filter(([, reduce]) => reduce !== undefined) @@ -347,7 +346,7 @@ export const reduceFirst = { } }; -const reduceTop = { +const reduceTitle = { reduceIndex(I, X) { const n = 5; const groups = sort( From 383cb40edc624d8bbce371ea8eff69d714071ecf Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Wed, 10 May 2023 20:38:23 -0700 Subject: [PATCH 49/56] tidier crosshair --- src/marks/crosshair.js | 62 +++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/src/marks/crosshair.js b/src/marks/crosshair.js index 1cab5899be..9c1b06020a 100644 --- a/src/marks/crosshair.js +++ b/src/marks/crosshair.js @@ -6,33 +6,24 @@ import {ruleX, ruleY} from "./rule.js"; import {text} from "./text.js"; export function crosshair(data, options = {}) { - const {x, y} = options; - const p = pointer({px: x, py: y}); - return marks( - ruleX(data, ruleXOptions(p, options, x)), - ruleY(data, ruleYOptions(p, options, y)), - text(data, textXOptions(p, options, x)), - text(data, textYOptions(p, options, y)) - ); + const p = pointer({px: options.x, py: options.y}); + return marks(pruleX(data, p, options), pruleY(data, p, options), ptextX(data, p, options), ptextY(data, p, options)); } export function crosshairX(data, options = {}) { - const {x} = options; - const p = pointerX({px: x}); - return marks(ruleX(data, ruleXOptions(p, options, x)), text(data, textXOptions(p, options, x))); + const p = pointerX({px: options.x}); + return marks(pruleX(data, p, options), ptextX(data, p, options)); } export function crosshairY(data, options = {}) { - const {y} = options; - const p = pointerY({py: y}); - return marks(ruleY(data, ruleYOptions(p, options, y)), text(data, textYOptions(p, options, y))); + const p = pointerY({py: options.y}); + return marks(pruleY(data, p, options), ptextY(data, p, options)); } function markOptions( + k, {channels: pointerChannels, ...pointerOptions}, - {facet, facetAnchor, fx, fy, channels, transform, initializer}, - x, - y + {facet, facetAnchor, fx, fy, [k]: p, channels, transform, initializer} ) { return { ...pointerOptions, @@ -40,60 +31,57 @@ function markOptions( facetAnchor, fx, fy, - x, - y, + [k]: p, channels: {...pointerChannels, ...channels}, transform, - initializer: pxpy(initializer, x, y) + initializer: pxpy(k, initializer) }; } // Wrap the initializer, if any, mapping px and py to x and y temporarily (e.g., // for hexbin) then mapping back to px and py for rendering. -function pxpy(i, ox, oy) { +function pxpy(k, i) { if (i == null) return i; return function (data, facets, {x: x1, y: y1, px, py, ...c1}, ...args) { const {channels: {x, y, ...c} = {}, ...rest} = i.call(this, data, facets, {...c1, x: px, y: py}, ...args); return { channels: { ...c, - ...(x && {px: x, ...(ox !== null && {x})}), - ...(y && {py: y, ...(oy !== null && {y})}) + ...(x && {px: x, ...(k === "x" && {x})}), + ...(y && {py: y, ...(k === "y" && {y})}) }, ...rest }; }; } -function ruleXOptions(pointerOptions, options, x) { - return ruleOptions(pointerOptions, options, x, null); +function pruleX(data, pointerOptions, options) { + return ruleX(data, ruleOptions("x", pointerOptions, options)); } -function ruleYOptions(pointerOptions, options, y) { - return ruleOptions(pointerOptions, options, null, y); +function pruleY(data, pointerOptions, options) { + return ruleY(data, ruleOptions("y", pointerOptions, options)); } -function ruleOptions(pointerOptions, options, x, y) { +function ruleOptions(k, pointerOptions, options) { const { color = "currentColor", ruleStroke: stroke = color, ruleStrokeOpacity: strokeOpacity = 0.2, ruleStrokeWidth: strokeWidth } = options; - return {...markOptions(pointerOptions, options, x, y), stroke, strokeOpacity, strokeWidth}; + return {...markOptions(k, pointerOptions, options), stroke, strokeOpacity, strokeWidth}; } -function textXOptions(pointerOptions, options, x) { - options = textChannel("x", options); - return textOptions({...pointerOptions, dy: 9, frameAnchor: "bottom", lineAnchor: "top"}, options, x, null); +function ptextX(data, pointerOptions, options) { + return text(data, textOptions("x", {...pointerOptions, dy: 9, frameAnchor: "bottom", lineAnchor: "top"}, options)); } -function textYOptions(pointerOptions, options, y) { - options = textChannel("y", options); - return textOptions({...pointerOptions, dx: -9, frameAnchor: "left", textAnchor: "end"}, options, null, y); +function ptextY(data, pointerOptions, options) { + return text(data, textOptions("y", {...pointerOptions, dx: -9, frameAnchor: "left", textAnchor: "end"}, options)); } -function textOptions(pointerOptions, options, x, y) { +function textOptions(k, pointerOptions, options) { const { color = "currentColor", textFill: fill = color, @@ -101,7 +89,7 @@ function textOptions(pointerOptions, options, x, y) { textStrokeOpacity: strokeOpacity, textStrokeWidth: strokeWidth = 5 } = options; - return {...markOptions(pointerOptions, options, x, y), fill, stroke, strokeOpacity, strokeWidth}; + return {...markOptions(k, pointerOptions, textChannel(k, options)), fill, stroke, strokeOpacity, strokeWidth}; } // Rather than aliasing text to have the same definition as x and y, we use an From c0ec5c505d06acad63efa9001751ea32dfdf8f29 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Thu, 11 May 2023 08:22:51 -0700 Subject: [PATCH 50/56] project p[xy], too --- src/mark.js | 28 ++++++++++++++++------------ src/projection.js | 30 ++++++++++++++++-------------- test/marks/rule-test.js | 7 ------- test/output/tipGeoCentroid.svg | 21 +++++++++++++++++++++ test/plots/tip.ts | 21 +++++++++++++++++++++ 5 files changed, 74 insertions(+), 33 deletions(-) create mode 100644 test/output/tipGeoCentroid.svg diff --git a/src/mark.js b/src/mark.js index 74e6ed72c9..e5a1b3a5e6 100644 --- a/src/mark.js +++ b/src/mark.js @@ -2,7 +2,7 @@ import {channelDomain, createChannels, valueObject} from "./channel.js"; import {defined} from "./defined.js"; import {maybeFacetAnchor} from "./facet.js"; import {arrayify, isDomainSort, isOptions, keyword, maybeNamed, range, singleton} from "./options.js"; -import {maybeProject} from "./projection.js"; +import {project} from "./projection.js"; import {maybeClip, styles} from "./style.js"; import {basic, initializer} from "./transforms/basic.js"; @@ -104,18 +104,22 @@ export class Mark { } return index; } - // If there is a projection, and there are both x and y channels (or x1 and - // y1, or x2 and y2 channels), and those channels are associated with the x - // and y scale respectively (and not already in screen coordinates as with an - // initializer), then apply the projection, replacing the x and y values. Note - // that the x and y scales themselves don’t exist if there is a projection, - // but whether the channels are associated with scales still determines - // whether the projection should apply; think of the projection as a - // combination xy-scale. + // If there is a projection, and there are paired x and y channels associated + // with the x and y scale respectively (and not already in screen coordinates + // as with an initializer), then apply the projection, replacing the x and y + // values. Note that the x and y scales themselves don’t exist if there is a + // projection, but whether the channels are associated with scales still + // determines whether the projection should apply; think of the projection as + // a combination xy-scale. project(channels, values, context) { - maybeProject("x", "y", channels, values, context); - maybeProject("x1", "y1", channels, values, context); - maybeProject("x2", "y2", channels, values, context); + for (const cx in channels) { + if (channels[cx].scale === "x" && /^x|x$/.test(cx)) { + const cy = cx.replace(/^x|x$/, "y"); + if (cy in channels && channels[cy].scale === "y") { + project(cx, cy, values, context.projection); + } + } + } } scale(channels, scales, context) { const values = valueObject(channels, scales); diff --git a/src/projection.js b/src/projection.js index 07e8f1e5f2..b228c6b117 100644 --- a/src/projection.js +++ b/src/projection.js @@ -204,19 +204,21 @@ const reflectY = constant( // Applies a point-wise projection to the given paired x and y channels. // Note: mutates values! -export function maybeProject(cx, cy, channels, values, context) { - const x = channels[cx] && channels[cx].scale === "x"; - const y = channels[cy] && channels[cy].scale === "y"; - if (x && y) { - project(cx, cy, values, context.projection); - } else if (x) { - throw new Error(`projection requires paired x and y channels; ${cx} is missing ${cy}`); - } else if (y) { - throw new Error(`projection requires paired x and y channels; ${cy} is missing ${cx}`); - } -} +// export function maybeProject(cx, cy, channels, values, context) { +// const x = channels[cx] && channels[cx].scale === "x"; +// const y = channels[cy] && channels[cy].scale === "y"; +// if (x && y) { +// project(cx, cy, values, context.projection); +// } else if (x) { +// throw new Error(`projection requires paired x and y channels; ${cx} is missing ${cy}`); +// } else if (y) { +// throw new Error(`projection requires paired x and y channels; ${cy} is missing ${cx}`); +// } +// } -function project(cx, cy, values, projection) { +// Applies a point-wise projection to the given paired x and y channels. +// Note: mutates values! +export function project(cx, cy, values, projection) { const x = values[cx]; const y = values[cy]; const n = x.length; @@ -254,13 +256,13 @@ export function projectionAspectRatio(projection, marks) { // Extract the (possibly) scaled values for the x and y channels, and apply the // projection if any. -export function applyPosition(channels, scales, context) { +export function applyPosition(channels, scales, {projection}) { const {x, y} = channels; let position = {}; if (x) position.x = x; if (y) position.y = y; position = valueObject(position, scales); - if (context.projection) maybeProject("x", "y", channels, position, context); + if (projection && x?.scale === "x" && y?.scale === "y") project("x", "y", position, projection); if (x) position.x = coerceNumbers(position.x); if (y) position.y = coerceNumbers(position.y); return position; diff --git a/test/marks/rule-test.js b/test/marks/rule-test.js index f6f91e3b3d..1b3fdac6a3 100644 --- a/test/marks/rule-test.js +++ b/test/marks/rule-test.js @@ -191,10 +191,3 @@ it("ruleY(data, {x1, x2, y}) specifies x1, x2, y", () => { assert.strictEqual(y.value, "2"); assert.strictEqual(y.scale, "y"); }); - -it("rule() is incompatible with a projection", () => { - assert.throws( - () => Plot.ruleX([]).plot({projection: {stream: () => ({})}}), - /projection requires paired x and y channels; x is missing y/ - ); -}); diff --git a/test/output/tipGeoCentroid.svg b/test/output/tipGeoCentroid.svg new file mode 100644 index 0000000000..462df284b3 --- /dev/null +++ b/test/output/tipGeoCentroid.svg @@ -0,0 +1,21 @@ + + + + + + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index fb0b5286d2..41cad58942 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -1,5 +1,6 @@ import * as Plot from "@observablehq/plot"; import * as d3 from "d3"; +import {feature, mesh} from "topojson-client"; function tipped(mark, options = {}, pointer = Plot.pointer) { return Plot.marks(mark, Plot.tip(mark.data, pointer(derive(mark, options)))); @@ -89,6 +90,26 @@ export async function tipDotFacets() { }); } +export async function tipGeoCentroid() { + const [[counties, countymesh]] = await Promise.all([ + d3 + .json("data/us-counties-10m.json") + .then((us) => [feature(us, us.objects.counties), mesh(us, us.objects.counties)]) + ]); + const {x, y} = Plot.geoCentroid(); + const pointer = Plot.pointer({px: x, py: y, x, y}); + return Plot.plot({ + width: 960, + height: 600, + projection: "albers-usa", + marks: [ + Plot.geo(countymesh), + Plot.geo(counties, {...pointer, stroke: "red", strokeWidth: 2}), + Plot.tip(counties.features, {...pointer, channels: {name: {value: (d) => d.properties.name}}}) + ] + }); +} + export async function tipHexbin() { const olympians = await d3.csv("data/athletes.csv", d3.autoType); return tipped(Plot.hexagon(olympians, Plot.hexbin({r: "count"}, {x: "weight", y: "height"}))).plot(); From 5f9c77e27f4f38ed813251f1a9aeba136504d994 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Thu, 11 May 2023 08:26:53 -0700 Subject: [PATCH 51/56] centroid test --- src/transforms/centroid.js | 2 +- test/plots/tip.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/transforms/centroid.js b/src/transforms/centroid.js index 0588d681c0..6be53a1fc0 100644 --- a/src/transforms/centroid.js +++ b/src/transforms/centroid.js @@ -11,7 +11,7 @@ export function centroid({geometry = identity, ...options} = {}) { const Y = new Float64Array(n); const path = geoPath(projection); for (let i = 0; i < n; ++i) [X[i], Y[i]] = path.centroid(G[i]); - return {data, facets, channels: {x: {value: X}, y: {value: Y}}}; + return {data, facets, channels: {x: {value: X, source: null}, y: {value: Y, source: null}}}; }); } diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 41cad58942..21fa915aa2 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -96,8 +96,10 @@ export async function tipGeoCentroid() { .json("data/us-counties-10m.json") .then((us) => [feature(us, us.objects.counties), mesh(us, us.objects.counties)]) ]); - const {x, y} = Plot.geoCentroid(); - const pointer = Plot.pointer({px: x, py: y, x, y}); + // Alternatively, using geoCentroid: + // const {x, y} = Plot.geoCentroid(); + // const pointer = Plot.pointer({px: x, py: y, x, y}); + const pointer = Plot.pointer(Plot.centroid()); return Plot.plot({ width: 960, height: 600, From 74e8423269f981612f073583a338e75627083bbb Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Thu, 11 May 2023 08:28:59 -0700 Subject: [PATCH 52/56] geoCentroid test --- test/plots/tip.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 21fa915aa2..0a0322fa96 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -96,10 +96,10 @@ export async function tipGeoCentroid() { .json("data/us-counties-10m.json") .then((us) => [feature(us, us.objects.counties), mesh(us, us.objects.counties)]) ]); - // Alternatively, using geoCentroid: - // const {x, y} = Plot.geoCentroid(); - // const pointer = Plot.pointer({px: x, py: y, x, y}); - const pointer = Plot.pointer(Plot.centroid()); + // Alternatively, using centroid (slower): + // const pointer = Plot.pointer(Plot.centroid()); + const {x, y} = Plot.geoCentroid(); + const pointer = Plot.pointer({px: x, py: y, x, y}); return Plot.plot({ width: 960, height: 600, From 0003e4f6ab490600a08f9af783b739ca2a3bb8ba Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Thu, 11 May 2023 08:41:11 -0700 Subject: [PATCH 53/56] shorthand extra channels --- src/channel.d.ts | 2 +- src/mark.d.ts | 4 ++-- src/mark.js | 3 ++- src/options.js | 9 +++++++++ test/plots/tip.ts | 7 ++----- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/channel.d.ts b/src/channel.d.ts index 11a6814b29..1b10f889ec 100644 --- a/src/channel.d.ts +++ b/src/channel.d.ts @@ -61,7 +61,7 @@ export type ChannelName = * An object literal of channel definitions. This is also used to represent * materialized channel states after mark initialization. */ -export type Channels = Record; +export type Channels = {[key in ChannelName]?: Channel}; /** * A channel definition. This is also used to represent the materialized channel diff --git a/src/mark.d.ts b/src/mark.d.ts index 6c497d3acf..cfcecc55c8 100644 --- a/src/mark.d.ts +++ b/src/mark.d.ts @@ -1,4 +1,4 @@ -import type {ChannelDomainSort, Channels, ChannelValue, ChannelValues, ChannelValueSpec} from "./channel.js"; +import type {Channel, ChannelDomainSort, ChannelValue, ChannelValues, ChannelValueSpec} from "./channel.js"; import type {Context} from "./context.js"; import type {Dimensions} from "./dimensions.js"; import type {plot} from "./plot.js"; @@ -448,7 +448,7 @@ export interface MarkOptions { * An object defining additional custom channels. This meta option may be used * by an **initializer** to declare extra channels. */ - channels?: Channels; + channels?: Record; } /** The abstract base class for Mark implementations. */ diff --git a/src/mark.js b/src/mark.js index e5a1b3a5e6..d268a33434 100644 --- a/src/mark.js +++ b/src/mark.js @@ -1,6 +1,7 @@ import {channelDomain, createChannels, valueObject} from "./channel.js"; import {defined} from "./defined.js"; import {maybeFacetAnchor} from "./facet.js"; +import {maybeValues} from "./options.js"; import {arrayify, isDomainSort, isOptions, keyword, maybeNamed, range, singleton} from "./options.js"; import {project} from "./projection.js"; import {maybeClip, styles} from "./style.js"; @@ -38,7 +39,7 @@ export class Mark { } this.facetAnchor = maybeFacetAnchor(facetAnchor); channels = maybeNamed(channels); - if (extraChannels !== undefined) channels = {...maybeNamed(extraChannels), ...channels}; + if (extraChannels !== undefined) channels = {...maybeValues(maybeNamed(extraChannels)), ...channels}; if (defaults !== undefined) channels = {...styles(this, options, defaults), ...channels}; this.channels = Object.fromEntries( Object.entries(channels) diff --git a/src/options.js b/src/options.js index e05a6e2c5b..02e412083b 100644 --- a/src/options.js +++ b/src/options.js @@ -328,6 +328,15 @@ export function maybeValue(value) { return value === undefined || isOptions(value) ? value : {value}; } +// Like maybeValue, but for an object for values. +export function maybeValues(channels) { + return Object.fromEntries( + Object.entries(channels).map(([name, channel]) => { + return [name, maybeValue(channel)]; + }) + ); +} + // Coerces the given channel values (if any) to numbers. This is useful when // values will be interpolated into other code, such as an SVG transform, and // where we don’t wish to allow unexpected behavior for weird input. diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 0a0322fa96..ad271cabcc 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -80,10 +80,7 @@ export async function tipDotFacets() { y: "height", fx: "sex", fy: "date_of_birth", - channels: { - name: {value: "name"}, - sport: {value: "sport"} - } + channels: {name: "name", sport: "sport"} }) ) ] @@ -107,7 +104,7 @@ export async function tipGeoCentroid() { marks: [ Plot.geo(countymesh), Plot.geo(counties, {...pointer, stroke: "red", strokeWidth: 2}), - Plot.tip(counties.features, {...pointer, channels: {name: {value: (d) => d.properties.name}}}) + Plot.tip(counties.features, {...pointer, channels: {name: (d) => d.properties.name}}) ] }); } From 727c45bf2b0ed3dbfe2fafe26c23a8c9a860328a Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Thu, 11 May 2023 11:34:10 -0700 Subject: [PATCH 54/56] no pointer-specific state --- src/interactions/pointer.js | 3 +- src/mark.d.ts | 3 + test/output/tipDotFilter.svg | 395 +++++++++++++++++++++++++++++++++++ test/plots/tip.ts | 8 + 4 files changed, 408 insertions(+), 1 deletion(-) create mode 100644 test/output/tipDotFilter.svg diff --git a/src/interactions/pointer.js b/src/interactions/pointer.js index 7289e14bdb..ba6e914084 100644 --- a/src/interactions/pointer.js +++ b/src/interactions/pointer.js @@ -1,6 +1,8 @@ import {pointer as pointof} from "d3"; import {applyFrameAnchor} from "../style.js"; +const states = new WeakMap(); + function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = {}) { maxRadius = +maxRadius; // When px or py is used, register an extra channel that the pointer @@ -9,7 +11,6 @@ function pointerK(kx, ky, {x, y, px, py, maxRadius = 40, channels, ...options} = // displayed. Also default x or y to null to disable maybeTuple etc. if (px != null) (x ??= null), (channels = {...channels, px: {value: px, scale: "x"}}); if (py != null) (y ??= null), (channels = {...channels, py: {value: py, scale: "y"}}); - const states = new WeakMap(); return { x, y, diff --git a/src/mark.d.ts b/src/mark.d.ts index cfcecc55c8..f6fbec934d 100644 --- a/src/mark.d.ts +++ b/src/mark.d.ts @@ -453,6 +453,9 @@ export interface MarkOptions { /** The abstract base class for Mark implementations. */ export class Mark { + /** The mark’s data. */ + data?: Data; + /** * Renders a new plot, prepending this mark as the first element of **marks** * of the specified *options*, and returns the corresponding SVG element, or diff --git a/test/output/tipDotFilter.svg b/test/output/tipDotFilter.svg new file mode 100644 index 0000000000..172bb3ef50 --- /dev/null +++ b/test/output/tipDotFilter.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + + + ↑ culmen_depth_mm + + + + + + + + + + 35 + 40 + 45 + 50 + 55 + + + culmen_length_mm → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index ad271cabcc..93c1f5748d 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -87,6 +87,14 @@ export async function tipDotFacets() { }); } +export async function tipDotFilter() { + const penguins = await d3.csv("data/penguins.csv", d3.autoType); + const xy = {x: "culmen_length_mm", y: "culmen_depth_mm", stroke: "sex"}; + const [dot1, tip1] = tipped(Plot.dot(penguins, {...xy, filter: (d) => d.sex === "MALE"}), {anchor: "left"}); + const [dot2, tip2] = tipped(Plot.dot(penguins, {...xy, filter: (d) => d.sex === "FEMALE"}), {anchor: "right"}); + return Plot.marks(dot1, dot2, tip1, tip2).plot(); +} + export async function tipGeoCentroid() { const [[counties, countymesh]] = await Promise.all([ d3 From 39216725367a45a6f3c51056202e3e6f3147dcf7 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Thu, 11 May 2023 11:49:37 -0700 Subject: [PATCH 55/56] revert Mark interface change --- src/mark.d.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/mark.d.ts b/src/mark.d.ts index f6fbec934d..cfcecc55c8 100644 --- a/src/mark.d.ts +++ b/src/mark.d.ts @@ -453,9 +453,6 @@ export interface MarkOptions { /** The abstract base class for Mark implementations. */ export class Mark { - /** The mark’s data. */ - data?: Data; - /** * Renders a new plot, prepending this mark as the first element of **marks** * of the specified *options*, and returns the corresponding SVG element, or From 7faaee349e132e60335a970edb95a938a00b44e9 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Thu, 11 May 2023 11:53:48 -0700 Subject: [PATCH 56/56] remove dead code --- src/projection.js | 14 -------------- src/style.js | 6 +----- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/src/projection.js b/src/projection.js index b228c6b117..e7f416f784 100644 --- a/src/projection.js +++ b/src/projection.js @@ -202,20 +202,6 @@ const reflectY = constant( }) ); -// Applies a point-wise projection to the given paired x and y channels. -// Note: mutates values! -// export function maybeProject(cx, cy, channels, values, context) { -// const x = channels[cx] && channels[cx].scale === "x"; -// const y = channels[cy] && channels[cy].scale === "y"; -// if (x && y) { -// project(cx, cy, values, context.projection); -// } else if (x) { -// throw new Error(`projection requires paired x and y channels; ${cx} is missing ${cy}`); -// } else if (y) { -// throw new Error(`projection requires paired x and y channels; ${cy} is missing ${cx}`); -// } -// } - // Applies a point-wise projection to the given paired x and y channels. // Note: mutates values! export function project(cx, cy, values, projection) { diff --git a/src/style.js b/src/style.js index 8224c04d03..5c229e192a 100644 --- a/src/style.js +++ b/src/style.js @@ -350,14 +350,10 @@ function applyClip(selection, mark, dimensions, context) { // Here we’re careful to apply the ARIA attributes to the outer G element when // clipping is applied, and to apply the ARIA attributes before any other // attributes (for readability). - applyAria(selection, mark); - applyAttr(selection, "clip-path", clipUrl); -} - -export function applyAria(selection, mark) { applyAttr(selection, "aria-label", mark.ariaLabel); applyAttr(selection, "aria-description", mark.ariaDescription); applyAttr(selection, "aria-hidden", mark.ariaHidden); + applyAttr(selection, "clip-path", clipUrl); } // Note: may mutate selection.node!