ActiveShapeUtils.js
12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Shape = Shape;
exports.compareFunnel = compareFunnel;
exports.comparePie = comparePie;
exports.compareScatter = compareScatter;
exports.getActiveShapeIndexForTooltip = getActiveShapeIndexForTooltip;
exports.getPropsFromShapeOption = getPropsFromShapeOption;
exports.isFunnel = isFunnel;
exports.isPie = isPie;
exports.isScatter = isScatter;
var _react = _interopRequireWildcard(require("react"));
var _isFunction = _interopRequireDefault(require("lodash/isFunction"));
var _isPlainObject = _interopRequireDefault(require("lodash/isPlainObject"));
var _isBoolean = _interopRequireDefault(require("lodash/isBoolean"));
var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
var _Rectangle = require("../shape/Rectangle");
var _Trapezoid = require("../shape/Trapezoid");
var _Sector = require("../shape/Sector");
var _Layer = require("../container/Layer");
var _Symbols = require("../shape/Symbols");
var _excluded = ["option", "shapeType", "propTransformer", "activeClassName", "isActive"];
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } } return target; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/**
* This is an abstraction for rendering a user defined prop for a customized shape in several forms.
*
* <Shape /> is the root and will handle taking in:
* - an object of svg properties
* - a boolean
* - a render prop(inline function that returns jsx)
* - a react element
*
* <ShapeSelector /> is a subcomponent of <Shape /> and used to match a component
* to the value of props.shapeType that is passed to the root.
*
*/
function defaultPropTransformer(option, props) {
return _objectSpread(_objectSpread({}, props), option);
}
function isSymbolsProps(shapeType, _elementProps) {
return shapeType === 'symbols';
}
function ShapeSelector(_ref) {
var shapeType = _ref.shapeType,
elementProps = _ref.elementProps;
switch (shapeType) {
case 'rectangle':
return /*#__PURE__*/_react["default"].createElement(_Rectangle.Rectangle, elementProps);
case 'trapezoid':
return /*#__PURE__*/_react["default"].createElement(_Trapezoid.Trapezoid, elementProps);
case 'sector':
return /*#__PURE__*/_react["default"].createElement(_Sector.Sector, elementProps);
case 'symbols':
if (isSymbolsProps(shapeType, elementProps)) {
return /*#__PURE__*/_react["default"].createElement(_Symbols.Symbols, elementProps);
}
break;
default:
return null;
}
}
function getPropsFromShapeOption(option) {
if ( /*#__PURE__*/(0, _react.isValidElement)(option)) {
return option.props;
}
return option;
}
function Shape(_ref2) {
var option = _ref2.option,
shapeType = _ref2.shapeType,
_ref2$propTransformer = _ref2.propTransformer,
propTransformer = _ref2$propTransformer === void 0 ? defaultPropTransformer : _ref2$propTransformer,
_ref2$activeClassName = _ref2.activeClassName,
activeClassName = _ref2$activeClassName === void 0 ? 'recharts-active-shape' : _ref2$activeClassName,
isActive = _ref2.isActive,
props = _objectWithoutProperties(_ref2, _excluded);
var shape;
if ( /*#__PURE__*/(0, _react.isValidElement)(option)) {
shape = /*#__PURE__*/(0, _react.cloneElement)(option, _objectSpread(_objectSpread({}, props), getPropsFromShapeOption(option)));
} else if ((0, _isFunction["default"])(option)) {
shape = option(props);
} else if ((0, _isPlainObject["default"])(option) && !(0, _isBoolean["default"])(option)) {
var nextProps = propTransformer(option, props);
shape = /*#__PURE__*/_react["default"].createElement(ShapeSelector, {
shapeType: shapeType,
elementProps: nextProps
});
} else {
var elementProps = props;
shape = /*#__PURE__*/_react["default"].createElement(ShapeSelector, {
shapeType: shapeType,
elementProps: elementProps
});
}
if (isActive) {
return /*#__PURE__*/_react["default"].createElement(_Layer.Layer, {
className: activeClassName
}, shape);
}
return shape;
}
/**
* This is an abstraction to handle identifying the active index from a tooltip mouse interaction
*/
function isFunnel(graphicalItem, _item) {
return _item != null && 'trapezoids' in graphicalItem.props;
}
function isPie(graphicalItem, _item) {
return _item != null && 'sectors' in graphicalItem.props;
}
function isScatter(graphicalItem, _item) {
return _item != null && 'points' in graphicalItem.props;
}
function compareFunnel(shapeData, activeTooltipItem) {
var _activeTooltipItem$la, _activeTooltipItem$la2;
var xMatches = shapeData.x === (activeTooltipItem === null || activeTooltipItem === void 0 || (_activeTooltipItem$la = activeTooltipItem.labelViewBox) === null || _activeTooltipItem$la === void 0 ? void 0 : _activeTooltipItem$la.x) || shapeData.x === activeTooltipItem.x;
var yMatches = shapeData.y === (activeTooltipItem === null || activeTooltipItem === void 0 || (_activeTooltipItem$la2 = activeTooltipItem.labelViewBox) === null || _activeTooltipItem$la2 === void 0 ? void 0 : _activeTooltipItem$la2.y) || shapeData.y === activeTooltipItem.y;
return xMatches && yMatches;
}
function comparePie(shapeData, activeTooltipItem) {
var startAngleMatches = shapeData.endAngle === activeTooltipItem.endAngle;
var endAngleMatches = shapeData.startAngle === activeTooltipItem.startAngle;
return startAngleMatches && endAngleMatches;
}
function compareScatter(shapeData, activeTooltipItem) {
var xMatches = shapeData.x === activeTooltipItem.x;
var yMatches = shapeData.y === activeTooltipItem.y;
var zMatches = shapeData.z === activeTooltipItem.z;
return xMatches && yMatches && zMatches;
}
function getComparisonFn(graphicalItem, activeItem) {
var comparison;
if (isFunnel(graphicalItem, activeItem)) {
comparison = compareFunnel;
} else if (isPie(graphicalItem, activeItem)) {
comparison = comparePie;
} else if (isScatter(graphicalItem, activeItem)) {
comparison = compareScatter;
}
return comparison;
}
function getShapeDataKey(graphicalItem, activeItem) {
var shapeKey;
if (isFunnel(graphicalItem, activeItem)) {
shapeKey = 'trapezoids';
} else if (isPie(graphicalItem, activeItem)) {
shapeKey = 'sectors';
} else if (isScatter(graphicalItem, activeItem)) {
shapeKey = 'points';
}
return shapeKey;
}
function getActiveShapeTooltipPayload(graphicalItem, activeItem) {
if (isFunnel(graphicalItem, activeItem)) {
var _activeItem$tooltipPa;
return (_activeItem$tooltipPa = activeItem.tooltipPayload) === null || _activeItem$tooltipPa === void 0 || (_activeItem$tooltipPa = _activeItem$tooltipPa[0]) === null || _activeItem$tooltipPa === void 0 || (_activeItem$tooltipPa = _activeItem$tooltipPa.payload) === null || _activeItem$tooltipPa === void 0 ? void 0 : _activeItem$tooltipPa.payload;
}
if (isPie(graphicalItem, activeItem)) {
var _activeItem$tooltipPa2;
return (_activeItem$tooltipPa2 = activeItem.tooltipPayload) === null || _activeItem$tooltipPa2 === void 0 || (_activeItem$tooltipPa2 = _activeItem$tooltipPa2[0]) === null || _activeItem$tooltipPa2 === void 0 || (_activeItem$tooltipPa2 = _activeItem$tooltipPa2.payload) === null || _activeItem$tooltipPa2 === void 0 ? void 0 : _activeItem$tooltipPa2.payload;
}
if (isScatter(graphicalItem, activeItem)) {
return activeItem.payload;
}
return {};
}
/**
*
* @param {GetActiveShapeIndexForTooltip} arg an object of incoming attributes from Tooltip
* @returns {number}
*
* To handle possible duplicates in the data set,
* match both the data value of the active item to a data value on a graph item,
* and match the mouse coordinates of the active item to the coordinates of in a particular components shape data.
* This assumes equal lengths of shape objects to data items.
*/
function getActiveShapeIndexForTooltip(_ref3) {
var activeTooltipItem = _ref3.activeTooltipItem,
graphicalItem = _ref3.graphicalItem,
itemData = _ref3.itemData;
var shapeKey = getShapeDataKey(graphicalItem, activeTooltipItem);
var tooltipPayload = getActiveShapeTooltipPayload(graphicalItem, activeTooltipItem);
var activeItemMatches = itemData.filter(function (datum, dataIndex) {
var valuesMatch = (0, _isEqual["default"])(tooltipPayload, datum);
var mouseCoordinateMatches = graphicalItem.props[shapeKey].filter(function (shapeData) {
var comparison = getComparisonFn(graphicalItem, activeTooltipItem);
return comparison(shapeData, activeTooltipItem);
});
// get the last index in case of multiple matches
var indexOfMouseCoordinates = graphicalItem.props[shapeKey].indexOf(mouseCoordinateMatches[mouseCoordinateMatches.length - 1]);
var coordinatesMatch = dataIndex === indexOfMouseCoordinates;
return valuesMatch && coordinatesMatch;
});
// get the last index in case of multiple matches
var activeIndex = itemData.indexOf(activeItemMatches[activeItemMatches.length - 1]);
return activeIndex;
}