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

3 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. 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; };
  2. function _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); } }
  3. import React from 'react';
  4. import PropTypes from 'prop-types';
  5. import { sankey, sankeyLinkHorizontal, sankeyLeft, sankeyRight, sankeyCenter, sankeyJustify } from 'd3-sankey';
  6. import XYPlot from '../plot/xy-plot';
  7. import { MarginPropType, getInnerDimensions } from '../utils/chart-utils';
  8. import VerticalRectSeries from '../plot/series/vertical-rect-series';
  9. import LabelSeries from '../plot/series/label-series';
  10. import Voronoi from '../plot/voronoi';
  11. import { DISCRETE_COLOR_RANGE } from '../theme';
  12. import SankeyLink from './sankey-link';
  13. var NOOP = function NOOP(f) {
  14. return f;
  15. };
  16. var ALIGNMENTS = {
  17. justify: sankeyJustify,
  18. center: sankeyCenter,
  19. left: sankeyLeft,
  20. right: sankeyRight
  21. };
  22. var DEFAULT_MARGINS = {
  23. top: 20,
  24. left: 20,
  25. right: 20,
  26. bottom: 20
  27. };
  28. function Sankey(props) {
  29. var align = props.align,
  30. animation = props.animation,
  31. children = props.children,
  32. className = props.className,
  33. hasVoronoi = props.hasVoronoi,
  34. height = props.height,
  35. hideLabels = props.hideLabels,
  36. labelRotation = props.labelRotation,
  37. layout = props.layout,
  38. links = props.links,
  39. linkOpacity = props.linkOpacity,
  40. margin = props.margin,
  41. nodePadding = props.nodePadding,
  42. nodes = props.nodes,
  43. nodeWidth = props.nodeWidth,
  44. onValueClick = props.onValueClick,
  45. onValueMouseOver = props.onValueMouseOver,
  46. onValueMouseOut = props.onValueMouseOut,
  47. onLinkClick = props.onLinkClick,
  48. onLinkMouseOver = props.onLinkMouseOver,
  49. onLinkMouseOut = props.onLinkMouseOut,
  50. style = props.style,
  51. width = props.width;
  52. var nodesCopy = [].concat(_toConsumableArray(new Array(nodes.length))).map(function (e, i) {
  53. return _extends({}, nodes[i]);
  54. });
  55. var linksCopy = [].concat(_toConsumableArray(new Array(links.length))).map(function (e, i) {
  56. return _extends({}, links[i]);
  57. });
  58. var _getInnerDimensions = getInnerDimensions({
  59. margin: margin,
  60. height: height,
  61. width: width
  62. }, DEFAULT_MARGINS),
  63. marginLeft = _getInnerDimensions.marginLeft,
  64. marginTop = _getInnerDimensions.marginTop,
  65. marginRight = _getInnerDimensions.marginRight,
  66. marginBottom = _getInnerDimensions.marginBottom;
  67. var sankeyInstance = sankey().extent([[marginLeft, marginTop], [width - marginRight, height - marginBottom - marginTop]]).nodeWidth(nodeWidth).nodePadding(nodePadding).nodes(nodesCopy).links(linksCopy).nodeAlign(ALIGNMENTS[align]).iterations(layout);
  68. sankeyInstance(nodesCopy);
  69. var nWidth = sankeyInstance.nodeWidth();
  70. var path = sankeyLinkHorizontal();
  71. return React.createElement(
  72. XYPlot,
  73. _extends({}, props, { yType: 'literal', className: 'rv-sankey ' + className }),
  74. linksCopy.map(function (link, i) {
  75. return React.createElement(SankeyLink, {
  76. style: style.links,
  77. data: path(link),
  78. opacity: link.opacity || linkOpacity,
  79. color: link.color,
  80. onLinkClick: onLinkClick,
  81. onLinkMouseOver: onLinkMouseOver,
  82. onLinkMouseOut: onLinkMouseOut,
  83. strokeWidth: Math.max(link.width, 1),
  84. node: link,
  85. nWidth: nWidth,
  86. key: 'link-' + i
  87. });
  88. }),
  89. React.createElement(VerticalRectSeries, {
  90. animation: animation,
  91. className: className + ' rv-sankey__node',
  92. data: nodesCopy.map(function (node) {
  93. return _extends({}, node, {
  94. y: node.y1 - marginTop,
  95. y0: node.y0 - marginTop,
  96. x: node.x1,
  97. x0: node.x0,
  98. color: node.color || DISCRETE_COLOR_RANGE[0],
  99. sourceLinks: null,
  100. targetLinks: null
  101. });
  102. }),
  103. style: style.rects,
  104. onValueClick: onValueClick,
  105. onValueMouseOver: onValueMouseOver,
  106. onValueMouseOut: onValueMouseOut,
  107. colorType: 'literal'
  108. }),
  109. !hideLabels && React.createElement(LabelSeries, {
  110. animation: animation,
  111. className: className,
  112. rotation: labelRotation,
  113. labelAnchorY: 'text-before-edge',
  114. data: nodesCopy.map(function (node, i) {
  115. return _extends({
  116. x: node.x0 + (node.x0 < width / 2 ? nWidth + 10 : -10),
  117. y: (node.y0 + node.y1) / 2 - marginTop,
  118. label: node.name,
  119. style: _extends({
  120. textAnchor: node.x0 < width / 2 ? 'start' : 'end',
  121. dy: '-.5em'
  122. }, style.labels)
  123. }, nodes[i]);
  124. })
  125. }),
  126. hasVoronoi && React.createElement(Voronoi, {
  127. className: 'rv-sankey__voronoi',
  128. extent: [[-marginLeft, -marginTop], [width + marginRight, height + marginBottom]],
  129. nodes: nodesCopy,
  130. onClick: onValueClick,
  131. onHover: onValueMouseOver,
  132. onBlur: onValueMouseOut,
  133. x: function x(d) {
  134. return d.x0 + (d.x1 - d.x0) / 2;
  135. },
  136. y: function y(d) {
  137. return d.y0 + (d.y1 - d.y0) / 2;
  138. }
  139. }),
  140. children
  141. );
  142. }
  143. Sankey.defaultProps = {
  144. align: 'justify',
  145. className: '',
  146. hasVoronoi: false,
  147. hideLabels: false,
  148. labelRotation: 0,
  149. layout: 50,
  150. margin: DEFAULT_MARGINS,
  151. nodePadding: 10,
  152. nodeWidth: 10,
  153. onValueMouseOver: NOOP,
  154. onValueClick: NOOP,
  155. onValueMouseOut: NOOP,
  156. onLinkClick: NOOP,
  157. onLinkMouseOver: NOOP,
  158. onLinkMouseOut: NOOP,
  159. style: {
  160. links: {},
  161. rects: {},
  162. labels: {}
  163. }
  164. };
  165. Sankey.propTypes = {
  166. align: PropTypes.oneOf(['justify', 'left', 'right', 'center']),
  167. className: PropTypes.string,
  168. hasVoronoi: PropTypes.bool,
  169. height: PropTypes.number.isRequired,
  170. hideLabels: PropTypes.bool,
  171. labelRotation: PropTypes.number,
  172. layout: PropTypes.number,
  173. links: PropTypes.arrayOf(PropTypes.shape({
  174. source: PropTypes.oneOfType([PropTypes.number, PropTypes.object]).isRequired,
  175. target: PropTypes.oneOfType([PropTypes.number, PropTypes.object]).isRequired
  176. })).isRequired,
  177. margin: MarginPropType,
  178. nodePadding: PropTypes.number,
  179. nodes: PropTypes.arrayOf(PropTypes.object).isRequired,
  180. nodeWidth: PropTypes.number,
  181. onValueMouseOver: PropTypes.func,
  182. onValueClick: PropTypes.func,
  183. onValueMouseOut: PropTypes.func,
  184. onLinkClick: PropTypes.func,
  185. onLinkMouseOver: PropTypes.func,
  186. onLinkMouseOut: PropTypes.func,
  187. style: PropTypes.shape({
  188. links: PropTypes.object,
  189. rects: PropTypes.object,
  190. labels: PropTypes.object
  191. }),
  192. width: PropTypes.number.isRequired
  193. };
  194. export default Sankey;