boxplot.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. "use strict";
  2. var __rest = (this && this.__rest) || function (s, e) {
  3. var t = {};
  4. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
  5. t[p] = s[p];
  6. if (s != null && typeof Object.getOwnPropertySymbols === "function")
  7. for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  8. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
  9. t[p[i]] = s[p[i]];
  10. }
  11. return t;
  12. };
  13. Object.defineProperty(exports, "__esModule", { value: true });
  14. exports.Boxplot = void 0;
  15. const d3_array_1 = require("d3-array");
  16. const helper_1 = require("../utils/helper");
  17. const mark_1 = require("../utils/mark");
  18. function min(I, V) {
  19. return (0, d3_array_1.min)(I, (i) => V[i]);
  20. }
  21. function max(I, V) {
  22. return (0, d3_array_1.max)(I, (i) => V[i]);
  23. }
  24. function lower(I, V) {
  25. const lo = q1(I, V) * 2.5 - q3(I, V) * 1.5;
  26. return (0, d3_array_1.min)(I, (i) => (V[i] >= lo ? V[i] : NaN));
  27. }
  28. function q1(I, V) {
  29. return (0, d3_array_1.quantile)(I, 0.25, (i) => V[i]);
  30. }
  31. function q2(I, V) {
  32. return (0, d3_array_1.quantile)(I, 0.5, (i) => V[i]);
  33. }
  34. function q3(I, V) {
  35. return (0, d3_array_1.quantile)(I, 0.75, (i) => V[i]);
  36. }
  37. function upper(I, V) {
  38. const hi = q3(I, V) * 2.5 - q1(I, V) * 1.5;
  39. return (0, d3_array_1.max)(I, (i) => (V[i] <= hi ? V[i] : NaN));
  40. }
  41. /**
  42. * Group marks by x and reserve outlier indexes.
  43. */
  44. function OutlierY() {
  45. return (I, mark) => {
  46. const { encode } = mark;
  47. const { y, x } = encode;
  48. const { value: V } = y;
  49. const { value: X } = x;
  50. const GI = Array.from((0, d3_array_1.group)(I, (i) => X[+i]).values());
  51. const FI = GI.flatMap((I) => {
  52. const lo = lower(I, V);
  53. const hi = upper(I, V);
  54. return I.filter((i) => V[i] < lo || V[i] > hi);
  55. });
  56. return [FI, mark];
  57. };
  58. }
  59. const Boxplot = (options) => {
  60. return () => {
  61. const { data, encode, style = {}, tooltip = {}, transform, animate } = options, rest = __rest(options, ["data", "encode", "style", "tooltip", "transform", "animate"]);
  62. const { point = true } = style, restStyle = __rest(style, ["point"]);
  63. const { y } = encode;
  64. const encodeY = { y, y1: y, y2: y, y3: y, y4: y };
  65. const qy = { y1: q1, y2: q2, y3: q3 };
  66. // Tooltips.
  67. const boxTooltip = (0, mark_1.subTooltip)(tooltip, 'box', {
  68. items: [
  69. { channel: 'y', name: 'min' },
  70. { channel: 'y1', name: 'q1' },
  71. { channel: 'y2', name: 'q2' },
  72. { channel: 'y3', name: 'q3' },
  73. { channel: 'y4', name: 'max' },
  74. ],
  75. }, true);
  76. const pointTooltip = (0, mark_1.subTooltip)(tooltip, 'point', {
  77. title: { channel: 'x' },
  78. items: [{ name: 'outlier', channel: 'y' }],
  79. });
  80. // Only show min and max instead of lower and upper.
  81. // Only draw a box.
  82. if (!point) {
  83. return [
  84. Object.assign({ type: 'box', data: data, transform: [
  85. Object.assign(Object.assign({ type: 'groupX', y: min }, qy), { y4: max }),
  86. ], encode: Object.assign(Object.assign({}, encode), encodeY), style: restStyle, tooltip: boxTooltip }, rest),
  87. ];
  88. }
  89. const boxStyle = (0, helper_1.subObject)(restStyle, 'box');
  90. const pointStyle = (0, helper_1.subObject)(restStyle, 'point');
  91. return [
  92. Object.assign({ type: 'box', data: data, transform: [
  93. Object.assign(Object.assign({ type: 'groupX', y: lower }, qy), { y4: upper }),
  94. ], encode: Object.assign(Object.assign({}, encode), encodeY), style: boxStyle, tooltip: boxTooltip, animate: (0, mark_1.maybeAnimation)(animate, 'box') }, rest),
  95. // Draw outliers.
  96. {
  97. type: 'point',
  98. data: data,
  99. transform: [{ type: OutlierY }],
  100. encode,
  101. style: Object.assign({}, pointStyle),
  102. tooltip: pointTooltip,
  103. animate: (0, mark_1.maybeAnimation)(animate, 'point'),
  104. },
  105. ];
  106. };
  107. };
  108. exports.Boxplot = Boxplot;
  109. exports.Boxplot.props = {};
  110. //# sourceMappingURL=boxplot.js.map