groupN.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. var __rest = (this && this.__rest) || function (s, e) {
  2. var t = {};
  3. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
  4. t[p] = s[p];
  5. if (s != null && typeof Object.getOwnPropertySymbols === "function")
  6. for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  7. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
  8. t[p[i]] = s[p[i]];
  9. }
  10. return t;
  11. };
  12. import { deepMix } from '@antv/util';
  13. import { max as d3Max, mean as d3Mean, sum as d3Sum, min as d3Min, median as d3Median, } from 'd3-array';
  14. import { indexOf } from '../utils/array';
  15. import { columnOf, column, nonConstantColumn } from './utils/helper';
  16. function builtinFormatter(summary) {
  17. return (d) => (d === null ? summary : `${summary} of ${d}`);
  18. }
  19. function normalizeReducer(reducer) {
  20. if (typeof reducer === 'function')
  21. return [reducer, null];
  22. const registry = { mean, max, count, first, last, sum, min, median };
  23. const reducerFunction = registry[reducer];
  24. if (!reducerFunction)
  25. throw new Error(`Unknown reducer: ${reducer}.`);
  26. return reducerFunction();
  27. }
  28. function mean() {
  29. const reducer = (I, V) => d3Mean(I, (i) => +V[i]);
  30. const formatter = builtinFormatter('mean');
  31. return [reducer, formatter];
  32. }
  33. function median() {
  34. const reducer = (I, V) => d3Median(I, (i) => +V[i]);
  35. const formatter = builtinFormatter('median');
  36. return [reducer, formatter];
  37. }
  38. function max() {
  39. const reducer = (I, V) => d3Max(I, (i) => +V[i]);
  40. const formatter = builtinFormatter('max');
  41. return [reducer, formatter];
  42. }
  43. function min() {
  44. const reducer = (I, V) => d3Min(I, (i) => +V[i]);
  45. const formatter = builtinFormatter('min');
  46. return [reducer, formatter];
  47. }
  48. function count() {
  49. const reducer = (I, V) => I.length;
  50. const formatter = builtinFormatter('count');
  51. return [reducer, formatter];
  52. }
  53. function sum() {
  54. const reducer = (I, V) => d3Sum(I, (i) => +V[i]);
  55. const formatter = builtinFormatter('sum');
  56. return [reducer, formatter];
  57. }
  58. function first() {
  59. const reducer = (I, V) => V[I[0]];
  60. const formatter = builtinFormatter('first');
  61. return [reducer, formatter];
  62. }
  63. function last() {
  64. const reducer = (I, V) => V[I[I.length - 1]];
  65. const formatter = builtinFormatter('last');
  66. return [reducer, formatter];
  67. }
  68. /**
  69. * The Group transform group data by x and y channels, and aggregate.
  70. */
  71. export const GroupN = (options = {}) => {
  72. const { groupBy } = options, rest = __rest(options, ["groupBy"]);
  73. return (I, mark) => {
  74. const { data, encode } = mark;
  75. const groups = groupBy(I, mark);
  76. if (!groups)
  77. return [I, mark];
  78. // Extract field from from channel
  79. // x1 from x, y1 from y, etc,.
  80. const maybeFrom = (field, reducer) => {
  81. if (field)
  82. return field;
  83. const { from } = reducer;
  84. if (!from)
  85. return field;
  86. const [, field1] = columnOf(encode, from);
  87. return field1;
  88. };
  89. const outputs = Object.entries(rest).map(([channel, reducer]) => {
  90. const [reducerFunction, formatter] = normalizeReducer(reducer);
  91. const [V, field] = columnOf(encode, channel);
  92. const field1 = maybeFrom(field, reducer);
  93. const RV = groups.map((I) => reducerFunction(I, V !== null && V !== void 0 ? V : data));
  94. return [
  95. channel,
  96. Object.assign(Object.assign({}, nonConstantColumn(RV, (formatter === null || formatter === void 0 ? void 0 : formatter(field1)) || field1)), { aggregate: true }),
  97. ];
  98. });
  99. const reducedColumns = Object.keys(encode).map((key) => {
  100. const [V, fv] = columnOf(encode, key);
  101. const GV = groups.map((I) => V[I[0]]);
  102. return [key, column(GV, fv)];
  103. });
  104. const GD = groups.map((I) => data[I[0]]);
  105. const GI = indexOf(groups);
  106. return [
  107. GI,
  108. deepMix({}, mark, {
  109. data: GD,
  110. encode: Object.fromEntries([...reducedColumns, ...outputs]),
  111. }),
  112. ];
  113. };
  114. };
  115. GroupN.props = {};
  116. //# sourceMappingURL=groupN.js.map