area.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import {area as shapeArea} from "d3";
  2. import {create} from "../context.js";
  3. import {maybeCurve} from "../curve.js";
  4. import {Mark} from "../mark.js";
  5. import {first, indexOf, maybeZ, second} from "../options.js";
  6. import {
  7. applyDirectStyles,
  8. applyIndirectStyles,
  9. applyTransform,
  10. applyGroupedChannelStyles,
  11. groupIndex
  12. } from "../style.js";
  13. import {maybeDenseIntervalX, maybeDenseIntervalY} from "../transforms/bin.js";
  14. import {maybeIdentityX, maybeIdentityY} from "../transforms/identity.js";
  15. import {maybeStackX, maybeStackY} from "../transforms/stack.js";
  16. const defaults = {
  17. ariaLabel: "area",
  18. strokeWidth: 1,
  19. strokeLinecap: "round",
  20. strokeLinejoin: "round",
  21. strokeMiterlimit: 1
  22. };
  23. export class Area extends Mark {
  24. constructor(data, options = {}) {
  25. const {x1, y1, x2, y2, z, curve, tension} = options;
  26. super(
  27. data,
  28. {
  29. x1: {value: x1, scale: "x"},
  30. y1: {value: y1, scale: "y"},
  31. x2: {value: x2, scale: "x", optional: true},
  32. y2: {value: y2, scale: "y", optional: true},
  33. z: {value: maybeZ(options), optional: true}
  34. },
  35. options,
  36. defaults
  37. );
  38. this.z = z;
  39. this.curve = maybeCurve(curve, tension);
  40. }
  41. filter(index) {
  42. return index;
  43. }
  44. render(index, scales, channels, dimensions, context) {
  45. const {x1: X1, y1: Y1, x2: X2 = X1, y2: Y2 = Y1} = channels;
  46. return create("svg:g", context)
  47. .call(applyIndirectStyles, this, dimensions, context)
  48. .call(applyTransform, this, scales, 0, 0)
  49. .call((g) =>
  50. g
  51. .selectAll()
  52. .data(groupIndex(index, [X1, Y1, X2, Y2], this, channels))
  53. .enter()
  54. .append("path")
  55. .call(applyDirectStyles, this)
  56. .call(applyGroupedChannelStyles, this, channels)
  57. .attr(
  58. "d",
  59. shapeArea()
  60. .curve(this.curve)
  61. .defined((i) => i >= 0)
  62. .x0((i) => X1[i])
  63. .y0((i) => Y1[i])
  64. .x1((i) => X2[i])
  65. .y1((i) => Y2[i])
  66. )
  67. )
  68. .node();
  69. }
  70. }
  71. export function area(data, options) {
  72. if (options === undefined) return areaY(data, {x: first, y: second});
  73. return new Area(data, options);
  74. }
  75. export function areaX(data, options) {
  76. const {y = indexOf, ...rest} = maybeDenseIntervalY(options);
  77. return new Area(data, maybeStackX(maybeIdentityX({...rest, y1: y, y2: undefined}, y === indexOf ? "x2" : "x")));
  78. }
  79. export function areaY(data, options) {
  80. const {x = indexOf, ...rest} = maybeDenseIntervalX(options);
  81. return new Area(data, maybeStackY(maybeIdentityY({...rest, x1: x, x2: undefined}, x === indexOf ? "y2" : "y")));
  82. }