mark.d.ts 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. import type {GeoPermissibleObjects} from "d3";
  2. import type {Channel, ChannelDomainSort, ChannelValue, ChannelValues, ChannelValueSpec} from "./channel.js";
  3. import type {Context} from "./context.js";
  4. import type {Dimensions} from "./dimensions.js";
  5. import type {PointerOptions} from "./interactions/pointer.js";
  6. import type {TipOptions} from "./marks/tip.js";
  7. import type {plot} from "./plot.js";
  8. import type {ScaleFunctions} from "./scales.js";
  9. import type {InitializerFunction, SortOrder, TransformFunction} from "./transforms/basic.js";
  10. /**
  11. * How to anchor a mark relative to the plot’s frame; one of:
  12. *
  13. * - *middle* - centered in the middle
  14. * - in the middle of one of the edges: *top*, *right*, *bottom*, *left*
  15. * - in one of the corners: *top-left*, *top-right*, *bottom-right*, *bottom-left*
  16. */
  17. export type FrameAnchor =
  18. | "middle"
  19. | "top-left"
  20. | "top"
  21. | "top-right"
  22. | "right"
  23. | "bottom-right"
  24. | "bottom"
  25. | "bottom-left"
  26. | "left";
  27. /** The pointer mode for the tip; corresponds to pointerX, pointerY, and pointer. */
  28. export type TipPointer = "x" | "y" | "xy";
  29. /**
  30. * A mark’s data; one of:
  31. *
  32. * - an array, typed array, or other iterable
  33. * - an object with a length property and indexed values
  34. * - an Apache Arrow Table
  35. */
  36. export type Data = Iterable<any> | ArrayLike<any>;
  37. /**
  38. * A bare renderable mark implementation. Given the mark’s *index*, an object of
  39. * the plot’s *scales*, the mark’s (possibly scaled) channel *values*, the
  40. * plot’s *dimensions* and *context*, returns a new SVGElement, or null if the
  41. * mark should display nothing.
  42. */
  43. export type RenderFunction = (
  44. /** The mark’s (filtered and transformed) index. */
  45. index: number[],
  46. /** The plot’s scale functions. */
  47. scales: ScaleFunctions,
  48. /** The mark’s (possibly scaled and transformed) channel values. */
  49. values: ChannelValues,
  50. /** The plot’s dimensions. */
  51. dimensions: Dimensions,
  52. /** The plot’s context. */
  53. context: Context,
  54. /** The next render function; for render transforms only. */
  55. next?: RenderFunction
  56. ) => SVGElement | null;
  57. /**
  58. * A mark implementation or mark-like object; one of:
  59. *
  60. * - a renderable mark, extending Mark and implementing *mark*.render
  61. * - a bare render function, for a custom functional mark
  62. * - an array of mark implementations or mark-like objects
  63. * - null or undefined, to render nothing
  64. */
  65. export type Markish = RenderableMark | RenderFunction | Markish[] | null | undefined;
  66. /** Shared options for all marks. */
  67. export interface MarkOptions {
  68. /**
  69. * Applies a transform to filter the mark’s index according to the given
  70. * channel values; only truthy values are retained. For example, to show only
  71. * data whose body mass is greater than 3,000g:
  72. *
  73. * ```js
  74. * filter: (d) => d.body_mass_g > 3000
  75. * ```
  76. *
  77. * Note that filtering only affects the rendered mark index, not the
  78. * associated channel values, and thus has no effect on imputed scale domains.
  79. */
  80. filter?: ChannelValue;
  81. /**
  82. * Applies a transform to reverse the order of the mark’s index, say for
  83. * reverse input order.
  84. */
  85. reverse?: boolean;
  86. /**
  87. * Either applies a transform to sort the mark’s index by the specified
  88. * channel values, or imputes ordinal scale domains from this mark’s channels.
  89. *
  90. * When imputing ordinal scale domains from channel values, the **sort**
  91. * option is an object whose keys are ordinal scale names such as *x* or *fx*,
  92. * and whose values are channel names such as *y*, *y1*, or *y2*. For example,
  93. * to impute the *y* scale’s domain from the associated *x* channel values in
  94. * ascending order:
  95. *
  96. * ```js
  97. * sort: {y: "x"}
  98. * ```
  99. *
  100. * For different sort options for different scales, replace the channel name
  101. * with a *value* object and per-scale options:
  102. *
  103. * ```js
  104. * sort: {y: {value: "-x"}}
  105. * ```
  106. *
  107. * When sorting the mark’s index, the **sort** option is instead one of:
  108. *
  109. * - a function for comparing data, returning a signed number
  110. * - a channel value definition for sorting given values in ascending order
  111. * - a {value, order} object for sorting given values
  112. * - a {channel, order} object for sorting the named channel’s values
  113. *
  114. * For example, to render in order of ascending body mass:
  115. *
  116. * ```js
  117. * sort: "body_mass_g"
  118. * ```
  119. *
  120. * See also the Plot.sort transform.
  121. */
  122. sort?: SortOrder | ChannelDomainSort;
  123. /** A custom mark transform. */
  124. transform?: TransformFunction;
  125. /** A custom mark initializer. */
  126. initializer?: InitializerFunction;
  127. /** A custom render transform. */
  128. render?: RenderFunction;
  129. /**
  130. * The horizontal facet position channel, for mark-level faceting, bound to
  131. * the *fx* scale.
  132. */
  133. fx?: ChannelValue;
  134. /**
  135. * The vertical facet position channel, for mark-level faceting, bound to the
  136. * *fy* scale.
  137. */
  138. fy?: ChannelValue;
  139. /**
  140. * Whether to enable or disable faceting; one of:
  141. *
  142. * - *auto* (default) - automatically determine if this mark should be faceted
  143. * - *include* (or true) - draw the subset of the mark’s data in the current facet
  144. * - *exclude* - draw the subset of the mark’s data *not* in the current facet
  145. * - *super* - draw this mark in a single frame that covers all facets
  146. * - null (or false) - repeat this mark’s data across all facets (*i.e.*, no faceting)
  147. *
  148. * When a mark uses *super* faceting, it is not allowed to use position scales
  149. * (*x*, *y*, *fx*, or *fy*); *super* faceting is intended for decorations,
  150. * such as labels and legends.
  151. *
  152. * When top-level faceting is used, the default *auto* setting is equivalent
  153. * to *include* when the mark data is strictly equal to the top-level facet
  154. * data; otherwise it is equivalent to null. When the *include* or *exclude*
  155. * facet mode is chosen, the mark data must be parallel to the top-level facet
  156. * data: the data must have the same length and order. If the data are not
  157. * parallel, then the wrong data may be shown in each facet. The default
  158. * *auto* therefore requires strict equality (`===`) for safety, and using the
  159. * facet data as mark data is recommended when using the *exclude* facet mode.
  160. * (To construct parallel data safely, consider using [*array*.map][1] on the
  161. * facet data.)
  162. *
  163. * When mark-level faceting is used, the default *auto* setting is equivalent
  164. * to *include*: the mark will be faceted if either the **fx** or **fy**
  165. * channel option (or both) is specified. The null or false option will
  166. * disable faceting, while *exclude* draws the subset of the mark’s data *not*
  167. * in the current facet.
  168. *
  169. * [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
  170. */
  171. facet?: "auto" | "include" | "exclude" | "super" | boolean | null;
  172. /**
  173. * How to place the mark with respect to facets; one of:
  174. *
  175. * - null (default for most marks) - display the mark in each non-empty facet
  176. * - *top*, *right*, *bottom*, or *left* - display the mark only in facets on
  177. * the given side
  178. * - *top-empty*, *right-empty*, *bottom-empty*, or *left-empty* (default for
  179. * axis marks) - display the mark only in facets that have empty space on
  180. * the given side: either the margin, or an empty facet
  181. * - *empty* - display the mark in empty facets only
  182. */
  183. facetAnchor?:
  184. | "top"
  185. | "right"
  186. | "bottom"
  187. | "left"
  188. | "top-left"
  189. | "top-right"
  190. | "bottom-left"
  191. | "bottom-right"
  192. | "top-empty"
  193. | "right-empty"
  194. | "bottom-empty"
  195. | "left-empty"
  196. | "empty"
  197. | null;
  198. /**
  199. * Shorthand to set the same default for all four mark margins: **marginTop**,
  200. * **marginRight**, **marginBottom**, and **marginLeft**; typically defaults
  201. * to 0, except for axis marks.
  202. */
  203. margin?: number;
  204. /**
  205. * The mark’s top margin; the minimum distance in pixels between the top edges
  206. * of the inner and outer plot area.
  207. */
  208. marginTop?: number;
  209. /**
  210. * The mark’s right margin; the minimum distance in pixels between the right
  211. * edges of the mark’s inner and outer plot area.
  212. */
  213. marginRight?: number;
  214. /**
  215. * The mark’s bottom margin; the minimum distance in pixels between the bottom
  216. * edges of the inner and outer plot area.
  217. */
  218. marginBottom?: number;
  219. /**
  220. * The mark’s left margin; the minimum distance in pixels between the left
  221. * edges of the inner and outer plot area.
  222. */
  223. marginLeft?: number;
  224. /**
  225. * The [class attribute][1]; a constant string.
  226. *
  227. * [1]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class
  228. */
  229. className?: string;
  230. /**
  231. * The [aria-description][1]; a constant textual description.
  232. *
  233. * [1]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-description
  234. */
  235. ariaDescription?: string;
  236. /**
  237. * The [aria-hidden][1] state; a constant indicating whether the element is
  238. * exposed to an accessibility API.
  239. *
  240. * [1]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-hidden
  241. */
  242. ariaHidden?: string;
  243. /**
  244. * The [aria-label][1]; a channel specifying short textual labels representing
  245. * the value in the accessibility tree.
  246. *
  247. * [1]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label
  248. */
  249. ariaLabel?: ChannelValue;
  250. /**
  251. * The [pointer-events][1] property; a constant string such as *none*.
  252. *
  253. * [1]: https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
  254. */
  255. pointerEvents?: string;
  256. /**
  257. * The title; a channel specifying accessible, short textual descriptions as
  258. * strings (possibly with newlines). If the tip option is specified, the title
  259. * will be displayed with an interactive tooltip instead of using the SVG
  260. * [title element][1].
  261. *
  262. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title
  263. */
  264. title?: ChannelValue;
  265. /** Whether to generate a tooltip for this mark, and any tip options. */
  266. tip?: boolean | TipPointer | (TipOptions & PointerOptions & {pointer?: TipPointer});
  267. /**
  268. * How to clip the mark; one of:
  269. *
  270. * - *frame* or true - clip to the plot’s frame (inner area)
  271. * - *sphere* - clip to the projected sphere (*e.g.*, front hemisphere)
  272. * - geojson - a GeoJSON object, typically with polygonal geometry
  273. * - null or false - do not clip
  274. *
  275. * The *sphere* clip option requires a geographic projection.
  276. */
  277. clip?: "frame" | "sphere" | GeoPermissibleObjects | boolean | null;
  278. /**
  279. * The horizontal offset in pixels; a constant option. On low-density screens,
  280. * an additional 0.5px offset may be applied for crisp edges.
  281. */
  282. dx?: number;
  283. /**
  284. * The vertical offset in pixels; a constant option. On low-density screens,
  285. * an additional 0.5px offset may be applied for crisp edges.
  286. */
  287. dy?: number;
  288. /**
  289. * The [fill][1]; a constant CSS color string, or a channel typically bound to
  290. * the *color* scale. If all channel values are valid CSS colors, by default
  291. * the channel will not be bound to the *color* scale, interpreting the colors
  292. * literally.
  293. *
  294. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill
  295. */
  296. fill?: ChannelValueSpec;
  297. /**
  298. * The [fill-opacity][1]; a constant number between 0 and 1, or a channel
  299. * typically bound to the *opacity* scale. If all channel values are numbers
  300. * in [0, 1], by default the channel will not be bound to the *opacity* scale,
  301. * interpreting the opacities literally.
  302. *
  303. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-opacity
  304. */
  305. fillOpacity?: ChannelValueSpec;
  306. /**
  307. * The [stroke][1]; a constant CSS color string, or a channel typically bound
  308. * to the *color* scale. If all channel values are valid CSS colors, by
  309. * default the channel will not be bound to the *color* scale, interpreting
  310. * the colors literally.
  311. *
  312. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke
  313. */
  314. stroke?: ChannelValueSpec;
  315. /**
  316. * The [stroke-dasharray][1]; a constant number indicating the length in
  317. * pixels of alternating dashes and gaps, or a constant string of numbers
  318. * separated by spaces or commas (_e.g._, *10 2* for dashes of 10 pixels
  319. * separated by gaps of 2 pixels), or *none* (the default) for no dashing
  320. *
  321. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray
  322. */
  323. strokeDasharray?: string | number;
  324. /**
  325. * The [stroke-dashoffset][1]; a constant indicating the offset in pixels of
  326. * the first dash along the stroke; defaults to zero.
  327. *
  328. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset
  329. */
  330. strokeDashoffset?: string | number;
  331. /**
  332. * The [stroke-linecap][1]; a constant specifying how to cap stroked paths,
  333. * such as *butt*, *round*, or *square*.
  334. *
  335. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap
  336. */
  337. strokeLinecap?: string;
  338. /**
  339. * The [stroke-linejoin][1]; a constant specifying how to join stroked paths,
  340. * such as *bevel*, *miter*, *miter-clip*, or *round*.
  341. *
  342. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin
  343. */
  344. strokeLinejoin?: string;
  345. /**
  346. * The [stroke-miterlimit][1]; a constant number specifying how to limit the
  347. * length of *miter* joins on stroked paths.
  348. *
  349. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit
  350. */
  351. strokeMiterlimit?: number;
  352. /**
  353. * The [stroke-opacity][1]; a constant between 0 and 1, or a channel typically
  354. * bound to the *opacity* scale. If all channel values are numbers in [0, 1],
  355. * by default the channel will not be bound to the *opacity* scale,
  356. * interpreting the opacities literally.
  357. *
  358. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-opacity
  359. */
  360. strokeOpacity?: ChannelValueSpec;
  361. /**
  362. * The [stroke-width][1]; a constant number in pixels, or a channel.
  363. *
  364. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-width
  365. */
  366. strokeWidth?: ChannelValueSpec;
  367. /**
  368. * The [opacity][1]; a constant between 0 and 1, or a channel typically bound
  369. * to the *opacity* scale. If all channel values are numbers in [0, 1], by
  370. * default the channel will not be bound to the *opacity* scale, interpreting
  371. * the opacities literally. For faster rendering, prefer the **strokeOpacity**
  372. * or **fillOpacity** option.
  373. *
  374. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/opacity
  375. */
  376. opacity?: ChannelValueSpec;
  377. /**
  378. * The [mix-blend-mode][1]; a constant string specifying how to blend content
  379. * such as *multiply*.
  380. *
  381. * [1]: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
  382. */
  383. mixBlendMode?: string;
  384. /**
  385. * A CSS [filter][1]; a constant string used to adjust the rendering of
  386. * images, such as *blur(5px)*.
  387. *
  388. * [1]: https://developer.mozilla.org/en-US/docs/Web/CSS/filter
  389. */
  390. imageFilter?: string;
  391. /**
  392. * The [paint-order][1]; a constant string specifying the order in which the
  393. * **fill**, **stroke**, and any markers are drawn; defaults to *normal*,
  394. * which draws the fill, then stroke, then markers; defaults to *stroke* for
  395. * the text mark to create a “halo” around text to improve legibility.
  396. *
  397. * [1]: https://developer.mozilla.org/en-US/docs/Web/CSS/paint-order
  398. */
  399. paintOrder?: string;
  400. /**
  401. * The [shape-rendering][1]; a constant string such as *crispEdges*.
  402. *
  403. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/shape-rendering
  404. */
  405. shapeRendering?: string;
  406. /**
  407. * The [href][1]; a channel specifying URLs for clickable links. May be used
  408. * in conjunction with the **target** option to open links in another window.
  409. *
  410. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/href
  411. */
  412. href?: ChannelValue;
  413. /**
  414. * The [target][1]; a constant string specifying the target window (_e.g._,
  415. * *_blank*) for clickable links; used in conjunction with the **href**
  416. * option.
  417. *
  418. * [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/target
  419. */
  420. target?: string;
  421. /**
  422. * An object defining additional custom channels. This meta option may be used
  423. * by an **initializer** to declare extra channels.
  424. */
  425. channels?: Record<string, Channel | ChannelValue>;
  426. }
  427. /** The abstract base class for Mark implementations. */
  428. export class Mark {
  429. /**
  430. * Renders a new plot, prepending this mark as the first element of **marks**
  431. * of the specified *options*, and returns the corresponding SVG element, or
  432. * an HTML figure element if a caption or legend is requested.
  433. */
  434. plot: typeof plot;
  435. }
  436. /** A concrete Mark implementation. */
  437. export class RenderableMark extends Mark {
  438. /** Renders this mark, returning a new SVGElement (or null). */
  439. render: RenderFunction;
  440. }
  441. /** A compound Mark, comprising other marks. */
  442. export type CompoundMark = Markish[] & Pick<Mark, "plot">;
  443. /** Given an array of marks, returns a compound mark; supports *mark*.plot shorthand. */
  444. export function marks(...marks: Markish[]): CompoundMark;