histogram.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { clone, each, getRange, groupBy, hasKey, isEmpty, sortBy, valuesOfKey } from '@antv/util';
  2. // 进行转换得到值所在的 range
  3. function getBinKey(value, binWidth, binNumber) {
  4. // 做一点特殊处理
  5. if (binNumber === 1) {
  6. return [0, binWidth];
  7. }
  8. var index = Math.floor(value / binWidth);
  9. return [binWidth * index, binWidth * (index + 1)];
  10. }
  11. // 默认 sturges 转换
  12. function sturges(values) {
  13. return Math.ceil(Math.log(values.length) / Math.LN2) + 1;
  14. }
  15. /**
  16. * 对数据进行百分比化
  17. * @param data
  18. * @param binField
  19. * @param binWidth
  20. * @param binNumber
  21. * @param stackField
  22. */
  23. export function binHistogram(data, binField, binWidth, binNumber, stackField) {
  24. var originData_copy = clone(data);
  25. // 根据 binField 对源数据进行排序
  26. sortBy(originData_copy, binField);
  27. // 获取源数据 binField 的 range
  28. var values = valuesOfKey(originData_copy, binField);
  29. var range = getRange(values);
  30. var rangeWidth = range.max - range.min;
  31. // 计算分箱,直方图分箱的计算基于 binWidth,如配置了 binNumber 则将其转为 binWidth 进行计算
  32. var _binWidth = binWidth;
  33. if (!binWidth && binNumber) {
  34. _binWidth = binNumber > 1 ? rangeWidth / (binNumber - 1) : range.max;
  35. }
  36. // 当 binWidth 和 binNumber 都没有指定的情况,采用 Sturges formula 自动生成 binWidth
  37. if (!binWidth && !binNumber) {
  38. var _defaultBinNumber = sturges(values);
  39. _binWidth = rangeWidth / _defaultBinNumber;
  40. }
  41. // 构建 key - StatisticData 结构
  42. var bins = {};
  43. var groups = groupBy(originData_copy, stackField);
  44. // 判断分组是否为空,如果为空,说明没有 stackField 字段
  45. if (isEmpty(groups)) {
  46. each(originData_copy, function (data) {
  47. var value = data[binField];
  48. var bin = getBinKey(value, _binWidth, binNumber);
  49. var binKey = "".concat(bin[0], "-").concat(bin[1]);
  50. if (!hasKey(bins, binKey)) {
  51. bins[binKey] = { range: bin, count: 0 };
  52. }
  53. bins[binKey].count += 1;
  54. });
  55. }
  56. else {
  57. Object.keys(groups).forEach(function (groupKey) {
  58. each(groups[groupKey], function (data) {
  59. var value = data[binField];
  60. var bin = getBinKey(value, _binWidth, binNumber);
  61. var binKey = "".concat(bin[0], "-").concat(bin[1]);
  62. var groupKeyBinKey = "".concat(binKey, "-").concat(groupKey);
  63. if (!hasKey(bins, groupKeyBinKey)) {
  64. bins[groupKeyBinKey] = { range: bin, count: 0 };
  65. bins[groupKeyBinKey][stackField] = groupKey;
  66. }
  67. bins[groupKeyBinKey].count += 1;
  68. });
  69. });
  70. }
  71. // 将分箱数据转换为 plotData 才是图表所需要的
  72. var plotData = [];
  73. each(bins, function (bin) {
  74. plotData.push(bin);
  75. });
  76. return plotData;
  77. }
  78. //# sourceMappingURL=histogram.js.map