From eb1710dfaddb2776fa6ecb055ddcad89462c3be3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Mon, 13 Apr 2026 11:11:32 +0200 Subject: [PATCH 1/2] add constructors to mark class types --- src/mark.d.ts | 5 ++- src/marks/area.d.ts | 4 ++- src/marks/arrow.d.ts | 4 ++- src/marks/bar.d.ts | 8 +++-- src/marks/cell.d.ts | 4 ++- src/marks/contour.d.ts | 4 ++- src/marks/density.d.ts | 4 ++- src/marks/difference.d.ts | 4 ++- src/marks/dot.d.ts | 4 ++- src/marks/frame.d.ts | 4 ++- src/marks/geo.d.ts | 4 ++- src/marks/hexgrid.d.ts | 4 ++- src/marks/image.d.ts | 4 ++- src/marks/line.d.ts | 4 ++- src/marks/link.d.ts | 4 ++- src/marks/raster.d.ts | 4 ++- src/marks/rect.d.ts | 4 ++- src/marks/rule.d.ts | 8 +++-- src/marks/text.d.ts | 4 ++- src/marks/tick.d.ts | 8 +++-- src/marks/tip.d.ts | 4 ++- src/marks/vector.d.ts | 4 ++- src/marks/waffle.d.ts | 8 +++-- test/mark-constructors-test.ts | 64 ++++++++++++++++++++++++++++++++++ test/output/rectRotate.svg | 40 +++++++++++++++++++++ test/plots/rect-rotate.ts | 46 ++++++++++++++++++++++++ 26 files changed, 232 insertions(+), 27 deletions(-) create mode 100644 test/mark-constructors-test.ts create mode 100644 test/output/rectRotate.svg create mode 100644 test/plots/rect-rotate.ts diff --git a/src/mark.d.ts b/src/mark.d.ts index 5866750c28..cdb8c52b21 100644 --- a/src/mark.d.ts +++ b/src/mark.d.ts @@ -482,6 +482,7 @@ export interface MarkOptions { /** The abstract base class for Mark implementations. */ export class Mark { + constructor(data?: Data, channels?: Record, options?: MarkOptions, defaults?: MarkOptions); /** * Renders a new plot, prepending this mark as the first element of **marks** * of the specified *options*, and returns the corresponding SVG element, or @@ -492,8 +493,10 @@ export class Mark { /** A concrete Mark implementation. */ export class RenderableMark extends Mark { + // Declared as a method rather than a property so that subclasses can override + // it and call super.render(). See https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-3.html#checks-for-super-property-accesses-on-instance-fields /** Renders this mark, returning a new SVGElement (or null). */ - render: RenderFunction; + render(...args: Parameters): ReturnType; } /** A compound Mark, comprising other marks. */ diff --git a/src/marks/area.d.ts b/src/marks/area.d.ts index 8eed9953e1..d67e27bc58 100644 --- a/src/marks/area.d.ts +++ b/src/marks/area.d.ts @@ -205,4 +205,6 @@ export function areaX(data?: Data, options?: AreaXOptions & AreaLineOptions): Ar export function areaY(data?: Data, options?: AreaYOptions & AreaLineOptions): Area; /** The area mark. */ -export class Area extends RenderableMark {} +export class Area extends RenderableMark { + constructor(data?: Data, options?: AreaOptions); +} diff --git a/src/marks/arrow.d.ts b/src/marks/arrow.d.ts index 1b6397eca5..92eca80675 100644 --- a/src/marks/arrow.d.ts +++ b/src/marks/arrow.d.ts @@ -111,4 +111,6 @@ export interface ArrowOptions extends MarkOptions { export function arrow(data?: Data, options?: ArrowOptions): Arrow; /** The arrow mark. */ -export class Arrow extends RenderableMark {} +export class Arrow extends RenderableMark { + constructor(data?: Data, options?: ArrowOptions); +} diff --git a/src/marks/bar.d.ts b/src/marks/bar.d.ts index 7dc92199b0..8f4d615161 100644 --- a/src/marks/bar.d.ts +++ b/src/marks/bar.d.ts @@ -203,7 +203,11 @@ export function barX(data?: Data, options?: BarXOptions): BarX; export function barY(data?: Data, options?: BarYOptions): BarY; /** The barX mark. */ -export class BarX extends RenderableMark {} +export class BarX extends RenderableMark { + constructor(data?: Data, options?: BarXOptions); +} /** The barY mark. */ -export class BarY extends RenderableMark {} +export class BarY extends RenderableMark { + constructor(data?: Data, options?: BarYOptions); +} diff --git a/src/marks/cell.d.ts b/src/marks/cell.d.ts index 11fb415666..e4eee2a430 100644 --- a/src/marks/cell.d.ts +++ b/src/marks/cell.d.ts @@ -71,4 +71,6 @@ export function cellX(data?: Data, options?: CellOptions): Cell; export function cellY(data?: Data, options?: CellOptions): Cell; /** The cell mark. */ -export class Cell extends RenderableMark {} +export class Cell extends RenderableMark { + constructor(data?: Data, options?: CellOptions); +} diff --git a/src/marks/contour.d.ts b/src/marks/contour.d.ts index 2b06111d24..fe0895277c 100644 --- a/src/marks/contour.d.ts +++ b/src/marks/contour.d.ts @@ -89,4 +89,6 @@ export function contour(data?: Data, options?: ContourOptions): Contour; export function contour(options?: ContourOptions): Contour; /** The contour mark. */ -export class Contour extends RenderableMark {} +export class Contour extends RenderableMark { + constructor(data?: Data, options?: ContourOptions); +} diff --git a/src/marks/density.d.ts b/src/marks/density.d.ts index f964a915ee..baccbbc32b 100644 --- a/src/marks/density.d.ts +++ b/src/marks/density.d.ts @@ -51,4 +51,6 @@ export interface DensityOptions extends MarkOptions { export function density(data?: Data, options?: DensityOptions): Density; /** The density mark. */ -export class Density extends RenderableMark {} +export class Density extends RenderableMark { + constructor(data?: Data, options?: DensityOptions); +} diff --git a/src/marks/difference.d.ts b/src/marks/difference.d.ts index b3606c7cc3..b589842f7d 100644 --- a/src/marks/difference.d.ts +++ b/src/marks/difference.d.ts @@ -97,4 +97,6 @@ export function differenceX(data?: Data, options?: DifferenceOptions): Differenc export function differenceY(data?: Data, options?: DifferenceOptions): Difference; /** The difference mark. */ -export class Difference extends RenderableMark {} +export class Difference extends RenderableMark { + constructor(data?: Data, options?: DifferenceOptions); +} diff --git a/src/marks/dot.d.ts b/src/marks/dot.d.ts index 20e572229b..f707b9e2ce 100644 --- a/src/marks/dot.d.ts +++ b/src/marks/dot.d.ts @@ -144,4 +144,6 @@ export function circle(data?: Data, options?: Omit): Dot; export function hexagon(data?: Data, options?: Omit): Dot; /** The dot mark. */ -export class Dot extends RenderableMark {} +export class Dot extends RenderableMark { + constructor(data?: Data, options?: DotOptions); +} diff --git a/src/marks/frame.d.ts b/src/marks/frame.d.ts index da2cb6a147..0edc253145 100644 --- a/src/marks/frame.d.ts +++ b/src/marks/frame.d.ts @@ -20,4 +20,6 @@ export interface FrameOptions extends MarkOptions, InsetOptions, RectCornerOptio export function frame(options?: FrameOptions): Frame; /** The frame decoration mark. */ -export class Frame extends RenderableMark {} +export class Frame extends RenderableMark { + constructor(options?: FrameOptions); +} diff --git a/src/marks/geo.d.ts b/src/marks/geo.d.ts index 035d774c69..44c9c0a741 100644 --- a/src/marks/geo.d.ts +++ b/src/marks/geo.d.ts @@ -72,4 +72,6 @@ export function sphere(options?: GeoOptions): Geo; export function graticule(options?: GeoOptions): Geo; /** The geo mark. */ -export class Geo extends RenderableMark {} +export class Geo extends RenderableMark { + constructor(data?: Data | GeoPermissibleObjects, options?: GeoOptions); +} diff --git a/src/marks/hexgrid.d.ts b/src/marks/hexgrid.d.ts index fb01d58a15..07b03b1879 100644 --- a/src/marks/hexgrid.d.ts +++ b/src/marks/hexgrid.d.ts @@ -31,4 +31,6 @@ export interface HexgridOptions extends MarkOptions { export function hexgrid(options?: HexgridOptions): Hexgrid; /** The hexgrid mark. */ -export class Hexgrid extends RenderableMark {} +export class Hexgrid extends RenderableMark { + constructor(options?: HexgridOptions); +} diff --git a/src/marks/image.d.ts b/src/marks/image.d.ts index 816b4965a6..6a80236ab2 100644 --- a/src/marks/image.d.ts +++ b/src/marks/image.d.ts @@ -104,4 +104,6 @@ export interface ImageOptions extends MarkOptions { export function image(data?: Data, options?: ImageOptions): Image; /** The image mark. */ -export class Image extends RenderableMark {} +export class Image extends RenderableMark { + constructor(data?: Data, options?: ImageOptions); +} diff --git a/src/marks/line.d.ts b/src/marks/line.d.ts index 0f1692a978..726c3eb0e2 100644 --- a/src/marks/line.d.ts +++ b/src/marks/line.d.ts @@ -154,4 +154,6 @@ export function lineX(data?: Data, options?: LineXOptions): Line; export function lineY(data?: Data, options?: LineYOptions): Line; /** The line mark. */ -export class Line extends RenderableMark {} +export class Line extends RenderableMark { + constructor(data?: Data, options?: LineOptions); +} diff --git a/src/marks/link.d.ts b/src/marks/link.d.ts index 48abedd7b9..60c5d4c2ae 100644 --- a/src/marks/link.d.ts +++ b/src/marks/link.d.ts @@ -74,4 +74,6 @@ export interface LinkOptions extends MarkOptions, MarkerOptions, CurveAutoOption export function link(data?: Data, options?: LinkOptions): Link; /** The link mark. */ -export class Link extends RenderableMark {} +export class Link extends RenderableMark { + constructor(data?: Data, options?: LinkOptions); +} diff --git a/src/marks/raster.d.ts b/src/marks/raster.d.ts index 3b2bcf4955..7b29c090ba 100644 --- a/src/marks/raster.d.ts +++ b/src/marks/raster.d.ts @@ -259,4 +259,6 @@ export function interpolatorRandomWalk(options?: { }): RasterInterpolateFunction; /** The raster mark. */ -export class Raster extends RenderableMark {} +export class Raster extends RenderableMark { + constructor(data?: Data, options?: RasterOptions); +} diff --git a/src/marks/rect.d.ts b/src/marks/rect.d.ts index 52a5b1a9a1..1cb9d8d363 100644 --- a/src/marks/rect.d.ts +++ b/src/marks/rect.d.ts @@ -270,4 +270,6 @@ export function rectX(data?: Data, options?: RectXOptions): Rect; export function rectY(data?: Data, options?: RectYOptions): Rect; /** The rect mark. */ -export class Rect extends RenderableMark {} +export class Rect extends RenderableMark { + constructor(data?: Data, options?: RectOptions); +} diff --git a/src/marks/rule.d.ts b/src/marks/rule.d.ts index 993ee0b835..5b6c9b5d11 100644 --- a/src/marks/rule.d.ts +++ b/src/marks/rule.d.ts @@ -137,7 +137,11 @@ export function ruleX(data?: Data, options?: RuleXOptions): RuleX; export function ruleY(data?: Data, options?: RuleYOptions): RuleY; /** The ruleX mark. */ -export class RuleX extends RenderableMark {} +export class RuleX extends RenderableMark { + constructor(data?: Data, options?: RuleXOptions); +} /** The ruleY mark. */ -export class RuleY extends RenderableMark {} +export class RuleY extends RenderableMark { + constructor(data?: Data, options?: RuleYOptions); +} diff --git a/src/marks/text.d.ts b/src/marks/text.d.ts index 8ad171cfbb..355c3db1b2 100644 --- a/src/marks/text.d.ts +++ b/src/marks/text.d.ts @@ -239,4 +239,6 @@ export function textX(data?: Data, options?: TextXOptions): Text; export function textY(data?: Data, options?: TextYOptions): Text; /** The text mark. */ -export class Text extends RenderableMark {} +export class Text extends RenderableMark { + constructor(data?: Data, options?: TextOptions); +} diff --git a/src/marks/tick.d.ts b/src/marks/tick.d.ts index 947bf61f43..b918ee5666 100644 --- a/src/marks/tick.d.ts +++ b/src/marks/tick.d.ts @@ -72,7 +72,11 @@ export function tickX(data?: Data, options?: TickXOptions): TickX; export function tickY(data?: Data, options?: TickYOptions): TickY; /** The tickX mark. */ -export class TickX extends RenderableMark {} +export class TickX extends RenderableMark { + constructor(data?: Data, options?: TickXOptions); +} /** The tickY mark. */ -export class TickY extends RenderableMark {} +export class TickY extends RenderableMark { + constructor(data?: Data, options?: TickYOptions); +} diff --git a/src/marks/tip.d.ts b/src/marks/tip.d.ts index 906051820c..7faf45b759 100644 --- a/src/marks/tip.d.ts +++ b/src/marks/tip.d.ts @@ -110,4 +110,6 @@ export type TipFormat = string | ((d: any, i: number) => string); export function tip(data?: Data, options?: TipOptions): Tip; /** The tip mark. */ -export class Tip extends RenderableMark {} +export class Tip extends RenderableMark { + constructor(data?: Data, options?: TipOptions); +} diff --git a/src/marks/vector.d.ts b/src/marks/vector.d.ts index 625d8b908d..2624582637 100644 --- a/src/marks/vector.d.ts +++ b/src/marks/vector.d.ts @@ -116,4 +116,6 @@ export function vectorY(data?: Data, options?: VectorOptions): Vector; export function spike(data?: Data, options?: VectorOptions): Vector; /** The vector mark. */ -export class Vector extends RenderableMark {} +export class Vector extends RenderableMark { + constructor(data?: Data, options?: VectorOptions); +} diff --git a/src/marks/waffle.d.ts b/src/marks/waffle.d.ts index 9a7d847337..2354101bc3 100644 --- a/src/marks/waffle.d.ts +++ b/src/marks/waffle.d.ts @@ -86,7 +86,11 @@ export function waffleY(data?: Data, options?: WaffleYOptions): WaffleY; export function waffleX(data?: Data, options?: WaffleXOptions): WaffleX; /** The waffleX mark. */ -export class WaffleX extends RenderableMark {} +export class WaffleX extends RenderableMark { + constructor(data?: Data, options?: WaffleXOptions); +} /** The waffleY mark. */ -export class WaffleY extends RenderableMark {} +export class WaffleY extends RenderableMark { + constructor(data?: Data, options?: WaffleYOptions); +} diff --git a/test/mark-constructors-test.ts b/test/mark-constructors-test.ts new file mode 100644 index 0000000000..46788f36a2 --- /dev/null +++ b/test/mark-constructors-test.ts @@ -0,0 +1,64 @@ +// Verify that all mark classes can be extended. +// See https://github.com/observablehq/plot/issues/2422 + +import * as Plot from "@observablehq/plot"; +import {describe, it} from "vitest"; + +describe("mark constructors", () => { + const data = [1, 2, 3]; + + // data + options + class MyArea extends Plot.Area { constructor(data: Plot.Data, options: Plot.AreaOptions) { super(data, options); } } + class MyArrow extends Plot.Arrow { constructor(data: Plot.Data, options: Plot.ArrowOptions) { super(data, options); } } + class MyBarX extends Plot.BarX { constructor(data: Plot.Data, options: Plot.BarXOptions) { super(data, options); } } + class MyBarY extends Plot.BarY { constructor(data: Plot.Data, options: Plot.BarYOptions) { super(data, options); } } + class MyCell extends Plot.Cell { constructor(data: Plot.Data, options: Plot.CellOptions) { super(data, options); } } + class MyContour extends Plot.Contour { constructor(data: Plot.Data, options: Plot.ContourOptions) { super(data, options); } } + class MyDensity extends Plot.Density { constructor(data: Plot.Data, options: Plot.DensityOptions) { super(data, options); } } + class MyDot extends Plot.Dot { constructor(data: Plot.Data, options: Plot.DotOptions) { super(data, options); } } + class MyGeo extends Plot.Geo { constructor(data: Plot.Data, options: Plot.GeoOptions) { super(data, options); } } + class MyImage extends Plot.Image { constructor(data: Plot.Data, options: Plot.ImageOptions) { super(data, options); } } + class MyLine extends Plot.Line { constructor(data: Plot.Data, options: Plot.LineOptions) { super(data, options); } } + class MyLink extends Plot.Link { constructor(data: Plot.Data, options: Plot.LinkOptions) { super(data, options); } } + class MyRaster extends Plot.Raster { constructor(data: Plot.Data, options: Plot.RasterOptions) { super(data, options); } } + class MyRect extends Plot.Rect { constructor(data: Plot.Data, options: Plot.RectOptions) { super(data, options); } } + class MyRuleX extends Plot.RuleX { constructor(data: Plot.Data, options: Plot.RuleXOptions) { super(data, options); } } + class MyRuleY extends Plot.RuleY { constructor(data: Plot.Data, options: Plot.RuleYOptions) { super(data, options); } } + class MyText extends Plot.Text { constructor(data: Plot.Data, options: Plot.TextOptions) { super(data, options); } } + class MyTickX extends Plot.TickX { constructor(data: Plot.Data, options: Plot.TickXOptions) { super(data, options); } } + class MyTickY extends Plot.TickY { constructor(data: Plot.Data, options: Plot.TickYOptions) { super(data, options); } } + class MyTip extends Plot.Tip { constructor(data: Plot.Data, options: Plot.TipOptions) { super(data, options); } } + class MyVector extends Plot.Vector { constructor(data: Plot.Data, options: Plot.VectorOptions) { super(data, options); } } + class MyWaffleX extends Plot.WaffleX { constructor(data: Plot.Data, options: Plot.WaffleXOptions) { super(data, options); } } + class MyWaffleY extends Plot.WaffleY { constructor(data: Plot.Data, options: Plot.WaffleYOptions) { super(data, options); } } + + // no data + class MyFrame extends Plot.Frame { constructor(options: Plot.FrameOptions) { super(options); } } + class MyHexgrid extends Plot.Hexgrid { constructor(options: Plot.HexgridOptions) { super(options); } } + + it("Area", () => Plot.plot({marks: [new MyArea(data, {x1: Plot.identity, y1: Plot.identity})]})); + it("Arrow", () => Plot.plot({marks: [new MyArrow(data, {x1: Plot.identity, y1: Plot.identity, x2: Plot.identity, y2: Plot.identity})]})); + it("BarX", () => Plot.plot({marks: [new MyBarX(data, {x1: 0, x2: Plot.identity, y: Plot.identity})]})); + it("BarY", () => Plot.plot({marks: [new MyBarY(data, {y1: 0, y2: Plot.identity, x: Plot.identity})]})); + it("Cell", () => Plot.plot({marks: [new MyCell(data, {x: Plot.identity})]})); + it("Contour", () => Plot.plot({marks: [new MyContour(data, {x: Plot.identity, y: Plot.identity, fill: Plot.identity})]})); + it("Density", () => Plot.plot({marks: [new MyDensity(data, {x: Plot.identity, y: Plot.identity})]})); + it("Dot", () => Plot.plot({marks: [new MyDot(data, {x: Plot.identity})]})); + it("Geo", () => Plot.plot({marks: [new MyGeo([{type: "Point", coordinates: [0, 0]}], {geometry: Plot.identity})]})); + it("Image", () => Plot.plot({marks: [new MyImage(data, {x: Plot.identity, y: Plot.identity, src: "test.png"})]})); + it("Line", () => Plot.plot({marks: [new MyLine(data, {x: Plot.identity, y: Plot.identity})]})); + it("Link", () => Plot.plot({marks: [new MyLink(data, {x1: Plot.identity, y1: Plot.identity, x2: Plot.identity, y2: Plot.identity})]})); + it("Raster", () => Plot.plot({marks: [new MyRaster(data, {x: Plot.identity, y: Plot.identity, fill: Plot.identity})]})); + it("Rect", () => Plot.plot({marks: [new MyRect(data, {x1: Plot.identity, x2: Plot.identity})]})); + it("RuleX", () => Plot.plot({marks: [new MyRuleX(data, {x: Plot.identity})]})); + it("RuleY", () => Plot.plot({marks: [new MyRuleY(data, {y: Plot.identity})]})); + it("Text", () => Plot.plot({marks: [new MyText(data, {x: Plot.identity, text: Plot.identity})]})); + it("TickX", () => Plot.plot({marks: [new MyTickX(data, {x: Plot.identity})]})); + it("TickY", () => Plot.plot({marks: [new MyTickY(data, {y: Plot.identity})]})); + it("Tip", () => Plot.plot({marks: [new MyTip(data, {x: Plot.identity})]})); + it("Vector", () => Plot.plot({marks: [new MyVector(data, {x: Plot.identity, y: Plot.identity})]})); + it("WaffleX", () => Plot.plot({marks: [new MyWaffleX(data, {x1: 0, x2: Plot.identity, y: Plot.identity})]})); + it("WaffleY", () => Plot.plot({marks: [new MyWaffleY(data, {y1: 0, y2: Plot.identity, x: Plot.identity})]})); + it("Frame", () => Plot.plot({marks: [new MyFrame({})]})); + it("Hexgrid", () => Plot.plot({marks: [new MyHexgrid({})]})); +}); diff --git a/test/output/rectRotate.svg b/test/output/rectRotate.svg new file mode 100644 index 0000000000..46f84b5594 --- /dev/null +++ b/test/output/rectRotate.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plots/rect-rotate.ts b/test/plots/rect-rotate.ts new file mode 100644 index 0000000000..ac65ea385f --- /dev/null +++ b/test/plots/rect-rotate.ts @@ -0,0 +1,46 @@ +// Verify that mark classes can be extended with a custom render. +// See https://github.com/observablehq/plot/issues/2422 + +import * as Plot from "@observablehq/plot"; +import * as d3 from "d3"; +import {test} from "test/plot"; + +interface RotatedRectOptions extends Plot.RectOptions { + rx?: number; +} + +class RotatedRect extends Plot.Rect { + private rx: number; + constructor(data: Plot.Data, {rx = 0, ...options}: RotatedRectOptions = {}) { + super(data, options); + this.rx = rx; + } + render(index: number[], scales: Plot.ScaleFunctions, values: Plot.ChannelValues, dimensions: Plot.Dimensions, context: Plot.Context) { + const g = super.render(index, scales, values, dimensions, context); + if (g) { + let i = 0; + for (const rect of g.querySelectorAll("rect")) { + const x = +rect.getAttribute("x")! + +rect.getAttribute("width")! / 2; + const y = +rect.getAttribute("y")! + +rect.getAttribute("height")! / 2; + rect.setAttribute("transform", `rotate(${i++ * 10}, ${x}, ${y})`); + if (this.rx) rect.setAttribute("rx", `${this.rx}`); + } + } + return g; + } +} + +test(function rectRotate() { + const colors = d3.schemeObservable10; + return Plot.plot({ + width: 330, + height: 60, + margin: 15, + axis: null, + color: {domain: d3.range(10), range: colors}, + marks: [ + new RotatedRect(d3.range(10), {x1: Plot.identity, x2: (d) => d + 1, y1: 0, y2: 1, fill: Plot.identity, stroke: "white", inset: -2, rx: 8}), + Plot.vector(d3.range(10), {x: (d) => d + 0.5, y: 0.5, rotate: (d) => d * 10, stroke: "white", length: 10, strokeWidth: 1.5}) + ] + }); +}); From b1d4a92a7ac2b2105947bf21356dc47d3c1a2ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Mon, 13 Apr 2026 11:16:06 +0200 Subject: [PATCH 2/2] prasnier --- test/mark-constructors-test.ts | 166 +++++++++++++++++++++++++++------ test/plots/rect-rotate.ts | 28 +++++- 2 files changed, 162 insertions(+), 32 deletions(-) diff --git a/test/mark-constructors-test.ts b/test/mark-constructors-test.ts index 46788f36a2..787035d771 100644 --- a/test/mark-constructors-test.ts +++ b/test/mark-constructors-test.ts @@ -8,47 +8,155 @@ describe("mark constructors", () => { const data = [1, 2, 3]; // data + options - class MyArea extends Plot.Area { constructor(data: Plot.Data, options: Plot.AreaOptions) { super(data, options); } } - class MyArrow extends Plot.Arrow { constructor(data: Plot.Data, options: Plot.ArrowOptions) { super(data, options); } } - class MyBarX extends Plot.BarX { constructor(data: Plot.Data, options: Plot.BarXOptions) { super(data, options); } } - class MyBarY extends Plot.BarY { constructor(data: Plot.Data, options: Plot.BarYOptions) { super(data, options); } } - class MyCell extends Plot.Cell { constructor(data: Plot.Data, options: Plot.CellOptions) { super(data, options); } } - class MyContour extends Plot.Contour { constructor(data: Plot.Data, options: Plot.ContourOptions) { super(data, options); } } - class MyDensity extends Plot.Density { constructor(data: Plot.Data, options: Plot.DensityOptions) { super(data, options); } } - class MyDot extends Plot.Dot { constructor(data: Plot.Data, options: Plot.DotOptions) { super(data, options); } } - class MyGeo extends Plot.Geo { constructor(data: Plot.Data, options: Plot.GeoOptions) { super(data, options); } } - class MyImage extends Plot.Image { constructor(data: Plot.Data, options: Plot.ImageOptions) { super(data, options); } } - class MyLine extends Plot.Line { constructor(data: Plot.Data, options: Plot.LineOptions) { super(data, options); } } - class MyLink extends Plot.Link { constructor(data: Plot.Data, options: Plot.LinkOptions) { super(data, options); } } - class MyRaster extends Plot.Raster { constructor(data: Plot.Data, options: Plot.RasterOptions) { super(data, options); } } - class MyRect extends Plot.Rect { constructor(data: Plot.Data, options: Plot.RectOptions) { super(data, options); } } - class MyRuleX extends Plot.RuleX { constructor(data: Plot.Data, options: Plot.RuleXOptions) { super(data, options); } } - class MyRuleY extends Plot.RuleY { constructor(data: Plot.Data, options: Plot.RuleYOptions) { super(data, options); } } - class MyText extends Plot.Text { constructor(data: Plot.Data, options: Plot.TextOptions) { super(data, options); } } - class MyTickX extends Plot.TickX { constructor(data: Plot.Data, options: Plot.TickXOptions) { super(data, options); } } - class MyTickY extends Plot.TickY { constructor(data: Plot.Data, options: Plot.TickYOptions) { super(data, options); } } - class MyTip extends Plot.Tip { constructor(data: Plot.Data, options: Plot.TipOptions) { super(data, options); } } - class MyVector extends Plot.Vector { constructor(data: Plot.Data, options: Plot.VectorOptions) { super(data, options); } } - class MyWaffleX extends Plot.WaffleX { constructor(data: Plot.Data, options: Plot.WaffleXOptions) { super(data, options); } } - class MyWaffleY extends Plot.WaffleY { constructor(data: Plot.Data, options: Plot.WaffleYOptions) { super(data, options); } } + class MyArea extends Plot.Area { + constructor(data: Plot.Data, options: Plot.AreaOptions) { + super(data, options); + } + } + class MyArrow extends Plot.Arrow { + constructor(data: Plot.Data, options: Plot.ArrowOptions) { + super(data, options); + } + } + class MyBarX extends Plot.BarX { + constructor(data: Plot.Data, options: Plot.BarXOptions) { + super(data, options); + } + } + class MyBarY extends Plot.BarY { + constructor(data: Plot.Data, options: Plot.BarYOptions) { + super(data, options); + } + } + class MyCell extends Plot.Cell { + constructor(data: Plot.Data, options: Plot.CellOptions) { + super(data, options); + } + } + class MyContour extends Plot.Contour { + constructor(data: Plot.Data, options: Plot.ContourOptions) { + super(data, options); + } + } + class MyDensity extends Plot.Density { + constructor(data: Plot.Data, options: Plot.DensityOptions) { + super(data, options); + } + } + class MyDot extends Plot.Dot { + constructor(data: Plot.Data, options: Plot.DotOptions) { + super(data, options); + } + } + class MyGeo extends Plot.Geo { + constructor(data: Plot.Data, options: Plot.GeoOptions) { + super(data, options); + } + } + class MyImage extends Plot.Image { + constructor(data: Plot.Data, options: Plot.ImageOptions) { + super(data, options); + } + } + class MyLine extends Plot.Line { + constructor(data: Plot.Data, options: Plot.LineOptions) { + super(data, options); + } + } + class MyLink extends Plot.Link { + constructor(data: Plot.Data, options: Plot.LinkOptions) { + super(data, options); + } + } + class MyRaster extends Plot.Raster { + constructor(data: Plot.Data, options: Plot.RasterOptions) { + super(data, options); + } + } + class MyRect extends Plot.Rect { + constructor(data: Plot.Data, options: Plot.RectOptions) { + super(data, options); + } + } + class MyRuleX extends Plot.RuleX { + constructor(data: Plot.Data, options: Plot.RuleXOptions) { + super(data, options); + } + } + class MyRuleY extends Plot.RuleY { + constructor(data: Plot.Data, options: Plot.RuleYOptions) { + super(data, options); + } + } + class MyText extends Plot.Text { + constructor(data: Plot.Data, options: Plot.TextOptions) { + super(data, options); + } + } + class MyTickX extends Plot.TickX { + constructor(data: Plot.Data, options: Plot.TickXOptions) { + super(data, options); + } + } + class MyTickY extends Plot.TickY { + constructor(data: Plot.Data, options: Plot.TickYOptions) { + super(data, options); + } + } + class MyTip extends Plot.Tip { + constructor(data: Plot.Data, options: Plot.TipOptions) { + super(data, options); + } + } + class MyVector extends Plot.Vector { + constructor(data: Plot.Data, options: Plot.VectorOptions) { + super(data, options); + } + } + class MyWaffleX extends Plot.WaffleX { + constructor(data: Plot.Data, options: Plot.WaffleXOptions) { + super(data, options); + } + } + class MyWaffleY extends Plot.WaffleY { + constructor(data: Plot.Data, options: Plot.WaffleYOptions) { + super(data, options); + } + } // no data - class MyFrame extends Plot.Frame { constructor(options: Plot.FrameOptions) { super(options); } } - class MyHexgrid extends Plot.Hexgrid { constructor(options: Plot.HexgridOptions) { super(options); } } + class MyFrame extends Plot.Frame { + constructor(options: Plot.FrameOptions) { + super(options); + } + } + class MyHexgrid extends Plot.Hexgrid { + constructor(options: Plot.HexgridOptions) { + super(options); + } + } it("Area", () => Plot.plot({marks: [new MyArea(data, {x1: Plot.identity, y1: Plot.identity})]})); - it("Arrow", () => Plot.plot({marks: [new MyArrow(data, {x1: Plot.identity, y1: Plot.identity, x2: Plot.identity, y2: Plot.identity})]})); + it("Arrow", () => + Plot.plot({ + marks: [new MyArrow(data, {x1: Plot.identity, y1: Plot.identity, x2: Plot.identity, y2: Plot.identity})] + })); it("BarX", () => Plot.plot({marks: [new MyBarX(data, {x1: 0, x2: Plot.identity, y: Plot.identity})]})); it("BarY", () => Plot.plot({marks: [new MyBarY(data, {y1: 0, y2: Plot.identity, x: Plot.identity})]})); it("Cell", () => Plot.plot({marks: [new MyCell(data, {x: Plot.identity})]})); - it("Contour", () => Plot.plot({marks: [new MyContour(data, {x: Plot.identity, y: Plot.identity, fill: Plot.identity})]})); + it("Contour", () => + Plot.plot({marks: [new MyContour(data, {x: Plot.identity, y: Plot.identity, fill: Plot.identity})]})); it("Density", () => Plot.plot({marks: [new MyDensity(data, {x: Plot.identity, y: Plot.identity})]})); it("Dot", () => Plot.plot({marks: [new MyDot(data, {x: Plot.identity})]})); it("Geo", () => Plot.plot({marks: [new MyGeo([{type: "Point", coordinates: [0, 0]}], {geometry: Plot.identity})]})); it("Image", () => Plot.plot({marks: [new MyImage(data, {x: Plot.identity, y: Plot.identity, src: "test.png"})]})); it("Line", () => Plot.plot({marks: [new MyLine(data, {x: Plot.identity, y: Plot.identity})]})); - it("Link", () => Plot.plot({marks: [new MyLink(data, {x1: Plot.identity, y1: Plot.identity, x2: Plot.identity, y2: Plot.identity})]})); - it("Raster", () => Plot.plot({marks: [new MyRaster(data, {x: Plot.identity, y: Plot.identity, fill: Plot.identity})]})); + it("Link", () => + Plot.plot({ + marks: [new MyLink(data, {x1: Plot.identity, y1: Plot.identity, x2: Plot.identity, y2: Plot.identity})] + })); + it("Raster", () => + Plot.plot({marks: [new MyRaster(data, {x: Plot.identity, y: Plot.identity, fill: Plot.identity})]})); it("Rect", () => Plot.plot({marks: [new MyRect(data, {x1: Plot.identity, x2: Plot.identity})]})); it("RuleX", () => Plot.plot({marks: [new MyRuleX(data, {x: Plot.identity})]})); it("RuleY", () => Plot.plot({marks: [new MyRuleY(data, {y: Plot.identity})]})); diff --git a/test/plots/rect-rotate.ts b/test/plots/rect-rotate.ts index ac65ea385f..d3ba85ad93 100644 --- a/test/plots/rect-rotate.ts +++ b/test/plots/rect-rotate.ts @@ -15,7 +15,13 @@ class RotatedRect extends Plot.Rect { super(data, options); this.rx = rx; } - render(index: number[], scales: Plot.ScaleFunctions, values: Plot.ChannelValues, dimensions: Plot.Dimensions, context: Plot.Context) { + render( + index: number[], + scales: Plot.ScaleFunctions, + values: Plot.ChannelValues, + dimensions: Plot.Dimensions, + context: Plot.Context + ) { const g = super.render(index, scales, values, dimensions, context); if (g) { let i = 0; @@ -39,8 +45,24 @@ test(function rectRotate() { axis: null, color: {domain: d3.range(10), range: colors}, marks: [ - new RotatedRect(d3.range(10), {x1: Plot.identity, x2: (d) => d + 1, y1: 0, y2: 1, fill: Plot.identity, stroke: "white", inset: -2, rx: 8}), - Plot.vector(d3.range(10), {x: (d) => d + 0.5, y: 0.5, rotate: (d) => d * 10, stroke: "white", length: 10, strokeWidth: 1.5}) + new RotatedRect(d3.range(10), { + x1: Plot.identity, + x2: (d) => d + 1, + y1: 0, + y2: 1, + fill: Plot.identity, + stroke: "white", + inset: -2, + rx: 8 + }), + Plot.vector(d3.range(10), { + x: (d) => d + 0.5, + y: 0.5, + rotate: (d) => d * 10, + stroke: "white", + length: 10, + strokeWidth: 1.5 + }) ] }); });