UNPKG

9.27 kBJavaScriptView Raw
1var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
2
3var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
4
5function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6
7function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
8
9function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
10
11function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
12
13// Copyright (c) 2017 Uber Technologies, Inc.
14//
15// Permission is hereby granted, free of charge, to any person obtaining a copy
16// of this software and associated documentation files (the "Software"), to deal
17// in the Software without restriction, including without limitation the rights
18// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19// copies of the Software, and to permit persons to whom the Software is
20// furnished to do so, subject to the following conditions:
21//
22// The above copyright notice and this permission notice shall be included in
23// all copies or substantial portions of the Software.
24//
25// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31// THE SOFTWARE.
32
33import React from 'react';
34import PropTypes from 'prop-types';
35
36import AbstractSeries from './abstract-series';
37import Animation from '../../animation';
38import { ANIMATED_SERIES_PROPS } from '../../utils/series-utils';
39
40var predefinedClassName = 'rv-xy-plot__series rv-xy-plot__series--custom-svg-wrapper';
41
42var DEFAULT_STYLE = {
43 stroke: 'blue',
44 fill: 'blue'
45};
46
47function predefinedComponents(type) {
48 var size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
49 var style = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_STYLE;
50
51 switch (type) {
52 case 'diamond':
53 return React.createElement('polygon', {
54 style: style,
55 points: '0 0 ' + size / 2 + ' ' + size / 2 + ' 0 ' + size + ' ' + -size / 2 + ' ' + size / 2 + ' 0 0'
56 });
57 case 'star':
58 var starPoints = [].concat(_toConsumableArray(new Array(5))).map(function (c, index) {
59 var angle = index / 5 * Math.PI * 2;
60 var innerAngle = angle + Math.PI / 10;
61 var outerAngle = angle - Math.PI / 10;
62 // ratio of inner polygon to outer polgyon
63 var innerRadius = size / 2.61;
64 return '\n ' + Math.cos(outerAngle) * size + ' ' + Math.sin(outerAngle) * size + '\n ' + Math.cos(innerAngle) * innerRadius + ' ' + Math.sin(innerAngle) * innerRadius + '\n ';
65 }).join(' ');
66 return React.createElement('polygon', {
67 points: starPoints,
68 x: '0',
69 y: '0',
70 height: size,
71 width: size,
72 style: style
73 });
74 case 'square':
75 return React.createElement('rect', {
76 x: '' + -size / 2,
77 y: '' + -size / 2,
78 height: size,
79 width: size,
80 style: style
81 });
82 default:
83 case 'circle':
84 return React.createElement('circle', { cx: '0', cy: '0', r: size / 2, style: style });
85 }
86}
87
88function getInnerComponent(_ref) {
89 var customComponent = _ref.customComponent,
90 defaultType = _ref.defaultType,
91 positionInPixels = _ref.positionInPixels,
92 positionFunctions = _ref.positionFunctions,
93 style = _ref.style,
94 propsSize = _ref.propsSize;
95 var size = customComponent.size;
96
97 var aggStyle = _extends({}, style, customComponent.style || {});
98 var innerComponent = customComponent.customComponent;
99 if (!innerComponent && typeof defaultType === 'string') {
100 return predefinedComponents(defaultType, size || propsSize, aggStyle);
101 }
102 // if default component is a function
103 if (!innerComponent) {
104 return defaultType(customComponent, positionInPixels, aggStyle);
105 }
106 if (typeof innerComponent === 'string') {
107 return predefinedComponents(innerComponent || defaultType, size, aggStyle);
108 }
109 // if inner component is a function
110 return innerComponent(customComponent, positionInPixels, aggStyle);
111}
112
113var CustomSVGSeries = function (_AbstractSeries) {
114 _inherits(CustomSVGSeries, _AbstractSeries);
115
116 function CustomSVGSeries() {
117 _classCallCheck(this, CustomSVGSeries);
118
119 return _possibleConstructorReturn(this, (CustomSVGSeries.__proto__ || Object.getPrototypeOf(CustomSVGSeries)).apply(this, arguments));
120 }
121
122 _createClass(CustomSVGSeries, [{
123 key: 'render',
124 value: function render() {
125 var _this2 = this;
126
127 var _props = this.props,
128 animation = _props.animation,
129 className = _props.className,
130 customComponent = _props.customComponent,
131 data = _props.data,
132 innerHeight = _props.innerHeight,
133 innerWidth = _props.innerWidth,
134 marginLeft = _props.marginLeft,
135 marginTop = _props.marginTop,
136 style = _props.style,
137 size = _props.size;
138
139
140 if (!data || !innerWidth || !innerHeight) {
141 return null;
142 }
143
144 if (animation) {
145 return React.createElement(
146 Animation,
147 _extends({}, this.props, { animatedProps: ANIMATED_SERIES_PROPS }),
148 React.createElement(CustomSVGSeries, _extends({}, this.props, { animation: false }))
149 );
150 }
151
152 var x = this._getAttributeFunctor('x');
153 var y = this._getAttributeFunctor('y');
154 var contents = data.map(function (seriesComponent, index) {
155 var positionInPixels = {
156 x: x(seriesComponent),
157 y: y(seriesComponent)
158 };
159 var innerComponent = getInnerComponent({
160 customComponent: seriesComponent,
161 positionInPixels: positionInPixels,
162 defaultType: customComponent,
163 positionFunctions: { x: x, y: y },
164 style: style,
165 propsSize: size
166 });
167 return React.createElement(
168 'g',
169 {
170 className: 'rv-xy-plot__series--custom-svg',
171 key: 'rv-xy-plot__series--custom-svg-' + index,
172 transform: 'translate(' + positionInPixels.x + ',' + positionInPixels.y + ')',
173 onMouseEnter: function onMouseEnter(e) {
174 return _this2._valueMouseOverHandler(seriesComponent, e);
175 },
176 onMouseLeave: function onMouseLeave(e) {
177 return _this2._valueMouseOutHandler(seriesComponent, e);
178 }
179 },
180 innerComponent
181 );
182 });
183 return React.createElement(
184 'g',
185 {
186 className: predefinedClassName + ' ' + className,
187 transform: 'translate(' + marginLeft + ',' + marginTop + ')'
188 },
189 contents
190 );
191 }
192 }]);
193
194 return CustomSVGSeries;
195}(AbstractSeries);
196
197CustomSVGSeries.propTypes = {
198 animation: PropTypes.bool,
199 className: PropTypes.string,
200 customComponent: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
201 data: PropTypes.arrayOf(PropTypes.shape({
202 x: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
203 y: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired
204 })).isRequired,
205 marginLeft: PropTypes.number,
206 marginTop: PropTypes.number,
207 style: PropTypes.object,
208 size: PropTypes.number,
209 onValueMouseOver: PropTypes.func,
210 onValueMouseOut: PropTypes.func
211};
212
213CustomSVGSeries.defaultProps = _extends({}, AbstractSeries.defaultProps, {
214 animation: false,
215 customComponent: 'circle',
216 style: {},
217 size: 2
218});
219
220export default CustomSVGSeries;
\No newline at end of file