UNPKG

@amcharts/amcharts5

Version:
777 lines 28.7 kB
import { LineSeries } from "../../xy/series/LineSeries"; import { Bullet } from "../../../core/render/Bullet"; import { Circle } from "../../../core/render/Circle"; import { Container } from "../../../core/render/Container"; import { Template } from "../../../core/util/Template"; import { ListTemplate } from "../../../core/util/List"; import * as $array from "../../../core/util/Array"; import * as $time from "../../../core/util/Time"; import * as $type from "../../../core/util/Type"; import * as $math from "../../../core/util/Math"; import * as $object from "../../../core/util/Object"; export class DrawingSeries extends LineSeries { constructor() { super(...arguments); Object.defineProperty(this, "_clickDp", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_moveDp", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_downDp", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_upDp", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_drawingEnabled", { enumerable: true, configurable: true, writable: true, value: false }); Object.defineProperty(this, "_isDragging", { enumerable: true, configurable: true, writable: true, value: false }); Object.defineProperty(this, "_clickPointerPoint", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_movePointerPoint", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_isDrawing", { enumerable: true, configurable: true, writable: true, value: false }); Object.defineProperty(this, "_isPointerDown", { enumerable: true, configurable: true, writable: true, value: false }); Object.defineProperty(this, "_index", { enumerable: true, configurable: true, writable: true, value: 0 }); Object.defineProperty(this, "_di", { enumerable: true, configurable: true, writable: true, value: [] }); Object.defineProperty(this, "_dragStartPX", { enumerable: true, configurable: true, writable: true, value: 0 }); Object.defineProperty(this, "_dragStartY", { enumerable: true, configurable: true, writable: true, value: 0 }); Object.defineProperty(this, "_dvpX", { enumerable: true, configurable: true, writable: true, value: {} }); Object.defineProperty(this, "_dvY", { enumerable: true, configurable: true, writable: true, value: {} }); Object.defineProperty(this, "_isHover", { enumerable: true, configurable: true, writable: true, value: false }); Object.defineProperty(this, "_erasingEnabled", { enumerable: true, configurable: true, writable: true, value: false }); Object.defineProperty(this, "_tag", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "_movePoint", { enumerable: true, configurable: true, writable: true, value: { x: 0, y: 0 } }); Object.defineProperty(this, "grips", { enumerable: true, configurable: true, writable: true, value: new ListTemplate(Template.new({}), () => Container._new(this._root, { themeTags: ["grip"], setStateOnChildren: true, draggable: true }, [this.grips.template])) }); Object.defineProperty(this, "circles", { enumerable: true, configurable: true, writable: true, value: new ListTemplate(Template.new({}), () => Circle._new(this._root, {}, [this.circles.template])) }); Object.defineProperty(this, "outerCircles", { enumerable: true, configurable: true, writable: true, value: new ListTemplate(Template.new({}), () => Circle._new(this._root, { themeTags: ["outline"] }, [this.outerCircles.template])) }); } _afterNew() { this.addTag("drawing"); this.setPrivate("allowChangeSnap", true); if (this._tag) { this.addTag(this._tag); } this.set("valueYField", "valueY"); this.set("valueXField", "valueX"); super._afterNew(); this.set("connect", false); this.set("autoGapCount", Infinity); this.set("ignoreMinMax", true); this.set("groupDataDisabled", true); const strokesTemplate = this.strokes.template; strokesTemplate.set("templateField", "stroke"); const fillsTemplate = this.fills.template; fillsTemplate.setAll({ templateField: "fill" }); fillsTemplate.events.on("dragstart", (e) => { this._handleFillDragStart(e, this._getIndex(e.target)); this._isPointerDown = true; }); fillsTemplate.events.on("pointerdown", (e) => { const index = this._getIndex(e.target); if (this._erasingEnabled) { this._disposeIndex(index); } else { const originalEvent = e.originalEvent; if (!originalEvent.button && this._drawingEnabled) { this._handlePointerDown(e); } } const stroke = this.strokes.getIndex(this._getStrokeIndex(index)); if (stroke) { stroke.dragStart(e); } }); strokesTemplate.events.on("pointerdown", (e) => { if (this._erasingEnabled) { this._disposeIndex(this._getIndex(e.target)); } else { const originalEvent = e.originalEvent; if (!originalEvent.button && this._drawingEnabled) { this._handlePointerDown(e); } } }); fillsTemplate.events.on("dragstop", (e) => { this._isPointerDown = false; const index = this._getIndex(e.target); this._handleFillDragStop(e, index); const stroke = this.strokes.getIndex(this._getStrokeIndex(index)); if (stroke) { stroke.dragStop(e); } }); fillsTemplate.events.on("pointerover", (e) => { const index = this._getIndex(e.target); const stroke = this.strokes.getIndex(this._getStrokeIndex(index)); if (stroke) { stroke.hover(); } this._isHover = true; this._showSegmentBullets(index); }); fillsTemplate.events.on("pointerout", () => { this._isHover = false; this._hideAllBullets(); }); strokesTemplate.events.on("pointerover", (e) => { this._isHover = true; this._showSegmentBullets(this._getIndex(e.target)); }); strokesTemplate.events.on("pointerout", () => { this._isHover = false; this._hideAllBullets(); }); strokesTemplate.events.on("dragstop", (e) => { this._handleFillDragStop(e, this._getIndex(e.target)); }); strokesTemplate.events.on("dragstart", (e) => { this._handleFillDragStart(e, this._getIndex(e.target)); }); this.bulletsContainer.states.create("hidden", { visible: true, opacity: 0 }); this.bullets.push((_root, _series, dataItem) => { const dataContext = dataItem.dataContext; const index = dataContext.index; const di = this._di[index]["e"]; let color = this.get("strokeColor", this.get("stroke")); if (di) { const dc = di.dataContext; if (dc) { const strokeTemplate = dc.stroke; if (strokeTemplate) { color = strokeTemplate.get("stroke"); } } } const container = this.grips.make(); container.setRaw("userData", "grip"); this.grips.push(container); const circle = container.children.push(this.circles.make()); this.circles.push(circle); circle.set("stroke", color); const outerCircle = container.children.push(this.outerCircles.make()); this.outerCircles.push(outerCircle); outerCircle.set("stroke", color); container.events.on("pointerover", (event) => { const dataItem = event.target.dataItem; if (dataItem) { const dataContext = dataItem.dataContext; this._showSegmentBullets(dataContext.index); } }); container.events.on("pointerout", () => { this._hideAllBullets(); }); this._addBulletInteraction(container); this._tweakBullet(container, dataItem); return Bullet.new(this._root, { locationX: undefined, sprite: container }); }); this.events.on("pointerover", () => { this._handlePointerOver(); }); this.events.on("pointerout", () => { this._handlePointerOut(); }); } _disposeIndex(index) { const dataItems = this._di[index]; if (dataItems) { $object.each(dataItems, (_key, dataItem) => { this.data.removeValue(dataItem.dataContext); }); } } _afterDataChange() { $array.each(this.dataItems, (dataItem) => { const dataContext = dataItem.dataContext; const index = dataContext.index; const corner = dataContext.corner; if (index != undefined) { if (this._di[index] == undefined) { this._di[index] = {}; } this._createElements(index, dataItem); this._di[index][corner] = dataItem; this._index = index; } }); } _createElements(_index, _dataItem) { } clearDrawings() { $array.each(this._di, (_dataItems, index) => { this._disposeIndex(index); }); this.data.setAll([]); this._index = 0; } _getIndex(sprite) { const userData = sprite.get("userData"); if (userData && userData.length > 0) { const dataItem = this.dataItems[userData[0]]; if (dataItem) { const dataContext = dataItem.dataContext; if (dataContext) { return dataContext.index; } } } return 0; } _getStrokeIndex(index) { let i = 0; let c = index; this.strokes.each((stroke) => { const strokeIndex = this._getIndex(stroke); if (strokeIndex == index) { c = i; } i++; }); return c; } setInteractive(value) { this.strokes.template.set("forceInactive", !value); this.fills.template.set("forceInactive", !value); this.grips.template.set("forceInactive", !value); this.circles.template.set("forceInactive", !value); this.outerCircles.template.set("forceInactive", !value); } _showSegmentBullets(index) { const dataItems = this._di[index]; if (dataItems) { $object.each(dataItems, (_key, dataItem) => { const bullets = dataItem.bullets; if (bullets) { $array.each(bullets, (bullet) => { const sprite = bullet.get("sprite"); if (sprite) { sprite.show(); } }); } }); } } _hideAllBullets() { this.strokes.each((stroke) => { stroke.unhover(); }); if (!this._drawingEnabled && !this._isDragging) { const dataItems = this.dataItems; $array.each(dataItems, (dataItem) => { const bullets = dataItem.bullets; if (bullets) { $array.each(bullets, (bullet) => { const sprite = bullet.get("sprite"); if (sprite) { sprite.hide(); } }); } }); } } showAllBullets() { $array.each(this.dataItems, (dataItem) => { const bullets = dataItem.bullets; if (bullets) { $array.each(bullets, (bullet) => { const sprite = bullet.get("sprite"); if (sprite) { sprite.show(); } }); } }); } _handleFillDragStart(event, index) { const chart = this.chart; if (chart) { const xAxis = this.get("xAxis"); const yAxis = this.get("yAxis"); const point = chart.plotContainer.toLocal(event.point); this._dragStartPX = xAxis.coordinateToPosition(point.x); const valueXns = xAxis.positionToValue(this._dragStartPX); this._dragStartY = this._getYValue(yAxis.positionToValue(yAxis.coordinateToPosition(point.y)), valueXns); const dataItems = this._di[index]; if (dataItems) { $object.each(dataItems, (key, dataItem) => { this._dvpX[key] = xAxis.valueToPosition(dataItem.get("valueX", 0)); this._dvY[key] = dataItem.get("valueY"); }); } } } _handleFillDragStop(event, index) { const chart = this.chart; if (chart) { const point = chart.plotContainer.toLocal(event.point); const xAxis = this.get("xAxis"); const yAxis = this.get("yAxis"); const posX = xAxis.coordinateToPosition(point.x); const valueXns = xAxis.positionToValue(xAxis.coordinateToPosition(point.x)); const valueY = this._getYValue(yAxis.positionToValue(yAxis.coordinateToPosition(point.y)), valueXns); const dpx = posX - this._dragStartPX; const dy = valueY - this._dragStartY; event.target.setAll({ x: 0, y: 0 }); const dataItems = this._di[index]; if (dataItems) { $object.each(dataItems, (key, dataItem) => { const dvpx = this._dvpX[key]; const dvy = this._dvY[key]; if ($type.isNumber(dvpx) && $type.isNumber(dvy)) { const vpx = dvpx + dpx; const vxns = xAxis.positionToValue(vpx); const vx = this._getXValue(vxns); let vy = dvy + dy; const yAxis = this.get("yAxis"); const roundTo = yAxis.getPrivate("stepDecimalPlaces", 0) + 1; vy = $math.round(vy, roundTo); vy = this._getYValue(vy, vxns, true); this._setContext(dataItem, "valueX", vx); this._setContext(dataItem, "valueY", vy, true); this._setXLocation(dataItem, vx); } }); } } this._updateSegment(index); } _updateSegment(_index) { this._updateElements(); } _updateChildren() { this._updateElements(); if (this._valuesDirty) { this.markDirtyDrawings(); } super._updateChildren(); } _updateElements() { } markDirtyDrawings() { const xAxis = this.get("xAxis"); if (xAxis) { const panel = xAxis.chart; if (panel) { const stockChart = panel.getPrivate("stockChart"); if (stockChart) { stockChart.markDirtyDrawings(); } } } } _getFillTemplate() { const fillTemplate = {}; const fillColor = this.get("fillColor"); if (fillColor != null) { fillTemplate.fill = fillColor; } const fillOpacity = this.get("fillOpacity"); if (fillOpacity != null) { fillTemplate.fillOpacity = fillOpacity; } return Template.new(fillTemplate); } _getStrokeTemplate() { const strokeTemplate = {}; const strokeColor = this.get("strokeColor"); if (strokeColor != null) { strokeTemplate.stroke = strokeColor; } const strokeOpacity = this.get("strokeOpacity"); if (strokeOpacity != null) { strokeTemplate.strokeOpacity = strokeOpacity; } const strokeDasharray = this.get("strokeDasharray"); if (strokeDasharray != null) { strokeTemplate.strokeDasharray = strokeDasharray; } const strokeWidth = this.get("strokeWidth"); if (strokeWidth != null) { strokeTemplate.strokeWidth = strokeWidth; } return Template.new(strokeTemplate); } _tweakBullet(_container, _dataItem) { } _addBulletInteraction(sprite) { sprite.events.on("dragged", (e) => { this._handleBulletDragged(e); this._isDragging = true; }); sprite.events.on("dragstart", (e) => { this._handleBulletDragStart(e); }); sprite.events.on("dragstop", (e) => { this._handleBulletDragStop(e); this.setTimeout(() => { this._isDragging = false; }, 100); }); sprite.events.on("click", (e) => { if (this._erasingEnabled) { const dataItem = e.target.dataItem; if (dataItem) { const dataContext = dataItem.dataContext; if (dataContext) { this._disposeIndex(dataContext.index); } } } else { this._handlePointerClick(e); } }); } _handlePointerClick(event) { if (this._drawingEnabled) { const chart = this.chart; if (chart) { this._clickPointerPoint = chart.plotContainer.toLocal(event.point); } } } // need this in order bullets not to be placed to the charts bullets container _placeBulletsContainer() { this.children.moveValue(this.bulletsContainer); this.enableDrawing(); this.disableDrawing(); } _handleBulletDragged(event) { const dataItem = event.target.dataItem; const chart = this.chart; if (chart) { const target = event.target; const point = { x: target.x(), y: target.y() }; this._handleBulletDraggedReal(dataItem, point); } const dataContext = dataItem.dataContext; if (dataContext) { const index = dataContext.index; this._updateSegment(index); } } _handleBulletDraggedReal(dataItem, point) { const xAxis = this.get("xAxis"); const yAxis = this.get("yAxis"); const valueXns = xAxis.positionToValue(xAxis.coordinateToPosition(point.x)); const valueX = this._getXValue(valueXns); const valueY = this._getYValue(yAxis.positionToValue(yAxis.coordinateToPosition(point.y)), valueXns); this._setContext(dataItem, "valueX", valueX); this._setContext(dataItem, "valueY", valueY, true); this._setXLocation(dataItem, valueX); this._positionBullets(dataItem); } _handleBulletDragStart(_event) { } _handleBulletDragStop(_event) { } _handlePointerOver() { } _handlePointerOut() { } enableDrawing() { const chart = this.chart; this._erasingEnabled = false; this._drawingEnabled = true; if (chart) { if (!this._clickDp) { this._clickDp = chart.plotContainer.events.on("click", (e) => { const originalEvent = e.originalEvent; if (!originalEvent.button && !this._erasingEnabled) { this._handlePointerClick(e); } }); } if (!this._downDp) { this._downDp = chart.plotContainer.events.on("pointerdown", (e) => { const originalEvent = e.originalEvent; if (!originalEvent.button && !this._erasingEnabled) { this._handlePointerDown(e); } }); } if (!this._upDp) { this._upDp = chart.plotContainer.events.on("globalpointerup", (e) => { const originalEvent = e.originalEvent; if (!originalEvent.button && !this._erasingEnabled) { this._handlePointerUp(e); } }); } if (!this._moveDp) { this._moveDp = chart.plotContainer.events.on("globalpointermove", (e) => { if (!this._erasingEnabled) { if (e.point.x != this._movePoint.x || e.point.y != this._movePoint.y) { this._handlePointerMove(e); } } }); } } } enableErasing() { this._erasingEnabled = true; } disableErasing() { this._erasingEnabled = false; } disableDrawing() { this._erasingEnabled = false; this._drawingEnabled = false; this._isDrawing = false; if (this._clickDp) { this._clickDp.dispose(); this._clickDp = undefined; } if (this._downDp) { this._downDp.dispose(); this._downDp = undefined; } if (this._upDp) { this._upDp.dispose(); this._upDp = undefined; } this._hideAllBullets(); } _handlePointerMove(event) { const chart = this.chart; if (chart) { this._movePointerPoint = chart.plotContainer.toLocal(event.point); } } _handlePointerDown(_event) { this._isPointerDown = true; } _handlePointerUp(_event) { this._isPointerDown = false; } startIndex() { return 0; } endIndex() { return this.dataItems.length; } _setXLocation(dataItem, value) { if (!this.get("snapToData")) { this._setXLocationReal(dataItem, value); } else { dataItem.set("locationX", undefined); } } _setXLocationReal(dataItem, value) { const xAxis = this.get("xAxis"); const baseInterval = xAxis.getPrivate("baseInterval"); const root = this._root; const firstDayOfWeek = root.locale.firstDayOfWeek; const open = $time.round(new Date(value), baseInterval.timeUnit, baseInterval.count, firstDayOfWeek, root.utc, undefined, root.timezone).getTime(); let close = open + $time.getDuration(baseInterval.timeUnit, baseInterval.count * 1.05); close = $time.round(new Date(close), baseInterval.timeUnit, baseInterval.count, firstDayOfWeek, root.utc, undefined, root.timezone).getTime(); const locationX = (value - open) / (close - open); dataItem.set("locationX", locationX); } disposeDataItem(dataItem) { super.disposeDataItem(dataItem); const dataContext = dataItem.dataContext; if (dataContext) { const index = dataContext.index; this.markDirtyValues(); const dataItems = this._di[index]; if (dataItems) { $object.each(dataItems, (_key, dataItem) => { super.disposeDataItem(dataItem); }); } delete this._di[index]; } } _getYValue(value, valueX, doNotConvert) { const series = this.get("series"); if (this.get("snapToData") && series) { const field = this.get("field", "value") + "Y"; return this._snap(valueX, value, field, series); } else { if (!doNotConvert && this.get("valueYShow") == "valueYChangeSelectionPercent") { const baseValueSeries = this.getPrivate("baseValueSeries"); if (baseValueSeries) { const baseValue = baseValueSeries._getBase("valueY"); value = value / 100 * baseValue + baseValue; } } const yAxis = this.get("yAxis"); const roundTo = yAxis.getPrivate("stepDecimalPlaces", 0) + 1; return $math.round(value, roundTo); } } _getXValue(value) { const series = this.get("series"); if (this.get("snapToData") && series) { const xAxis = this.get("xAxis"); const min = xAxis.getPrivate("min", 0) + 1; const max = xAxis.getPrivate("max", 1) - 1; value = $math.fitToRange(value, min, max); value = this._snap(value, value, "valueX", series) + 1; // important! return value; } else { return Math.round(value); } } _setContext(dataItem, key, value, working) { dataItem.set(key, value); if (working) { dataItem.set(key + "Working", value); } const dataContext = dataItem.dataContext; const field = this.get(key + "Field"); if (field) { dataContext[field] = value; } } _snap(value, realValue, key, series) { const xAxis = this.get("xAxis"); const dataItem = xAxis.getSeriesItem(series, Math.max(0, xAxis.valueToPosition(value)), 0.5, true); if (dataItem) { return dataItem.get(key); } return realValue; } _getStockChart() { return this.get("series").chart.getPrivate("stockChart"); } } Object.defineProperty(DrawingSeries, "className", { enumerable: true, configurable: true, writable: true, value: "DrawingSeries" }); Object.defineProperty(DrawingSeries, "classNames", { enumerable: true, configurable: true, writable: true, value: LineSeries.classNames.concat([DrawingSeries.className]) }); //# sourceMappingURL=DrawingSeries.js.map