victory-candlestick
Advanced tools
Comparing version 32.3.7 to 33.0.0
277
es/candle.js
@@ -9,186 +9,129 @@ import _isFunction from "lodash/isFunction"; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } } | ||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } | ||
function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } | ||
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } 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; } | ||
/*eslint no-magic-numbers: ["error", { "ignore": [0, 0.5, 1, 2] }]*/ | ||
import React from "react"; | ||
import PropTypes from "prop-types"; | ||
import { Helpers, CommonProps, Rect, Line } from "victory-core"; | ||
import { Helpers, CommonProps, Line, Rect } from "victory-core"; | ||
var Candle = | ||
/*#__PURE__*/ | ||
function (_React$Component) { | ||
_inherits(Candle, _React$Component); | ||
var getCandleWidth = function (props, style) { | ||
var candleWidth = props.candleWidth; | ||
function Candle() { | ||
_classCallCheck(this, Candle); | ||
return _possibleConstructorReturn(this, (Candle.__proto__ || Object.getPrototypeOf(Candle)).apply(this, arguments)); | ||
if (candleWidth) { | ||
return _isFunction(candleWidth) ? Helpers.evaluateProp(candleWidth, props) : candleWidth; | ||
} else if (style.width) { | ||
return style.width; | ||
} | ||
_createClass(Candle, [{ | ||
key: "getCandleWidth", | ||
value: function getCandleWidth(props, style) { | ||
var active = props.active, | ||
datum = props.datum, | ||
data = props.data, | ||
candleWidth = props.candleWidth, | ||
scale = props.scale, | ||
defaultCandleWidth = props.defaultCandleWidth; | ||
return candleWidth; | ||
}; | ||
if (candleWidth) { | ||
return _isFunction(candleWidth) ? Helpers.evaluateProp(candleWidth, datum, active) : candleWidth; | ||
} else if (style.width) { | ||
return style.width; | ||
} | ||
var getCandleProps = function (props, style) { | ||
var id = props.id, | ||
x = props.x, | ||
close = props.close, | ||
open = props.open, | ||
horizontal = props.horizontal; | ||
var candleWidth = getCandleWidth(props, style); | ||
var candleLength = Math.abs(close - open); | ||
return { | ||
key: "".concat(id, "-candle"), | ||
style: Helpers.omit(style, ["width"]), | ||
x: horizontal ? Math.min(open, close) : x - candleWidth / 2, | ||
y: horizontal ? x - candleWidth / 2 : Math.min(open, close), | ||
width: horizontal ? candleLength : candleWidth, | ||
height: horizontal ? candleWidth : candleLength | ||
}; | ||
}; | ||
var range = scale.x.range(); | ||
var extent = Math.abs(range[1] - range[0]); | ||
var candles = data.length + 2; | ||
var candleRatio = props.candleRatio || 0.5; | ||
var defaultWidth = candleRatio * (data.length < 2 ? defaultCandleWidth : extent / candles); | ||
return Math.max(1, defaultWidth); | ||
} | ||
}, { | ||
key: "getCandleProps", | ||
value: function getCandleProps(props, style) { | ||
var id = props.id, | ||
x = props.x, | ||
close = props.close, | ||
open = props.open, | ||
horizontal = props.horizontal; | ||
var candleWidth = this.getCandleWidth(props, style); | ||
var candleLength = Math.abs(close - open); | ||
return { | ||
key: "".concat(id, "-candle"), | ||
style: Helpers.omit(style, ["width"]), | ||
x: horizontal ? Math.min(open, close) : x - candleWidth / 2, | ||
y: horizontal ? x - candleWidth / 2 : Math.min(open, close), | ||
width: horizontal ? candleLength : candleWidth, | ||
height: horizontal ? candleWidth : candleLength | ||
}; | ||
} | ||
}, { | ||
key: "getHighWickProps", | ||
value: function getHighWickProps(props, style) { | ||
var horizontal = props.horizontal, | ||
high = props.high, | ||
open = props.open, | ||
close = props.close, | ||
x = props.x, | ||
id = props.id; | ||
return { | ||
key: "".concat(id, "-highWick"), | ||
style: Helpers.omit(style, ["width"]), | ||
x1: horizontal ? high : x, | ||
x2: horizontal ? Math.max(open, close) : x, | ||
y1: horizontal ? x : high, | ||
y2: horizontal ? x : Math.min(open, close) | ||
}; | ||
} | ||
}, { | ||
key: "getLowWickProps", | ||
value: function getLowWickProps(props, style) { | ||
var horizontal = props.horizontal, | ||
low = props.low, | ||
open = props.open, | ||
close = props.close, | ||
x = props.x, | ||
id = props.id; | ||
return { | ||
key: "".concat(id, "-lowWick"), | ||
style: Helpers.omit(style, ["width"]), | ||
x1: horizontal ? Math.min(open, close) : x, | ||
x2: horizontal ? low : x, | ||
y1: horizontal ? x : Math.max(open, close), | ||
y2: horizontal ? x : low | ||
}; | ||
} | ||
}, { | ||
key: "render", | ||
value: function render() { | ||
var _props = this.props, | ||
datum = _props.datum, | ||
active = _props.active, | ||
events = _props.events, | ||
groupComponent = _props.groupComponent, | ||
clipPath = _props.clipPath, | ||
rectComponent = _props.rectComponent, | ||
lineComponent = _props.lineComponent, | ||
role = _props.role, | ||
shapeRendering = _props.shapeRendering, | ||
className = _props.className, | ||
wickStrokeWidth = _props.wickStrokeWidth, | ||
transform = _props.transform; | ||
var style = Helpers.evaluateStyle(_assign({ | ||
stroke: "black" | ||
}, this.props.style), datum, active); | ||
var getHighWickProps = function (props, style) { | ||
var horizontal = props.horizontal, | ||
high = props.high, | ||
open = props.open, | ||
close = props.close, | ||
x = props.x, | ||
id = props.id; | ||
return { | ||
key: "".concat(id, "-highWick"), | ||
style: Helpers.omit(style, ["width"]), | ||
x1: horizontal ? high : x, | ||
x2: horizontal ? Math.max(open, close) : x, | ||
y1: horizontal ? x : high, | ||
y2: horizontal ? x : Math.min(open, close) | ||
}; | ||
}; | ||
var wickStyle = _defaults({ | ||
strokeWidth: wickStrokeWidth | ||
}, style); | ||
var getLowWickProps = function (props, style) { | ||
var horizontal = props.horizontal, | ||
low = props.low, | ||
open = props.open, | ||
close = props.close, | ||
x = props.x, | ||
id = props.id; | ||
return { | ||
key: "".concat(id, "-lowWick"), | ||
style: Helpers.omit(style, ["width"]), | ||
x1: horizontal ? Math.min(open, close) : x, | ||
x2: horizontal ? low : x, | ||
y1: horizontal ? x : Math.max(open, close), | ||
y2: horizontal ? x : low | ||
}; | ||
}; | ||
var sharedProps = { | ||
role: role, | ||
shapeRendering: shapeRendering, | ||
className: className, | ||
events: events, | ||
transform: transform, | ||
clipPath: clipPath | ||
}; | ||
var Candle = function (props) { | ||
var events = props.events, | ||
groupComponent = props.groupComponent, | ||
clipPath = props.clipPath, | ||
rectComponent = props.rectComponent, | ||
lineComponent = props.lineComponent, | ||
role = props.role, | ||
shapeRendering = props.shapeRendering, | ||
className = props.className, | ||
wickStrokeWidth = props.wickStrokeWidth, | ||
transform = props.transform; | ||
var style = Helpers.evaluateStyle(_assign({ | ||
stroke: "black" | ||
}, props.style), props); | ||
var candleProps = _assign(this.getCandleProps(this.props, style), sharedProps); | ||
var wickStyle = _defaults({ | ||
strokeWidth: wickStrokeWidth | ||
}, style); | ||
var highWickProps = _assign(this.getHighWickProps(this.props, wickStyle), sharedProps); | ||
var sharedProps = _objectSpread({ | ||
role: role, | ||
shapeRendering: shapeRendering, | ||
className: className, | ||
transform: transform, | ||
clipPath: clipPath | ||
}, events); | ||
var lowWickProps = _assign(this.getLowWickProps(this.props, wickStyle), sharedProps); | ||
var candleProps = _assign(getCandleProps(props, style), sharedProps); | ||
return React.cloneElement(groupComponent, {}, [React.cloneElement(rectComponent, candleProps), React.cloneElement(lineComponent, highWickProps), React.cloneElement(lineComponent, lowWickProps)]); | ||
} | ||
}]); | ||
var highWickProps = _assign(getHighWickProps(props, wickStyle), sharedProps); | ||
return Candle; | ||
}(React.Component); | ||
var lowWickProps = _assign(getLowWickProps(props, wickStyle), sharedProps); | ||
Object.defineProperty(Candle, "propTypes", { | ||
configurable: true, | ||
enumerable: true, | ||
writable: true, | ||
value: _objectSpread({}, CommonProps.primitiveProps, { | ||
candleRatio: PropTypes.number, | ||
candleWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.func]), | ||
close: PropTypes.number, | ||
datum: PropTypes.object, | ||
defaultCandleWidth: PropTypes.number, | ||
groupComponent: PropTypes.element, | ||
high: PropTypes.number, | ||
lineComponent: PropTypes.element, | ||
low: PropTypes.number, | ||
open: PropTypes.number, | ||
rectComponent: PropTypes.element, | ||
wickStrokeWidth: PropTypes.number, | ||
width: PropTypes.number, | ||
x: PropTypes.number | ||
}) | ||
return React.cloneElement(groupComponent, {}, [React.cloneElement(rectComponent, candleProps), React.cloneElement(lineComponent, highWickProps), React.cloneElement(lineComponent, lowWickProps)]); | ||
}; | ||
Candle.propTypes = _objectSpread({}, CommonProps.primitiveProps, { | ||
candleRatio: PropTypes.number, | ||
candleWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.func]), | ||
close: PropTypes.number, | ||
datum: PropTypes.object, | ||
groupComponent: PropTypes.element, | ||
high: PropTypes.number, | ||
lineComponent: PropTypes.element, | ||
low: PropTypes.number, | ||
open: PropTypes.number, | ||
rectComponent: PropTypes.element, | ||
wickStrokeWidth: PropTypes.number, | ||
width: PropTypes.number, | ||
x: PropTypes.number | ||
}); | ||
Object.defineProperty(Candle, "defaultProps", { | ||
configurable: true, | ||
enumerable: true, | ||
writable: true, | ||
value: { | ||
defaultCandleWidth: 8, | ||
groupComponent: React.createElement("g", null), | ||
lineComponent: React.createElement(Line, null), | ||
rectComponent: React.createElement(Rect, null) | ||
} | ||
}); | ||
export { Candle as default }; | ||
Candle.defaultProps = { | ||
groupComponent: React.createElement("g", null), | ||
lineComponent: React.createElement(Line, null), | ||
rectComponent: React.createElement(Rect, null), | ||
role: "presentation", | ||
shapeRendering: "auto" | ||
}; | ||
export default Candle; |
@@ -0,4 +1,8 @@ | ||
import _isPlainObject from "lodash/isPlainObject"; | ||
import _isFunction from "lodash/isFunction"; | ||
import _isNil from "lodash/isNil"; | ||
import _defaults from "lodash/defaults"; | ||
import _assign from "lodash/assign"; | ||
import { Helpers, LabelHelpers, Scale, Domain, Data } from "victory-core"; | ||
import { Helpers, Scale, Domain, Data, LabelHelpers } from "victory-core"; | ||
var TYPES = ["close", "open", "high", "low"]; | ||
@@ -41,2 +45,36 @@ var getData = function (props) { | ||
var getStyles = function (style) { | ||
var defaultStyles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var width = "100%"; | ||
var height = "100%"; | ||
if (!style) { | ||
return _defaults({ | ||
parent: { | ||
height: height, | ||
width: width | ||
} | ||
}, defaultStyles); | ||
} | ||
var defaultParent = defaultStyles.parent || {}; | ||
var defaultLabels = defaultStyles.labels || {}; | ||
var defaultData = defaultStyles.data || {}; | ||
var labelStyle = _defaults({}, style.labels, defaultLabels); | ||
return { | ||
parent: _defaults({}, style.parent, defaultParent, { | ||
width: width, | ||
height: height | ||
}), | ||
labels: labelStyle, | ||
data: _defaults({}, style.data, defaultData), | ||
openLabels: _defaults({}, style.openLabels, defaultStyles.openLabels, labelStyle), | ||
closeLabels: _defaults({}, style.closeLabels, defaultStyles.closeLabels, labelStyle), | ||
lowLabels: _defaults({}, style.lowLabels, defaultStyles.lowLabels, labelStyle), | ||
highLabels: _defaults({}, style.highLabels, defaultStyles.highLabels, labelStyle) | ||
}; | ||
}; | ||
var getCalculatedValues = function (props) { | ||
@@ -46,3 +84,3 @@ var theme = props.theme, | ||
var defaultStyle = theme && theme.candlestick && theme.candlestick.style ? theme.candlestick.style : {}; | ||
var style = Helpers.getStyles(props.style, defaultStyle); | ||
var style = getStyles(props.style, defaultStyle); | ||
var data = getData(props); | ||
@@ -62,2 +100,4 @@ var range = { | ||
var origin = polar ? props.origin || Helpers.getPolarOrigin(props) : undefined; | ||
var defaultOrientation = props.horizontal ? "top" : "right"; | ||
var labelOrientation = props.labelOrientation || defaultOrientation; | ||
return { | ||
@@ -68,3 +108,4 @@ domain: domain, | ||
style: style, | ||
origin: origin | ||
origin: origin, | ||
labelOrientation: labelOrientation | ||
}; | ||
@@ -89,19 +130,149 @@ }; | ||
var getLabelProps = function (dataProps, text, style) { | ||
var x = dataProps.x, | ||
high = dataProps.high, | ||
index = dataProps.index, | ||
scale = dataProps.scale, | ||
datum = dataProps.datum, | ||
data = dataProps.data, | ||
horizontal = dataProps.horizontal; | ||
var labelStyle = style.labels || {}; | ||
var defaultAnchors = { | ||
vertical: horizontal ? "middle" : "end", | ||
text: horizontal ? "start" : "middle" | ||
var getText = function (props, type) { | ||
var datum = props.datum, | ||
index = props.index, | ||
labels = props.labels; | ||
var propName = "".concat(type, "Labels"); | ||
var labelProp = props[propName]; | ||
if (!labelProp && !labels) { | ||
return null; | ||
} else if (labelProp === true || labels === true) { | ||
var dataName = "_".concat(type); | ||
return "".concat(datum[dataName]); | ||
} | ||
return Array.isArray(labelProp) ? labelProp[index] : labelProp; | ||
}; | ||
var getCandleWidth = function (props, style) { | ||
var data = props.data, | ||
candleWidth = props.candleWidth, | ||
scale = props.scale, | ||
defaultCandleWidth = props.defaultCandleWidth; | ||
if (candleWidth) { | ||
return _isFunction(candleWidth) ? Helpers.evaluateProp(candleWidth, props) : candleWidth; | ||
} else if (style && style.width) { | ||
return style.width; | ||
} | ||
var range = scale.x.range(); | ||
var extent = Math.abs(range[1] - range[0]); | ||
var candles = data.length + 2; | ||
var candleRatio = props.candleRatio || 0.5; | ||
var defaultWidth = candleRatio * (data.length < 2 ? defaultCandleWidth : extent / candles); | ||
return Math.max(1, defaultWidth); | ||
}; | ||
var getOrientation = function (labelOrientation) { | ||
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "labels"; | ||
return _isPlainObject(labelOrientation) ? labelOrientation[type] : labelOrientation; | ||
}; | ||
/* eslint-disable complexity*/ | ||
var calculatePlotValues = function (props) { | ||
var positions = props.positions, | ||
labelStyle = props.labelStyle, | ||
x = props.x, | ||
horizontal = props.horizontal, | ||
computedType = props.computedType, | ||
candleWidth = props.candleWidth, | ||
orientation = props.orientation; | ||
positions.labels = (positions.open + positions.close) / 2; | ||
var signX = orientation === "left" ? -1 : 1; | ||
var signY = orientation === "top" ? -1 : 1; | ||
if (horizontal) { | ||
var yValue = x; | ||
var xValue = positions[computedType]; | ||
var dy = orientation === "top" || orientation === "bottom" ? signY * (candleWidth / 2) + signY * (labelStyle.padding || 0) : 0; | ||
var dx = orientation === "top" || orientation === "bottom" ? 0 : signX * (labelStyle.padding || 1); | ||
return { | ||
yValue: yValue, | ||
xValue: xValue, | ||
dx: dx, | ||
dy: dy | ||
}; | ||
} else { | ||
var _xValue = x; | ||
var _yValue = positions[computedType]; | ||
var _dy = orientation === "top" || orientation === "bottom" ? signY * (labelStyle.padding || 1) : 0; | ||
var _dx = orientation === "top" || orientation === "bottom" ? 0 : signX * (candleWidth / 2) + signX * (labelStyle.padding || 0); | ||
return { | ||
yValue: _yValue, | ||
xValue: _xValue, | ||
dx: _dx, | ||
dy: _dy | ||
}; | ||
} | ||
}; | ||
/* eslint-enable complexity*/ | ||
/* eslint-disable max-params*/ | ||
var getLabelProps = function (props, text, style, type) { | ||
var x = props.x, | ||
high = props.high, | ||
low = props.low, | ||
open = props.open, | ||
close = props.close, | ||
index = props.index, | ||
scale = props.scale, | ||
datum = props.datum, | ||
data = props.data, | ||
horizontal = props.horizontal, | ||
candleWidth = props.candleWidth, | ||
labelOrientation = props.labelOrientation; | ||
var component = props["".concat(type, "LabelComponent")] || props.labelComponent; | ||
var defaultOrientation = horizontal ? "top" : "right"; | ||
var orientation = component.props && component.props.orientation || getOrientation(labelOrientation, type) || defaultOrientation; | ||
var positions = { | ||
high: high, | ||
low: low, | ||
open: open, | ||
close: close | ||
}; | ||
var namespace = type ? "".concat(type, "Labels") : "labels"; | ||
var labelStyle = style[namespace] || style.labels; | ||
var defaultVerticalAnchors = { | ||
top: "end", | ||
bottom: "start", | ||
left: "middle", | ||
right: "middle" | ||
}; | ||
var defaultTextAnchors = { | ||
left: "end", | ||
right: "start", | ||
top: "middle", | ||
bottom: "middle" | ||
}; | ||
var computedType = type ? type : "labels"; | ||
var plotProps = { | ||
positions: positions, | ||
labelStyle: labelStyle, | ||
x: x, | ||
horizontal: horizontal, | ||
computedType: computedType, | ||
candleWidth: candleWidth, | ||
orientation: orientation | ||
}; | ||
var _calculatePlotValues = calculatePlotValues(plotProps), | ||
yValue = _calculatePlotValues.yValue, | ||
xValue = _calculatePlotValues.xValue, | ||
dx = _calculatePlotValues.dx, | ||
dy = _calculatePlotValues.dy; | ||
return { | ||
style: labelStyle, | ||
y: horizontal ? x : high - (labelStyle.padding || 0), | ||
x: horizontal ? high + (labelStyle.padding || 0) : x, | ||
y: yValue, | ||
x: xValue, | ||
dx: dx, | ||
dy: dy, | ||
text: text, | ||
@@ -112,4 +283,5 @@ index: index, | ||
data: data, | ||
textAnchor: labelStyle.textAnchor || defaultAnchors.text, | ||
verticalAnchor: labelStyle.verticalAnchor || defaultAnchors.vertical, | ||
orientation: orientation, | ||
textAnchor: labelStyle.textAnchor || defaultTextAnchors[orientation], | ||
verticalAnchor: labelStyle.verticalAnchor || defaultVerticalAnchors[orientation], | ||
angle: labelStyle.angle, | ||
@@ -119,3 +291,5 @@ horizontal: horizontal | ||
}; | ||
/* eslint-enable max-params*/ | ||
var getBaseProps = function (props, fallbackProps) { | ||
@@ -129,3 +303,4 @@ // eslint-disable-line max-statements | ||
domain = calculatedValues.domain, | ||
origin = calculatedValues.origin; | ||
origin = calculatedValues.origin, | ||
labelOrientation = calculatedValues.labelOrientation; | ||
var _props = props, | ||
@@ -190,13 +365,30 @@ groupComponent = _props.groupComponent, | ||
close: close, | ||
horizontal: horizontal | ||
horizontal: horizontal, | ||
labelOrientation: labelOrientation | ||
}; | ||
dataProps.candleWidth = getCandleWidth(dataProps); | ||
var extendedProps = _defaults(Object.assign({}, dataProps), props); | ||
childProps[eventKey] = { | ||
data: dataProps | ||
}; | ||
var text = LabelHelpers.getText(props, datum, index); | ||
if (text !== undefined && text !== null || labels && (events || sharedEvents)) { | ||
childProps[eventKey].labels = getLabelProps(dataProps, text, style); | ||
if (labels) { | ||
var text = LabelHelpers.getText(props, datum, index); | ||
if (text !== undefined && text !== null || labels && (events || sharedEvents)) { | ||
childProps[eventKey].labels = getLabelProps(extendedProps, text, style); | ||
} | ||
} | ||
TYPES.forEach(function (type) { | ||
var labelText = getText(extendedProps, type); | ||
var labelProp = props.labels || props["".concat(type, "Labels")]; | ||
if (labelText !== null && labelText !== undefined || labelProp && (events || sharedEvents)) { | ||
var target = "".concat(type, "Labels"); | ||
childProps[eventKey][target] = getLabelProps(extendedProps, labelText, style, type); | ||
} | ||
}); | ||
return childProps; | ||
@@ -203,0 +395,0 @@ }, initialChildProps); |
@@ -0,1 +1,2 @@ | ||
import _flatten from "lodash/flatten"; | ||
import _isNil from "lodash/isNil"; | ||
@@ -7,2 +8,10 @@ | ||
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } | ||
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } | ||
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } | ||
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
@@ -36,2 +45,20 @@ | ||
}; | ||
var options = { | ||
components: [{ | ||
name: "lowLabels" | ||
}, { | ||
name: "highLabels" | ||
}, { | ||
name: "openLabels" | ||
}, { | ||
name: "closeLabels" | ||
}, { | ||
name: "labels" | ||
}, { | ||
name: "data" | ||
}, { | ||
name: "parent", | ||
index: "parent" | ||
}] | ||
}; | ||
var defaultData = [{ | ||
@@ -88,2 +115,6 @@ x: new Date(2016, 6, 1), | ||
var datumHasXandY = function (datum) { | ||
return !_isNil(datum._x) && !_isNil(datum._y); | ||
}; | ||
var VictoryCandlestick = | ||
@@ -112,2 +143,53 @@ /*#__PURE__*/ | ||
}, { | ||
key: "renderCandleData", | ||
value: function renderCandleData(props) { | ||
var _this = this; | ||
var shouldRenderDatum = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : datumHasXandY; | ||
var dataComponent = props.dataComponent, | ||
labelComponent = props.labelComponent, | ||
groupComponent = props.groupComponent; | ||
var types = ["close", "open", "low", "high"]; | ||
var dataComponents = this.dataKeys.reduce(function (validDataComponents, _dataKey, index) { | ||
var dataProps = _this.getComponentProps(dataComponent, "data", index); | ||
if (shouldRenderDatum(dataProps.datum)) { | ||
validDataComponents.push(React.cloneElement(dataComponent, dataProps)); | ||
} | ||
return validDataComponents; | ||
}, []); | ||
var labelComponents = _flatten(types.map(function (type) { | ||
var components = _this.dataKeys.map(function (key, index) { | ||
var name = "".concat(type, "Labels"); | ||
var baseComponent = props["".concat(type, "LabelComponent")]; | ||
var labelProps = _this.getComponentProps(baseComponent, name, index); | ||
if (labelProps.text !== undefined && labelProps.text !== null) { | ||
return React.cloneElement(baseComponent, labelProps); | ||
} | ||
return undefined; | ||
}); | ||
return components.filter(Boolean); | ||
})); | ||
var labelsComponents = this.dataKeys.map(function (_dataKey, index) { | ||
var labelProps = _this.getComponentProps(labelComponent, "labels", index); | ||
if (labelProps.text !== undefined && labelProps.text !== null) { | ||
return React.cloneElement(labelComponent, labelProps); | ||
} | ||
return undefined; | ||
}).filter(Boolean); | ||
var children = _toConsumableArray(dataComponents).concat(_toConsumableArray(labelComponents), _toConsumableArray(labelsComponents)); | ||
return this.renderContainer(groupComponent, children); | ||
} | ||
}, { | ||
key: "render", | ||
@@ -123,3 +205,3 @@ value: function render() { | ||
var children = this.renderData(props, this.shouldRenderDatum); | ||
var children = this.renderCandleData(props, this.shouldRenderDatum); | ||
return props.standalone ? this.renderContainer(props.containerComponent, children) : children; | ||
@@ -168,5 +250,36 @@ } | ||
close: PropTypes.oneOfType([PropTypes.func, CustomPropTypes.allOfType([CustomPropTypes.integer, CustomPropTypes.nonNegative]), PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), | ||
closeLabelComponent: PropTypes.element, | ||
closeLabels: PropTypes.oneOfType([PropTypes.func, PropTypes.array, PropTypes.bool]), | ||
events: PropTypes.arrayOf(PropTypes.shape({ | ||
target: PropTypes.oneOf(["data", "labels", "open", "openLabels", "close", "closeLabels", "low", "lowLabels", "high", "highLabels"]), | ||
eventKey: PropTypes.oneOfType([PropTypes.array, CustomPropTypes.allOfType([CustomPropTypes.integer, CustomPropTypes.nonNegative]), PropTypes.string]), | ||
eventHandlers: PropTypes.object | ||
})), | ||
high: PropTypes.oneOfType([PropTypes.func, CustomPropTypes.allOfType([CustomPropTypes.integer, CustomPropTypes.nonNegative]), PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), | ||
highLabelComponent: PropTypes.element, | ||
highLabels: PropTypes.oneOfType([PropTypes.func, PropTypes.array, PropTypes.bool]), | ||
labelOrientation: PropTypes.oneOfType([PropTypes.oneOf(["top", "bottom", "left", "right"]), PropTypes.shape({ | ||
open: PropTypes.oneOf(["top", "bottom", "left", "right"]), | ||
close: PropTypes.oneOf(["top", "bottom", "left", "right"]), | ||
low: PropTypes.oneOf(["top", "bottom", "left", "right"]), | ||
high: PropTypes.oneOf(["top", "bottom", "left", "right"]) | ||
})]), | ||
low: PropTypes.oneOfType([PropTypes.func, CustomPropTypes.allOfType([CustomPropTypes.integer, CustomPropTypes.nonNegative]), PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), | ||
lowLabelComponent: PropTypes.element, | ||
lowLabels: PropTypes.oneOfType([PropTypes.func, PropTypes.array, PropTypes.bool]), | ||
open: PropTypes.oneOfType([PropTypes.func, CustomPropTypes.allOfType([CustomPropTypes.integer, CustomPropTypes.nonNegative]), PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), | ||
openLabelComponent: PropTypes.element, | ||
openLabels: PropTypes.oneOfType([PropTypes.func, PropTypes.array, PropTypes.bool]), | ||
style: PropTypes.shape({ | ||
data: PropTypes.object, | ||
labels: PropTypes.object, | ||
close: PropTypes.object, | ||
closeLabels: PropTypes.object, | ||
open: PropTypes.object, | ||
openLabels: PropTypes.object, | ||
high: PropTypes.object, | ||
highLabels: PropTypes.object, | ||
low: PropTypes.object, | ||
lowLabels: PropTypes.object | ||
}), | ||
wickStrokeWidth: PropTypes.number | ||
@@ -180,2 +293,3 @@ }) | ||
value: { | ||
defaultCandleWidth: 8, | ||
containerComponent: React.createElement(VictoryContainer, null), | ||
@@ -188,2 +302,6 @@ data: defaultData, | ||
labelComponent: React.createElement(VictoryLabel, null), | ||
highLabelComponent: React.createElement(VictoryLabel, null), | ||
lowLabelComponent: React.createElement(VictoryLabel, null), | ||
openLabelComponent: React.createElement(VictoryLabel, null), | ||
closeLabelComponent: React.createElement(VictoryLabel, null), | ||
samples: 50, | ||
@@ -219,4 +337,4 @@ sortOrder: "ascending", | ||
writable: true, | ||
value: ["dataComponent", "labelComponent", "groupComponent", "containerComponent"] | ||
value: ["openLabelComponent", "closeLabelComponent", "highLabelComponent", "lowLabelComponent", "dataComponent", "labelComponent", "groupComponent", "containerComponent"] | ||
}); | ||
export default addEvents(VictoryCandlestick); | ||
export default addEvents(VictoryCandlestick, options); |
@@ -26,177 +26,123 @@ "use strict"; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var getCandleWidth = function (props, style) { | ||
var candleWidth = props.candleWidth; | ||
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); } } | ||
if (candleWidth) { | ||
return (0, _isFunction2.default)(candleWidth) ? _victoryCore.Helpers.evaluateProp(candleWidth, props) : candleWidth; | ||
} else if (style.width) { | ||
return style.width; | ||
} | ||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } | ||
return candleWidth; | ||
}; | ||
function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } | ||
var getCandleProps = function (props, style) { | ||
var id = props.id, | ||
x = props.x, | ||
close = props.close, | ||
open = props.open, | ||
horizontal = props.horizontal; | ||
var candleWidth = getCandleWidth(props, style); | ||
var candleLength = Math.abs(close - open); | ||
return { | ||
key: "".concat(id, "-candle"), | ||
style: _victoryCore.Helpers.omit(style, ["width"]), | ||
x: horizontal ? Math.min(open, close) : x - candleWidth / 2, | ||
y: horizontal ? x - candleWidth / 2 : Math.min(open, close), | ||
width: horizontal ? candleLength : candleWidth, | ||
height: horizontal ? candleWidth : candleLength | ||
}; | ||
}; | ||
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } | ||
var getHighWickProps = function (props, style) { | ||
var horizontal = props.horizontal, | ||
high = props.high, | ||
open = props.open, | ||
close = props.close, | ||
x = props.x, | ||
id = props.id; | ||
return { | ||
key: "".concat(id, "-highWick"), | ||
style: _victoryCore.Helpers.omit(style, ["width"]), | ||
x1: horizontal ? high : x, | ||
x2: horizontal ? Math.max(open, close) : x, | ||
y1: horizontal ? x : high, | ||
y2: horizontal ? x : Math.min(open, close) | ||
}; | ||
}; | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } 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 getLowWickProps = function (props, style) { | ||
var horizontal = props.horizontal, | ||
low = props.low, | ||
open = props.open, | ||
close = props.close, | ||
x = props.x, | ||
id = props.id; | ||
return { | ||
key: "".concat(id, "-lowWick"), | ||
style: _victoryCore.Helpers.omit(style, ["width"]), | ||
x1: horizontal ? Math.min(open, close) : x, | ||
x2: horizontal ? low : x, | ||
y1: horizontal ? x : Math.max(open, close), | ||
y2: horizontal ? x : low | ||
}; | ||
}; | ||
var Candle = | ||
/*#__PURE__*/ | ||
function (_React$Component) { | ||
_inherits(Candle, _React$Component); | ||
var Candle = function (props) { | ||
var events = props.events, | ||
groupComponent = props.groupComponent, | ||
clipPath = props.clipPath, | ||
rectComponent = props.rectComponent, | ||
lineComponent = props.lineComponent, | ||
role = props.role, | ||
shapeRendering = props.shapeRendering, | ||
className = props.className, | ||
wickStrokeWidth = props.wickStrokeWidth, | ||
transform = props.transform; | ||
function Candle() { | ||
_classCallCheck(this, Candle); | ||
var style = _victoryCore.Helpers.evaluateStyle((0, _assign2.default)({ | ||
stroke: "black" | ||
}, props.style), props); | ||
return _possibleConstructorReturn(this, (Candle.__proto__ || Object.getPrototypeOf(Candle)).apply(this, arguments)); | ||
} | ||
var wickStyle = (0, _defaults2.default)({ | ||
strokeWidth: wickStrokeWidth | ||
}, style); | ||
_createClass(Candle, [{ | ||
key: "getCandleWidth", | ||
value: function getCandleWidth(props, style) { | ||
var active = props.active, | ||
datum = props.datum, | ||
data = props.data, | ||
candleWidth = props.candleWidth, | ||
scale = props.scale, | ||
defaultCandleWidth = props.defaultCandleWidth; | ||
var sharedProps = _objectSpread({ | ||
role: role, | ||
shapeRendering: shapeRendering, | ||
className: className, | ||
transform: transform, | ||
clipPath: clipPath | ||
}, events); | ||
if (candleWidth) { | ||
return (0, _isFunction2.default)(candleWidth) ? _victoryCore.Helpers.evaluateProp(candleWidth, datum, active) : candleWidth; | ||
} else if (style.width) { | ||
return style.width; | ||
} | ||
var candleProps = (0, _assign2.default)(getCandleProps(props, style), sharedProps); | ||
var highWickProps = (0, _assign2.default)(getHighWickProps(props, wickStyle), sharedProps); | ||
var lowWickProps = (0, _assign2.default)(getLowWickProps(props, wickStyle), sharedProps); | ||
return _react.default.cloneElement(groupComponent, {}, [_react.default.cloneElement(rectComponent, candleProps), _react.default.cloneElement(lineComponent, highWickProps), _react.default.cloneElement(lineComponent, lowWickProps)]); | ||
}; | ||
var range = scale.x.range(); | ||
var extent = Math.abs(range[1] - range[0]); | ||
var candles = data.length + 2; | ||
var candleRatio = props.candleRatio || 0.5; | ||
var defaultWidth = candleRatio * (data.length < 2 ? defaultCandleWidth : extent / candles); | ||
return Math.max(1, defaultWidth); | ||
} | ||
}, { | ||
key: "getCandleProps", | ||
value: function getCandleProps(props, style) { | ||
var id = props.id, | ||
x = props.x, | ||
close = props.close, | ||
open = props.open, | ||
horizontal = props.horizontal; | ||
var candleWidth = this.getCandleWidth(props, style); | ||
var candleLength = Math.abs(close - open); | ||
return { | ||
key: "".concat(id, "-candle"), | ||
style: _victoryCore.Helpers.omit(style, ["width"]), | ||
x: horizontal ? Math.min(open, close) : x - candleWidth / 2, | ||
y: horizontal ? x - candleWidth / 2 : Math.min(open, close), | ||
width: horizontal ? candleLength : candleWidth, | ||
height: horizontal ? candleWidth : candleLength | ||
}; | ||
} | ||
}, { | ||
key: "getHighWickProps", | ||
value: function getHighWickProps(props, style) { | ||
var horizontal = props.horizontal, | ||
high = props.high, | ||
open = props.open, | ||
close = props.close, | ||
x = props.x, | ||
id = props.id; | ||
return { | ||
key: "".concat(id, "-highWick"), | ||
style: _victoryCore.Helpers.omit(style, ["width"]), | ||
x1: horizontal ? high : x, | ||
x2: horizontal ? Math.max(open, close) : x, | ||
y1: horizontal ? x : high, | ||
y2: horizontal ? x : Math.min(open, close) | ||
}; | ||
} | ||
}, { | ||
key: "getLowWickProps", | ||
value: function getLowWickProps(props, style) { | ||
var horizontal = props.horizontal, | ||
low = props.low, | ||
open = props.open, | ||
close = props.close, | ||
x = props.x, | ||
id = props.id; | ||
return { | ||
key: "".concat(id, "-lowWick"), | ||
style: _victoryCore.Helpers.omit(style, ["width"]), | ||
x1: horizontal ? Math.min(open, close) : x, | ||
x2: horizontal ? low : x, | ||
y1: horizontal ? x : Math.max(open, close), | ||
y2: horizontal ? x : low | ||
}; | ||
} | ||
}, { | ||
key: "render", | ||
value: function render() { | ||
var _props = this.props, | ||
datum = _props.datum, | ||
active = _props.active, | ||
events = _props.events, | ||
groupComponent = _props.groupComponent, | ||
clipPath = _props.clipPath, | ||
rectComponent = _props.rectComponent, | ||
lineComponent = _props.lineComponent, | ||
role = _props.role, | ||
shapeRendering = _props.shapeRendering, | ||
className = _props.className, | ||
wickStrokeWidth = _props.wickStrokeWidth, | ||
transform = _props.transform; | ||
var style = _victoryCore.Helpers.evaluateStyle((0, _assign2.default)({ | ||
stroke: "black" | ||
}, this.props.style), datum, active); | ||
var wickStyle = (0, _defaults2.default)({ | ||
strokeWidth: wickStrokeWidth | ||
}, style); | ||
var sharedProps = { | ||
role: role, | ||
shapeRendering: shapeRendering, | ||
className: className, | ||
events: events, | ||
transform: transform, | ||
clipPath: clipPath | ||
}; | ||
var candleProps = (0, _assign2.default)(this.getCandleProps(this.props, style), sharedProps); | ||
var highWickProps = (0, _assign2.default)(this.getHighWickProps(this.props, wickStyle), sharedProps); | ||
var lowWickProps = (0, _assign2.default)(this.getLowWickProps(this.props, wickStyle), sharedProps); | ||
return _react.default.cloneElement(groupComponent, {}, [_react.default.cloneElement(rectComponent, candleProps), _react.default.cloneElement(lineComponent, highWickProps), _react.default.cloneElement(lineComponent, lowWickProps)]); | ||
} | ||
}]); | ||
return Candle; | ||
}(_react.default.Component); | ||
exports.default = Candle; | ||
Object.defineProperty(Candle, "propTypes", { | ||
configurable: true, | ||
enumerable: true, | ||
writable: true, | ||
value: _objectSpread({}, _victoryCore.CommonProps.primitiveProps, { | ||
candleRatio: _propTypes.default.number, | ||
candleWidth: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.func]), | ||
close: _propTypes.default.number, | ||
datum: _propTypes.default.object, | ||
defaultCandleWidth: _propTypes.default.number, | ||
groupComponent: _propTypes.default.element, | ||
high: _propTypes.default.number, | ||
lineComponent: _propTypes.default.element, | ||
low: _propTypes.default.number, | ||
open: _propTypes.default.number, | ||
rectComponent: _propTypes.default.element, | ||
wickStrokeWidth: _propTypes.default.number, | ||
width: _propTypes.default.number, | ||
x: _propTypes.default.number | ||
}) | ||
Candle.propTypes = _objectSpread({}, _victoryCore.CommonProps.primitiveProps, { | ||
candleRatio: _propTypes.default.number, | ||
candleWidth: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.func]), | ||
close: _propTypes.default.number, | ||
datum: _propTypes.default.object, | ||
groupComponent: _propTypes.default.element, | ||
high: _propTypes.default.number, | ||
lineComponent: _propTypes.default.element, | ||
low: _propTypes.default.number, | ||
open: _propTypes.default.number, | ||
rectComponent: _propTypes.default.element, | ||
wickStrokeWidth: _propTypes.default.number, | ||
width: _propTypes.default.number, | ||
x: _propTypes.default.number | ||
}); | ||
Object.defineProperty(Candle, "defaultProps", { | ||
configurable: true, | ||
enumerable: true, | ||
writable: true, | ||
value: { | ||
defaultCandleWidth: 8, | ||
groupComponent: _react.default.createElement("g", null), | ||
lineComponent: _react.default.createElement(_victoryCore.Line, null), | ||
rectComponent: _react.default.createElement(_victoryCore.Rect, null) | ||
} | ||
}); | ||
Candle.defaultProps = { | ||
groupComponent: _react.default.createElement("g", null), | ||
lineComponent: _react.default.createElement(_victoryCore.Line, null), | ||
rectComponent: _react.default.createElement(_victoryCore.Rect, null), | ||
role: "presentation", | ||
shapeRendering: "auto" | ||
}; | ||
var _default = Candle; | ||
exports.default = _default; |
@@ -8,4 +8,10 @@ "use strict"; | ||
var _isPlainObject2 = _interopRequireDefault(require("lodash/isPlainObject")); | ||
var _isFunction2 = _interopRequireDefault(require("lodash/isFunction")); | ||
var _isNil2 = _interopRequireDefault(require("lodash/isNil")); | ||
var _defaults2 = _interopRequireDefault(require("lodash/defaults")); | ||
var _assign2 = _interopRequireDefault(require("lodash/assign")); | ||
@@ -17,2 +23,4 @@ | ||
var TYPES = ["close", "open", "high", "low"]; | ||
var getData = function (props) { | ||
@@ -60,2 +68,34 @@ var accessorTypes = ["x", "high", "low", "close", "open"]; | ||
var getStyles = function (style) { | ||
var defaultStyles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var width = "100%"; | ||
var height = "100%"; | ||
if (!style) { | ||
return (0, _defaults2.default)({ | ||
parent: { | ||
height: height, | ||
width: width | ||
} | ||
}, defaultStyles); | ||
} | ||
var defaultParent = defaultStyles.parent || {}; | ||
var defaultLabels = defaultStyles.labels || {}; | ||
var defaultData = defaultStyles.data || {}; | ||
var labelStyle = (0, _defaults2.default)({}, style.labels, defaultLabels); | ||
return { | ||
parent: (0, _defaults2.default)({}, style.parent, defaultParent, { | ||
width: width, | ||
height: height | ||
}), | ||
labels: labelStyle, | ||
data: (0, _defaults2.default)({}, style.data, defaultData), | ||
openLabels: (0, _defaults2.default)({}, style.openLabels, defaultStyles.openLabels, labelStyle), | ||
closeLabels: (0, _defaults2.default)({}, style.closeLabels, defaultStyles.closeLabels, labelStyle), | ||
lowLabels: (0, _defaults2.default)({}, style.lowLabels, defaultStyles.lowLabels, labelStyle), | ||
highLabels: (0, _defaults2.default)({}, style.highLabels, defaultStyles.highLabels, labelStyle) | ||
}; | ||
}; | ||
var getCalculatedValues = function (props) { | ||
@@ -65,5 +105,3 @@ var theme = props.theme, | ||
var defaultStyle = theme && theme.candlestick && theme.candlestick.style ? theme.candlestick.style : {}; | ||
var style = _victoryCore.Helpers.getStyles(props.style, defaultStyle); | ||
var style = getStyles(props.style, defaultStyle); | ||
var data = getData(props); | ||
@@ -83,2 +121,4 @@ var range = { | ||
var origin = polar ? props.origin || _victoryCore.Helpers.getPolarOrigin(props) : undefined; | ||
var defaultOrientation = props.horizontal ? "top" : "right"; | ||
var labelOrientation = props.labelOrientation || defaultOrientation; | ||
return { | ||
@@ -89,3 +129,4 @@ domain: domain, | ||
style: style, | ||
origin: origin | ||
origin: origin, | ||
labelOrientation: labelOrientation | ||
}; | ||
@@ -110,19 +151,149 @@ }; | ||
var getLabelProps = function (dataProps, text, style) { | ||
var x = dataProps.x, | ||
high = dataProps.high, | ||
index = dataProps.index, | ||
scale = dataProps.scale, | ||
datum = dataProps.datum, | ||
data = dataProps.data, | ||
horizontal = dataProps.horizontal; | ||
var labelStyle = style.labels || {}; | ||
var defaultAnchors = { | ||
vertical: horizontal ? "middle" : "end", | ||
text: horizontal ? "start" : "middle" | ||
var getText = function (props, type) { | ||
var datum = props.datum, | ||
index = props.index, | ||
labels = props.labels; | ||
var propName = "".concat(type, "Labels"); | ||
var labelProp = props[propName]; | ||
if (!labelProp && !labels) { | ||
return null; | ||
} else if (labelProp === true || labels === true) { | ||
var dataName = "_".concat(type); | ||
return "".concat(datum[dataName]); | ||
} | ||
return Array.isArray(labelProp) ? labelProp[index] : labelProp; | ||
}; | ||
var getCandleWidth = function (props, style) { | ||
var data = props.data, | ||
candleWidth = props.candleWidth, | ||
scale = props.scale, | ||
defaultCandleWidth = props.defaultCandleWidth; | ||
if (candleWidth) { | ||
return (0, _isFunction2.default)(candleWidth) ? _victoryCore.Helpers.evaluateProp(candleWidth, props) : candleWidth; | ||
} else if (style && style.width) { | ||
return style.width; | ||
} | ||
var range = scale.x.range(); | ||
var extent = Math.abs(range[1] - range[0]); | ||
var candles = data.length + 2; | ||
var candleRatio = props.candleRatio || 0.5; | ||
var defaultWidth = candleRatio * (data.length < 2 ? defaultCandleWidth : extent / candles); | ||
return Math.max(1, defaultWidth); | ||
}; | ||
var getOrientation = function (labelOrientation) { | ||
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "labels"; | ||
return (0, _isPlainObject2.default)(labelOrientation) ? labelOrientation[type] : labelOrientation; | ||
}; | ||
/* eslint-disable complexity*/ | ||
var calculatePlotValues = function (props) { | ||
var positions = props.positions, | ||
labelStyle = props.labelStyle, | ||
x = props.x, | ||
horizontal = props.horizontal, | ||
computedType = props.computedType, | ||
candleWidth = props.candleWidth, | ||
orientation = props.orientation; | ||
positions.labels = (positions.open + positions.close) / 2; | ||
var signX = orientation === "left" ? -1 : 1; | ||
var signY = orientation === "top" ? -1 : 1; | ||
if (horizontal) { | ||
var yValue = x; | ||
var xValue = positions[computedType]; | ||
var dy = orientation === "top" || orientation === "bottom" ? signY * (candleWidth / 2) + signY * (labelStyle.padding || 0) : 0; | ||
var dx = orientation === "top" || orientation === "bottom" ? 0 : signX * (labelStyle.padding || 1); | ||
return { | ||
yValue: yValue, | ||
xValue: xValue, | ||
dx: dx, | ||
dy: dy | ||
}; | ||
} else { | ||
var _xValue = x; | ||
var _yValue = positions[computedType]; | ||
var _dy = orientation === "top" || orientation === "bottom" ? signY * (labelStyle.padding || 1) : 0; | ||
var _dx = orientation === "top" || orientation === "bottom" ? 0 : signX * (candleWidth / 2) + signX * (labelStyle.padding || 0); | ||
return { | ||
yValue: _yValue, | ||
xValue: _xValue, | ||
dx: _dx, | ||
dy: _dy | ||
}; | ||
} | ||
}; | ||
/* eslint-enable complexity*/ | ||
/* eslint-disable max-params*/ | ||
var getLabelProps = function (props, text, style, type) { | ||
var x = props.x, | ||
high = props.high, | ||
low = props.low, | ||
open = props.open, | ||
close = props.close, | ||
index = props.index, | ||
scale = props.scale, | ||
datum = props.datum, | ||
data = props.data, | ||
horizontal = props.horizontal, | ||
candleWidth = props.candleWidth, | ||
labelOrientation = props.labelOrientation; | ||
var component = props["".concat(type, "LabelComponent")] || props.labelComponent; | ||
var defaultOrientation = horizontal ? "top" : "right"; | ||
var orientation = component.props && component.props.orientation || getOrientation(labelOrientation, type) || defaultOrientation; | ||
var positions = { | ||
high: high, | ||
low: low, | ||
open: open, | ||
close: close | ||
}; | ||
var namespace = type ? "".concat(type, "Labels") : "labels"; | ||
var labelStyle = style[namespace] || style.labels; | ||
var defaultVerticalAnchors = { | ||
top: "end", | ||
bottom: "start", | ||
left: "middle", | ||
right: "middle" | ||
}; | ||
var defaultTextAnchors = { | ||
left: "end", | ||
right: "start", | ||
top: "middle", | ||
bottom: "middle" | ||
}; | ||
var computedType = type ? type : "labels"; | ||
var plotProps = { | ||
positions: positions, | ||
labelStyle: labelStyle, | ||
x: x, | ||
horizontal: horizontal, | ||
computedType: computedType, | ||
candleWidth: candleWidth, | ||
orientation: orientation | ||
}; | ||
var _calculatePlotValues = calculatePlotValues(plotProps), | ||
yValue = _calculatePlotValues.yValue, | ||
xValue = _calculatePlotValues.xValue, | ||
dx = _calculatePlotValues.dx, | ||
dy = _calculatePlotValues.dy; | ||
return { | ||
style: labelStyle, | ||
y: horizontal ? x : high - (labelStyle.padding || 0), | ||
x: horizontal ? high + (labelStyle.padding || 0) : x, | ||
y: yValue, | ||
x: xValue, | ||
dx: dx, | ||
dy: dy, | ||
text: text, | ||
@@ -133,4 +304,5 @@ index: index, | ||
data: data, | ||
textAnchor: labelStyle.textAnchor || defaultAnchors.text, | ||
verticalAnchor: labelStyle.verticalAnchor || defaultAnchors.vertical, | ||
orientation: orientation, | ||
textAnchor: labelStyle.textAnchor || defaultTextAnchors[orientation], | ||
verticalAnchor: labelStyle.verticalAnchor || defaultVerticalAnchors[orientation], | ||
angle: labelStyle.angle, | ||
@@ -140,3 +312,5 @@ horizontal: horizontal | ||
}; | ||
/* eslint-enable max-params*/ | ||
var getBaseProps = function (props, fallbackProps) { | ||
@@ -150,3 +324,4 @@ // eslint-disable-line max-statements | ||
domain = calculatedValues.domain, | ||
origin = calculatedValues.origin; | ||
origin = calculatedValues.origin, | ||
labelOrientation = calculatedValues.labelOrientation; | ||
var _props = props, | ||
@@ -211,4 +386,7 @@ groupComponent = _props.groupComponent, | ||
close: close, | ||
horizontal: horizontal | ||
horizontal: horizontal, | ||
labelOrientation: labelOrientation | ||
}; | ||
dataProps.candleWidth = getCandleWidth(dataProps); | ||
var extendedProps = (0, _defaults2.default)(Object.assign({}, dataProps), props); | ||
childProps[eventKey] = { | ||
@@ -218,8 +396,19 @@ data: dataProps | ||
var text = _victoryCore.LabelHelpers.getText(props, datum, index); | ||
if (labels) { | ||
var text = _victoryCore.LabelHelpers.getText(props, datum, index); | ||
if (text !== undefined && text !== null || labels && (events || sharedEvents)) { | ||
childProps[eventKey].labels = getLabelProps(dataProps, text, style); | ||
if (text !== undefined && text !== null || labels && (events || sharedEvents)) { | ||
childProps[eventKey].labels = getLabelProps(extendedProps, text, style); | ||
} | ||
} | ||
TYPES.forEach(function (type) { | ||
var labelText = getText(extendedProps, type); | ||
var labelProp = props.labels || props["".concat(type, "Labels")]; | ||
if (labelText !== null && labelText !== undefined || labelProp && (events || sharedEvents)) { | ||
var target = "".concat(type, "Labels"); | ||
childProps[eventKey][target] = getLabelProps(extendedProps, labelText, style, type); | ||
} | ||
}); | ||
return childProps; | ||
@@ -226,0 +415,0 @@ }, initialChildProps); |
@@ -8,2 +8,4 @@ "use strict"; | ||
var _flatten2 = _interopRequireDefault(require("lodash/flatten")); | ||
var _isNil2 = _interopRequireDefault(require("lodash/isNil")); | ||
@@ -27,2 +29,10 @@ | ||
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } | ||
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } | ||
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } | ||
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
@@ -50,2 +60,20 @@ | ||
}; | ||
var options = { | ||
components: [{ | ||
name: "lowLabels" | ||
}, { | ||
name: "highLabels" | ||
}, { | ||
name: "openLabels" | ||
}, { | ||
name: "closeLabels" | ||
}, { | ||
name: "labels" | ||
}, { | ||
name: "data" | ||
}, { | ||
name: "parent", | ||
index: "parent" | ||
}] | ||
}; | ||
var defaultData = [{ | ||
@@ -102,2 +130,6 @@ x: new Date(2016, 6, 1), | ||
var datumHasXandY = function (datum) { | ||
return !(0, _isNil2.default)(datum._x) && !(0, _isNil2.default)(datum._y); | ||
}; | ||
var VictoryCandlestick = | ||
@@ -126,2 +158,51 @@ /*#__PURE__*/ | ||
}, { | ||
key: "renderCandleData", | ||
value: function renderCandleData(props) { | ||
var _this = this; | ||
var shouldRenderDatum = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : datumHasXandY; | ||
var dataComponent = props.dataComponent, | ||
labelComponent = props.labelComponent, | ||
groupComponent = props.groupComponent; | ||
var types = ["close", "open", "low", "high"]; | ||
var dataComponents = this.dataKeys.reduce(function (validDataComponents, _dataKey, index) { | ||
var dataProps = _this.getComponentProps(dataComponent, "data", index); | ||
if (shouldRenderDatum(dataProps.datum)) { | ||
validDataComponents.push(_react.default.cloneElement(dataComponent, dataProps)); | ||
} | ||
return validDataComponents; | ||
}, []); | ||
var labelComponents = (0, _flatten2.default)(types.map(function (type) { | ||
var components = _this.dataKeys.map(function (key, index) { | ||
var name = "".concat(type, "Labels"); | ||
var baseComponent = props["".concat(type, "LabelComponent")]; | ||
var labelProps = _this.getComponentProps(baseComponent, name, index); | ||
if (labelProps.text !== undefined && labelProps.text !== null) { | ||
return _react.default.cloneElement(baseComponent, labelProps); | ||
} | ||
return undefined; | ||
}); | ||
return components.filter(Boolean); | ||
})); | ||
var labelsComponents = this.dataKeys.map(function (_dataKey, index) { | ||
var labelProps = _this.getComponentProps(labelComponent, "labels", index); | ||
if (labelProps.text !== undefined && labelProps.text !== null) { | ||
return _react.default.cloneElement(labelComponent, labelProps); | ||
} | ||
return undefined; | ||
}).filter(Boolean); | ||
var children = _toConsumableArray(dataComponents).concat(_toConsumableArray(labelComponents), _toConsumableArray(labelsComponents)); | ||
return this.renderContainer(groupComponent, children); | ||
} | ||
}, { | ||
key: "render", | ||
@@ -138,3 +219,3 @@ value: function render() { | ||
var children = this.renderData(props, this.shouldRenderDatum); | ||
var children = this.renderCandleData(props, this.shouldRenderDatum); | ||
return props.standalone ? this.renderContainer(props.containerComponent, children) : children; | ||
@@ -183,5 +264,36 @@ } | ||
close: _propTypes.default.oneOfType([_propTypes.default.func, _victoryCore.PropTypes.allOfType([_victoryCore.PropTypes.integer, _victoryCore.PropTypes.nonNegative]), _propTypes.default.string, _propTypes.default.arrayOf(_propTypes.default.string)]), | ||
closeLabelComponent: _propTypes.default.element, | ||
closeLabels: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.array, _propTypes.default.bool]), | ||
events: _propTypes.default.arrayOf(_propTypes.default.shape({ | ||
target: _propTypes.default.oneOf(["data", "labels", "open", "openLabels", "close", "closeLabels", "low", "lowLabels", "high", "highLabels"]), | ||
eventKey: _propTypes.default.oneOfType([_propTypes.default.array, _victoryCore.PropTypes.allOfType([_victoryCore.PropTypes.integer, _victoryCore.PropTypes.nonNegative]), _propTypes.default.string]), | ||
eventHandlers: _propTypes.default.object | ||
})), | ||
high: _propTypes.default.oneOfType([_propTypes.default.func, _victoryCore.PropTypes.allOfType([_victoryCore.PropTypes.integer, _victoryCore.PropTypes.nonNegative]), _propTypes.default.string, _propTypes.default.arrayOf(_propTypes.default.string)]), | ||
highLabelComponent: _propTypes.default.element, | ||
highLabels: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.array, _propTypes.default.bool]), | ||
labelOrientation: _propTypes.default.oneOfType([_propTypes.default.oneOf(["top", "bottom", "left", "right"]), _propTypes.default.shape({ | ||
open: _propTypes.default.oneOf(["top", "bottom", "left", "right"]), | ||
close: _propTypes.default.oneOf(["top", "bottom", "left", "right"]), | ||
low: _propTypes.default.oneOf(["top", "bottom", "left", "right"]), | ||
high: _propTypes.default.oneOf(["top", "bottom", "left", "right"]) | ||
})]), | ||
low: _propTypes.default.oneOfType([_propTypes.default.func, _victoryCore.PropTypes.allOfType([_victoryCore.PropTypes.integer, _victoryCore.PropTypes.nonNegative]), _propTypes.default.string, _propTypes.default.arrayOf(_propTypes.default.string)]), | ||
lowLabelComponent: _propTypes.default.element, | ||
lowLabels: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.array, _propTypes.default.bool]), | ||
open: _propTypes.default.oneOfType([_propTypes.default.func, _victoryCore.PropTypes.allOfType([_victoryCore.PropTypes.integer, _victoryCore.PropTypes.nonNegative]), _propTypes.default.string, _propTypes.default.arrayOf(_propTypes.default.string)]), | ||
openLabelComponent: _propTypes.default.element, | ||
openLabels: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.array, _propTypes.default.bool]), | ||
style: _propTypes.default.shape({ | ||
data: _propTypes.default.object, | ||
labels: _propTypes.default.object, | ||
close: _propTypes.default.object, | ||
closeLabels: _propTypes.default.object, | ||
open: _propTypes.default.object, | ||
openLabels: _propTypes.default.object, | ||
high: _propTypes.default.object, | ||
highLabels: _propTypes.default.object, | ||
low: _propTypes.default.object, | ||
lowLabels: _propTypes.default.object | ||
}), | ||
wickStrokeWidth: _propTypes.default.number | ||
@@ -195,2 +307,3 @@ }) | ||
value: { | ||
defaultCandleWidth: 8, | ||
containerComponent: _react.default.createElement(_victoryCore.VictoryContainer, null), | ||
@@ -203,2 +316,6 @@ data: defaultData, | ||
labelComponent: _react.default.createElement(_victoryCore.VictoryLabel, null), | ||
highLabelComponent: _react.default.createElement(_victoryCore.VictoryLabel, null), | ||
lowLabelComponent: _react.default.createElement(_victoryCore.VictoryLabel, null), | ||
openLabelComponent: _react.default.createElement(_victoryCore.VictoryLabel, null), | ||
closeLabelComponent: _react.default.createElement(_victoryCore.VictoryLabel, null), | ||
samples: 50, | ||
@@ -234,7 +351,7 @@ sortOrder: "ascending", | ||
writable: true, | ||
value: ["dataComponent", "labelComponent", "groupComponent", "containerComponent"] | ||
value: ["openLabelComponent", "closeLabelComponent", "highLabelComponent", "lowLabelComponent", "dataComponent", "labelComponent", "groupComponent", "containerComponent"] | ||
}); | ||
var _default = (0, _victoryCore.addEvents)(VictoryCandlestick); | ||
var _default = (0, _victoryCore.addEvents)(VictoryCandlestick, options); | ||
exports.default = _default; |
{ | ||
"name": "victory-candlestick", | ||
"version": "32.3.7", | ||
"version": "33.0.0", | ||
"description": "Candlestick Component for Victory", | ||
@@ -24,3 +24,3 @@ "keywords": [ | ||
"prop-types": "^15.5.8", | ||
"victory-core": "^32.3.7" | ||
"victory-core": "^33.0.0" | ||
}, | ||
@@ -27,0 +27,0 @@ "scripts": { |
/*eslint no-magic-numbers: ["error", { "ignore": [0, 0.5, 1, 2] }]*/ | ||
import React from "react"; | ||
import PropTypes from "prop-types"; | ||
import { Helpers, CommonProps, Rect, Line } from "victory-core"; | ||
import { Helpers, CommonProps, Line, Rect } from "victory-core"; | ||
import { assign, defaults, isFunction } from "lodash"; | ||
export default class Candle extends React.Component { | ||
static propTypes = { | ||
...CommonProps.primitiveProps, | ||
candleRatio: PropTypes.number, | ||
candleWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.func]), | ||
close: PropTypes.number, | ||
datum: PropTypes.object, | ||
defaultCandleWidth: PropTypes.number, | ||
groupComponent: PropTypes.element, | ||
high: PropTypes.number, | ||
lineComponent: PropTypes.element, | ||
low: PropTypes.number, | ||
open: PropTypes.number, | ||
rectComponent: PropTypes.element, | ||
wickStrokeWidth: PropTypes.number, | ||
width: PropTypes.number, | ||
x: PropTypes.number | ||
const getCandleWidth = (props, style) => { | ||
const { candleWidth } = props; | ||
if (candleWidth) { | ||
return isFunction(candleWidth) ? Helpers.evaluateProp(candleWidth, props) : candleWidth; | ||
} else if (style.width) { | ||
return style.width; | ||
} | ||
return candleWidth; | ||
}; | ||
const getCandleProps = (props, style) => { | ||
const { id, x, close, open, horizontal } = props; | ||
const candleWidth = getCandleWidth(props, style); | ||
const candleLength = Math.abs(close - open); | ||
return { | ||
key: `${id}-candle`, | ||
style: Helpers.omit(style, ["width"]), | ||
x: horizontal ? Math.min(open, close) : x - candleWidth / 2, | ||
y: horizontal ? x - candleWidth / 2 : Math.min(open, close), | ||
width: horizontal ? candleLength : candleWidth, | ||
height: horizontal ? candleWidth : candleLength | ||
}; | ||
}; | ||
static defaultProps = { | ||
defaultCandleWidth: 8, | ||
groupComponent: <g />, | ||
lineComponent: <Line />, | ||
rectComponent: <Rect /> | ||
const getHighWickProps = (props, style) => { | ||
const { horizontal, high, open, close, x, id } = props; | ||
return { | ||
key: `${id}-highWick`, | ||
style: Helpers.omit(style, ["width"]), | ||
x1: horizontal ? high : x, | ||
x2: horizontal ? Math.max(open, close) : x, | ||
y1: horizontal ? x : high, | ||
y2: horizontal ? x : Math.min(open, close) | ||
}; | ||
}; | ||
getCandleWidth(props, style) { | ||
const { active, datum, data, candleWidth, scale, defaultCandleWidth } = props; | ||
if (candleWidth) { | ||
return isFunction(candleWidth) | ||
? Helpers.evaluateProp(candleWidth, datum, active) | ||
: candleWidth; | ||
} else if (style.width) { | ||
return style.width; | ||
} | ||
const range = scale.x.range(); | ||
const extent = Math.abs(range[1] - range[0]); | ||
const candles = data.length + 2; | ||
const candleRatio = props.candleRatio || 0.5; | ||
const defaultWidth = candleRatio * (data.length < 2 ? defaultCandleWidth : extent / candles); | ||
return Math.max(1, defaultWidth); | ||
} | ||
const getLowWickProps = (props, style) => { | ||
const { horizontal, low, open, close, x, id } = props; | ||
return { | ||
key: `${id}-lowWick`, | ||
style: Helpers.omit(style, ["width"]), | ||
x1: horizontal ? Math.min(open, close) : x, | ||
x2: horizontal ? low : x, | ||
y1: horizontal ? x : Math.max(open, close), | ||
y2: horizontal ? x : low | ||
}; | ||
}; | ||
getCandleProps(props, style) { | ||
const { id, x, close, open, horizontal } = props; | ||
const candleWidth = this.getCandleWidth(props, style); | ||
const candleLength = Math.abs(close - open); | ||
return { | ||
key: `${id}-candle`, | ||
style: Helpers.omit(style, ["width"]), | ||
x: horizontal ? Math.min(open, close) : x - candleWidth / 2, | ||
y: horizontal ? x - candleWidth / 2 : Math.min(open, close), | ||
width: horizontal ? candleLength : candleWidth, | ||
height: horizontal ? candleWidth : candleLength | ||
}; | ||
} | ||
const Candle = (props) => { | ||
const { | ||
events, | ||
groupComponent, | ||
clipPath, | ||
rectComponent, | ||
lineComponent, | ||
role, | ||
shapeRendering, | ||
className, | ||
wickStrokeWidth, | ||
transform | ||
} = props; | ||
const style = Helpers.evaluateStyle(assign({ stroke: "black" }, props.style), props); | ||
const wickStyle = defaults({ strokeWidth: wickStrokeWidth }, style); | ||
const sharedProps = { role, shapeRendering, className, transform, clipPath, ...events }; | ||
const candleProps = assign(getCandleProps(props, style), sharedProps); | ||
const highWickProps = assign(getHighWickProps(props, wickStyle), sharedProps); | ||
const lowWickProps = assign(getLowWickProps(props, wickStyle), sharedProps); | ||
getHighWickProps(props, style) { | ||
const { horizontal, high, open, close, x, id } = props; | ||
return { | ||
key: `${id}-highWick`, | ||
style: Helpers.omit(style, ["width"]), | ||
x1: horizontal ? high : x, | ||
x2: horizontal ? Math.max(open, close) : x, | ||
y1: horizontal ? x : high, | ||
y2: horizontal ? x : Math.min(open, close) | ||
}; | ||
} | ||
return React.cloneElement(groupComponent, {}, [ | ||
React.cloneElement(rectComponent, candleProps), | ||
React.cloneElement(lineComponent, highWickProps), | ||
React.cloneElement(lineComponent, lowWickProps) | ||
]); | ||
}; | ||
getLowWickProps(props, style) { | ||
const { horizontal, low, open, close, x, id } = props; | ||
return { | ||
key: `${id}-lowWick`, | ||
style: Helpers.omit(style, ["width"]), | ||
x1: horizontal ? Math.min(open, close) : x, | ||
x2: horizontal ? low : x, | ||
y1: horizontal ? x : Math.max(open, close), | ||
y2: horizontal ? x : low | ||
}; | ||
} | ||
Candle.propTypes = { | ||
...CommonProps.primitiveProps, | ||
candleRatio: PropTypes.number, | ||
candleWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.func]), | ||
close: PropTypes.number, | ||
datum: PropTypes.object, | ||
groupComponent: PropTypes.element, | ||
high: PropTypes.number, | ||
lineComponent: PropTypes.element, | ||
low: PropTypes.number, | ||
open: PropTypes.number, | ||
rectComponent: PropTypes.element, | ||
wickStrokeWidth: PropTypes.number, | ||
width: PropTypes.number, | ||
x: PropTypes.number | ||
}; | ||
render() { | ||
const { | ||
datum, | ||
active, | ||
events, | ||
groupComponent, | ||
clipPath, | ||
rectComponent, | ||
lineComponent, | ||
role, | ||
shapeRendering, | ||
className, | ||
wickStrokeWidth, | ||
transform | ||
} = this.props; | ||
const style = Helpers.evaluateStyle( | ||
assign({ stroke: "black" }, this.props.style), | ||
datum, | ||
active | ||
); | ||
const wickStyle = defaults({ strokeWidth: wickStrokeWidth }, style); | ||
const sharedProps = { role, shapeRendering, className, events, transform, clipPath }; | ||
const candleProps = assign(this.getCandleProps(this.props, style), sharedProps); | ||
const highWickProps = assign(this.getHighWickProps(this.props, wickStyle), sharedProps); | ||
const lowWickProps = assign(this.getLowWickProps(this.props, wickStyle), sharedProps); | ||
Candle.defaultProps = { | ||
groupComponent: <g />, | ||
lineComponent: <Line />, | ||
rectComponent: <Rect />, | ||
role: "presentation", | ||
shapeRendering: "auto" | ||
}; | ||
return React.cloneElement(groupComponent, {}, [ | ||
React.cloneElement(rectComponent, candleProps), | ||
React.cloneElement(lineComponent, highWickProps), | ||
React.cloneElement(lineComponent, lowWickProps) | ||
]); | ||
} | ||
} | ||
export default Candle; |
@@ -1,4 +0,6 @@ | ||
import { assign, isNil } from "lodash"; | ||
import { Helpers, LabelHelpers, Scale, Domain, Data } from "victory-core"; | ||
import { assign, defaults, isNil, isFunction, isPlainObject } from "lodash"; | ||
import { Helpers, Scale, Domain, Data, LabelHelpers } from "victory-core"; | ||
const TYPES = ["close", "open", "high", "low"]; | ||
const getData = (props) => { | ||
@@ -39,2 +41,36 @@ const accessorTypes = ["x", "high", "low", "close", "open"]; | ||
const getStyles = (style, defaultStyles = {}) => { | ||
const width = "100%"; | ||
const height = "100%"; | ||
if (!style) { | ||
return defaults( | ||
{ | ||
parent: { | ||
height, | ||
width | ||
} | ||
}, | ||
defaultStyles | ||
); | ||
} | ||
const defaultParent = defaultStyles.parent || {}; | ||
const defaultLabels = defaultStyles.labels || {}; | ||
const defaultData = defaultStyles.data || {}; | ||
const labelStyle = defaults({}, style.labels, defaultLabels); | ||
return { | ||
parent: defaults({}, style.parent, defaultParent, { | ||
width, | ||
height | ||
}), | ||
labels: labelStyle, | ||
data: defaults({}, style.data, defaultData), | ||
openLabels: defaults({}, style.openLabels, defaultStyles.openLabels, labelStyle), | ||
closeLabels: defaults({}, style.closeLabels, defaultStyles.closeLabels, labelStyle), | ||
lowLabels: defaults({}, style.lowLabels, defaultStyles.lowLabels, labelStyle), | ||
highLabels: defaults({}, style.highLabels, defaultStyles.highLabels, labelStyle) | ||
}; | ||
}; | ||
const getCalculatedValues = (props) => { | ||
@@ -44,3 +80,3 @@ const { theme, polar } = props; | ||
theme && theme.candlestick && theme.candlestick.style ? theme.candlestick.style : {}; | ||
const style = Helpers.getStyles(props.style, defaultStyle); | ||
const style = getStyles(props.style, defaultStyle); | ||
const data = getData(props); | ||
@@ -64,3 +100,5 @@ const range = { | ||
const origin = polar ? props.origin || Helpers.getPolarOrigin(props) : undefined; | ||
return { domain, data, scale, style, origin }; | ||
const defaultOrientation = props.horizontal ? "top" : "right"; | ||
const labelOrientation = props.labelOrientation || defaultOrientation; | ||
return { domain, data, scale, style, origin, labelOrientation }; | ||
}; | ||
@@ -82,13 +120,119 @@ | ||
const getLabelProps = (dataProps, text, style) => { | ||
const { x, high, index, scale, datum, data, horizontal } = dataProps; | ||
const labelStyle = style.labels || {}; | ||
const defaultAnchors = { | ||
vertical: horizontal ? "middle" : "end", | ||
text: horizontal ? "start" : "middle" | ||
const getText = (props, type) => { | ||
const { datum, index, labels } = props; | ||
const propName = `${type}Labels`; | ||
const labelProp = props[propName]; | ||
if (!labelProp && !labels) { | ||
return null; | ||
} else if (labelProp === true || labels === true) { | ||
const dataName = `_${type}`; | ||
return `${datum[dataName]}`; | ||
} | ||
return Array.isArray(labelProp) ? labelProp[index] : labelProp; | ||
}; | ||
const getCandleWidth = (props, style) => { | ||
const { data, candleWidth, scale, defaultCandleWidth } = props; | ||
if (candleWidth) { | ||
return isFunction(candleWidth) ? Helpers.evaluateProp(candleWidth, props) : candleWidth; | ||
} else if (style && style.width) { | ||
return style.width; | ||
} | ||
const range = scale.x.range(); | ||
const extent = Math.abs(range[1] - range[0]); | ||
const candles = data.length + 2; | ||
const candleRatio = props.candleRatio || 0.5; | ||
const defaultWidth = candleRatio * (data.length < 2 ? defaultCandleWidth : extent / candles); | ||
return Math.max(1, defaultWidth); | ||
}; | ||
const getOrientation = (labelOrientation, type = "labels") => { | ||
return isPlainObject(labelOrientation) ? labelOrientation[type] : labelOrientation; | ||
}; | ||
/* eslint-disable complexity*/ | ||
const calculatePlotValues = (props) => { | ||
const { positions, labelStyle, x, horizontal, computedType, candleWidth, orientation } = props; | ||
positions.labels = (positions.open + positions.close) / 2; | ||
const signX = orientation === "left" ? -1 : 1; | ||
const signY = orientation === "top" ? -1 : 1; | ||
if (horizontal) { | ||
const yValue = x; | ||
const xValue = positions[computedType]; | ||
const dy = | ||
orientation === "top" || orientation === "bottom" | ||
? signY * (candleWidth / 2) + signY * (labelStyle.padding || 0) | ||
: 0; | ||
const dx = | ||
orientation === "top" || orientation === "bottom" ? 0 : signX * (labelStyle.padding || 1); | ||
return { yValue, xValue, dx, dy }; | ||
} else { | ||
const xValue = x; | ||
const yValue = positions[computedType]; | ||
const dy = | ||
orientation === "top" || orientation === "bottom" ? signY * (labelStyle.padding || 1) : 0; | ||
const dx = | ||
orientation === "top" || orientation === "bottom" | ||
? 0 | ||
: signX * (candleWidth / 2) + signX * (labelStyle.padding || 0); | ||
return { yValue, xValue, dx, dy }; | ||
} | ||
}; | ||
/* eslint-enable complexity*/ | ||
/* eslint-disable max-params*/ | ||
const getLabelProps = (props, text, style, type) => { | ||
const { | ||
x, | ||
high, | ||
low, | ||
open, | ||
close, | ||
index, | ||
scale, | ||
datum, | ||
data, | ||
horizontal, | ||
candleWidth, | ||
labelOrientation | ||
} = props; | ||
const component = props[`${type}LabelComponent`] || props.labelComponent; | ||
const defaultOrientation = horizontal ? "top" : "right"; | ||
const orientation = | ||
(component.props && component.props.orientation) || | ||
getOrientation(labelOrientation, type) || | ||
defaultOrientation; | ||
const positions = { high, low, open, close }; | ||
const namespace = type ? `${type}Labels` : "labels"; | ||
const labelStyle = style[namespace] || style.labels; | ||
const defaultVerticalAnchors = { top: "end", bottom: "start", left: "middle", right: "middle" }; | ||
const defaultTextAnchors = { left: "end", right: "start", top: "middle", bottom: "middle" }; | ||
const computedType = type ? type : "labels"; | ||
const plotProps = { | ||
positions, | ||
labelStyle, | ||
x, | ||
horizontal, | ||
computedType, | ||
candleWidth, | ||
orientation | ||
}; | ||
const { yValue, xValue, dx, dy } = calculatePlotValues(plotProps); | ||
return { | ||
style: labelStyle, | ||
y: horizontal ? x : high - (labelStyle.padding || 0), | ||
x: horizontal ? high + (labelStyle.padding || 0) : x, | ||
y: yValue, | ||
x: xValue, | ||
dx, | ||
dy, | ||
text, | ||
@@ -99,4 +243,5 @@ index, | ||
data, | ||
textAnchor: labelStyle.textAnchor || defaultAnchors.text, | ||
verticalAnchor: labelStyle.verticalAnchor || defaultAnchors.vertical, | ||
orientation, | ||
textAnchor: labelStyle.textAnchor || defaultTextAnchors[orientation], | ||
verticalAnchor: labelStyle.verticalAnchor || defaultVerticalAnchors[orientation], | ||
angle: labelStyle.angle, | ||
@@ -106,2 +251,3 @@ horizontal | ||
}; | ||
/* eslint-enable max-params*/ | ||
@@ -112,3 +258,3 @@ const getBaseProps = (props, fallbackProps) => { | ||
const calculatedValues = getCalculatedValues(props); | ||
const { data, style, scale, domain, origin } = calculatedValues; | ||
const { data, style, scale, domain, origin, labelOrientation } = calculatedValues; | ||
const { | ||
@@ -175,4 +321,7 @@ groupComponent, | ||
close, | ||
horizontal | ||
horizontal, | ||
labelOrientation | ||
}; | ||
dataProps.candleWidth = getCandleWidth(dataProps); | ||
const extendedProps = defaults(Object.assign({}, dataProps), props); | ||
@@ -182,7 +331,22 @@ childProps[eventKey] = { | ||
}; | ||
const text = LabelHelpers.getText(props, datum, index); | ||
if ((text !== undefined && text !== null) || (labels && (events || sharedEvents))) { | ||
childProps[eventKey].labels = getLabelProps(dataProps, text, style); | ||
if (labels) { | ||
const text = LabelHelpers.getText(props, datum, index); | ||
if ((text !== undefined && text !== null) || (labels && (events || sharedEvents))) { | ||
childProps[eventKey].labels = getLabelProps(extendedProps, text, style); | ||
} | ||
} | ||
TYPES.forEach((type) => { | ||
const labelText = getText(extendedProps, type); | ||
const labelProp = props.labels || props[`${type}Labels`]; | ||
if ( | ||
(labelText !== null && labelText !== undefined) || | ||
(labelProp && (events || sharedEvents)) | ||
) { | ||
const target = `${type}Labels`; | ||
childProps[eventKey][target] = getLabelProps(extendedProps, labelText, style, type); | ||
} | ||
}); | ||
return childProps; | ||
@@ -189,0 +353,0 @@ }, initialChildProps); |
@@ -13,3 +13,3 @@ import PropTypes from "prop-types"; | ||
} from "victory-core"; | ||
import { isNil } from "lodash"; | ||
import { isNil, flatten } from "lodash"; | ||
import Candle from "./candle"; | ||
@@ -29,2 +29,14 @@ import { getDomain, getData, getBaseProps } from "./helper-methods"; | ||
const options = { | ||
components: [ | ||
{ name: "lowLabels" }, | ||
{ name: "highLabels" }, | ||
{ name: "openLabels" }, | ||
{ name: "closeLabels" }, | ||
{ name: "labels" }, | ||
{ name: "data" }, | ||
{ name: "parent", index: "parent" } | ||
] | ||
}; | ||
const defaultData = [ | ||
@@ -41,2 +53,5 @@ { x: new Date(2016, 6, 1), open: 5, close: 10, high: 15, low: 0 }, | ||
/*eslint-enable no-magic-numbers */ | ||
const datumHasXandY = (datum) => { | ||
return !isNil(datum._x) && !isNil(datum._y); | ||
}; | ||
@@ -71,2 +86,26 @@ class VictoryCandlestick extends React.Component { | ||
]), | ||
closeLabelComponent: PropTypes.element, | ||
closeLabels: PropTypes.oneOfType([PropTypes.func, PropTypes.array, PropTypes.bool]), | ||
events: PropTypes.arrayOf( | ||
PropTypes.shape({ | ||
target: PropTypes.oneOf([ | ||
"data", | ||
"labels", | ||
"open", | ||
"openLabels", | ||
"close", | ||
"closeLabels", | ||
"low", | ||
"lowLabels", | ||
"high", | ||
"highLabels" | ||
]), | ||
eventKey: PropTypes.oneOfType([ | ||
PropTypes.array, | ||
CustomPropTypes.allOfType([CustomPropTypes.integer, CustomPropTypes.nonNegative]), | ||
PropTypes.string | ||
]), | ||
eventHandlers: PropTypes.object | ||
}) | ||
), | ||
high: PropTypes.oneOfType([ | ||
@@ -78,2 +117,13 @@ PropTypes.func, | ||
]), | ||
highLabelComponent: PropTypes.element, | ||
highLabels: PropTypes.oneOfType([PropTypes.func, PropTypes.array, PropTypes.bool]), | ||
labelOrientation: PropTypes.oneOfType([ | ||
PropTypes.oneOf(["top", "bottom", "left", "right"]), | ||
PropTypes.shape({ | ||
open: PropTypes.oneOf(["top", "bottom", "left", "right"]), | ||
close: PropTypes.oneOf(["top", "bottom", "left", "right"]), | ||
low: PropTypes.oneOf(["top", "bottom", "left", "right"]), | ||
high: PropTypes.oneOf(["top", "bottom", "left", "right"]) | ||
}) | ||
]), | ||
low: PropTypes.oneOfType([ | ||
@@ -85,2 +135,4 @@ PropTypes.func, | ||
]), | ||
lowLabelComponent: PropTypes.element, | ||
lowLabels: PropTypes.oneOfType([PropTypes.func, PropTypes.array, PropTypes.bool]), | ||
open: PropTypes.oneOfType([ | ||
@@ -92,2 +144,16 @@ PropTypes.func, | ||
]), | ||
openLabelComponent: PropTypes.element, | ||
openLabels: PropTypes.oneOfType([PropTypes.func, PropTypes.array, PropTypes.bool]), | ||
style: PropTypes.shape({ | ||
data: PropTypes.object, | ||
labels: PropTypes.object, | ||
close: PropTypes.object, | ||
closeLabels: PropTypes.object, | ||
open: PropTypes.object, | ||
openLabels: PropTypes.object, | ||
high: PropTypes.object, | ||
highLabels: PropTypes.object, | ||
low: PropTypes.object, | ||
lowLabels: PropTypes.object | ||
}), | ||
wickStrokeWidth: PropTypes.number | ||
@@ -97,2 +163,3 @@ }; | ||
static defaultProps = { | ||
defaultCandleWidth: 8, | ||
containerComponent: <VictoryContainer />, | ||
@@ -103,2 +170,6 @@ data: defaultData, | ||
labelComponent: <VictoryLabel />, | ||
highLabelComponent: <VictoryLabel />, | ||
lowLabelComponent: <VictoryLabel />, | ||
openLabelComponent: <VictoryLabel />, | ||
closeLabelComponent: <VictoryLabel />, | ||
samples: 50, | ||
@@ -114,2 +185,6 @@ sortOrder: "ascending", | ||
static expectedComponents = [ | ||
"openLabelComponent", | ||
"closeLabelComponent", | ||
"highLabelComponent", | ||
"lowLabelComponent", | ||
"dataComponent", | ||
@@ -136,2 +211,43 @@ "labelComponent", | ||
renderCandleData(props, shouldRenderDatum = datumHasXandY) { | ||
const { dataComponent, labelComponent, groupComponent } = props; | ||
const types = ["close", "open", "low", "high"]; | ||
const dataComponents = this.dataKeys.reduce((validDataComponents, _dataKey, index) => { | ||
const dataProps = this.getComponentProps(dataComponent, "data", index); | ||
if (shouldRenderDatum(dataProps.datum)) { | ||
validDataComponents.push(React.cloneElement(dataComponent, dataProps)); | ||
} | ||
return validDataComponents; | ||
}, []); | ||
const labelComponents = flatten( | ||
types.map((type) => { | ||
const components = this.dataKeys.map((key, index) => { | ||
const name = `${type}Labels`; | ||
const baseComponent = props[`${type}LabelComponent`]; | ||
const labelProps = this.getComponentProps(baseComponent, name, index); | ||
if (labelProps.text !== undefined && labelProps.text !== null) { | ||
return React.cloneElement(baseComponent, labelProps); | ||
} | ||
return undefined; | ||
}); | ||
return components.filter(Boolean); | ||
}) | ||
); | ||
const labelsComponents = this.dataKeys | ||
.map((_dataKey, index) => { | ||
const labelProps = this.getComponentProps(labelComponent, "labels", index); | ||
if (labelProps.text !== undefined && labelProps.text !== null) { | ||
return React.cloneElement(labelComponent, labelProps); | ||
} | ||
return undefined; | ||
}) | ||
.filter(Boolean); | ||
const children = [...dataComponents, ...labelComponents, ...labelsComponents]; | ||
return this.renderContainer(groupComponent, children); | ||
} | ||
render() { | ||
@@ -145,3 +261,3 @@ const { animationWhitelist, role } = VictoryCandlestick; | ||
const children = this.renderData(props, this.shouldRenderDatum); | ||
const children = this.renderCandleData(props, this.shouldRenderDatum); | ||
return props.standalone ? this.renderContainer(props.containerComponent, children) : children; | ||
@@ -151,2 +267,2 @@ } | ||
export default addEvents(VictoryCandlestick); | ||
export default addEvents(VictoryCandlestick, options); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
22777
1206342
+ Addedvictory-core@33.1.7(transitive)
- Removedvictory-core@32.3.7(transitive)
Updatedvictory-core@^33.0.0