@devexperts/dxcharts-lite
Advanced tools
Comparing version 2.4.6 to 2.5.0
@@ -47,2 +47,3 @@ /* | ||
export declare const DEFAULT_BOUNDS: Bounds; | ||
export declare const DEFAULT_MIN_PANE_HEIGHT = 20; | ||
/** | ||
@@ -65,2 +66,3 @@ * This component listens EVENT_DRAW and recalculates bounds of canvas chart elements. | ||
panesOrderChangedSubject: Subject<string[]>; | ||
paneVisibilityChangedSubject: Subject<void>; | ||
xAxisHeight: number | undefined; | ||
@@ -90,4 +92,3 @@ yAxisWidths: YAxisWidths; | ||
* @throws {Error} If the sum of the height ratios is not equal to 1. | ||
*/ | ||
*/ | ||
overrideChartHeightRatios(heightRatios: Record<string, number>): void; | ||
@@ -115,2 +116,4 @@ /** | ||
reorderPanes(newPanesOrder: string[]): void; | ||
hidePaneBounds(uuid: string): void; | ||
showPaneBounds(uuid: string): void; | ||
/** | ||
@@ -121,3 +124,3 @@ * Removes the bounds of a pane with the given uuid from the canvas element. | ||
*/ | ||
removedPaneBounds(uuid: string): void; | ||
removePaneBounds(uuid: string): void; | ||
/** | ||
@@ -334,2 +337,3 @@ * Recalculates the bounds of the chart elements based on the current configuration and canvas size. | ||
} | ||
export declare const getHeightRatios: (pecLength: number) => [number, number]; | ||
export declare const isInBounds: (point: Point, bounds: Bounds) => boolean; | ||
@@ -336,0 +340,0 @@ export declare const isInVerticalBounds: (y: number, bounds: Bounds) => boolean; |
@@ -43,3 +43,3 @@ /* | ||
export const DEFAULT_BOUNDS = { x: 0, y: 0, pageX: 0, pageY: 0, width: 0, height: 0 }; | ||
const DEFAULT_MIN_PANE_HEIGHT = 20; | ||
export const DEFAULT_MIN_PANE_HEIGHT = 20; | ||
const N_MAP_H = 35; | ||
@@ -76,2 +76,3 @@ const N_MAP_BUTTON_W = 15; | ||
this.panesOrderChangedSubject = new Subject(); | ||
this.paneVisibilityChangedSubject = new Subject(); | ||
// both will be calculated based on font/content size | ||
@@ -125,4 +126,3 @@ this.xAxisHeight = undefined; | ||
* @throws {Error} If the sum of the height ratios is not equal to 1. | ||
*/ | ||
*/ | ||
overrideChartHeightRatios(heightRatios) { | ||
@@ -180,2 +180,23 @@ const resultRatio = Object.assign(Object.assign({}, this.graphsHeightRatio), heightRatios); | ||
} | ||
hidePaneBounds(uuid) { | ||
this.graphsHeightRatio[uuid] = 0; | ||
this.recalculatePanesHeightRatios(); | ||
this.paneVisibilityChangedSubject.next(); | ||
} | ||
showPaneBounds(uuid) { | ||
if (uuid === CHART_UUID) { | ||
const [defaultChartHeightRatio] = getHeightRatios(this.panesOrder.length - 1); | ||
this.graphsHeightRatio[uuid] = defaultChartHeightRatio; | ||
} | ||
else { | ||
// when pane is hidden it has ratio of 0 | ||
// when we want pane to be visible again we want `recalculatePanesHeightRatios` function | ||
// to treat it as a new pane | ||
// to do so we need to delete its ratio (which is 0 because it is hidden) from graphsHeightRatio | ||
// NOTE: CHART_UUID pane is exception, it is treated differently and should always have some ratio | ||
delete this.graphsHeightRatio[uuid]; | ||
} | ||
this.recalculatePanesHeightRatios(); | ||
this.paneVisibilityChangedSubject.next(); | ||
} | ||
/** | ||
@@ -186,3 +207,3 @@ * Removes the bounds of a pane with the given uuid from the canvas element. | ||
*/ | ||
removedPaneBounds(uuid) { | ||
removePaneBounds(uuid) { | ||
arrayRemove2(this.panesOrder, uuid); | ||
@@ -231,9 +252,10 @@ delete this.graphsHeightRatio[uuid]; | ||
// panes | ||
const firstVisiblePaneIdx = this.panesOrder.findIndex(uuid => this.graphsHeightRatio[uuid] > 0); | ||
this.panesOrder.forEach((uuid, index) => { | ||
var _a; | ||
const paneHeightRatio = this.graphsHeightRatio[this.panesOrder[index]]; | ||
// hide resizer for first pane with index === 0 | ||
const resizerVisible = this.config.components.paneResizer.visible && index !== 0; | ||
// hide resizer for the first visible pane | ||
const resizerUUID = CanvasElement.PANE_UUID_RESIZER(uuid); | ||
const paneUUID = CanvasElement.PANE_UUID(uuid); | ||
const resizerVisible = this.config.components.paneResizer.visible && index > firstVisiblePaneIdx && paneHeightRatio > 0; | ||
if (resizerVisible) { | ||
@@ -246,3 +268,3 @@ upsertBounds(this.bounds, resizerUUID, 0, nextY, canvas.width, paneResizerHeight, this.canvasOnPageLocation); | ||
const paneYStart = nextY + (resizerVisible ? paneResizerHeight : 0); | ||
const paneBounds = upsertBounds(this.bounds, paneUUID, paneXStart, paneYStart, chartWidth, chartHeight * paneHeightRatio - (resizerVisible ? this.config.components.paneResizer.height : 0), this.canvasOnPageLocation); | ||
const paneBounds = upsertBounds(this.bounds, paneUUID, paneXStart, paneYStart, chartWidth, chartHeight * paneHeightRatio - (resizerVisible ? paneResizerHeight : 0), this.canvasOnPageLocation); | ||
// y axis | ||
@@ -435,9 +457,9 @@ if (this.config.components.yAxis.visible) { | ||
pec.push(...this.panesOrder.filter(p => p !== CHART_UUID)); | ||
this.panesOrder.forEach(pane => { | ||
if (this.graphsHeightRatio[pane] === 0) { | ||
delete this.graphsHeightRatio[pane]; | ||
} | ||
}); | ||
const pecRatios = pec.map(graph => this.graphsHeightRatio[graph] === undefined ? undefined : this.graphsHeightRatio[graph]); | ||
const oldPecNumber = pecRatios.filter(ratio => ratio !== undefined).length; | ||
const pecRatios = pec.map(uuid => this.graphsHeightRatio[uuid] === undefined ? undefined : this.graphsHeightRatio[uuid]); | ||
// we should count only visible panes, to escape wheight distribution for hidden panes | ||
const visiblePecRatios = pecRatios.filter(ratio => ratio !== 0); | ||
const visiblePecNumber = visiblePecRatios.length; | ||
// we don't count as an old PEC panes that are not visible, because they don't whey in the final result | ||
const oldPecNumber = visiblePecRatios.filter(ratio => ratio !== undefined).length; | ||
// if ratio in undefined for a given pane it means that it's a new pane | ||
const newPecNumber = pecRatios.filter(ratio => ratio === undefined).length; | ||
@@ -449,5 +471,6 @@ let freeRatioForPec = 0; | ||
if (newPecNumber > 0) { | ||
[ratioForOldPec, ratioForNewPec] = getHeightRatios(pec.length); | ||
[ratioForOldPec, ratioForNewPec] = getHeightRatios(visiblePecNumber); | ||
chartRatio *= ratioForOldPec; | ||
} | ||
// this means we should keep in mind only new panes | ||
if (oldPecNumber === 0) { | ||
@@ -457,3 +480,3 @@ chartRatio = 1 - ratioForNewPec * newPecNumber; | ||
freeRatio = 1 - chartRatio - ratioForNewPec * newPecNumber; | ||
pecRatios.forEach(ratio => { | ||
visiblePecRatios.forEach(ratio => { | ||
if (ratio) { | ||
@@ -463,5 +486,16 @@ freeRatio -= ratio * ratioForOldPec; | ||
}); | ||
freeRatioForPec = freeRatio / (pec.length + 1); | ||
const proportions = pecRatios.map(ratio => ratio ? ratio * ratioForOldPec + freeRatioForPec : ratioForNewPec + freeRatioForPec); | ||
chartRatio += freeRatioForPec; | ||
// || 1 to escape division by zero | ||
// because there's might be no visible panes except CHART | ||
freeRatioForPec = freeRatio / (visiblePecNumber || 1); | ||
// distribute left free ratio between new and old panes | ||
const proportions = pecRatios.map(ratio => { | ||
// if ratio === 0 it means, that it's hidden | ||
if (ratio === 0) { | ||
return ratio; | ||
} | ||
if (!ratio) { | ||
return ratioForNewPec + freeRatioForPec; | ||
} | ||
return ratio * ratioForOldPec + freeRatioForPec; | ||
}); | ||
this._graphsHeightRatio = {}; | ||
@@ -492,84 +526,85 @@ this.graphsHeightRatio[CHART_UUID] = chartRatio; | ||
var _a, _b, _c, _d; | ||
if (this.config.components.navigationMap.visible) { | ||
const nMap = this.getBounds(CanvasElement.N_MAP); | ||
const { height, width } = this.config.components.navigationMap.knots; | ||
const knotHeightFromConfig = height !== null && height !== void 0 ? height : 0; | ||
const knotWidthFromConfig = isMobile() ? width * KNOTS_W_MOBILE_MULTIPLIER : width !== null && width !== void 0 ? width : 0; | ||
const knotY = !knotHeightFromConfig ? nMap.y : nMap.y + (nMap.height - knotHeightFromConfig) / 2; | ||
// time labels | ||
const timeLabelsVisible = (_b = (_a = this.config.components.navigationMap) === null || _a === void 0 ? void 0 : _a.timeLabels) === null || _b === void 0 ? void 0 : _b.visible; | ||
const calcLabelBounds = (timestamp) => { | ||
return calcTimeLabelBounds(this.canvasModel.ctx, timestamp, this.formatterFactory, this.config)[0]; | ||
}; | ||
const candleSource = flat((_d = (_c = this.mainCandleSeries) === null || _c === void 0 ? void 0 : _c.getSeriesInViewport()) !== null && _d !== void 0 ? _d : []); | ||
const leftTimeLabelWidth = timeLabelsVisible && candleSource.length ? calcLabelBounds(candleSource[0].candle.timestamp) : 0; | ||
const rightTimeLabelWidth = timeLabelsVisible && candleSource.length | ||
? calcLabelBounds(candleSource[candleSource.length - 1].candle.timestamp) | ||
: 0; | ||
const timeLabelWidth = Math.max(leftTimeLabelWidth, rightTimeLabelWidth); | ||
if (timeLabelsVisible) { | ||
const nMapLabelL = this.getBounds(CanvasElement.N_MAP_LABEL_L); | ||
nMapLabelL.x = nMap.x; | ||
nMapLabelL.y = nMap.y; | ||
nMapLabelL.width = timeLabelWidth; | ||
nMapLabelL.height = nMap.height; | ||
const nMapLabelR = this.getBounds(CanvasElement.N_MAP_LABEL_R); | ||
nMapLabelR.x = nMap.x + nMap.width - timeLabelWidth; | ||
nMapLabelR.y = nMap.y; | ||
nMapLabelR.width = timeLabelWidth; | ||
nMapLabelR.height = nMap.height; | ||
} | ||
// buttons left and right | ||
const nMapBtnL = this.getBounds(CanvasElement.N_MAP_BTN_L); | ||
nMapBtnL.x = nMap.x + timeLabelWidth; | ||
nMapBtnL.y = nMap.y; | ||
nMapBtnL.width = N_MAP_BUTTON_W; | ||
nMapBtnL.height = nMap.height; | ||
const nMapBtnR = this.getBounds(CanvasElement.N_MAP_BTN_R); | ||
nMapBtnR.x = nMap.x + nMap.width - N_MAP_BUTTON_W - timeLabelWidth; | ||
nMapBtnR.y = nMap.y; | ||
nMapBtnR.width = N_MAP_BUTTON_W; | ||
nMapBtnR.height = nMap.height; | ||
// knots | ||
const navMapChartStart = nMapBtnL.x + nMapBtnL.width; | ||
const navMapChartWidth = nMapBtnR.x - navMapChartStart; | ||
const navMapChartEnd = navMapChartStart + navMapChartWidth; | ||
const minSliderW = this.config.components.navigationMap.minSliderWindowWidth; | ||
const knotW = knotWidthFromConfig !== null && knotWidthFromConfig !== void 0 ? knotWidthFromConfig : N_MAP_KNOT_W; | ||
const knotH = knotHeightFromConfig !== null && knotHeightFromConfig !== void 0 ? knotHeightFromConfig : nMap.height; | ||
const minDistanceBetweenKnotsX = knotW + minSliderW; | ||
// Left drag button | ||
const knotL = this.getBounds(CanvasElement.N_MAP_KNOT_L); | ||
knotL.x = navMapChartStart + navMapChartWidth * this.leftRatio; | ||
// limit left knot to min distance from right border | ||
knotL.x = Math.min(knotL.x, navMapChartEnd - minDistanceBetweenKnotsX); | ||
knotL.y = knotY; | ||
knotL.width = knotW; | ||
knotL.height = knotH; | ||
// Right drag button | ||
const knotR = this.getBounds(CanvasElement.N_MAP_KNOT_R); | ||
knotR.x = navMapChartStart + navMapChartWidth * this.rightRatio - N_MAP_KNOT_W; | ||
// limit right knot to min distance from left border | ||
knotR.x = Math.max(knotR.x, navMapChartStart + minDistanceBetweenKnotsX); | ||
knotR.y = knotY; | ||
knotR.width = knotW; | ||
knotR.height = knotH; | ||
const distanceDiff = minDistanceBetweenKnotsX - (knotR.x - knotL.x); | ||
// if distance between knots is less than min distance - move left knot start | ||
if (distanceDiff > 0) { | ||
knotL.x -= distanceDiff; | ||
} | ||
// slider | ||
const slider = this.getBounds(CanvasElement.N_MAP_SLIDER_WINDOW); | ||
slider.x = knotL.x + knotL.width; | ||
slider.y = nMap.y; | ||
slider.width = knotR.x - slider.x; | ||
slider.height = nMap.height; | ||
// chart | ||
const nMapChart = this.getBounds(CanvasElement.N_MAP_CHART); | ||
nMapChart.x = navMapChartStart; | ||
nMapChart.y = nMap.y; | ||
nMapChart.width = navMapChartWidth; | ||
nMapChart.height = nMap.height; | ||
if (!this.config.components.navigationMap.visible) { | ||
return; | ||
} | ||
const nMap = this.getBounds(CanvasElement.N_MAP); | ||
const { height, width } = this.config.components.navigationMap.knots; | ||
const knotHeightFromConfig = height !== null && height !== void 0 ? height : 0; | ||
const knotWidthFromConfig = isMobile() ? width * KNOTS_W_MOBILE_MULTIPLIER : width !== null && width !== void 0 ? width : 0; | ||
const knotY = !knotHeightFromConfig ? nMap.y : nMap.y + (nMap.height - knotHeightFromConfig) / 2; | ||
// time labels | ||
const timeLabelsVisible = (_b = (_a = this.config.components.navigationMap) === null || _a === void 0 ? void 0 : _a.timeLabels) === null || _b === void 0 ? void 0 : _b.visible; | ||
const calcLabelBounds = (timestamp) => { | ||
return calcTimeLabelBounds(this.canvasModel.ctx, timestamp, this.formatterFactory, this.config)[0]; | ||
}; | ||
const candleSource = flat((_d = (_c = this.mainCandleSeries) === null || _c === void 0 ? void 0 : _c.getSeriesInViewport()) !== null && _d !== void 0 ? _d : []); | ||
const leftTimeLabelWidth = timeLabelsVisible && candleSource.length ? calcLabelBounds(candleSource[0].candle.timestamp) : 0; | ||
const rightTimeLabelWidth = timeLabelsVisible && candleSource.length | ||
? calcLabelBounds(candleSource[candleSource.length - 1].candle.timestamp) | ||
: 0; | ||
const timeLabelWidth = Math.max(leftTimeLabelWidth, rightTimeLabelWidth); | ||
if (timeLabelsVisible) { | ||
const nMapLabelL = this.getBounds(CanvasElement.N_MAP_LABEL_L); | ||
nMapLabelL.x = nMap.x; | ||
nMapLabelL.y = nMap.y; | ||
nMapLabelL.width = timeLabelWidth; | ||
nMapLabelL.height = nMap.height; | ||
const nMapLabelR = this.getBounds(CanvasElement.N_MAP_LABEL_R); | ||
nMapLabelR.x = nMap.x + nMap.width - timeLabelWidth; | ||
nMapLabelR.y = nMap.y; | ||
nMapLabelR.width = timeLabelWidth; | ||
nMapLabelR.height = nMap.height; | ||
} | ||
// buttons left and right | ||
const nMapBtnL = this.getBounds(CanvasElement.N_MAP_BTN_L); | ||
nMapBtnL.x = nMap.x + timeLabelWidth; | ||
nMapBtnL.y = nMap.y; | ||
nMapBtnL.width = N_MAP_BUTTON_W; | ||
nMapBtnL.height = nMap.height; | ||
const nMapBtnR = this.getBounds(CanvasElement.N_MAP_BTN_R); | ||
nMapBtnR.x = nMap.x + nMap.width - N_MAP_BUTTON_W - timeLabelWidth; | ||
nMapBtnR.y = nMap.y; | ||
nMapBtnR.width = N_MAP_BUTTON_W; | ||
nMapBtnR.height = nMap.height; | ||
// knots | ||
const navMapChartStart = nMapBtnL.x + nMapBtnL.width; | ||
const navMapChartWidth = nMapBtnR.x - navMapChartStart; | ||
const navMapChartEnd = navMapChartStart + navMapChartWidth; | ||
const minSliderW = this.config.components.navigationMap.minSliderWindowWidth; | ||
const knotW = knotWidthFromConfig !== null && knotWidthFromConfig !== void 0 ? knotWidthFromConfig : N_MAP_KNOT_W; | ||
const knotH = knotHeightFromConfig !== null && knotHeightFromConfig !== void 0 ? knotHeightFromConfig : nMap.height; | ||
const minDistanceBetweenKnotsX = knotW + minSliderW; | ||
// Left drag button | ||
const knotL = this.getBounds(CanvasElement.N_MAP_KNOT_L); | ||
knotL.x = navMapChartStart + navMapChartWidth * this.leftRatio; | ||
// limit left knot to min distance from right border | ||
knotL.x = Math.min(knotL.x, navMapChartEnd - minDistanceBetweenKnotsX); | ||
knotL.y = knotY; | ||
knotL.width = knotW; | ||
knotL.height = knotH; | ||
// Right drag button | ||
const knotR = this.getBounds(CanvasElement.N_MAP_KNOT_R); | ||
knotR.x = navMapChartStart + navMapChartWidth * this.rightRatio - N_MAP_KNOT_W; | ||
// limit right knot to min distance from left border | ||
knotR.x = Math.max(knotR.x, navMapChartStart + minDistanceBetweenKnotsX); | ||
knotR.y = knotY; | ||
knotR.width = knotW; | ||
knotR.height = knotH; | ||
const distanceDiff = minDistanceBetweenKnotsX - (knotR.x - knotL.x); | ||
// if distance between knots is less than min distance - move left knot start | ||
if (distanceDiff > 0) { | ||
knotL.x -= distanceDiff; | ||
} | ||
// slider | ||
const slider = this.getBounds(CanvasElement.N_MAP_SLIDER_WINDOW); | ||
slider.x = knotL.x + knotL.width; | ||
slider.y = nMap.y; | ||
slider.width = knotR.x - slider.x; | ||
slider.height = nMap.height; | ||
// chart | ||
const nMapChart = this.getBounds(CanvasElement.N_MAP_CHART); | ||
nMapChart.x = navMapChartStart; | ||
nMapChart.y = nMap.y; | ||
nMapChart.width = navMapChartWidth; | ||
nMapChart.height = nMap.height; | ||
} | ||
@@ -698,7 +733,16 @@ /** | ||
doResizePaneVertically(idx, yDeltaPixels) { | ||
const prevPaneIdx = idx - 1; | ||
// get prev visible pane index | ||
let prevVisiblePaneIdx = idx - 1; | ||
const prevPaneUUID = this.panesOrder[prevVisiblePaneIdx]; | ||
if (this._graphsHeightRatio[prevPaneUUID] <= 0) { | ||
for (let i = 0; i < idx; i++) { | ||
if (this._graphsHeightRatio[this.panesOrder[i]] > 0) { | ||
prevVisiblePaneIdx = i; | ||
} | ||
} | ||
} | ||
const allPanesHeight = this.getBounds(CanvasElement.ALL_PANES).height; | ||
const minAllowedPaneHeight = this.config.components.paneResizer.height + DEFAULT_MIN_PANE_HEIGHT; | ||
const minAllowedPaneHeight = DEFAULT_MIN_PANE_HEIGHT; | ||
const resultPaneHeight = allPanesHeight * this.graphsHeightRatio[this.panesOrder[idx]]; | ||
const dependResultPaneHeight = allPanesHeight * this.graphsHeightRatio[this.panesOrder[prevPaneIdx]]; | ||
const dependResultPaneHeight = allPanesHeight * this.graphsHeightRatio[this.panesOrder[prevVisiblePaneIdx]]; | ||
// check if changes fit allowed minimal pane height | ||
@@ -711,3 +755,3 @@ const fitPane = resultPaneHeight + yDeltaPixels > minAllowedPaneHeight; | ||
this.graphsHeightRatio[this.panesOrder[idx]] += yDeltaPercent; | ||
this.graphsHeightRatio[this.panesOrder[prevPaneIdx]] -= yDeltaPercent; | ||
this.graphsHeightRatio[this.panesOrder[prevVisiblePaneIdx]] -= yDeltaPercent; | ||
this.recalculateBounds(); | ||
@@ -808,3 +852,3 @@ } | ||
// NOTE: pec stands for panes except main chart | ||
const getHeightRatios = (pecLength) => { | ||
export const getHeightRatios = (pecLength) => { | ||
var _a; | ||
@@ -811,0 +855,0 @@ const chartHeightRatio = (_a = DEFAULT_RATIOS[pecLength]) !== null && _a !== void 0 ? _a : 0.4; |
@@ -53,2 +53,6 @@ /* | ||
const state = c.getYAxisState(); | ||
// if YAxis is not visible, do not add it to contributors width | ||
if (!state.visible) { | ||
return; | ||
} | ||
const margin = state.labelBoxMargin.start + state.labelBoxMargin.end; | ||
@@ -55,0 +59,0 @@ const width = this.getTextWidth(c.getLargestLabel()) + margin; |
@@ -212,3 +212,3 @@ /* | ||
showWhen: { | ||
periodMoreThen: 84600000, | ||
periodMoreThen: 24 * 60 * 60 * 1000, | ||
}, | ||
@@ -219,4 +219,4 @@ }, | ||
showWhen: { | ||
periodLessThen: 84600000, | ||
periodMoreThen: 6000, | ||
periodLessThen: 24 * 60 * 60 * 1000, | ||
periodMoreThen: 6 * 1000, | ||
}, | ||
@@ -227,3 +227,3 @@ }, | ||
showWhen: { | ||
periodLessThen: 6000, | ||
periodLessThen: 6 * 1000, | ||
}, | ||
@@ -230,0 +230,0 @@ }, |
@@ -27,3 +27,2 @@ /* | ||
* It extends the ChartBaseElement class and has the following properties: | ||
* @property {MainCanvasTouchHandler} touchHandler - An instance of the MainCanvasTouchHandler class. | ||
* @property {Point} currentPoint - An object that represents the current point of the chart area. | ||
@@ -38,3 +37,2 @@ * @property {number} xDraggedCandlesDelta - A number that represents the number of candles delta changed during X dragging. | ||
* @param {ScaleModel} scaleModel - An instance of the ScaleModel class. | ||
* @param {Element} mainCanvasParent - The parent element of the main canvas. | ||
* @param {CanvasInputListenerComponent} canvasInputListener - An instance of the CanvasInputListenerComponent class. | ||
@@ -50,3 +48,2 @@ * @param {CanvasBoundsContainer} canvasBoundsContainer - An instance of the CanvasBoundsContainer class. | ||
private scale; | ||
private mainCanvasParent; | ||
private canvasInputListener; | ||
@@ -57,3 +54,2 @@ private canvasBoundsContainer; | ||
private hitTestCanvasModel; | ||
private readonly touchHandler; | ||
private currentPoint; | ||
@@ -64,3 +60,3 @@ xDraggedCandlesDelta: number; | ||
chartPanningOptions: ChartPanningOptions; | ||
constructor(bus: EventBus, config: FullChartConfig, scale: ScaleModel, mainCanvasParent: Element, canvasInputListener: CanvasInputListenerComponent, canvasBoundsContainer: CanvasBoundsContainer, canvasAnimation: CanvasAnimation, chartPanComponent: ChartPanComponent, hitTestCanvasModel: HitTestCanvasModel); | ||
constructor(bus: EventBus, config: FullChartConfig, scale: ScaleModel, canvasInputListener: CanvasInputListenerComponent, canvasBoundsContainer: CanvasBoundsContainer, canvasAnimation: CanvasAnimation, chartPanComponent: ChartPanComponent, hitTestCanvasModel: HitTestCanvasModel); | ||
/** | ||
@@ -67,0 +63,0 @@ * It observes the wheel event on all panes of the canvas and throttles it to the specified time. |
@@ -10,3 +10,2 @@ /* | ||
import { CanvasElement } from '../../canvas/canvas-bounds-container'; | ||
import { MainCanvasTouchHandler } from '../../inputhandlers/main-canvas-touch.handler'; | ||
import { ChartBaseElement } from '../../model/chart-base-element'; | ||
@@ -21,3 +20,2 @@ import { pixelsToUnits } from '../../model/scaling/viewport.model'; | ||
* It extends the ChartBaseElement class and has the following properties: | ||
* @property {MainCanvasTouchHandler} touchHandler - An instance of the MainCanvasTouchHandler class. | ||
* @property {Point} currentPoint - An object that represents the current point of the chart area. | ||
@@ -32,3 +30,2 @@ * @property {number} xDraggedCandlesDelta - A number that represents the number of candles delta changed during X dragging. | ||
* @param {ScaleModel} scaleModel - An instance of the ScaleModel class. | ||
* @param {Element} mainCanvasParent - The parent element of the main canvas. | ||
* @param {CanvasInputListenerComponent} canvasInputListener - An instance of the CanvasInputListenerComponent class. | ||
@@ -41,3 +38,3 @@ * @param {CanvasBoundsContainer} canvasBoundsContainer - An instance of the CanvasBoundsContainer class. | ||
export class ChartAreaPanHandler extends ChartBaseElement { | ||
constructor(bus, config, scale, mainCanvasParent, canvasInputListener, canvasBoundsContainer, canvasAnimation, chartPanComponent, hitTestCanvasModel) { | ||
constructor(bus, config, scale, canvasInputListener, canvasBoundsContainer, canvasAnimation, chartPanComponent, hitTestCanvasModel) { | ||
super(); | ||
@@ -47,3 +44,2 @@ this.bus = bus; | ||
this.scale = scale; | ||
this.mainCanvasParent = mainCanvasParent; | ||
this.canvasInputListener = canvasInputListener; | ||
@@ -105,3 +101,2 @@ this.canvasBoundsContainer = canvasBoundsContainer; | ||
}; | ||
this.touchHandler = new MainCanvasTouchHandler(this.scale, this.canvasInputListener, this.mainCanvasParent); | ||
const allPanesHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.ALL_PANES); | ||
@@ -162,4 +157,2 @@ //#region drag-n-drop logic | ||
})); | ||
this.touchHandler.activate(); | ||
this.addSubscription(this.touchHandler.deactivate.bind(this.touchHandler)); | ||
} | ||
@@ -166,0 +159,0 @@ calculateDynamicSesitivity(e, maxSensitivity) { |
@@ -21,8 +21,2 @@ /* | ||
protected doActivate(): void; | ||
/** | ||
* This method overrides the doDeactivate method of the parent class and calls it using the super keyword. | ||
* It is used to deactivate the current object and perform any necessary cleanup operations. | ||
* @protected | ||
*/ | ||
protected doDeactivate(): void; | ||
} |
@@ -25,10 +25,2 @@ /* | ||
} | ||
/** | ||
* This method overrides the doDeactivate method of the parent class and calls it using the super keyword. | ||
* It is used to deactivate the current object and perform any necessary cleanup operations. | ||
* @protected | ||
*/ | ||
doDeactivate() { | ||
super.doDeactivate(); | ||
} | ||
} |
@@ -18,7 +18,2 @@ /* | ||
protected doActivate(): void; | ||
/** | ||
* This method overrides the doDeactivate method of the parent class and calls the parent method before executing its own code. | ||
* It is a protected method, which means it can only be accessed within the class and its subclasses. | ||
*/ | ||
protected doDeactivate(): void; | ||
} |
@@ -22,9 +22,2 @@ /* | ||
} | ||
/** | ||
* This method overrides the doDeactivate method of the parent class and calls the parent method before executing its own code. | ||
* It is a protected method, which means it can only be accessed within the class and its subclasses. | ||
*/ | ||
doDeactivate() { | ||
super.doDeactivate(); | ||
} | ||
} |
@@ -32,13 +32,2 @@ /* | ||
constructor(hitTest: HitBoundsTest, dragCallbacks: DragNDropComponentCallbacks, canvasInputListener: CanvasInputListenerComponent, chartPanComponent: ChartPanComponent, dragComponentOptions: DragComponentOptions); | ||
/** | ||
* Calls the parent class's doActivate method and performs any additional activation logic. | ||
* This method is protected and can only be accessed by the class itself and its subclasses. | ||
*/ | ||
protected doActivate(): void; | ||
/** | ||
* This method overrides the doDeactivate method of the parent class and calls it using the super keyword. | ||
* It is a protected method that can only be accessed within the class and its subclasses. | ||
* This method is responsible for deactivating the current object. | ||
*/ | ||
protected doDeactivate(): void; | ||
protected onDragStart: (point: Point) => void; | ||
@@ -45,0 +34,0 @@ protected onDragTick: (yDelta: number) => void; |
@@ -43,3 +43,2 @@ /* | ||
this.dragCallbacks.onDragEnd && this.dragCallbacks.onDragEnd(this.draggedPixels); | ||
this.chartPanComponent.activateChartPanHandlers(); | ||
} | ||
@@ -49,17 +48,2 @@ } | ||
} | ||
/** | ||
* Calls the parent class's doActivate method and performs any additional activation logic. | ||
* This method is protected and can only be accessed by the class itself and its subclasses. | ||
*/ | ||
doActivate() { | ||
super.doActivate(); | ||
} | ||
/** | ||
* This method overrides the doDeactivate method of the parent class and calls it using the super keyword. | ||
* It is a protected method that can only be accessed within the class and its subclasses. | ||
* This method is responsible for deactivating the current object. | ||
*/ | ||
doDeactivate() { | ||
super.doDeactivate(); | ||
} | ||
} |
@@ -10,3 +10,3 @@ /* | ||
import EventBus from '../../events/event-bus'; | ||
import { ChartBaseElement, ChartEntity } from '../../model/chart-base-element'; | ||
import { ChartBaseElement } from '../../model/chart-base-element'; | ||
import { CanvasInputListenerComponent } from '../../inputlisteners/canvas-input-listener.component'; | ||
@@ -17,2 +17,3 @@ import { ScaleModel } from '../../model/scale.model'; | ||
import { HitTestCanvasModel } from '../../model/hit-test-canvas.model'; | ||
import { MainCanvasTouchHandler } from '../../inputhandlers/main-canvas-touch.handler'; | ||
export declare class ChartPanComponent extends ChartBaseElement { | ||
@@ -28,18 +29,6 @@ private eventBus; | ||
private hitTestCanvasModel; | ||
chartPanComponents: Array<ChartEntity>; | ||
chartAreaPanHandler: ChartAreaPanHandler; | ||
mainCanvasTouchHandler: MainCanvasTouchHandler; | ||
constructor(eventBus: EventBus, mainScale: ScaleModel, canvasBoundsContainer: CanvasBoundsContainer, config: FullChartConfig, canvasAnimation: CanvasAnimation, canvasInputListener: CanvasInputListenerComponent, mainCanvasParent: Element, chartBaseModel: ChartBaseModel<BaseType>, hitTestCanvasModel: HitTestCanvasModel); | ||
/** | ||
* Activates the chart pan handlers. | ||
* @protected | ||
* @returns {void} | ||
*/ | ||
protected doActivate(): void; | ||
/** | ||
* This method is used to deactivate the pan handlers. | ||
* @returns {void} | ||
* @protected | ||
*/ | ||
protected doDeactivate(): void; | ||
/** | ||
* Activates user mouse handlers on main chart view. | ||
@@ -46,0 +35,0 @@ * @function |
@@ -8,2 +8,3 @@ /* | ||
import { ChartAreaPanHandler } from '../chart/chart-area-pan.handler'; | ||
import { MainCanvasTouchHandler } from '../../inputhandlers/main-canvas-touch.handler'; | ||
export class ChartPanComponent extends ChartBaseElement { | ||
@@ -21,23 +22,8 @@ constructor(eventBus, mainScale, canvasBoundsContainer, config, canvasAnimation, canvasInputListener, mainCanvasParent, chartBaseModel, hitTestCanvasModel) { | ||
this.hitTestCanvasModel = hitTestCanvasModel; | ||
this.chartPanComponents = []; | ||
this.chartAreaPanHandler = new ChartAreaPanHandler(this.eventBus, this.config, this.mainScale, this.mainCanvasParent, this.canvasInputListener, this.canvasBoundsContainer, this.canvasAnimation, this, this.hitTestCanvasModel); | ||
this.chartPanComponents.push(this.chartAreaPanHandler); | ||
this.chartAreaPanHandler = new ChartAreaPanHandler(this.eventBus, this.config, this.mainScale, this.canvasInputListener, this.canvasBoundsContainer, this.canvasAnimation, this, this.hitTestCanvasModel); | ||
this.addChildEntity(this.chartAreaPanHandler); | ||
this.mainCanvasTouchHandler = new MainCanvasTouchHandler(this.chartAreaPanHandler, this.mainScale, this.canvasInputListener, this.mainCanvasParent); | ||
this.addChildEntity(this.mainCanvasTouchHandler); | ||
} | ||
/** | ||
* Activates the chart pan handlers. | ||
* @protected | ||
* @returns {void} | ||
*/ | ||
doActivate() { | ||
this.activateChartPanHandlers(); | ||
} | ||
/** | ||
* This method is used to deactivate the pan handlers. | ||
* @returns {void} | ||
* @protected | ||
*/ | ||
doDeactivate() { | ||
this.deactivatePanHandlers(); | ||
} | ||
/** | ||
* Activates user mouse handlers on main chart view. | ||
@@ -51,3 +37,3 @@ * @function | ||
activateChartPanHandlers() { | ||
this.chartPanComponents.forEach(c => c.activate()); | ||
this.activate(); | ||
} | ||
@@ -58,3 +44,3 @@ /** | ||
deactivatePanHandlers() { | ||
this.chartPanComponents.forEach(c => c.deactivate()); | ||
this.deactivate(); | ||
} | ||
@@ -61,0 +47,0 @@ setChartPanningOptions(horizontal, vertical) { |
@@ -75,2 +75,23 @@ /* | ||
/** | ||
* Moves the canvas bounds container up by calling the movePaneUp method with the uuid of the current object. | ||
* @returns {void} | ||
*/ | ||
movePaneUp(uuid: string): void; | ||
/** | ||
* Moves the canvas bounds container down by calling the movePaneDown method with the uuid of the current object. | ||
* @returns {void} | ||
*/ | ||
movePaneDown(uuid: string): void; | ||
/** | ||
* Checks if the current pane can move up. | ||
* @returns {boolean} - Returns true if the current pane can move up, otherwise false. | ||
*/ | ||
canMovePaneUp(uuid: string): boolean; | ||
/** | ||
* Checks if the current pane can move down. | ||
* | ||
* @returns {boolean} - Returns true if the current pane is not the last one in the canvasBoundsContainer, otherwise returns false. | ||
*/ | ||
canMovePaneDown(uuid: string): boolean; | ||
/** | ||
* Removes pane from the chart and all related components | ||
@@ -81,2 +102,10 @@ * @param uuid | ||
/** | ||
* Hides a pane from the chart and all related components | ||
*/ | ||
hidePane(paneUUID: string): void; | ||
/** | ||
* Shows a pane, use if the pane is hidden | ||
*/ | ||
showPane(paneUUID: string): void; | ||
/** | ||
* Adds cursors to the chart elements based on the provided uuid and cursor type. | ||
@@ -83,0 +112,0 @@ * @private |
@@ -15,3 +15,3 @@ /* | ||
import { PaneComponent } from './pane.component'; | ||
import { flatMap } from '../../utils/array.utils'; | ||
import { firstOf, flatMap, lastOf } from '../../utils/array.utils'; | ||
export class PaneManager extends ChartBaseElement { | ||
@@ -57,3 +57,3 @@ /** | ||
this.canvasBoundsContainer.addPaneBounds(uuid, order); | ||
return () => this.canvasBoundsContainer.removedPaneBounds(uuid); | ||
return () => this.canvasBoundsContainer.removePaneBounds(uuid); | ||
} | ||
@@ -116,2 +116,35 @@ /** | ||
/** | ||
* Moves the canvas bounds container up by calling the movePaneUp method with the uuid of the current object. | ||
* @returns {void} | ||
*/ | ||
movePaneUp(uuid) { | ||
this.canvasBoundsContainer.movePaneUp(uuid); | ||
} | ||
/** | ||
* Moves the canvas bounds container down by calling the movePaneDown method with the uuid of the current object. | ||
* @returns {void} | ||
*/ | ||
movePaneDown(uuid) { | ||
this.canvasBoundsContainer.movePaneDown(uuid); | ||
} | ||
/** | ||
* Checks if the current pane can move up. | ||
* @returns {boolean} - Returns true if the current pane can move up, otherwise false. | ||
*/ | ||
canMovePaneUp(uuid) { | ||
var _a, _b; | ||
const firstVisiblePane = firstOf(this.canvasBoundsContainer.panesOrder.filter(uuid => { var _a, _b; return (_b = (_a = this.panes[uuid]) === null || _a === void 0 ? void 0 : _a.visible) !== null && _b !== void 0 ? _b : false; })); | ||
return uuid !== firstVisiblePane && ((_b = (_a = this.panes[uuid]) === null || _a === void 0 ? void 0 : _a.visible) !== null && _b !== void 0 ? _b : false); | ||
} | ||
/** | ||
* Checks if the current pane can move down. | ||
* | ||
* @returns {boolean} - Returns true if the current pane is not the last one in the canvasBoundsContainer, otherwise returns false. | ||
*/ | ||
canMovePaneDown(uuid) { | ||
var _a, _b; | ||
const lastVisiblePane = lastOf(this.canvasBoundsContainer.panesOrder.filter(uuid => { var _a, _b; return (_b = (_a = this.panes[uuid]) === null || _a === void 0 ? void 0 : _a.visible) !== null && _b !== void 0 ? _b : false; })); | ||
return uuid !== lastVisiblePane && ((_b = (_a = this.panes[uuid]) === null || _a === void 0 ? void 0 : _a.visible) !== null && _b !== void 0 ? _b : false); | ||
} | ||
/** | ||
* Removes pane from the chart and all related components | ||
@@ -122,11 +155,41 @@ * @param uuid | ||
const pane = this.panes[uuid]; | ||
if (pane !== undefined) { | ||
this.paneRemovedSubject.next(pane); | ||
pane.disable(); | ||
pane.yExtentComponents.forEach(yExtentComponent => yExtentComponent.disable()); | ||
delete this.panes[uuid]; | ||
this.recalculateState(); | ||
if (pane === undefined) { | ||
return; | ||
} | ||
this.paneRemovedSubject.next(pane); | ||
pane.disable(); | ||
pane.yExtentComponents.forEach(yExtentComponent => yExtentComponent.disable()); | ||
delete this.panes[uuid]; | ||
this.recalculateState(); | ||
} | ||
/** | ||
* Hides a pane from the chart and all related components | ||
*/ | ||
hidePane(paneUUID) { | ||
const pane = this.panes[paneUUID]; | ||
// hide pane only if we have more than one visible pane | ||
if (pane === undefined || !pane.visible) { | ||
return; | ||
} | ||
const paneResizerId = CanvasElement.PANE_UUID_RESIZER(paneUUID); | ||
const resizer = this.userInputListenerComponents.find(el => el instanceof BarResizerComponent && el.id === paneResizerId); | ||
resizer === null || resizer === void 0 ? void 0 : resizer.disable(); | ||
this.canvasBoundsContainer.hidePaneBounds(paneUUID); | ||
this.recalculateState(); | ||
} | ||
/** | ||
* Shows a pane, use if the pane is hidden | ||
*/ | ||
showPane(paneUUID) { | ||
const pane = this.panes[paneUUID]; | ||
const paneResizerId = CanvasElement.PANE_UUID_RESIZER(paneUUID); | ||
if (pane === undefined || pane.visible) { | ||
return; | ||
} | ||
const resizer = this.userInputListenerComponents.find(el => el instanceof BarResizerComponent && el.id === paneResizerId); | ||
resizer === null || resizer === void 0 ? void 0 : resizer.enable(); | ||
this.canvasBoundsContainer.showPaneBounds(paneUUID); | ||
this.recalculateState(); | ||
} | ||
/** | ||
* Adds cursors to the chart elements based on the provided uuid and cursor type. | ||
@@ -133,0 +196,0 @@ * @private |
@@ -47,3 +47,2 @@ /* | ||
private hitTestCanvasModel; | ||
private _paneOrder; | ||
/** | ||
@@ -57,2 +56,3 @@ * Pane hit test (without Y-Axis and resizer) | ||
get dataSeries(): DataSeriesModel<import("../../model/data-series.model").DataSeriesPoint, import("../../model/data-series.model").VisualSeriesPoint>[]; | ||
get visible(): boolean; | ||
mainExtent: YExtentComponent; | ||
@@ -102,18 +102,2 @@ constructor(chartBaseModel: ChartBaseModel<'candle'>, mainCanvasModel: CanvasModel, yAxisLabelsCanvasModel: CanvasModel, dynamicObjectsCanvasModel: CanvasModel, hitTestController: PaneHitTestController, config: FullChartConfig, mainScale: ScaleModel, drawingManager: DrawingManager, chartPanComponent: ChartPanComponent, canvasInputListener: CanvasInputListenerComponent, canvasAnimation: CanvasAnimation, cursorHandler: CursorHandler, eventBus: EventBus, canvasBoundsContainer: CanvasBoundsContainer, uuid: string, seriesAddedSubject: Subject<DataSeriesModel>, seriesRemovedSubject: Subject<DataSeriesModel>, hitTestCanvasModel: HitTestCanvasModel, options?: AtLeastOne<YExtentCreationOptions>); | ||
/** | ||
* Hides the pane by removing its bounds from the canvasBoundsContainer and firing a draw event. | ||
* @function | ||
* @name hide | ||
* @memberof PaneComponent | ||
* @returns {void} | ||
*/ | ||
hide(): void; | ||
/** | ||
* Adds the bounds of the pane to the canvas bounds container and fires a draw event. | ||
* @function | ||
* @name show | ||
* @memberof PaneComponent | ||
* @returns {void} | ||
*/ | ||
show(): void; | ||
/** | ||
* Creates a new DataSeriesModel object. | ||
@@ -146,2 +130,3 @@ * @returns {DataSeriesModel} - The newly created DataSeriesModel object. | ||
* @returns {void} | ||
* @deprecated Use `paneManager.movePaneUp()` instead | ||
*/ | ||
@@ -152,2 +137,3 @@ moveUp(): void; | ||
* @returns {void} | ||
* @deprecated Use `paneManager.movePaneDown()` instead | ||
*/ | ||
@@ -158,2 +144,3 @@ moveDown(): void; | ||
* @returns {boolean} - Returns true if the current pane can move up, otherwise false. | ||
* @deprecated Use `paneManager.canMovePaneUp()` instead | ||
*/ | ||
@@ -165,2 +152,3 @@ canMoveUp(): boolean; | ||
* @returns {boolean} - Returns true if the current pane is not the last one in the canvasBoundsContainer, otherwise returns false. | ||
* @deprecated Use `paneManager.canMovePaneDown()` instead | ||
*/ | ||
@@ -167,0 +155,0 @@ canMoveDown(): boolean; |
@@ -25,2 +25,5 @@ /* | ||
} | ||
get visible() { | ||
return this.canvasBoundsContainer.graphsHeightRatio[this.uuid] > 0; | ||
} | ||
constructor(chartBaseModel, mainCanvasModel, yAxisLabelsCanvasModel, dynamicObjectsCanvasModel, hitTestController, config, mainScale, drawingManager, chartPanComponent, canvasInputListener, canvasAnimation, cursorHandler, eventBus, canvasBoundsContainer, uuid, seriesAddedSubject, seriesRemovedSubject, hitTestCanvasModel, options) { | ||
@@ -46,3 +49,2 @@ super(); | ||
this.hitTestCanvasModel = hitTestCanvasModel; | ||
this._paneOrder = 0; | ||
this.yExtentComponents = []; | ||
@@ -182,25 +184,2 @@ this.getYAxisBounds = () => { | ||
/** | ||
* Hides the pane by removing its bounds from the canvasBoundsContainer and firing a draw event. | ||
* @function | ||
* @name hide | ||
* @memberof PaneComponent | ||
* @returns {void} | ||
*/ | ||
hide() { | ||
this._paneOrder = this.canvasBoundsContainer.panesOrder.indexOf(this.uuid); | ||
this.canvasBoundsContainer.removedPaneBounds(this.uuid); | ||
this.eventBus.fireDraw(); | ||
} | ||
/** | ||
* Adds the bounds of the pane to the canvas bounds container and fires a draw event. | ||
* @function | ||
* @name show | ||
* @memberof PaneComponent | ||
* @returns {void} | ||
*/ | ||
show() { | ||
this.canvasBoundsContainer.addPaneBounds(this.uuid, this._paneOrder); | ||
this.eventBus.fireDraw(); | ||
} | ||
/** | ||
* Creates a new DataSeriesModel object. | ||
@@ -245,2 +224,3 @@ * @returns {DataSeriesModel} - The newly created DataSeriesModel object. | ||
* @returns {void} | ||
* @deprecated Use `paneManager.movePaneUp()` instead | ||
*/ | ||
@@ -253,2 +233,3 @@ moveUp() { | ||
* @returns {void} | ||
* @deprecated Use `paneManager.movePaneDown()` instead | ||
*/ | ||
@@ -261,6 +242,7 @@ moveDown() { | ||
* @returns {boolean} - Returns true if the current pane can move up, otherwise false. | ||
* @deprecated Use `paneManager.canMovePaneUp()` instead | ||
*/ | ||
canMoveUp() { | ||
const firstPane = firstOf(this.canvasBoundsContainer.panesOrder); | ||
return this.uuid !== firstPane; | ||
const firstVisiblePane = firstOf(this.canvasBoundsContainer.panesOrder.filter(uuid => this.canvasBoundsContainer.graphsHeightRatio[uuid] > 0)); | ||
return this.uuid !== firstVisiblePane && this.visible; | ||
} | ||
@@ -271,6 +253,7 @@ /** | ||
* @returns {boolean} - Returns true if the current pane is not the last one in the canvasBoundsContainer, otherwise returns false. | ||
* @deprecated Use `paneManager.canMovePaneDown()` instead | ||
*/ | ||
canMoveDown() { | ||
const lastPane = lastOf(this.canvasBoundsContainer.panesOrder); | ||
return this.uuid !== lastPane; | ||
const lastVisiblePane = lastOf(this.canvasBoundsContainer.panesOrder.filter(uuid => this.canvasBoundsContainer.graphsHeightRatio[uuid] > 0)); | ||
return this.uuid !== lastVisiblePane && this.visible; | ||
} | ||
@@ -277,0 +260,0 @@ get regularFormatter() { |
@@ -25,3 +25,3 @@ /* | ||
export declare class BarResizerComponent extends ChartBaseElement { | ||
private id; | ||
readonly id: string; | ||
private boundsProvider; | ||
@@ -28,0 +28,0 @@ private hitTest; |
@@ -42,2 +42,3 @@ /* | ||
this.hitTestCanvasModel.hitTestDrawersPredicateSubject.next(false); | ||
this.chartPanComponent.deactivatePanHandlers(); | ||
}; | ||
@@ -50,2 +51,3 @@ this.onYDragEnd = () => { | ||
this.hitTestCanvasModel.hitTestDrawersPredicateSubject.next(true); | ||
this.chartPanComponent.activateChartPanHandlers(); | ||
}; | ||
@@ -80,3 +82,3 @@ this.onYDragTick = (dragInfo) => { | ||
onDragStart: this.onYDragStart, | ||
onDragEnd: this.onYDragEnd | ||
onDragEnd: this.onYDragEnd, | ||
}, this.canvasInputListener, this.chartPanComponent, { | ||
@@ -83,0 +85,0 @@ dragPredicate: this.dragPredicate, |
@@ -7,3 +7,3 @@ /* | ||
import { Subject } from 'rxjs'; | ||
import { CanvasElement } from '../../canvas/canvas-bounds-container'; | ||
import { CanvasElement, DEFAULT_MIN_PANE_HEIGHT } from '../../canvas/canvas-bounds-container'; | ||
import { ChartBaseElement } from '../../model/chart-base-element'; | ||
@@ -39,3 +39,3 @@ import { DragNDropYComponent } from '../dran-n-drop_helper/drag-n-drop-y.component'; | ||
this.lastYHeight = this.scale.yEnd - this.scale.yStart; | ||
this.lastYPxHeight = this.bounds.getBounds(CanvasElement.Y_AXIS).height; | ||
this.lastYPxHeight = Math.max(this.bounds.getBounds(CanvasElement.Y_AXIS).height, DEFAULT_MIN_PANE_HEIGHT); | ||
// Stop redrawing hit test | ||
@@ -78,3 +78,3 @@ this.hitTestCanvasModel.hitTestDrawersPredicateSubject.next(false); | ||
}, canvasInputListener, panning, { | ||
dragPredicate: () => panning.chartAreaPanHandler.chartPanningOptions.vertical && config.type !== 'percent' && config.visible, | ||
dragPredicate: () => panning.chartAreaPanHandler.chartPanningOptions.vertical && config.type !== 'percent', | ||
}); | ||
@@ -81,0 +81,0 @@ this.addChildEntity(dragNDropYComponent); |
@@ -179,3 +179,3 @@ /* | ||
this.config.components.yAxis.visible = isVisible; | ||
isVisible ? this.enable() : this.disable(); | ||
isVisible ? this.activate() : this.deactivate(); | ||
this.model.fancyLabelsModel.updateLabels(); | ||
@@ -182,0 +182,0 @@ this.model.baseLabelsModel.updateLabels(); |
@@ -61,3 +61,3 @@ /* | ||
xFormatter: DateTimeFormatter; | ||
constructor(crossEventProducer: CrossEventProducerComponent, scale: ScaleModel, config: FullChartConfig, chartModel: ChartModel, canvasInputListener: CanvasInputListenerComponent, canvasBoundsContainer: CanvasBoundsContainer, paneManager: PaneManager, timeZoneModel: TimeZoneModel, formatterFactory: (format: string) => (timestamp: number | Date) => string); | ||
constructor(crossEventProducer: CrossEventProducerComponent, scale: ScaleModel, config: FullChartConfig, chartModel: ChartModel, canvasInputListener: CanvasInputListenerComponent, canvasBoundsContainer: CanvasBoundsContainer, paneManager: PaneManager, timeZoneModel: TimeZoneModel, formatterFactory: (format: string) => (timestamp: number) => string); | ||
/** | ||
@@ -64,0 +64,0 @@ * This method is responsible for activating the chart hover functionality. It subscribes to several observables to |
@@ -9,2 +9,3 @@ /* | ||
import { ScaleModel } from '../model/scale.model'; | ||
import { ChartAreaPanHandler } from '../components/chart/chart-area-pan.handler'; | ||
/** | ||
@@ -14,2 +15,3 @@ * Handles chart touch events. | ||
export declare class MainCanvasTouchHandler extends ChartBaseElement { | ||
private chartAreaPanHandler; | ||
private scale; | ||
@@ -19,3 +21,5 @@ private canvasInputListeners; | ||
private touchedCandleIndexes; | ||
constructor(scale: ScaleModel, canvasInputListeners: CanvasInputListenerComponent, mainCanvasParent: Element); | ||
private pinchDistance; | ||
private isDraggable; | ||
constructor(chartAreaPanHandler: ChartAreaPanHandler, scale: ScaleModel, canvasInputListeners: CanvasInputListenerComponent, mainCanvasParent: Element); | ||
/** | ||
@@ -37,5 +41,10 @@ * Activates canvas input listeners for touch start and touch move events. | ||
* @returns {void} | ||
*/ | ||
*/ | ||
private handleTouchMoveEvent; | ||
/** | ||
* Handles touch end event | ||
* @returns {void} | ||
*/ | ||
private handleTouchEndEvent; | ||
/** | ||
* Gets candle positions touched by user in pixels. | ||
@@ -42,0 +51,0 @@ * @param e - touch event with "touches" array |
@@ -7,2 +7,3 @@ /* | ||
import { ChartBaseElement } from '../model/chart-base-element'; | ||
const MIN_PINCH_DISTANCE = 30; | ||
/** | ||
@@ -12,4 +13,5 @@ * Handles chart touch events. | ||
export class MainCanvasTouchHandler extends ChartBaseElement { | ||
constructor(scale, canvasInputListeners, mainCanvasParent) { | ||
constructor(chartAreaPanHandler, scale, canvasInputListeners, mainCanvasParent) { | ||
super(); | ||
this.chartAreaPanHandler = chartAreaPanHandler; | ||
this.scale = scale; | ||
@@ -20,2 +22,6 @@ this.canvasInputListeners = canvasInputListeners; | ||
this.touchedCandleIndexes = [0, 0]; | ||
// number of px between touch events | ||
this.pinchDistance = 0; | ||
// used when maximum zoom in/out reached, can't use deactivate because it unsubscribes from all touch events | ||
this.isDraggable = true; | ||
} | ||
@@ -30,2 +36,3 @@ /** | ||
this.addRxSubscription(this.canvasInputListeners.observeTouchMove().subscribe(e => this.handleTouchMoveEvent(e))); | ||
this.addRxSubscription(this.canvasInputListeners.observeTouchEndDocument().subscribe(e => this.handleTouchEndEvent(e))); | ||
} | ||
@@ -39,2 +46,4 @@ /** | ||
if (e.touches.length === 2) { | ||
this.isDraggable = true; | ||
this.chartAreaPanHandler.deactivate(); | ||
// @ts-ignore | ||
@@ -49,3 +58,3 @@ // TODO rework this | ||
* @returns {void} | ||
*/ | ||
*/ | ||
handleTouchMoveEvent(e) { | ||
@@ -57,2 +66,12 @@ if (e.touches.length === 2) { | ||
/** | ||
* Handles touch end event | ||
* @returns {void} | ||
*/ | ||
handleTouchEndEvent(e) { | ||
// zero touches means the user stopped resizing completely (both fingers are up) | ||
if (e.touches.length === 0) { | ||
this.chartAreaPanHandler.activate(); | ||
} | ||
} | ||
/** | ||
* Gets candle positions touched by user in pixels. | ||
@@ -80,2 +99,12 @@ * @param e - touch event with "touches" array | ||
pinchHandler(candleIndexes, touchPositions) { | ||
const diff = Math.abs(touchPositions[0]) - Math.abs(touchPositions[1]); | ||
const pinchDistance = Math.abs(diff); | ||
const zoomIn = pinchDistance > this.pinchDistance; | ||
if (this.scale.isMaxZoomXReached(zoomIn)) { | ||
this.isDraggable = false; | ||
} | ||
if (!this.isDraggable || pinchDistance < MIN_PINCH_DISTANCE) { | ||
return; | ||
} | ||
this.pinchDistance = pinchDistance; | ||
const first = (touchPositions[0] * candleIndexes[1] - touchPositions[1] * candleIndexes[0]) / | ||
@@ -86,4 +115,7 @@ (touchPositions[0] - touchPositions[1]); | ||
this.scale.getBounds().width; | ||
if (first >= last) { | ||
return; | ||
} | ||
this.scale.setXScale(first, last); | ||
} | ||
} |
@@ -22,2 +22,3 @@ /* | ||
private chartModel; | ||
private chartPanComponent; | ||
private canvasModel; | ||
@@ -33,2 +34,4 @@ private canvasInputListener; | ||
protected doActivate(): void; | ||
private dragStartCb; | ||
private dragEndCb; | ||
private dragTickCb; | ||
@@ -35,0 +38,0 @@ /** |
@@ -18,2 +18,3 @@ /* | ||
this.chartModel = chartModel; | ||
this.chartPanComponent = chartPanComponent; | ||
this.canvasModel = canvasModel; | ||
@@ -30,2 +31,4 @@ this.canvasInputListener = canvasInputListener; | ||
}); | ||
this.dragStartCb = () => this.chartPanComponent.deactivatePanHandlers(); | ||
this.dragEndCb = () => this.chartPanComponent.activateChartPanHandlers(); | ||
this.dragTickCb = (dragInfo) => { | ||
@@ -42,2 +45,4 @@ const { delta: yDelta } = dragInfo; | ||
onDragTick: this.dragTickCb, | ||
onDragStart: this.dragStartCb, | ||
onDragEnd: this.dragEndCb, | ||
}, canvasInputListener, chartPanComponent); | ||
@@ -44,0 +49,0 @@ this.addChildEntity(dndHelper); |
@@ -49,2 +49,3 @@ /* | ||
* @returns {void} | ||
* @deprecated use `ChartBaseElement.activate()` instead | ||
*/ | ||
@@ -56,2 +57,3 @@ enable(): void; | ||
* @returns {void} | ||
* @deprecated use `ChartBaseElement.deactivate()` instead | ||
*/ | ||
@@ -58,0 +60,0 @@ disable(): void; |
@@ -37,2 +37,3 @@ /* | ||
* @returns {void} | ||
* @deprecated use `ChartBaseElement.activate()` instead | ||
*/ | ||
@@ -49,2 +50,3 @@ enable() { | ||
* @returns {void} | ||
* @deprecated use `ChartBaseElement.deactivate()` instead | ||
*/ | ||
@@ -51,0 +53,0 @@ disable() { |
@@ -12,6 +12,6 @@ /* | ||
export interface DateTimeFormatter { | ||
(date: Date | number): string; | ||
(date: number): string; | ||
} | ||
export type DateTimeFormatterFactory = (format: string) => DateTimeFormatter; | ||
export declare const defaultDateTimeFormatter: () => (date: Date | number) => string; | ||
export declare const defaultDateTimeFormatter: () => (date: number) => string; | ||
/** | ||
@@ -24,2 +24,19 @@ * Default chart-core time formatter. | ||
export declare const dateTimeFormatterFactory: (config: FullChartConfig, offsetFunction: (timezone: string) => (time: number) => Date) => DateTimeFormatterFactory; | ||
export declare const recalculateXFormatter: (xAxisLabelFormat: string | Array<DateTimeFormatConfig>, period: number, formatterFactory: (format: string) => (timestamp: number | Date) => string) => DateTimeFormatter; | ||
/** | ||
* Returns an array of short day names based on the provided configuration object. | ||
* If the configuration object does not contain shortDays property, it returns an array of default short day names. | ||
* | ||
* @param {TimeFormatterConfig} config - The configuration object containing shortDays property. | ||
* @returns {string[]} - An array of short day names. | ||
*/ | ||
export declare function getShortDays(config: TimeFormatterConfig): string[]; | ||
/** | ||
* Returns an array of short month names based on the provided configuration object. | ||
* If the configuration object does not have a 'shortMonths' property, it returns the default array of short month names. | ||
* | ||
* @param {TimeFormatterConfig} config - The configuration object that contains the shortMonths property. | ||
* @returns {string[]} - An array of short month names. | ||
*/ | ||
export declare function getShortMonths(config: TimeFormatterConfig): string[]; | ||
export declare const recalculateXFormatter: (xAxisLabelFormat: string | Array<DateTimeFormatConfig>, period: number, formatterFactory: (format: string) => (timestamp: number) => string) => DateTimeFormatter; | ||
export declare const formatDate: (date: Date, patternStr: string, daysOfWeek: string[], months: string[]) => string; |
@@ -34,3 +34,2 @@ /* | ||
}); | ||
const re = new RegExp(Object.keys(patterns).sort().reverse().join('|'), 'g'); | ||
/** | ||
@@ -62,10 +61,2 @@ * Returns a string that concatenates the result of the function getPrefix with the input string fn and the string '()'. | ||
} | ||
/** | ||
* Returns a string that concatenates a pattern from an object with a string | ||
* @param {string} pattern - The key of the pattern to be concatenated | ||
* @returns {string} - A string that concatenates a pattern from an object with a string | ||
*/ | ||
function applyPattern(pattern) { | ||
return "' + (" + patterns[pattern] + ") + '"; | ||
} | ||
return function (pattern) { | ||
@@ -94,7 +85,6 @@ var _a; | ||
function (date) { | ||
return date instanceof Date ? date : new Date(+date); | ||
return new Date(+date); | ||
}, | ||
}; | ||
// eslint-disable-next-line no-new-func | ||
return new Function('date', 'date=this.' + 'tzDate' + "(date); return '" + pattern.replace(re, applyPattern) + "'").bind(context); | ||
return (date) => formatDate(context.tzDate(date), pattern, context.shortDays, context.shortMonths); | ||
}; | ||
@@ -109,3 +99,3 @@ }; | ||
*/ | ||
function getShortDays(config) { | ||
export function getShortDays(config) { | ||
var _a; | ||
@@ -121,3 +111,3 @@ return (_a = config.shortDays) !== null && _a !== void 0 ? _a : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; | ||
*/ | ||
function getShortMonths(config) { | ||
export function getShortMonths(config) { | ||
var _a; | ||
@@ -162,1 +152,59 @@ return (_a = config.shortMonths) !== null && _a !== void 0 ? _a : ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; | ||
}; | ||
//#region Custom date pattern parser, transforms Date object to string by given pattern | ||
// examples: dd.MM => 15.12, YYYY => 2024, HH:mm => 15:56 | ||
export const formatDate = (date, patternStr, daysOfWeek, months) => { | ||
if (!patternStr) { | ||
patternStr = 'M/d/yyyy'; | ||
} | ||
const day = date.getDate(); | ||
const month = date.getMonth(); | ||
const year = date.getFullYear(); | ||
const hour = date.getHours(); | ||
const minute = date.getMinutes(); | ||
const second = date.getSeconds(); | ||
const miliseconds = date.getMilliseconds(); | ||
const h = hour % 12; | ||
const hh = twoDigitPad(h); | ||
const HH = twoDigitPad(hour); | ||
const mm = twoDigitPad(minute); | ||
const ss = twoDigitPad(second); | ||
const aaa = hour < 12 ? 'AM' : 'PM'; | ||
const EEEE = daysOfWeek[date.getDay()]; | ||
const EEE = EEEE.substring(0, 3); | ||
const dd = twoDigitPad(day); | ||
const M = month + 1; | ||
const MM = twoDigitPad(M); | ||
const MMMM = months[month]; | ||
const MMM = MMMM.substring(0, 3); | ||
const yyyy = year + ''; | ||
const yy = yyyy.substring(2, 4); | ||
// checks to see if month name will be used | ||
patternStr = patternStr | ||
.replace('hh', hh + '') | ||
.replace('h', h + '') | ||
.replace('HH', HH + '') | ||
.replace('H', hour + '') | ||
.replace('mm', mm + '') | ||
.replace('m', minute + '') | ||
.replace('ss', ss + '') | ||
.replace('s', second + '') | ||
.replace('S', miliseconds + '') | ||
.replace('dd', dd + '') | ||
.replace('d', day + '') | ||
.replace('EEEE', EEEE) | ||
.replace('EEE', EEE) | ||
.replace('YYYY', yyyy) | ||
.replace('yyyy', yyyy) | ||
.replace('YY', yy) | ||
.replace('yy', yy) | ||
.replace('aaa', aaa); | ||
if (patternStr.indexOf('MMM') > -1) { | ||
patternStr = patternStr.replace('MMMM', MMMM).replace('MMM', MMM); | ||
} | ||
else { | ||
patternStr = patternStr.replace('MM', MM + '').replace('M', M + ''); | ||
} | ||
return patternStr; | ||
}; | ||
const twoDigitPad = (num) => (typeof num === 'number' && num < 10 ? '0' + num : num); | ||
//#endregion |
@@ -49,2 +49,6 @@ /* | ||
xConstraints: Constraints[]; | ||
maxZoomReached: { | ||
zoomIn: boolean; | ||
zoomOut: boolean; | ||
}; | ||
readonly state: ChartScale; | ||
@@ -86,2 +90,3 @@ constructor(config: FullChartConfig, getBounds: BoundsProvider, canvasAnimation: CanvasAnimation); | ||
private zoomXTo; | ||
isMaxZoomXReached(zoomIn: boolean): boolean; | ||
/** | ||
@@ -88,0 +93,0 @@ * Moves the viewport to exactly xStart..xEnd place. |
@@ -44,2 +44,3 @@ /* | ||
this.xConstraints = []; | ||
this.maxZoomReached = { zoomIn: false, zoomOut: false }; | ||
this.scalePostProcessor = (initialState, state) => { | ||
@@ -53,3 +54,7 @@ // for now <s>reduceRight<s/> reduce bcs ChartModel#getZoomConstrait should be invoked first | ||
this.offsets = this.config.components.offsets; | ||
this.addXConstraint((initialState, state) => zoomConstraint(initialState, state, this.config.components.chart, this.getBounds)); | ||
this.addXConstraint((initialState, state) => { | ||
const { maxZoomReached, newState } = zoomConstraint(initialState, state, this.config.components.chart, this.getBounds); | ||
this.maxZoomReached = maxZoomReached; | ||
return newState; | ||
}); | ||
} | ||
@@ -146,2 +151,5 @@ doActivate() { | ||
} | ||
isMaxZoomXReached(zoomIn) { | ||
return (this.maxZoomReached.zoomIn && zoomIn) || (this.maxZoomReached.zoomOut && !zoomIn); | ||
} | ||
/** | ||
@@ -148,0 +156,0 @@ * Moves the viewport to exactly xStart..xEnd place. |
@@ -36,9 +36,7 @@ /* | ||
export declare const zoomConstraint: (_: ViewportModelState, state: ViewportModelState, chartConfig: ChartConfigComponentsChart, boundsProvider: BoundsProvider) => { | ||
xStart: number; | ||
xEnd: number; | ||
yStart: number; | ||
yEnd: number; | ||
zoomX: number; | ||
zoomY: number; | ||
inverseY: boolean; | ||
newState: ViewportModelState; | ||
maxZoomReached: { | ||
zoomIn: boolean; | ||
zoomOut: boolean; | ||
}; | ||
}; |
@@ -56,3 +56,3 @@ /* | ||
newState.zoomX = calculateZoom(newState.xEnd - newState.xStart, bounds.width); | ||
return newState; | ||
return { newState, maxZoomReached: { zoomOut: true, zoomIn: false } }; | ||
} | ||
@@ -62,6 +62,6 @@ if (minViewportReached) { | ||
newState.zoomX = calculateZoom(newState.xEnd - newState.xStart, bounds.width); | ||
return newState; | ||
return { newState, maxZoomReached: { zoomOut: false, zoomIn: true } }; | ||
} | ||
} | ||
return newState; | ||
return { newState, maxZoomReached: { zoomOut: false, zoomIn: false } }; | ||
}; |
@@ -90,3 +90,5 @@ /* | ||
return time => { | ||
return new Date(time + getTimezoneOffset(timezone, time) + new Date(time).getTimezoneOffset() * timeMultiplier); | ||
return new Date(time + | ||
getTimezoneOffset(timezone, time) + | ||
new Date(time).getTimezoneOffset() * timeMultiplier); | ||
}; | ||
@@ -93,0 +95,0 @@ } |
{ | ||
"name": "@devexperts/dxcharts-lite", | ||
"version": "2.4.6", | ||
"version": "2.5.0", | ||
"description": "DXCharts Lite", | ||
@@ -5,0 +5,0 @@ "author": "Devexperts Solutions IE Limited", |
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
1738935
386
31877