ct-react-stockcharts
Version:
Highly customizable stock charts with ReactJS and d3
1,418 lines (1,211 loc) • 49.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
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; };
/* eslint-disable no-unused-vars */
/* eslint-enable no-unused-vars */
var _react = require("react");
var _react2 = _interopRequireDefault(_react);
var _propTypes = require("prop-types");
var _propTypes2 = _interopRequireDefault(_propTypes);
var _d3Array = require("d3-array");
var _utils = require("./utils");
var _zoomBehavior = require("./utils/zoomBehavior");
var _ChartDataUtil = require("./utils/ChartDataUtil");
var _EventCapture = require("./EventCapture");
var _EventCapture2 = _interopRequireDefault(_EventCapture);
var _CanvasContainer = require("./CanvasContainer");
var _CanvasContainer2 = _interopRequireDefault(_CanvasContainer);
var _evaluator2 = require("./scale/evaluator");
var _evaluator3 = _interopRequireDefault(_evaluator2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
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 log = (0, _utils.getLogger)("ChartCanvas");
var CANDIDATES_FOR_RESET = ["seriesName"];
function shouldResetChart(thisProps, nextProps) {
return !CANDIDATES_FOR_RESET.every(function (key) {
var result = (0, _utils.shallowEqual)(thisProps[key], nextProps[key]);
// console.log(key, result);
return result;
});
}
function getCursorStyle() {
var tooltipStyle = "\n\t.react-stockcharts-grabbing-cursor {\n\t\tpointer-events: all;\n\t\tcursor: -moz-grabbing;\n\t\tcursor: -webkit-grabbing;\n\t\tcursor: grabbing;\n\t}\n\t.react-stockcharts-crosshair-cursor {\n\t\tpointer-events: all;\n\t\tcursor: crosshair;\n\t}\n\t.react-stockcharts-tooltip-hover {\n\t\tpointer-events: all;\n\t\tcursor: pointer;\n\t}\n\t.react-stockcharts-avoid-interaction {\n\t\tpointer-events: none;\n\t}\n\t.react-stockcharts-enable-interaction {\n\t\tpointer-events: all;\n\t}\n\t.react-stockcharts-tooltip {\n\t\tpointer-events: all;\n\t\tcursor: pointer;\n\t}\n\t.react-stockcharts-default-cursor {\n\t\tcursor: default;\n\t}\n\t.react-stockcharts-move-cursor {\n\t\tcursor: move;\n\t}\n\t.react-stockcharts-pointer-cursor {\n\t\tcursor: pointer;\n\t}\n\t.react-stockcharts-ns-resize-cursor {\n\t\tcursor: ns-resize;\n\t}\n\t.react-stockcharts-ew-resize-cursor {\n\t\tcursor: ew-resize;\n\t}";
return _react2.default.createElement(
"style",
{ type: "text/css" },
tooltipStyle
);
}
function getDimensions(props) {
return {
height: props.height - props.margin.top - props.margin.bottom,
width: props.width - props.margin.left - props.margin.right
};
}
function getXScaleDirection(flipXScale) {
return flipXScale ? -1 : 1;
}
function calculateFullData(props) {
var fullData = props.data,
plotFull = props.plotFull,
xScale = props.xScale,
clamp = props.clamp,
pointsPerPxThreshold = props.pointsPerPxThreshold,
flipXScale = props.flipXScale;
var xAccessor = props.xAccessor,
displayXAccessor = props.displayXAccessor,
minPointsPerPxThreshold = props.minPointsPerPxThreshold;
var useWholeData = (0, _utils.isDefined)(plotFull) ? plotFull : xAccessor === _utils.identity;
var _evaluator = (0, _evaluator3.default)({
xScale: xScale,
useWholeData: useWholeData,
clamp: clamp,
pointsPerPxThreshold: pointsPerPxThreshold,
minPointsPerPxThreshold: minPointsPerPxThreshold,
flipXScale: flipXScale
}),
filterData = _evaluator.filterData;
return {
xAccessor: xAccessor,
displayXAccessor: displayXAccessor || xAccessor,
xScale: xScale.copy(),
fullData: fullData,
filterData: filterData
};
}
function resetChart(props) {
var firstCalculation = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (process.env.NODE_ENV !== "production") {
if (!firstCalculation) log("CHART RESET");
}
var state = calculateState(props);
var xAccessor = state.xAccessor,
displayXAccessor = state.displayXAccessor,
fullData = state.fullData;
var initialPlotData = state.plotData,
xScale = state.xScale;
var postCalculator = props.postCalculator,
children = props.children;
var plotData = postCalculator(initialPlotData);
var dimensions = getDimensions(props);
var chartConfig = (0, _ChartDataUtil.getChartConfigWithUpdatedYScales)((0, _ChartDataUtil.getNewChartConfig)(dimensions, children), { plotData: plotData, xAccessor: xAccessor, displayXAccessor: displayXAccessor, fullData: fullData }, xScale.domain());
return _extends({}, state, {
xScale: xScale,
plotData: plotData,
chartConfig: chartConfig
});
}
function updateChart(newState, initialXScale, props, lastItemWasVisible, initialChartConfig) {
var fullData = newState.fullData,
xScale = newState.xScale,
xAccessor = newState.xAccessor,
displayXAccessor = newState.displayXAccessor,
filterData = newState.filterData;
var lastItem = (0, _utils.last)(fullData);
var _initialXScale$domain = initialXScale.domain(),
_initialXScale$domain2 = _slicedToArray(_initialXScale$domain, 2),
start = _initialXScale$domain2[0],
end = _initialXScale$domain2[1];
if (process.env.NODE_ENV !== "production") {
log("TRIVIAL CHANGE");
}
var postCalculator = props.postCalculator,
children = props.children,
padding = props.padding,
flipXScale = props.flipXScale;
var maintainPointsPerPixelOnResize = props.maintainPointsPerPixelOnResize;
var direction = getXScaleDirection(flipXScale);
var dimensions = getDimensions(props);
var updatedXScale = setXRange(xScale, dimensions, padding, direction);
// console.log("lastItemWasVisible =", lastItemWasVisible, end, xAccessor(lastItem), end >= xAccessor(lastItem));
var initialPlotData = void 0;
if (!lastItemWasVisible || end >= xAccessor(lastItem)) {
// resize comes here...
var _initialXScale$range = initialXScale.range(),
_initialXScale$range2 = _slicedToArray(_initialXScale$range, 2),
rangeStart = _initialXScale$range2[0],
rangeEnd = _initialXScale$range2[1];
var _updatedXScale$range = updatedXScale.range(),
_updatedXScale$range2 = _slicedToArray(_updatedXScale$range, 2),
newRangeStart = _updatedXScale$range2[0],
newRangeEnd = _updatedXScale$range2[1];
var newDomainExtent = (newRangeEnd - newRangeStart) / (rangeEnd - rangeStart) * (end - start);
var newStart = maintainPointsPerPixelOnResize ? end - newDomainExtent : start;
var lastItemX = initialXScale(xAccessor(lastItem));
// console.log("pointsPerPixel => ", newStart, start, end, updatedXScale(end));
var response = filterData(fullData, [newStart, end], xAccessor, updatedXScale, { fallbackStart: start, fallbackEnd: { lastItem: lastItem, lastItemX: lastItemX } });
initialPlotData = response.plotData;
updatedXScale.domain(response.domain);
// console.log("HERE!!!!!", start, end);
} else if (lastItemWasVisible && end < xAccessor(lastItem)) {
// this is when a new item is added and last item was visible
// so slide over and show the new item also
// get plotData between [xAccessor(l) - (end - start), xAccessor(l)] and DO change the domain
var dx = initialXScale(xAccessor(lastItem)) - initialXScale.range()[1];
var _initialXScale$range$ = initialXScale.range().map(function (x) {
return x + dx;
}).map(initialXScale.invert),
_initialXScale$range$2 = _slicedToArray(_initialXScale$range$, 2),
_newStart = _initialXScale$range$2[0],
newEnd = _initialXScale$range$2[1];
var _response = filterData(fullData, [_newStart, newEnd], xAccessor, updatedXScale);
initialPlotData = _response.plotData;
updatedXScale.domain(_response.domain); // if last item was visible, then shift
}
// plotData = getDataOfLength(fullData, showingInterval, plotData.length)
var plotData = postCalculator(initialPlotData);
var chartConfig = (0, _ChartDataUtil.getChartConfigWithUpdatedYScales)((0, _ChartDataUtil.getNewChartConfig)(dimensions, children, initialChartConfig), { plotData: plotData, xAccessor: xAccessor, displayXAccessor: displayXAccessor, fullData: fullData }, updatedXScale.domain());
return {
xScale: updatedXScale,
xAccessor: xAccessor,
chartConfig: chartConfig,
plotData: plotData,
fullData: fullData,
filterData: filterData
};
}
function calculateState(props) {
var inputXAccesor = props.xAccessor,
xExtentsProp = props.xExtents,
data = props.data,
padding = props.padding,
flipXScale = props.flipXScale;
if (process.env.NODE_ENV !== "production" && (0, _utils.isDefined)(props.xScale.invert)) {
for (var i = 1; i < data.length; i++) {
var prev = data[i - 1];
var curr = data[i];
if (inputXAccesor(prev) > inputXAccesor(curr)) {
throw new Error("'data' is not sorted on 'xAccessor', send 'data' sorted in ascending order of 'xAccessor'");
}
}
}
var direction = getXScaleDirection(flipXScale);
var dimensions = getDimensions(props);
var extent = typeof xExtentsProp === "function" ? xExtentsProp(data) : (0, _d3Array.extent)(xExtentsProp.map(function (d) {
return (0, _utils.functor)(d);
}).map(function (each) {
return each(data, inputXAccesor);
}));
var _calculateFullData = calculateFullData(props),
xAccessor = _calculateFullData.xAccessor,
displayXAccessor = _calculateFullData.displayXAccessor,
xScale = _calculateFullData.xScale,
fullData = _calculateFullData.fullData,
filterData = _calculateFullData.filterData;
var updatedXScale = setXRange(xScale, dimensions, padding, direction);
var _filterData = filterData(fullData, extent, inputXAccesor, updatedXScale),
plotData = _filterData.plotData,
domain = _filterData.domain;
if (process.env.NODE_ENV !== "production" && plotData.length <= 1) {
throw new Error("Showing " + plotData.length + " datapoints, review the 'xExtents' prop of ChartCanvas");
}
return {
plotData: plotData,
xScale: updatedXScale.domain(domain),
xAccessor: xAccessor,
displayXAccessor: displayXAccessor,
fullData: fullData,
filterData: filterData
};
}
function setXRange(xScale, dimensions, padding) {
var direction = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
if (xScale.rangeRoundPoints) {
if (isNaN(padding)) throw new Error("padding has to be a number for ordinal scale");
xScale.rangeRoundPoints([0, dimensions.width], padding);
} else if (xScale.padding) {
if (isNaN(padding)) throw new Error("padding has to be a number for ordinal scale");
xScale.range([0, dimensions.width]);
xScale.padding(padding / 2);
} else {
var _ref = isNaN(padding) ? padding : { left: padding, right: padding },
left = _ref.left,
right = _ref.right;
if (direction > 0) {
xScale.range([left, dimensions.width - right]);
} else {
xScale.range([dimensions.width - right, left]);
}
}
return xScale;
}
function pinchCoordinates(pinch) {
var touch1Pos = pinch.touch1Pos,
touch2Pos = pinch.touch2Pos;
return {
topLeft: [Math.min(touch1Pos[0], touch2Pos[0]), Math.min(touch1Pos[1], touch2Pos[1])],
bottomRight: [Math.max(touch1Pos[0], touch2Pos[0]), Math.max(touch1Pos[1], touch2Pos[1])]
};
}
var ChartCanvas = function (_Component) {
_inherits(ChartCanvas, _Component);
function ChartCanvas() {
_classCallCheck(this, ChartCanvas);
var _this = _possibleConstructorReturn(this, (ChartCanvas.__proto__ || Object.getPrototypeOf(ChartCanvas)).call(this));
_this.getDataInfo = _this.getDataInfo.bind(_this);
_this.getCanvasContexts = _this.getCanvasContexts.bind(_this);
_this.handleMouseMove = _this.handleMouseMove.bind(_this);
_this.handleMouseEnter = _this.handleMouseEnter.bind(_this);
_this.handleMouseLeave = _this.handleMouseLeave.bind(_this);
_this.handleZoom = _this.handleZoom.bind(_this);
_this.handlePinchZoom = _this.handlePinchZoom.bind(_this);
_this.handlePinchZoomEnd = _this.handlePinchZoomEnd.bind(_this);
_this.handlePan = _this.handlePan.bind(_this);
_this.handlePanEnd = _this.handlePanEnd.bind(_this);
_this.handleClick = _this.handleClick.bind(_this);
_this.handleMouseDown = _this.handleMouseDown.bind(_this);
_this.handleDoubleClick = _this.handleDoubleClick.bind(_this);
_this.handleContextMenu = _this.handleContextMenu.bind(_this);
_this.handleDragStart = _this.handleDragStart.bind(_this);
_this.handleDrag = _this.handleDrag.bind(_this);
_this.handleDragEnd = _this.handleDragEnd.bind(_this);
_this.panHelper = _this.panHelper.bind(_this);
_this.pinchZoomHelper = _this.pinchZoomHelper.bind(_this);
_this.xAxisZoom = _this.xAxisZoom.bind(_this);
_this.yAxisZoom = _this.yAxisZoom.bind(_this);
_this.resetYDomain = _this.resetYDomain.bind(_this);
_this.calculateStateForDomain = _this.calculateStateForDomain.bind(_this);
_this.generateSubscriptionId = _this.generateSubscriptionId.bind(_this);
_this.draw = _this.draw.bind(_this);
_this.redraw = _this.redraw.bind(_this);
_this.getAllPanConditions = _this.getAllPanConditions.bind(_this);
_this.subscriptions = [];
_this.subscribe = _this.subscribe.bind(_this);
_this.unsubscribe = _this.unsubscribe.bind(_this);
_this.amIOnTop = _this.amIOnTop.bind(_this);
_this.saveEventCaptureNode = _this.saveEventCaptureNode.bind(_this);
_this.saveCanvasContainerNode = _this.saveCanvasContainerNode.bind(_this);
_this.setCursorClass = _this.setCursorClass.bind(_this);
_this.getMutableState = _this.getMutableState.bind(_this);
// this.canvasDrawCallbackList = [];
_this.interactiveState = [];
_this.panInProgress = false;
_this.state = {};
_this.mutableState = {};
_this.lastSubscriptionId = 0;
return _this;
}
_createClass(ChartCanvas, [{
key: "saveEventCaptureNode",
value: function saveEventCaptureNode(node) {
this.eventCaptureNode = node;
}
}, {
key: "saveCanvasContainerNode",
value: function saveCanvasContainerNode(node) {
this.canvasContainerNode = node;
}
}, {
key: "getMutableState",
value: function getMutableState() {
return this.mutableState;
}
}, {
key: "getDataInfo",
value: function getDataInfo() {
return _extends({}, this.state, {
fullData: this.fullData
});
}
}, {
key: "getCanvasContexts",
value: function getCanvasContexts() {
if (this.canvasContainerNode) {
return this.canvasContainerNode.getCanvasContexts();
}
}
}, {
key: "generateSubscriptionId",
value: function generateSubscriptionId() {
this.lastSubscriptionId++;
return this.lastSubscriptionId;
}
}, {
key: "clearBothCanvas",
value: function clearBothCanvas() {
var canvases = this.getCanvasContexts();
if (canvases && canvases.axes) {
(0, _utils.clearCanvas)([canvases.axes,
// canvases.hover,
canvases.mouseCoord], this.props.ratio);
}
}
}, {
key: "clearMouseCanvas",
value: function clearMouseCanvas() {
var canvases = this.getCanvasContexts();
if (canvases && canvases.mouseCoord) {
(0, _utils.clearCanvas)([canvases.mouseCoord], this.props.ratio);
}
}
}, {
key: "clearThreeCanvas",
value: function clearThreeCanvas() {
var canvases = this.getCanvasContexts();
if (canvases && canvases.axes) {
(0, _utils.clearCanvas)([canvases.axes,
// canvases.hover,
canvases.mouseCoord, canvases.bg], this.props.ratio);
}
}
}, {
key: "subscribe",
value: function subscribe(id, rest) {
var _rest$getPanCondition = rest.getPanConditions,
getPanConditions = _rest$getPanCondition === undefined ? (0, _utils.functor)({
draggable: false,
panEnabled: true
}) : _rest$getPanCondition;
this.subscriptions = this.subscriptions.concat(_extends({
id: id
}, rest, {
getPanConditions: getPanConditions
}));
}
}, {
key: "unsubscribe",
value: function unsubscribe(id) {
this.subscriptions = this.subscriptions.filter(function (each) {
return each.id !== id;
});
}
}, {
key: "getAllPanConditions",
value: function getAllPanConditions() {
return this.subscriptions.map(function (each) {
return each.getPanConditions();
});
}
}, {
key: "setCursorClass",
value: function setCursorClass(className) {
if (this.eventCaptureNode != null) {
this.eventCaptureNode.setCursorClass(className);
}
}
}, {
key: "amIOnTop",
value: function amIOnTop(id) {
var dragableComponents = this.subscriptions.filter(function (each) {
return each.getPanConditions().draggable;
});
return dragableComponents.length > 0 && (0, _utils.last)(dragableComponents).id === id;
}
}, {
key: "handleContextMenu",
value: function handleContextMenu(mouseXY, e) {
var _state = this.state,
xAccessor = _state.xAccessor,
chartConfig = _state.chartConfig,
plotData = _state.plotData,
xScale = _state.xScale;
var currentCharts = (0, _ChartDataUtil.getCurrentCharts)(chartConfig, mouseXY);
var currentItem = (0, _ChartDataUtil.getCurrentItem)(xScale, xAccessor, mouseXY, plotData);
this.triggerEvent("contextmenu", {
mouseXY: mouseXY,
currentItem: currentItem,
currentCharts: currentCharts
}, e);
}
}, {
key: "calculateStateForDomain",
value: function calculateStateForDomain(newDomain) {
var _state2 = this.state,
xAccessor = _state2.xAccessor,
displayXAccessor = _state2.displayXAccessor,
initialXScale = _state2.xScale,
initialChartConfig = _state2.chartConfig,
initialPlotData = _state2.plotData;
var filterData = this.state.filterData;
var fullData = this.fullData;
var postCalculator = this.props.postCalculator;
var _filterData2 = filterData(fullData, newDomain, xAccessor, initialXScale, {
currentPlotData: initialPlotData,
currentDomain: initialXScale.domain()
}),
beforePlotData = _filterData2.plotData,
domain = _filterData2.domain;
var plotData = postCalculator(beforePlotData);
var updatedScale = initialXScale.copy().domain(domain);
var chartConfig = (0, _ChartDataUtil.getChartConfigWithUpdatedYScales)(initialChartConfig, { plotData: plotData, xAccessor: xAccessor, displayXAccessor: displayXAccessor, fullData: fullData }, updatedScale.domain());
return {
xScale: updatedScale,
plotData: plotData,
chartConfig: chartConfig
};
}
}, {
key: "pinchZoomHelper",
value: function pinchZoomHelper(initialPinch, finalPinch) {
var initialPinchXScale = initialPinch.xScale;
var _state3 = this.state,
initialXScale = _state3.xScale,
initialChartConfig = _state3.chartConfig,
initialPlotData = _state3.plotData,
xAccessor = _state3.xAccessor,
displayXAccessor = _state3.displayXAccessor;
var filterData = this.state.filterData;
var fullData = this.fullData;
var postCalculator = this.props.postCalculator;
var _pinchCoordinates = pinchCoordinates(initialPinch),
iTL = _pinchCoordinates.topLeft,
iBR = _pinchCoordinates.bottomRight;
var _pinchCoordinates2 = pinchCoordinates(finalPinch),
fTL = _pinchCoordinates2.topLeft,
fBR = _pinchCoordinates2.bottomRight;
var e = initialPinchXScale.range()[1];
var xDash = Math.round(-(iBR[0] * fTL[0] - iTL[0] * fBR[0]) / (iTL[0] - iBR[0]));
var yDash = Math.round(e + ((e - iBR[0]) * (e - fTL[0]) - (e - iTL[0]) * (e - fBR[0])) / (e - iTL[0] - (e - iBR[0])));
var x = Math.round(-xDash * iTL[0] / (-xDash + fTL[0]));
var y = Math.round(e - (yDash - e) * (e - iTL[0]) / (yDash + (e - fTL[0])));
var newDomain = [x, y].map(initialPinchXScale.invert);
// var domainR = initial.right + right;
var _filterData3 = filterData(fullData, newDomain, xAccessor, initialPinchXScale, {
currentPlotData: initialPlotData,
currentDomain: initialXScale.domain()
}),
beforePlotData = _filterData3.plotData,
domain = _filterData3.domain;
var plotData = postCalculator(beforePlotData);
var updatedScale = initialXScale.copy().domain(domain);
var mouseXY = finalPinch.touch1Pos;
var chartConfig = (0, _ChartDataUtil.getChartConfigWithUpdatedYScales)(initialChartConfig, { plotData: plotData, xAccessor: xAccessor, displayXAccessor: displayXAccessor, fullData: fullData }, updatedScale.domain());
var currentItem = (0, _ChartDataUtil.getCurrentItem)(updatedScale, xAccessor, mouseXY, plotData);
return {
chartConfig: chartConfig,
xScale: updatedScale,
plotData: plotData,
mouseXY: mouseXY,
currentItem: currentItem
};
}
}, {
key: "cancelDrag",
value: function cancelDrag() {
this.eventCaptureNode.cancelDrag();
this.triggerEvent("dragcancel");
}
}, {
key: "handlePinchZoom",
value: function handlePinchZoom(initialPinch, finalPinch, e) {
var _this2 = this;
if (!this.waitingForPinchZoomAnimationFrame) {
this.waitingForPinchZoomAnimationFrame = true;
var state = this.pinchZoomHelper(initialPinch, finalPinch);
this.triggerEvent("pinchzoom", state, e);
this.finalPinch = finalPinch;
requestAnimationFrame(function () {
_this2.clearBothCanvas();
_this2.draw({ trigger: "pinchzoom" });
_this2.waitingForPinchZoomAnimationFrame = false;
});
}
}
}, {
key: "handlePinchZoomEnd",
value: function handlePinchZoomEnd(initialPinch, e) {
var xAccessor = this.state.xAccessor;
if (this.finalPinch) {
var state = this.pinchZoomHelper(initialPinch, this.finalPinch);
var xScale = state.xScale;
this.triggerEvent("pinchzoom", state, e);
this.finalPinch = null;
this.clearThreeCanvas();
var fullData = this.fullData;
var firstItem = (0, _utils.head)(fullData);
var start = (0, _utils.head)(xScale.domain());
var end = xAccessor(firstItem);
var onLoadMore = this.props.onLoadMore;
this.setState(state, function () {
if (start < end) {
onLoadMore(start, end);
}
});
}
}
}, {
key: "handleZoom",
value: function handleZoom(zoomDirection, mouseXY, e) {
if (this.panInProgress) return;
// console.log("zoomDirection ", zoomDirection, " mouseXY ", mouseXY);
var _state4 = this.state,
xAccessor = _state4.xAccessor,
initialXScale = _state4.xScale,
initialPlotData = _state4.plotData;
var _props = this.props,
zoomMultiplier = _props.zoomMultiplier,
zoomAnchor = _props.zoomAnchor;
var fullData = this.fullData;
var item = zoomAnchor({
xScale: initialXScale,
xAccessor: xAccessor,
mouseXY: mouseXY,
plotData: initialPlotData,
fullData: fullData
});
var cx = initialXScale(item);
var c = zoomDirection > 0 ? 1 * zoomMultiplier : 1 / zoomMultiplier;
var newDomain = initialXScale.range().map(function (x) {
return cx + (x - cx) * c;
}).map(initialXScale.invert);
var _calculateStateForDom = this.calculateStateForDomain(newDomain),
xScale = _calculateStateForDom.xScale,
plotData = _calculateStateForDom.plotData,
chartConfig = _calculateStateForDom.chartConfig;
var currentItem = (0, _ChartDataUtil.getCurrentItem)(xScale, xAccessor, mouseXY, plotData);
var currentCharts = (0, _ChartDataUtil.getCurrentCharts)(chartConfig, mouseXY);
this.clearThreeCanvas();
var firstItem = (0, _utils.head)(fullData);
var start = (0, _utils.head)(xScale.domain());
var end = xAccessor(firstItem);
var onLoadMore = this.props.onLoadMore;
this.mutableState = {
mouseXY: mouseXY,
currentItem: currentItem,
currentCharts: currentCharts
};
this.triggerEvent("zoom", {
xScale: xScale,
plotData: plotData,
chartConfig: chartConfig,
mouseXY: mouseXY,
currentCharts: currentCharts,
currentItem: currentItem,
show: true
}, e);
this.setState({
xScale: xScale,
plotData: plotData,
chartConfig: chartConfig
}, function () {
if (start < end) {
onLoadMore(start, end);
}
});
}
}, {
key: "xAxisZoom",
value: function xAxisZoom(newDomain) {
var _calculateStateForDom2 = this.calculateStateForDomain(newDomain),
xScale = _calculateStateForDom2.xScale,
plotData = _calculateStateForDom2.plotData,
chartConfig = _calculateStateForDom2.chartConfig;
this.clearThreeCanvas();
var xAccessor = this.state.xAccessor;
var fullData = this.fullData;
var firstItem = (0, _utils.head)(fullData);
var start = (0, _utils.head)(xScale.domain());
var end = xAccessor(firstItem);
var onLoadMore = this.props.onLoadMore;
this.setState({
xScale: xScale,
plotData: plotData,
chartConfig: chartConfig
}, function () {
if (start < end) onLoadMore(start, end);
});
}
}, {
key: "yAxisZoom",
value: function yAxisZoom(chartId, newDomain) {
this.clearThreeCanvas();
var initialChartConfig = this.state.chartConfig;
var chartConfig = initialChartConfig.map(function (each) {
if (each.id === chartId) {
var yScale = each.yScale;
return _extends({}, each, {
yScale: yScale.copy().domain(newDomain),
yPanEnabled: true
});
} else {
return each;
}
});
this.setState({
chartConfig: chartConfig
});
}
}, {
key: "triggerEvent",
value: function triggerEvent(type, props, e) {
var _this3 = this;
// console.log("triggering ->", type);
this.subscriptions.forEach(function (each) {
var state = _extends({}, _this3.state, {
fullData: _this3.fullData,
subscriptions: _this3.subscriptions
});
each.listener(type, props, state, e);
});
}
}, {
key: "draw",
value: function draw(props) {
this.subscriptions.forEach(function (each) {
if ((0, _utils.isDefined)(each.draw)) each.draw(props);
});
}
}, {
key: "redraw",
value: function redraw() {
this.clearThreeCanvas();
this.draw({ force: true });
}
}, {
key: "panHelper",
value: function panHelper(mouseXY, initialXScale, _ref2, chartsToPan) {
var dx = _ref2.dx,
dy = _ref2.dy;
var _state5 = this.state,
xAccessor = _state5.xAccessor,
displayXAccessor = _state5.displayXAccessor,
initialChartConfig = _state5.chartConfig;
var filterData = this.state.filterData;
var fullData = this.fullData;
var postCalculator = this.props.postCalculator;
// console.log(dx, dy);
if ((0, _utils.isNotDefined)(initialXScale.invert)) throw new Error("xScale provided does not have an invert() method." + "You are likely using an ordinal scale. This scale does not support zoom, pan");
var newDomain = initialXScale.range().map(function (x) {
return x - dx;
}).map(initialXScale.invert);
var _filterData4 = filterData(fullData, newDomain, xAccessor, initialXScale, {
currentPlotData: this.hackyWayToStopPanBeyondBounds__plotData,
currentDomain: this.hackyWayToStopPanBeyondBounds__domain
}),
beforePlotData = _filterData4.plotData,
domain = _filterData4.domain;
var updatedScale = initialXScale.copy().domain(domain);
var plotData = postCalculator(beforePlotData);
// console.log(last(plotData));
var currentItem = (0, _ChartDataUtil.getCurrentItem)(updatedScale, xAccessor, mouseXY, plotData);
var chartConfig = (0, _ChartDataUtil.getChartConfigWithUpdatedYScales)(initialChartConfig, { plotData: plotData, xAccessor: xAccessor, displayXAccessor: displayXAccessor, fullData: fullData }, updatedScale.domain(), dy, chartsToPan);
var currentCharts = (0, _ChartDataUtil.getCurrentCharts)(chartConfig, mouseXY);
// console.log(initialXScale.domain(), newDomain, updatedScale.domain());
return {
xScale: updatedScale,
plotData: plotData,
chartConfig: chartConfig,
mouseXY: mouseXY,
currentCharts: currentCharts,
currentItem: currentItem
};
}
}, {
key: "handlePan",
value: function handlePan(mousePosition, panStartXScale, dxdy, chartsToPan, e) {
var _this4 = this;
if (!this.waitingForPanAnimationFrame) {
this.waitingForPanAnimationFrame = true;
this.hackyWayToStopPanBeyondBounds__plotData = this.hackyWayToStopPanBeyondBounds__plotData || this.state.plotData;
this.hackyWayToStopPanBeyondBounds__domain = this.hackyWayToStopPanBeyondBounds__domain || this.state.xScale.domain();
var state = this.panHelper(mousePosition, panStartXScale, dxdy, chartsToPan);
this.hackyWayToStopPanBeyondBounds__plotData = state.plotData;
this.hackyWayToStopPanBeyondBounds__domain = state.xScale.domain();
this.panInProgress = true;
// console.log(panStartXScale.domain(), state.xScale.domain());
this.triggerEvent("pan", state, e);
this.mutableState = {
mouseXY: state.mouseXY,
currentItem: state.currentItem,
currentCharts: state.currentCharts
};
requestAnimationFrame(function () {
_this4.waitingForPanAnimationFrame = false;
_this4.clearBothCanvas();
_this4.draw({ trigger: "pan" });
});
}
}
}, {
key: "handlePanEnd",
value: function handlePanEnd(mousePosition, panStartXScale, dxdy, chartsToPan, e) {
var _this5 = this;
var state = this.panHelper(mousePosition, panStartXScale, dxdy, chartsToPan);
// console.log(this.canvasDrawCallbackList.map(d => d.type));
this.hackyWayToStopPanBeyondBounds__plotData = null;
this.hackyWayToStopPanBeyondBounds__domain = null;
this.panInProgress = false;
// console.log("PANEND", panEnd++);
var xScale = state.xScale,
plotData = state.plotData,
chartConfig = state.chartConfig;
this.triggerEvent("panend", state, e);
requestAnimationFrame(function () {
var xAccessor = _this5.state.xAccessor;
var fullData = _this5.fullData;
var firstItem = (0, _utils.head)(fullData);
var start = (0, _utils.head)(xScale.domain());
var end = xAccessor(firstItem);
// console.log(start, end, start < end ? "Load more" : "I have it");
var onLoadMore = _this5.props.onLoadMore;
_this5.clearThreeCanvas();
_this5.setState({
xScale: xScale,
plotData: plotData,
chartConfig: chartConfig
}, function () {
if (start < end) onLoadMore(start, end);
});
});
}
}, {
key: "handleMouseDown",
value: function handleMouseDown(mousePosition, currentCharts, e) {
this.triggerEvent("mousedown", this.mutableState, e);
}
}, {
key: "handleMouseEnter",
value: function handleMouseEnter(e) {
this.triggerEvent("mouseenter", {
show: true
}, e);
}
}, {
key: "handleMouseMove",
value: function handleMouseMove(mouseXY, inputType, e) {
var _this6 = this;
if (!this.waitingForMouseMoveAnimationFrame) {
this.waitingForMouseMoveAnimationFrame = true;
var _state6 = this.state,
chartConfig = _state6.chartConfig,
plotData = _state6.plotData,
xScale = _state6.xScale,
xAccessor = _state6.xAccessor;
var currentCharts = (0, _ChartDataUtil.getCurrentCharts)(chartConfig, mouseXY);
var currentItem = (0, _ChartDataUtil.getCurrentItem)(xScale, xAccessor, mouseXY, plotData);
this.triggerEvent("mousemove", {
show: true,
mouseXY: mouseXY,
// prevMouseXY is used in interactive components
prevMouseXY: this.prevMouseXY,
currentItem: currentItem,
currentCharts: currentCharts
}, e);
this.prevMouseXY = mouseXY;
this.mutableState = {
mouseXY: mouseXY,
currentItem: currentItem,
currentCharts: currentCharts
};
requestAnimationFrame(function () {
_this6.clearMouseCanvas();
_this6.draw({ trigger: "mousemove" });
_this6.waitingForMouseMoveAnimationFrame = false;
});
}
}
}, {
key: "handleMouseLeave",
value: function handleMouseLeave(e) {
this.triggerEvent("mouseleave", { show: false }, e);
this.clearMouseCanvas();
this.draw({ trigger: "mouseleave" });
}
}, {
key: "handleDragStart",
value: function handleDragStart(_ref3, e) {
var startPos = _ref3.startPos;
this.triggerEvent("dragstart", { startPos: startPos }, e);
}
}, {
key: "handleDrag",
value: function handleDrag(_ref4, e) {
var _this7 = this;
var startPos = _ref4.startPos,
mouseXY = _ref4.mouseXY;
var _state7 = this.state,
chartConfig = _state7.chartConfig,
plotData = _state7.plotData,
xScale = _state7.xScale,
xAccessor = _state7.xAccessor;
var currentCharts = (0, _ChartDataUtil.getCurrentCharts)(chartConfig, mouseXY);
var currentItem = (0, _ChartDataUtil.getCurrentItem)(xScale, xAccessor, mouseXY, plotData);
this.triggerEvent("drag", {
startPos: startPos,
mouseXY: mouseXY,
currentItem: currentItem,
currentCharts: currentCharts
}, e);
this.mutableState = {
mouseXY: mouseXY,
currentItem: currentItem,
currentCharts: currentCharts
};
requestAnimationFrame(function () {
_this7.clearMouseCanvas();
_this7.draw({ trigger: "drag" });
});
}
}, {
key: "handleDragEnd",
value: function handleDragEnd(_ref5, e) {
var _this8 = this;
var mouseXY = _ref5.mouseXY;
this.triggerEvent("dragend", { mouseXY: mouseXY }, e);
requestAnimationFrame(function () {
_this8.clearMouseCanvas();
_this8.draw({ trigger: "dragend" });
});
}
}, {
key: "handleClick",
value: function handleClick(mousePosition, e) {
var _this9 = this;
this.triggerEvent("click", this.mutableState, e);
requestAnimationFrame(function () {
_this9.clearMouseCanvas();
_this9.draw({ trigger: "click" });
});
}
}, {
key: "handleDoubleClick",
value: function handleDoubleClick(mousePosition, e) {
this.triggerEvent("dblclick", {}, e);
}
}, {
key: "getChildContext",
value: function getChildContext() {
var dimensions = getDimensions(this.props);
return {
fullData: this.fullData,
plotData: this.state.plotData,
width: dimensions.width,
height: dimensions.height,
chartConfig: this.state.chartConfig,
xScale: this.state.xScale,
xAccessor: this.state.xAccessor,
displayXAccessor: this.state.displayXAccessor,
chartCanvasType: this.props.type,
margin: this.props.margin,
ratio: this.props.ratio,
xAxisZoom: this.xAxisZoom,
yAxisZoom: this.yAxisZoom,
getCanvasContexts: this.getCanvasContexts,
redraw: this.redraw,
subscribe: this.subscribe,
unsubscribe: this.unsubscribe,
generateSubscriptionId: this.generateSubscriptionId,
getMutableState: this.getMutableState,
amIOnTop: this.amIOnTop,
setCursorClass: this.setCursorClass
};
}
}, {
key: "componentWillMount",
value: function componentWillMount() {
var _resetChart = resetChart(this.props, true),
fullData = _resetChart.fullData,
state = _objectWithoutProperties(_resetChart, ["fullData"]);
this.setState(state);
this.fullData = fullData;
}
}, {
key: "componentWillReceiveProps",
value: function componentWillReceiveProps(nextProps) {
var reset = shouldResetChart(this.props, nextProps);
var interaction = isInteractionEnabled(this.state.xScale, this.state.xAccessor, this.state.plotData);
var initialChartConfig = this.state.chartConfig;
var newState = void 0;
if (!interaction || reset || !(0, _utils.shallowEqual)(this.props.xExtents, nextProps.xExtents)) {
if (process.env.NODE_ENV !== "production") {
if (!interaction) log("RESET CHART, changes to a non interactive chart");else if (reset) log("RESET CHART, one or more of these props changed", CANDIDATES_FOR_RESET);else log("xExtents changed");
}
// do reset
newState = resetChart(nextProps);
} else {
var _state$xScale$domain = this.state.xScale.domain(),
_state$xScale$domain2 = _slicedToArray(_state$xScale$domain, 2),
start = _state$xScale$domain2[0],
end = _state$xScale$domain2[1];
var prevLastItem = (0, _utils.last)(this.fullData);
var calculatedState = calculateFullData(nextProps);
var xAccessor = calculatedState.xAccessor;
var lastItemWasVisible = xAccessor(prevLastItem) <= end && xAccessor(prevLastItem) >= start;
if (process.env.NODE_ENV !== "production") {
if (this.props.data !== nextProps.data) log("data is changed but seriesName did not, change the seriesName if you wish to reset the chart and lastItemWasVisible = ", lastItemWasVisible);else log("Trivial change, may be width/height or type changed, but that does not matter");
}
newState = updateChart(calculatedState, this.state.xScale, nextProps, lastItemWasVisible, initialChartConfig);
}
var _newState = newState,
fullData = _newState.fullData,
state = _objectWithoutProperties(_newState, ["fullData"]);
if (this.panInProgress) {
if (process.env.NODE_ENV !== "production") {
log("Pan is in progress");
}
} else {
/*
if (!reset) {
state.chartConfig
.forEach((each) => {
// const sourceChartConfig = initialChartConfig.filter(d => d.id === each.id);
const prevChartConfig = find(initialChartConfig, d => d.id === each.id);
if (isDefined(prevChartConfig) && prevChartConfig.yPanEnabled) {
each.yScale.domain(prevChartConfig.yScale.domain());
each.yPanEnabled = prevChartConfig.yPanEnabled;
}
});
}
*/
this.clearThreeCanvas();
this.setState(state);
}
this.fullData = fullData;
}
/*
componentDidUpdate(prevProps, prevState) {
console.error(this.state.chartConfig, this.state.chartConfig.map(d => d.yScale.domain()));
}
*/
}, {
key: "resetYDomain",
value: function resetYDomain(chartId) {
var chartConfig = this.state.chartConfig;
var changed = false;
var newChartConfig = chartConfig.map(function (each) {
if (((0, _utils.isNotDefined)(chartId) || each.id === chartId) && !(0, _utils.shallowEqual)(each.yScale.domain(), each.realYDomain)) {
changed = true;
return _extends({}, each, {
yScale: each.yScale.domain(each.realYDomain),
yPanEnabled: false
});
}
return each;
});
if (changed) {
this.clearThreeCanvas();
this.setState({
chartConfig: newChartConfig
});
}
}
}, {
key: "shouldComponentUpdate",
value: function shouldComponentUpdate() {
// console.log("Happneing.....", !this.panInProgress)
return !this.panInProgress;
}
}, {
key: "render",
value: function render() {
var _props2 = this.props,
type = _props2.type,
height = _props2.height,
width = _props2.width,
margin = _props2.margin,
className = _props2.className,
zIndex = _props2.zIndex,
defaultFocus = _props2.defaultFocus,
ratio = _props2.ratio,
mouseMoveEvent = _props2.mouseMoveEvent,
panEvent = _props2.panEvent,
zoomEvent = _props2.zoomEvent;
var _props3 = this.props,
useCrossHairStyleCursor = _props3.useCrossHairStyleCursor,
onSelect = _props3.onSelect;
var _state8 = this.state,
plotData = _state8.plotData,
xScale = _state8.xScale,
xAccessor = _state8.xAccessor,
chartConfig = _state8.chartConfig;
var dimensions = getDimensions(this.props);
var interaction = isInteractionEnabled(xScale, xAccessor, plotData);
var cursorStyle = useCrossHairStyleCursor && interaction;
var cursor = getCursorStyle();
return _react2.default.createElement(
"div",
{ style: { position: "relative", width: width, height: height }, className: className, onClick: onSelect },
_react2.default.createElement(_CanvasContainer2.default, { ref: this.saveCanvasContainerNode,
type: type,
ratio: ratio,
width: width, height: height, zIndex: zIndex }),
_react2.default.createElement(
"svg",
{ className: className, width: width, height: height, style: { position: "absolute", zIndex: zIndex + 5 } },
cursor,
_react2.default.createElement(
"defs",
null,
_react2.default.createElement(
"clipPath",
{ id: "chart-area-clip" },
_react2.default.createElement("rect", { x: "0", y: "0", width: dimensions.width, height: dimensions.height })
),
chartConfig.map(function (each, idx) {
return _react2.default.createElement(
"clipPath",
{ key: idx, id: "chart-area-clip-" + each.id },
_react2.default.createElement("rect", { x: "0", y: "0", width: each.width, height: each.height })
);
})
),
_react2.default.createElement(
"g",
{ transform: "translate(" + (margin.left + 0.5) + ", " + (margin.top + 0.5) + ")" },
_react2.default.createElement(_EventCapture2.default, {
ref: this.saveEventCaptureNode,
useCrossHairStyleCursor: cursorStyle,
mouseMove: mouseMoveEvent && interaction,
zoom: zoomEvent && interaction,
pan: panEvent && interaction,
width: dimensions.width,
height: dimensions.height,
chartConfig: chartConfig,
xScale: xScale,
xAccessor: xAccessor,
focus: defaultFocus,
disableInteraction: this.props.disableInteraction,
getAllPanConditions: this.getAllPanConditions,
onContextMenu: this.handleContextMenu,
onClick: this.handleClick,
onDoubleClick: this.handleDoubleClick,
onMouseDown: this.handleMouseDown,
onMouseMove: this.handleMouseMove,
onMouseEnter: this.handleMouseEnter,
onMouseLeave: this.handleMouseLeave,
onDragStart: this.handleDragStart,
onDrag: this.handleDrag,
onDragComplete: this.handleDragEnd,
onZoom: this.handleZoom,
onPinchZoom: this.handlePinchZoom,
onPinchZoomEnd: this.handlePinchZoomEnd,
onPan: this.handlePan,
onPanEnd: this.handlePanEnd
}),
_react2.default.createElement(
"g",
{ className: "react-stockcharts-avoid-interaction" },
this.props.children
)
)
)
);
}
}]);
return ChartCanvas;
}(_react.Component);
function isInteractionEnabled(xScale, xAccessor, data) {
var interaction = !isNaN(xScale(xAccessor((0, _utils.head)(data)))) && (0, _utils.isDefined)(xScale.invert);
return interaction;
}
ChartCanvas.propTypes = {
width: _propTypes2.default.number.isRequired,
height: _propTypes2.default.number.isRequired,
margin: _propTypes2.default.object,
ratio: _propTypes2.default.number.isRequired,
// interval: PropTypes.oneOf(["D", "W", "M"]), // ,"m1", "m5", "m15", "W", "M"
type: _propTypes2.default.oneOf(["svg", "hybrid"]),
pointsPerPxThreshold: _propTypes2.default.number,
minPointsPerPxThreshold: _propTypes2.default.number,
data: _propTypes2.default.array.isRequired,
// initialDisplay: PropTypes.number,
xAccessor: _propTypes2.default.func,
xExtents: _propTypes2.default.oneOfType([_propTypes2.default.array, _propTypes2.default.func]),
zoomAnchor: _propTypes2.default.func,
className: _propTypes2.default.string,
seriesName: _propTypes2.default.string.isRequired,
zIndex: _propTypes2.default.number,
children: _propTypes2.default.node.isRequired,
xScale: _propTypes2.default.func.isRequired,
postCalculator: _propTypes2.default.func,
flipXScale: _propTypes2.default.bool,
useCrossHairStyleCursor: _propTypes2.default.bool,
padding: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.shape({
left: _propTypes2.default.number,
right: _propTypes2.default.number
})]),
defaultFocus: _propTypes2.default.bool,
zoomMultiplier: _propTypes2.default.number,
onLoadMore: _propTypes2.default.func,
displayXAccessor: function displayXAccessor(props, propName /* , componentName */) {
if ((0, _utils.isNotDefined)(props[propName])) {
console.warn("`displayXAccessor` is not defined," + " will use the value from `xAccessor` as `displayXAccessor`." + " This might be ok if you do not use a discontinuous scale" + " but if you do, provide a `displayXAccessor` prop to `ChartCanvas`");
} else if (typeof props[propName] !== "function") {
return new Error("displayXAccessor has to be a function");
}
},
mouseMoveEvent: _propTypes2.default.bool,
panEvent: _propTypes2.default.bool,
clamp: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.bool, _propTypes2.default.func]),
zoomEvent: _propTypes2.default.bool,
onSelect: _propTypes2.default.func,
maintainPointsPerPixelOnResize: _propTypes2.default.bool,
disableInteraction: _propTypes2.default.bool
};
ChartCanvas.defaultProps = {
margin: { top: 20, right: 30, bottom: 30, left: 80 },
type: "hybrid",
pointsPerPxThreshold: 2,
minPointsPerPxThreshold: 1 / 100,
className: "react-stockchart",
zIndex: 1,
xExtents: [_d3Array.min, _d3Array.max],
postCalculator: _utils.identity,
padding: 0,
xAccessor: _utils.identity,
flipXScale: false,
useCrossHairStyleCursor: true,
defaultFocus: true,
onLoadMore: _utils.noop,
onSelect: _utils.noop,
mouseMoveEvent: true,
panEvent: true,
zoomEvent: true,
zoomMultiplier: 1.1,
clamp: false,
zoomAnchor: _zoomBehavior.mouseBasedZoomAnchor,
maintainPointsPerPixelOnResize: true,
// ratio: 2,
disableInteraction: false
};
ChartCanvas.childContextTypes = {
plotData: _propTypes2.default.array,
fullData: _propTypes2.default.array,
chartConfig: _propTypes2.default.arrayOf(_propTypes2.default.shape({
id: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.string]).isRequired,
origin: _propTypes2.default.arrayOf(_propTypes2.default.number).isRequired,
padding: _propTypes2.default.oneOfType([_propTypes2.default.number, _propTypes2.default.shape({
top: _propTypes2.default.number,
bottom: _propTypes2.default.number
})]),
yExtents: _propTypes2.default.arrayOf(_propTypes2.default.func),
yExtentsProvider: _propTypes2.default.func,
yScale: _propTypes2.default.func.isRequired,
mouseCoordinates: _propTypes2.default.shape({
at: _propTypes2.default.string,
format: _propTypes2.default.func
}),
width: _propTypes2.default.number.isRequired,
height: _propTypes2.default.number.isRequired
})).isRequired,
xScale: _propTypes2.default.func.isRequired,
xAccessor: _propTypes2.default.func.isRequired,
displayXAccessor: _propTypes2.default.func.isRequired,
width: _propTypes2.default.number.isRequired,
height: _propTypes2.default.number.isRequired,
chartCanvasType: _propTypes2.default.oneOf(["svg", "hybrid"]).isRequired,
margin: _propTypes2.default.object.isRequired,
ratio: _propTypes2.default.number.isRequired,
getCanvasContexts: _propTypes2.default.func,
xAxisZoom: _propTypes2.default.func,
yAxisZoom: _propTypes2.default.func,
amIOnTop: _propTypes2.default.func,
redraw: _propTypes2.default.func,
subscribe: _propTypes2.default.func,
unsubscribe: _propTypes2.default.func,
setCursorClass: _propTypes2.default.func,
generateSubscriptionId: _propTypes2.default.func,
getMutableState: _propTypes2.default.func
};
ChartCanvas.ohlcv = function (d) {
return { date: d.date, open: d.open, high: d.high, low: d.low, close: d.close, volume: d.volume };
};
exports.default = ChartCanvas;
//# sourceMappingURL=ChartCanvas.js.map