Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

253 строки
8.4 KiB

  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _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; }; // Copyright (c) 2016 - 2017 Uber Technologies, Inc.
  6. //
  7. // Permission is hereby granted, free of charge, to any person obtaining a copy
  8. // of this software and associated documentation files (the "Software"), to deal
  9. // in the Software without restriction, including without limitation the rights
  10. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the Software is
  12. // furnished to do so, subject to the following conditions:
  13. //
  14. // The above copyright notice and this permission notice shall be included in
  15. // all copies or substantial portions of the Software.
  16. //
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. // THE SOFTWARE.
  24. var _react = require('react');
  25. var _react2 = _interopRequireDefault(_react);
  26. var _propTypes = require('prop-types');
  27. var _propTypes2 = _interopRequireDefault(_propTypes);
  28. var _d3Hierarchy = require('d3-hierarchy');
  29. var _d3Scale = require('d3-scale');
  30. var _animation = require('../animation');
  31. var _labelSeries = require('../plot/series/label-series');
  32. var _labelSeries2 = _interopRequireDefault(_labelSeries);
  33. var _arcSeries = require('../plot/series/arc-series');
  34. var _arcSeries2 = _interopRequireDefault(_arcSeries);
  35. var _xyPlot = require('../plot/xy-plot');
  36. var _xyPlot2 = _interopRequireDefault(_xyPlot);
  37. var _seriesUtils = require('../utils/series-utils');
  38. var _chartUtils = require('../utils/chart-utils');
  39. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  40. var predefinedClassName = 'rv-sunburst';
  41. var LISTENERS_TO_OVERWRITE = ['onValueMouseOver', 'onValueMouseOut', 'onValueClick', 'onValueRightClick', 'onSeriesMouseOver', 'onSeriesMouseOut', 'onSeriesClick', 'onSeriesRightClick'];
  42. /**
  43. * Create the list of nodes to render.
  44. * @param {Object} props
  45. props.data {Object} - tree structured data (each node has a name anc an array of children)
  46. props.height {number} - the height of the graphic to be rendered
  47. props.hideRootNode {boolean} - whether or not to hide the root node
  48. props.width {number} - the width of the graphic to be rendered
  49. props.getSize {function} - accessor for the size
  50. * @returns {Array} Array of nodes.
  51. */
  52. function getNodesToRender(_ref) {
  53. var data = _ref.data,
  54. height = _ref.height,
  55. hideRootNode = _ref.hideRootNode,
  56. width = _ref.width,
  57. getSize = _ref.getSize;
  58. var partitionFunction = (0, _d3Hierarchy.partition)();
  59. var structuredInput = (0, _d3Hierarchy.hierarchy)(data).sum(getSize);
  60. var radius = Math.min(width, height) / 2 - 10;
  61. var x = (0, _d3Scale.scaleLinear)().range([0, 2 * Math.PI]);
  62. var y = (0, _d3Scale.scaleSqrt)().range([0, radius]);
  63. return partitionFunction(structuredInput).descendants().reduce(function (res, cell, index) {
  64. if (hideRootNode && index === 0) {
  65. return res;
  66. }
  67. return res.concat([_extends({
  68. angle0: Math.max(0, Math.min(2 * Math.PI, x(cell.x0))),
  69. angle: Math.max(0, Math.min(2 * Math.PI, x(cell.x1))),
  70. radius0: Math.max(0, y(cell.y0)),
  71. radius: Math.max(0, y(cell.y1)),
  72. depth: cell.depth,
  73. parent: cell.parent
  74. }, cell.data)]);
  75. }, []);
  76. }
  77. /**
  78. * Convert arc nodes into label rows.
  79. * Important to use mappedData rather than regular data, bc it is already unrolled
  80. * @param {Array} mappedData - Array of nodes.
  81. * @param {Object} accessors - object of accessors
  82. * @returns {Array} array of node for rendering as labels
  83. */
  84. function buildLabels(mappedData, accessors) {
  85. var getAngle = accessors.getAngle,
  86. getAngle0 = accessors.getAngle0,
  87. getLabel = accessors.getLabel,
  88. getRadius0 = accessors.getRadius0;
  89. return mappedData.filter(getLabel).map(function (row) {
  90. var truedAngle = -1 * getAngle(row) + Math.PI / 2;
  91. var truedAngle0 = -1 * getAngle0(row) + Math.PI / 2;
  92. var angle = (truedAngle0 + truedAngle) / 2;
  93. var rotateLabels = !row.dontRotateLabel;
  94. var rotAngle = -angle / (2 * Math.PI) * 360;
  95. return _extends({}, row, {
  96. children: null,
  97. angle: null,
  98. radius: null,
  99. x: getRadius0(row) * Math.cos(angle),
  100. y: getRadius0(row) * Math.sin(angle),
  101. style: _extends({
  102. textAnchor: rotAngle > 90 ? 'end' : 'start'
  103. }, row.labelStyle),
  104. rotation: rotateLabels ? rotAngle > 90 ? rotAngle + 180 : rotAngle === 90 ? 90 : rotAngle : null
  105. });
  106. });
  107. }
  108. var NOOP = function NOOP() {};
  109. function Sunburst(props) {
  110. var getAngle = props.getAngle,
  111. getAngle0 = props.getAngle0,
  112. animation = props.animation,
  113. className = props.className,
  114. children = props.children,
  115. data = props.data,
  116. height = props.height,
  117. hideRootNode = props.hideRootNode,
  118. getLabel = props.getLabel,
  119. width = props.width,
  120. getSize = props.getSize,
  121. colorType = props.colorType;
  122. var mappedData = getNodesToRender({
  123. data: data,
  124. height: height,
  125. hideRootNode: hideRootNode,
  126. width: width,
  127. getSize: getSize
  128. });
  129. var radialDomain = (0, _seriesUtils.getRadialDomain)(mappedData);
  130. var margin = (0, _chartUtils.getRadialLayoutMargin)(width, height, radialDomain);
  131. var labelData = buildLabels(mappedData, {
  132. getAngle: getAngle,
  133. getAngle0: getAngle0,
  134. getLabel: getLabel,
  135. getRadius0: function getRadius0(d) {
  136. return d.radius0;
  137. }
  138. });
  139. var hofBuilder = function hofBuilder(f) {
  140. return function (e, i) {
  141. return f ? f(mappedData[e.index], i) : NOOP;
  142. };
  143. };
  144. return _react2.default.createElement(
  145. _xyPlot2.default,
  146. {
  147. height: height,
  148. hasTreeStructure: true,
  149. width: width,
  150. className: predefinedClassName + ' ' + className,
  151. margin: margin,
  152. xDomain: [-radialDomain, radialDomain],
  153. yDomain: [-radialDomain, radialDomain]
  154. },
  155. _react2.default.createElement(_arcSeries2.default, _extends({
  156. colorType: colorType
  157. }, props, {
  158. animation: animation,
  159. radiusDomain: [0, radialDomain],
  160. // need to present a stripped down version for interpolation
  161. data: animation ? mappedData.map(function (row, index) {
  162. return _extends({}, row, {
  163. parent: null,
  164. children: null,
  165. index: index
  166. });
  167. }) : mappedData,
  168. _data: animation ? mappedData : null,
  169. arcClassName: predefinedClassName + '__series--radial__arc'
  170. }, LISTENERS_TO_OVERWRITE.reduce(function (acc, propName) {
  171. var prop = props[propName];
  172. acc[propName] = animation ? hofBuilder(prop) : prop;
  173. return acc;
  174. }, {}))),
  175. labelData.length > 0 && _react2.default.createElement(_labelSeries2.default, { data: labelData, getLabel: getLabel }),
  176. children
  177. );
  178. }
  179. Sunburst.displayName = 'Sunburst';
  180. Sunburst.propTypes = {
  181. animation: _animation.AnimationPropType,
  182. getAngle: _propTypes2.default.func,
  183. getAngle0: _propTypes2.default.func,
  184. className: _propTypes2.default.string,
  185. colorType: _propTypes2.default.string,
  186. data: _propTypes2.default.object.isRequired,
  187. height: _propTypes2.default.number.isRequired,
  188. hideRootNode: _propTypes2.default.bool,
  189. getLabel: _propTypes2.default.func,
  190. onValueClick: _propTypes2.default.func,
  191. onValueMouseOver: _propTypes2.default.func,
  192. onValueMouseOut: _propTypes2.default.func,
  193. getSize: _propTypes2.default.func,
  194. width: _propTypes2.default.number.isRequired,
  195. padAngle: _propTypes2.default.oneOfType([_propTypes2.default.func, _propTypes2.default.number])
  196. };
  197. Sunburst.defaultProps = {
  198. getAngle: function getAngle(d) {
  199. return d.angle;
  200. },
  201. getAngle0: function getAngle0(d) {
  202. return d.angle0;
  203. },
  204. className: '',
  205. colorType: 'literal',
  206. getColor: function getColor(d) {
  207. return d.color;
  208. },
  209. hideRootNode: false,
  210. getLabel: function getLabel(d) {
  211. return d.label;
  212. },
  213. getSize: function getSize(d) {
  214. return d.size;
  215. },
  216. padAngle: 0
  217. };
  218. exports.default = Sunburst;