UNPKG

recharts

Version:
1,255 lines (1,036 loc) 41.7 kB
'use strict'; 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; }; var _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; }; }(); var _class, _temp; /** * @fileOverview Cartesian Chart */ Object.defineProperty(exports, "__esModule", { value: true }); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _reactDom = require('react-dom'); var _reactDom2 = _interopRequireDefault(_reactDom); var _rechartsScale = require('recharts-scale'); var _d3Scale = require('d3-scale'); var _d3Scale2 = _interopRequireDefault(_d3Scale); var _d3Shape = require('d3-shape'); var _d3Shape2 = _interopRequireDefault(_d3Shape); var _invariant = require('invariant'); var _invariant2 = _interopRequireDefault(_invariant); var _ouiDomUtils = require('oui-dom-utils'); var _ouiDomUtils2 = _interopRequireDefault(_ouiDomUtils); var _Layer = require('../container/Layer'); var _Layer2 = _interopRequireDefault(_Layer); var _Tooltip = require('../component/Tooltip'); var _Tooltip2 = _interopRequireDefault(_Tooltip); var _Legend = require('../component/Legend'); var _Legend2 = _interopRequireDefault(_Legend); var _ReactUtils = require('../util/ReactUtils'); var _ReactUtils2 = _interopRequireDefault(_ReactUtils); var _DOMUtils = require('../util/DOMUtils'); var _DOMUtils2 = _interopRequireDefault(_DOMUtils); var _LodashUtils = require('../util/LodashUtils'); var _LodashUtils2 = _interopRequireDefault(_LodashUtils); var _CartesianAxis = require('../cartesian/CartesianAxis'); var _CartesianAxis2 = _interopRequireDefault(_CartesianAxis); var _CartesianGrid = require('../cartesian/CartesianGrid'); var _CartesianGrid2 = _interopRequireDefault(_CartesianGrid); var _ReferenceLine = require('../cartesian/ReferenceLine'); var _ReferenceLine2 = _interopRequireDefault(_ReferenceLine); var _XAxis = require('../cartesian/XAxis'); var _XAxis2 = _interopRequireDefault(_XAxis); var _YAxis = require('../cartesian/YAxis'); var _YAxis2 = _interopRequireDefault(_YAxis); var _Brush = require('../cartesian/Brush'); var _Brush2 = _interopRequireDefault(_Brush); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _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; } function _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; } var ORIENT_MAP = { xAxis: ['bottom', 'top'], yAxis: ['left', 'right'] }; /** * The base class of chart in cartesian coordinate system */ var CartesianChart = (_temp = _class = function (_Component) { _inherits(CartesianChart, _Component); function CartesianChart(props) { _classCallCheck(this, CartesianChart); var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(CartesianChart).call(this, props)); _this.state = { dataStartIndex: 0, dataEndIndex: _this.props.data.length - 1, activeTooltipIndex: -1, activeTooltipLabel: '', activeTooltipCoord: { x: 0, y: 0 }, isTooltipActive: false, activeLineKey: null, activeBarKey: null }; _this.validateAxes(); return _this; } _createClass(CartesianChart, [{ key: 'getStackGroupsByAxisId', value: function getStackGroupsByAxisId(items, axisIdKey) { var _this2 = this; var stackGroups = items.reduce(function (result, item) { var _item$props = item.props; var stackId = _item$props.stackId; var dataKey = _item$props.dataKey; var axisId = item.props[axisIdKey]; if (!result[axisId]) { result[axisId] = { hasStack: false, stackGroups: {} }; } if (_LodashUtils2.default.isNumber(stackId) || _LodashUtils2.default.isString(stackId)) { if (!result[axisId].stackGroups[stackId]) { result[axisId].stackGroups[stackId] = { items: [] }; } result[axisId].stackGroups[stackId].items.push(item); if (result[axisId].stackGroups[stackId].items.length >= 2) { result[axisId].hasStack = true; } } else { result[axisId].stackGroups[_LodashUtils2.default.getUniqueId('_stackId_')] = { items: [item] }; } return result; }, {}); return Object.keys(stackGroups).reduce(function (result, axisId) { var group = stackGroups[axisId]; if (group.hasStack) { group.stackGroups = Object.keys(group.stackGroups).reduce(function (res, stackId) { var g = group.stackGroups[stackId]; res[stackId] = { items: g.items, stackedData: _this2.getStackedData(g.items) }; return res; }, {}); } result[axisId] = group; return result; }, {}); } }, { key: 'getStackedData', value: function getStackedData(stackItems) { var data = this.props.data; var dataKeys = stackItems.map(function (item) { return item.props.dataKey; }); var stack = _d3Shape2.default.stack().keys(dataKeys).value(function (d, key) { return +d[key] || 0; }).order(_d3Shape2.default.stackOrderNone).offset(_d3Shape2.default.stackOffsetNone); return stack(data); } }, { key: 'getStackedDataOfItem', value: function getStackedDataOfItem(item, stackGroups) { var stackId = item.props.stackId; if (_LodashUtils2.default.isNumber(stackId) || _LodashUtils2.default.isString(stackId)) { var group = stackGroups[stackId]; if (group && group.items.length) { var itemIndex = -1; for (var i = 0, len = group.items.length; i < len; i++) { if (group.items[i] === item) { itemIndex = i; break; } } return itemIndex >= 0 ? group.stackedData[itemIndex] : null; } } return null; } /** * Calculate coordinate of cursor in chart * @param {Object} e Event object * @param {Object} containerOffset The offset of main part in the svg element * @return {Object} {chartX, chartY} */ }, { key: 'getChartPosition', value: function getChartPosition(e, containerOffset) { return { chartX: Math.round(e.pageX - containerOffset.left), chartY: Math.round(e.pageY - containerOffset.top) }; } /** * get domain of ticks * @param {Array} ticks Ticks of axis * @param {String} type The type of axis * @return {Array} domain */ }, { key: 'getDomainOfTicks', value: function getDomainOfTicks(ticks, type) { if (type === 'number') { return [Math.min.apply(null, ticks), Math.max.apply(null, ticks)]; } return ticks; } /** * Get domain of data by key * @param {String} key The unique key of a group of data * @param {String} type The type of axis * @return {Array} Domain of data */ }, { key: 'getDomainByKey', value: function getDomainByKey(key, type) { var data = this.props.data; var _state = this.state; var dataStartIndex = _state.dataStartIndex; var dataEndIndex = _state.dataEndIndex; var domain = data.slice(dataStartIndex, dataEndIndex + 1).map(function (entry) { return entry[key] || 0; }); return type === 'number' ? [Math.min.apply(null, domain), Math.max.apply(null, domain)] : domain; } }, { key: 'getDomainOfStackGroups', value: function getDomainOfStackGroups(stackGroups) { var _state2 = this.state; var dataStartIndex = _state2.dataStartIndex; var dataEndIndex = _state2.dataEndIndex; return Object.keys(stackGroups).reduce(function (result, stackId) { var group = stackGroups[stackId]; var stackedData = group.stackedData; var minList = stackedData[0].slice(dataStartIndex, dataEndIndex + 1); var maxList = stackedData[stackedData.length - 1].slice(dataStartIndex, dataEndIndex + 1); var min = minList.reduce(function (res, entry) { return Math.min(res, entry[0]); }, Infinity); var max = maxList.reduce(function (res, entry) { return Math.max(res, entry[1]); }, -Infinity); return [Math.min(min, result[0]), Math.max(max, result[1])]; }, [Infinity, -Infinity]); } /** * Get domain of data by the configuration of item element * @param {Array} items The instances of item * @param {String} type The type of axis, number - Number Axis, category - Category Axis * @return {Array} Domain */ }, { key: 'getDomainOfItemsWithSameAxis', value: function getDomainOfItemsWithSameAxis(items, type) { var _this3 = this; var domains = items.map(function (item) { return _this3.getDomainByKey(item.props.dataKey, type); }); if (type === 'number') { // Calculate the domain of number axis return domains.reduce(function (result, entry) { return [Math.min(result[0], entry[0]), Math.max(result[1], entry[1])]; }, [Infinity, -Infinity]); } var tag = {}; // Get the union set of category axis return domains.reduce(function (result, entry) { for (var i = 0, len = entry.length; i < len; i++) { if (!tag[entry[i]]) { tag[entry[i]] = true; result.push(entry[i]); } } return result; }, []); } /** * Get the configuration of all x-axis or y-axis * @param {String} axisType The type of axis * @param {Array} items The instances of item * @param {Object} stackGroups The items grouped by axisId and stackId * @return {Object} Configuration */ }, { key: 'getAxisMap', value: function getAxisMap() { var axisType = arguments.length <= 0 || arguments[0] === undefined ? 'xAxis' : arguments[0]; var items = arguments[1]; var stackGroups = arguments[2]; var children = this.props.children; var Axis = axisType === 'xAxis' ? _XAxis2.default : _YAxis2.default; var axisIdKey = axisType === 'xAxis' ? 'xAxisId' : 'yAxisId'; // Get all the instance of Axis var axes = _ReactUtils2.default.findAllByType(children, Axis); var axisMap = {}; if (axes && axes.length) { axisMap = this.getAxisMapByAxes(axes, items, axisType, axisIdKey, stackGroups); } else if (items && items.length) { axisMap = this.getAxisMapByItems(items, Axis, axisType, axisIdKey, stackGroups); } return axisMap; } /** * Get the configuration of axis by the options of axis instance * @param {Array} axes The instance of axes * @param {Array} items The instances of item * @param {String} axisType The type of axis, xAxis - x-axis, yAxis - y-axis * @param {String} axisIdKey The unique id of an axis * @param {Object} stackGroups The items grouped by axisId and stackId * @return {Object} Configuration */ }, { key: 'getAxisMapByAxes', value: function getAxisMapByAxes(axes, items, axisType, axisIdKey, stackGroups) { var _this4 = this; var layout = this.props.layout; var _state3 = this.state; var dataEndIndex = _state3.dataEndIndex; var dataStartIndex = _state3.dataStartIndex; var len = dataEndIndex - dataStartIndex + 1; var isCategoryAxis = layout === 'horizontal' && axisType === 'xAxis' || layout === 'vertical' && axisType === 'yAxis'; // Eliminate duplicated axes var axisMap = axes.reduce(function (result, child) { var _child$props = child.props; var type = _child$props.type; var dataKey = _child$props.dataKey; var axisId = child.props[axisIdKey]; if (!result[axisId]) { var domain = undefined; var isDomainFixed = false; if (dataKey) { domain = _this4.getDomainByKey(dataKey, type); } else if (stackGroups && stackGroups[axisId] && stackGroups[axisId].hasStack && type === 'number') { domain = _this4.getDomainOfStackGroups(stackGroups[axisId].stackGroups); } else if (isCategoryAxis) { domain = _LodashUtils2.default.range(0, len); } else { domain = _this4.getDomainOfItemsWithSameAxis(items.filter(function (entry) { return entry.props[axisIdKey] === axisId; }), type); } if (type === 'number' && child.props.domain) { isDomainFixed = true; domain = _this4.parseSpecifiedDomain(child.props.domain, domain); } return _extends({}, result, _defineProperty({}, axisId, _extends({}, child.props, { axisType: axisType, domain: domain, isDomainFixed: isDomainFixed }))); } return result; }, {}); return axisMap; } /** * Get the configuration of axis by the options of item, this kind of axis does not display in chart * @param {Array} items The instances of item * @param {ReactElement} Axis Axis Component * @param {String} axisType The type of axis, xAxis - x-axis, yAxis - y-axis * @param {String} axisIdKey The unique id of an axis * @param {Object} stackGroups The items grouped by axisId and stackId * @return {Object} Configuration */ }, { key: 'getAxisMapByItems', value: function getAxisMapByItems(items, Axis, axisType, axisIdKey, stackGroups) { var _this5 = this; var layout = this.props.layout; var _state4 = this.state; var dataEndIndex = _state4.dataEndIndex; var dataStartIndex = _state4.dataStartIndex; var len = dataEndIndex - dataStartIndex + 1; var index = -1; var isCategoryAxis = layout === 'horizontal' && axisType === 'xAxis' || layout === 'vertical' && axisType === 'yAxis'; // The default type of x-axis is category axis, // The default contents of x-axis is the serial numbers of data // The default type of y-axis is number axis // The default contents of y-axis is the domain of data var axisMap = items.reduce(function (result, child) { var axisId = child.props[axisIdKey]; if (!result[axisId]) { index++; var domain = undefined; if (isCategoryAxis) { domain = _LodashUtils2.default.range(0, len); } else if (stackGroups && stackGroups[axisId] && stackGroups[axisId].hasStack) { domain = _this5.getDomainOfStackGroups(stackGroups[axisId].stackGroups); } else { domain = _this5.getDomainOfItemsWithSameAxis(items.filter(function (entry) { return entry.props[axisIdKey] === axisId; }), 'number'); } return _extends({}, result, _defineProperty({}, axisId, { axisType: axisType, type: Axis.defaultProps.type, hide: true, isAutoGenerated: true, width: Axis.defaultProps.width, height: Axis.defaultProps.height, tickCount: Axis.defaultProps.tickCount, orientation: ORIENT_MAP[axisType][index % 2], domain: domain })); } return result; }, {}); return axisMap; } /** * Calculate the offset of main part in the svg element * @param {Object} xAxisMap The configuration of x-axis * @param {Object} yAxisMap The configuration of y-axis * @return {Object} The offset of main part in the svg element */ }, { key: 'getOffset', value: function getOffset(xAxisMap, yAxisMap) { var _props = this.props; var width = _props.width; var height = _props.height; var margin = _props.margin; var children = _props.children; var brushItem = _ReactUtils2.default.findChildByType(children, _Brush2.default); var offsetH = Object.keys(yAxisMap).reduce(function (result, id) { var entry = yAxisMap[id]; var orientation = entry.orientation; result[orientation] += entry.hide ? 0 : entry.width; return result; }, { left: margin.left || 0, right: margin.right || 0 }); var offsetV = Object.keys(xAxisMap).reduce(function (result, id) { var entry = xAxisMap[id]; var orientation = entry.orientation; result[orientation] += entry.hide ? 0 : entry.height; return result; }, { top: margin.top || 0, bottom: margin.bottom || 0 }); if (brushItem) { offsetV.bottom += brushItem.props.height || _Brush2.default.defaultProps.height; } return _extends({}, offsetH, offsetV, { width: width - offsetH.left - offsetH.right, height: height - offsetV.top - offsetV.bottom }); } /** * Get the main color of each graphic item * @param {ReactElement} item A graphic item * @return {String} Color */ }, { key: 'getMainColorOfItem', value: function getMainColorOfItem(item) { var displayName = item.type.displayName; var result = undefined; switch (displayName) { case 'Line': result = item.props.stroke; break; default: result = item.props.fill; break; } return result; } /** * Configure the scale function of axis * @param {Object} scale The scale function * @param {Object} opts The configuration of axis * @return {Object} null */ }, { key: 'setTicksOfScale', value: function setTicksOfScale(scale, opts) { // Give priority to use the options of ticks if (opts.ticks && opts.ticks) { scale.domain(this.getDomainOfTicks(opts.ticks, opts.type)); return; } if (opts.type === 'number' && opts.isAutoGenerated) { scale.domain([0, scale.domain()[1]]); } else if (opts.tickCount && opts.type === 'number' && !opts.isDomainFixed) { // Calculate the ticks by the number of grid when the axis is a number axis var domain = scale.domain(); var tickValues = (0, _rechartsScale.getNiceTickValues)(domain, opts.tickCount); opts.ticks = tickValues; scale.domain(this.getDomainOfTicks(tickValues, opts.type)); } } /** * Calculate the scale function, position, width, height of axes * @param {Object} axisMap The configuration of axes * @param {Object} offset The offset of main part in the svg element * @param {Object} axisType The type of axes, x-axis or y-axis * @return {Object} Configuration */ }, { key: 'getFormatAxisMap', value: function getFormatAxisMap(axisMap, offset, axisType) { var _this6 = this; var _props2 = this.props; var width = _props2.width; var height = _props2.height; var layout = _props2.layout; var displayName = this.constructor.displayName; var ids = Object.keys(axisMap); var steps = { left: offset.left, right: width - offset.right, top: offset.top, bottom: height - offset.bottom }; return ids.reduce(function (result, id) { var axis = axisMap[id]; var orientation = axis.orientation; var type = axis.type; var domain = axis.domain; var range = undefined; if (axisType === 'xAxis') { range = [offset.left, offset.left + offset.width]; } else { range = layout === 'horizontal' ? [offset.top + offset.height, offset.top] : [offset.top, offset.top + offset.height]; } var scale = undefined; if (type === 'number') { scale = _d3Scale2.default.linear().domain(domain).range(range); } else if (displayName === 'LineChart' || displayName === 'AreaChart') { scale = _d3Scale2.default.point().domain(domain).range(range); } else { scale = _d3Scale2.default.band().domain(domain).range(range); } _this6.setTicksOfScale(scale, axis); var x = undefined; var y = undefined; if (axisType === 'xAxis') { x = offset.left; y = orientation === 'top' ? steps[orientation] - axis.height : steps[orientation]; } else { x = orientation === 'left' ? steps[orientation] - axis.width : steps[orientation]; y = offset.top; } result[id] = _extends({}, axis, { x: x, y: y, scale: scale, width: axisType === 'xAxis' ? offset.width : axis.width, height: axisType === 'yAxis' ? offset.height : axis.height }); if (!axis.hide && axisType === 'xAxis') { steps[orientation] += (orientation === 'top' ? -1 : 1) * result[id].height; } else if (!axis.hide) { steps[orientation] += (orientation === 'left' ? -1 : 1) * result[id].width; } return result; }, {}); } /** * Get the ticks of an axis * @param {Object} axis The configuration of an axis * @param {Boolean} isGrid Whether or not are the ticks in grid * @return {Array} Ticks */ }, { key: 'getAxisTicks', value: function getAxisTicks(axis) { var isGrid = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; var scale = axis.scale; var offset = isGrid && axis.type === 'category' ? scale.bandwidth() / 2 : 0; if (axis.ticks) { return axis.ticks.map(function (entry) { return { coord: scale(entry) + offset, value: entry }; }); } if (scale.ticks) { return scale.ticks(axis.tickCount).map(function (entry) { return { coord: scale(entry) + offset, value: entry }; }); } return scale.domain().map(function (entry) { return { coord: scale(entry) + offset, value: entry }; }); } /** * Calculate the ticks of grid * @param {Array} ticks The ticks in axis * @param {Number} min The minimun value of axis * @param {Number} max The maximun value of axis * @return {Array} Ticks */ }, { key: 'getGridTicks', value: function getGridTicks(ticks, min, max) { var hasMin = undefined; var hasMax = undefined; var values = undefined; values = ticks.map(function (entry) { if (entry.coord === min) { hasMin = true; } if (entry.coord === max) { hasMax = true; } return entry.coord; }); if (!hasMin) { values.push(min); } if (!hasMax) { values.push(max); } return values; } /** * Get the information of mouse in chart, return null when the mouse is not in the chart * @param {Object} xAxisMap The configuration of all x-axes * @param {Object} yAxisMap The configuration of all y-axes * @param {Object} offset The offset of main part in the svg element * @param {Object} e The event object * @return {Object} Mouse data */ }, { key: 'getMouseInfo', value: function getMouseInfo(xAxisMap, yAxisMap, offset, e) { var isIn = e.chartX >= offset.left && e.chartX <= offset.left + offset.width && e.chartY >= offset.top && e.chartY <= offset.top + offset.height; if (!isIn) { return null; } var layout = this.props.layout; var axisMap = layout === 'horizontal' ? xAxisMap : yAxisMap; var pos = layout === 'horizontal' ? e.chartX : e.chartY; var ids = Object.keys(axisMap); var axis = axisMap[ids[0]]; var ticks = this.getAxisTicks(axis, true); var index = 0; var len = ticks.length; if (len > 1) { for (var i = 0; i < len; i++) { if (i === 0 && pos <= (ticks[i].coord + ticks[i + 1].coord) / 2 || i > 0 && i < len - 1 && pos > (ticks[i].coord + ticks[i - 1].coord) / 2 && pos <= (ticks[i].coord + ticks[i + 1].coord) / 2 || i === len - 1 && pos > (ticks[i].coord + ticks[i - 1].coord) / 2) { index = i; break; } } } return { activeTooltipIndex: index, activeTooltipLabel: ticks[index].value, activeTooltipCoord: { x: layout === 'horizontal' ? ticks[index].coord : e.chartX, y: layout === 'horizontal' ? e.chartY : ticks[index].coord } }; } /** * Get the content to be displayed in the tooltip * @param {Array} items The instances of item * @return {Array} The content of tooltip */ }, { key: 'getTooltipContent', value: function getTooltipContent(items) { var _this7 = this; var _state5 = this.state; var activeLineKey = _state5.activeLineKey; var activeBarKey = _state5.activeBarKey; var activeAreaKey = _state5.activeAreaKey; var activeTooltipIndex = _state5.activeTooltipIndex; var dataStartIndex = _state5.dataStartIndex; var dataEndIndex = _state5.dataEndIndex; var data = this.props.data.slice(dataStartIndex, dataEndIndex + 1); if (activeTooltipIndex < 0 || !items || !items.length) { return null; } var activeItems = items; if (activeLineKey) { activeItems = items.filter(function (item) { return item.props.dataKey === activeLineKey && item.type.displayName === 'Line'; }); } else if (activeBarKey) { activeItems = items.filter(function (item) { return item.props.dataKey === activeBarKey && item.type.displayName === 'Bar'; }); } else if (activeAreaKey) { activeItems = items.filter(function (item) { return item.props.dataKey === activeAreaKey && item.type.displayName === 'Area'; }); } return activeItems.map(function (child) { var _child$props2 = child.props; var dataKey = _child$props2.dataKey; var name = _child$props2.name; var unit = _child$props2.unit; var formatter = _child$props2.formatter; return { key: name || dataKey, unit: unit || '', color: _this7.getMainColorOfItem(child), value: data[activeTooltipIndex][dataKey], formatter: formatter }; }); } }, { key: 'validateAxes', value: function validateAxes() { var _props3 = this.props; var layout = _props3.layout; var children = _props3.children; var xAxes = _ReactUtils2.default.findAllByType(children, _XAxis2.default); var yAxes = _ReactUtils2.default.findAllByType(children, _YAxis2.default); if (layout === 'horizontal' && xAxes && xAxes.length) { xAxes.forEach(function (axis) { (0, _invariant2.default)(axis.props.type === 'category', 'x-axis should be category axis when the layout is horizontal'); }); } else if (layout === 'vertical') { var displayName = this.constructor.displayName; (0, _invariant2.default)(yAxes && yAxes.length, 'You should add <YAxis type="number"/> in ' + displayName + '.' + 'The layout is vertical now, y-axis should be category axis,' + 'but y-axis is number axis when no YAxis is added.'); (0, _invariant2.default)(xAxes && xAxes.length, 'You should add <XAxis /> in ' + displayName + '.' + 'The layout is vertical now, x-axis is category when no XAxis is added.'); if (yAxes && yAxes.length) { yAxes.forEach(function (axis) { (0, _invariant2.default)(axis.props.type === 'category', 'y-axis should be category axis when the layout is vertical'); }); } } return null; } }, { key: 'parseSpecifiedDomain', value: function parseSpecifiedDomain(specifiedDomain, autoDomain) { if (!_LodashUtils2.default.isArray(specifiedDomain)) { return autoDomain; } var domain = []; if (!_LodashUtils2.default.isNumber(specifiedDomain[0]) || specifiedDomain[0] > autoDomain[0]) { domain[0] = autoDomain[0]; } else { domain[0] = specifiedDomain[0]; } if (!_LodashUtils2.default.isNumber(specifiedDomain[1]) || specifiedDomain[1] < autoDomain[1]) { domain[1] = autoDomain[1]; } else { domain[1] = specifiedDomain[1]; } return domain; } }, { key: 'handleBrushChange', value: function handleBrushChange(_ref) { var startIndex = _ref.startIndex; var endIndex = _ref.endIndex; this.setState({ dataStartIndex: startIndex, dataEndIndex: endIndex }); } /** * The handler of mouse entering chart * @param {Object} offset The offset of main part in the svg element * @param {Object} xAxisMap The configuration of all x-axes * @param {Object} yAxisMap The configuration of all y-axes * @param {Object} e Event object * @return {Null} null */ }, { key: 'handleMouseEnter', value: function handleMouseEnter(offset, xAxisMap, yAxisMap, e) { var container = _reactDom2.default.findDOMNode(this); var containerOffset = _ouiDomUtils2.default.getOffset(container); var ne = this.getChartPosition(e, containerOffset); var mouse = this.getMouseInfo(xAxisMap, yAxisMap, offset, ne); if (mouse) { this.setState(_extends({}, mouse, { isTooltipActive: true, chartX: ne.chartX, chartY: ne.chartY })); } } /** * The handler of mouse moving in chart * @param {Object} offset The offset of main part in the svg element * @param {Object} xAxisMap The configuration of all x-axes * @param {Object} yAxisMap The configuration of all y-axes * @param {Object} e Event object * @return {Null} no return */ }, { key: 'handleMouseMove', value: function handleMouseMove(offset, xAxisMap, yAxisMap, e) { var container = _reactDom2.default.findDOMNode(this); var containerOffset = _ouiDomUtils2.default.getOffset(container); var ne = this.getChartPosition(e, containerOffset); var mouse = this.getMouseInfo(xAxisMap, yAxisMap, offset, ne); if (mouse) { this.setState(_extends({}, mouse, { isTooltipActive: true, chartX: ne.chartX, chartY: ne.chartY })); } else { this.setState({ isTooltipActive: false }); } } /** * The handler if mouse leaving chart * @return {Null} no return */ }, { key: 'handleMouseLeave', value: function handleMouseLeave() { this.setState({ isTooltipActive: false }); } /** * Draw x-axes * @param {Object} xAxisMap The configuration of all x-axes * @return {ReactElement} The instance of x-axes */ }, { key: 'renderXAxis', value: function renderXAxis(xAxisMap) { var _props4 = this.props; var width = _props4.width; var height = _props4.height; var ids = xAxisMap && Object.keys(xAxisMap); if (ids && ids.length) { var xAxes = []; for (var i = 0, len = ids.length; i < len; i++) { var axis = xAxisMap[ids[i]]; if (!axis.hide) { xAxes.push(_react2.default.createElement(_CartesianAxis2.default, _extends({}, axis, { x: axis.x, y: axis.y, width: axis.width, height: axis.height, key: 'x-axis-' + ids[i], orientation: axis.orientation, viewBox: { x: 0, y: 0, width: width, height: height }, ticks: this.getAxisTicks(axis, true) }))); } } return xAxes.length ? _react2.default.createElement( _Layer2.default, { key: 'x-axis-layer', className: 'recharts-x-axis' }, xAxes ) : null; } } /** * Draw y-axes * @param {Object} yAxisMap The configuration of all y-axes * @return {ReactElement} The instance of y-axes */ }, { key: 'renderYAxis', value: function renderYAxis(yAxisMap) { var _props5 = this.props; var width = _props5.width; var height = _props5.height; var ids = yAxisMap && Object.keys(yAxisMap); if (ids && ids.length) { var yAxes = []; for (var i = 0, len = ids.length; i < len; i++) { var axis = yAxisMap[ids[i]]; if (!axis.hide) { yAxes.push(_react2.default.createElement(_CartesianAxis2.default, _extends({}, axis, { key: 'y-axis-' + ids[i], x: axis.x, y: axis.y, width: axis.width, height: axis.height, orientation: axis.orientation, viewBox: { x: 0, y: 0, width: width, height: height }, ticks: this.getAxisTicks(axis, true) }))); } } return yAxes.length ? _react2.default.createElement( _Layer2.default, { key: 'y-axis-layer', className: 'recharts-y-axis' }, yAxes ) : null; } } /** * Draw grid * @param {Object} xAxisMap The configuration of all x-axes * @param {Object} yAxisMap The configuration of all y-axes * @param {Object} offset The offset of main part in the svg element * @return {ReactElement} The instance of grid */ }, { key: 'renderGrid', value: function renderGrid(xAxisMap, yAxisMap, offset) { var _props6 = this.props; var children = _props6.children; var width = _props6.width; var height = _props6.height; var gridItem = _ReactUtils2.default.findChildByType(children, _CartesianGrid2.default); if (!gridItem) { return null; } var xIds = Object.keys(xAxisMap); var yIds = Object.keys(yAxisMap); var xAxis = xAxisMap[xIds[0]]; var yAxis = yAxisMap[yIds[0]]; var verticalPoints = this.getGridTicks(_CartesianAxis2.default.getTicks(_extends({}, _CartesianAxis2.default.defaultProps, xAxis, { ticks: this.getAxisTicks(xAxis, true), viewBox: { x: 0, y: 0, width: width, height: height } })), offset.left, offset.left + offset.width); var horizontalPoints = this.getGridTicks(_CartesianAxis2.default.getTicks(_extends({}, _CartesianAxis2.default.defaultProps, yAxis, { ticks: this.getAxisTicks(yAxis, true), viewBox: { x: 0, y: 0, width: width, height: height } })), offset.top, offset.top + offset.height); return _react2.default.cloneElement(gridItem, { key: 'grid', x: offset.left, y: offset.top, width: offset.width, height: offset.height, verticalPoints: verticalPoints, horizontalPoints: horizontalPoints }); } /** * Draw legend * @param {Array} items The instances of item * @return {ReactElement} The instance of Legend */ }, { key: 'renderLegend', value: function renderLegend(items) { var _this8 = this; var _props7 = this.props; var children = _props7.children; var width = _props7.width; var height = _props7.height; var legendItem = _ReactUtils2.default.findChildByType(children, _Legend2.default); if (!legendItem) { return null; } var legendData = items.map(function (child) { var _child$props3 = child.props; var dataKey = _child$props3.dataKey; var name = _child$props3.name; var legendType = _child$props3.legendType; return { type: legendType || 'square', color: _this8.getMainColorOfItem(child), value: name || dataKey }; }, this); return _react2.default.cloneElement(legendItem, _extends({}, _Legend2.default.getWithHeight(legendItem, width, height), { payload: legendData })); } /** * Draw Tooltip * @param {Array} items The instances of item * @param {Object} offset The offset of main part in the svg element * @return {ReactElement} The instance of Tooltip */ }, { key: 'renderTooltip', value: function renderTooltip(items, offset) { var children = this.props.children; var tooltipItem = _ReactUtils2.default.findChildByType(children, _Tooltip2.default); if (!tooltipItem) { return null; } var _state6 = this.state; var chartX = _state6.chartX; var chartY = _state6.chartY; var isTooltipActive = _state6.isTooltipActive; var activeTooltipLabel = _state6.activeTooltipLabel; var activeTooltipCoord = _state6.activeTooltipCoord; var viewBox = { x: offset.left, y: offset.top, width: offset.width, height: offset.height }; return _react2.default.cloneElement(tooltipItem, { viewBox: viewBox, active: isTooltipActive, label: activeTooltipLabel, payload: isTooltipActive ? this.getTooltipContent(items) : [], coordinate: activeTooltipCoord, mouseX: chartX, mouseY: chartY }); } }, { key: 'renderBrush', value: function renderBrush(xAxisMap, yAxisMap, offset) { var _props8 = this.props; var children = _props8.children; var data = _props8.data; var brushItem = _ReactUtils2.default.findChildByType(children, _Brush2.default); if (!brushItem) { return null; } var dataKey = brushItem.props.dataKey; var height = (brushItem.props.height || _Brush2.default.defaultProps.height) + 1; return _react2.default.cloneElement(brushItem, { onChange: this.handleBrushChange.bind(this), data: data.map(function (entry) { return entry[dataKey]; }), x: offset.left, y: offset.top + offset.height + offset.bottom - height, width: offset.width }); } }, { key: 'renderReferenceLines', value: function renderReferenceLines(xAxisMap, yAxisMap, offset) { var children = this.props.children; var lines = _ReactUtils2.default.findAllByType(children, _ReferenceLine2.default); if (!lines || !lines.length) { return null; } return lines.map(function (entry, i) { return _react2.default.cloneElement(entry, { key: 'reference-line-' + i, xAxisMap: xAxisMap, yAxisMap: yAxisMap, viewBox: { x: offset.left, y: offset.top, width: offset.width, height: offset.height } }); }); } }]); return CartesianChart; }(_react.Component), _class.propTypes = { width: _react.PropTypes.number, height: _react.PropTypes.number, data: _react.PropTypes.arrayOf(_react.PropTypes.object), layout: _react.PropTypes.oneOf(['horizontal', 'vertical']), margin: _react.PropTypes.shape({ top: _react.PropTypes.number, right: _react.PropTypes.number, bottom: _react.PropTypes.number, left: _react.PropTypes.number }), className: _react.PropTypes.string, stackType: _react.PropTypes.oneOf(['value', 'percent']), title: _react.PropTypes.string, style: _react.PropTypes.object, barCategoryGap: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.string]), barGap: _react.PropTypes.number, barSize: _react.PropTypes.number, children: _react.PropTypes.oneOfType([_react.PropTypes.arrayOf(_react.PropTypes.node), _react.PropTypes.node]) }, _class.defaultProps = { style: {}, barCategoryGap: '10%', barGap: 4, layout: 'horizontal', margin: { top: 5, right: 5, bottom: 5, left: 5 } }, _temp); exports.default = CartesianChart;