UNPKG

@amcharts/amcharts5

Version:
342 lines 13.8 kB
import { RoundedRectangle } from "../render/RoundedRectangle"; import { Container } from "./Container"; import { Graphics } from "./Graphics"; import { Button } from "./Button"; import * as $type from "../util/Type"; import * as $utils from "../util/Utils"; /** * A control that allows zooming chart's axes, or other uses requiring range * selection. * * @see {@link https://www.amcharts.com/docs/v5/charts/xy-chart/scrollbars/} for more info */ export class Scrollbar extends Container { constructor() { super(...arguments); /** * A thumb elment - a draggable square between the grips, used for panning * the selection. */ this.thumb = this._makeThumb(); /** * Start grip button. */ this.startGrip = this._makeButton(); /** * End grip button. */ this.endGrip = this._makeButton(); this._thumbBusy = false; this._startDown = false; this._endDown = false; this._thumbDown = false; } _addOrientationClass() { this._settings.themeTags = $utils.mergeTags(this._settings.themeTags, ["scrollbar", this._settings.orientation]); this._setDefaultTagged("background", $utils.mergeTags(this._settings.themeTags, ["main", "background"]), () => { return RoundedRectangle.new(this._root, {}); }); } _makeButton() { return this.children.push(Button.new(this._root, { themeTags: ["resize", "button", this.get("orientation")], icon: Graphics.new(this._root, { themeTags: ["icon"] })._markC("themeTags") })._markC("themeTags", "icon")); } _makeThumb() { return this.children.push(RoundedRectangle.new(this._root, { themeTags: ["thumb", this.get("orientation")] })._markC("themeTags")); } _handleAnimation(animation) { if (animation) { this._disposers.push(animation.events.on("stopped", () => { this.setPrivateRaw("isBusy", false); this._thumbBusy = false; })); } } _afterNew() { this._addOrientationClass(); super._afterNew(); const startGrip = this.startGrip; const endGrip = this.endGrip; const thumb = this.thumb; const background = this.get("background"); if (background) { this._disposers.push(background.events.on("click", (event) => { this.setPrivateRaw("isBusy", true); const point = this._display.toLocal(event.point); const w = this.width(); const h = this.height(); const orientation = this.get("orientation"); let newMiddle; if (orientation == "vertical") { newMiddle = (point.y - thumb.height() / 2) / h; } else { newMiddle = (point.x - thumb.width() / 2) / w; } let newCoordinate; let key; if (orientation == "vertical") { newCoordinate = newMiddle * h; key = "y"; } else { newCoordinate = newMiddle * w; key = "x"; } const duration = this.get("animationDuration", 0); if (duration > 0) { this._thumbBusy = true; this._handleAnimation(this.thumb.animate({ key: key, to: newCoordinate, duration: duration, easing: this.get("animationEasing") })); } else { this.thumb._setC(key, newCoordinate); this._root.events.once("frameended", () => { this.setPrivateRaw("isBusy", false); }); } })); } this._disposers.push(thumb.events.on("dblclick", (event) => { if (!$utils.isLocalEvent(event.originalEvent, this)) { return; } const duration = this.get("animationDuration", 0); const easing = this.get("animationEasing"); this.animate({ key: "start", to: 0, duration: duration, easing: easing }); this.animate({ key: "end", to: 1, duration: duration, easing: easing }); })); this._disposers.push(startGrip.events.on("pointerdown", () => { this.setPrivateRaw("isBusy", true); this._startDown = true; this._gripDown = "start"; })); this._disposers.push(endGrip.events.on("pointerdown", () => { this.setPrivateRaw("isBusy", true); this._endDown = true; this._gripDown = "end"; })); this._disposers.push(thumb.events.on("pointerdown", () => { this.setPrivateRaw("isBusy", true); this._thumbDown = true; this._gripDown = undefined; })); this._disposers.push(startGrip.events.on("globalpointerup", () => { if (this._startDown) { this.setPrivateRaw("isBusy", false); this._released(); } this._startDown = false; })); this._disposers.push(endGrip.events.on("globalpointerup", () => { if (this._endDown) { this.setPrivateRaw("isBusy", false); this._released(); } this._endDown = false; })); this._disposers.push(thumb.events.on("globalpointerup", () => { if (this._thumbDown) { this.setPrivateRaw("isBusy", false); this._released(); } this._thumbDown = false; })); this._disposers.push(startGrip.on("x", () => { this._updateThumb(); })); this._disposers.push(endGrip.on("x", () => { this._updateThumb(); })); this._disposers.push(startGrip.on("y", () => { this._updateThumb(); })); this._disposers.push(endGrip.on("y", () => { this._updateThumb(); })); this._disposers.push(thumb.events.on("positionchanged", () => { this._updateGripsByThumb(); })); if (this.get("orientation") == "vertical") { startGrip._setC("x", 0); endGrip._setC("x", 0); this._disposers.push(thumb.adapters.add("y", (value) => { return Math.max(Math.min(Number(value), this.height() - thumb.height()), 0); })); this._disposers.push(thumb.adapters.add("x", (_value) => { return this.width() / 2; })); this._disposers.push(startGrip.adapters.add("x", (_value) => { return this.width() / 2; })); this._disposers.push(endGrip.adapters.add("x", (_value) => { return this.width() / 2; })); this._disposers.push(startGrip.adapters.add("y", (value) => { return Math.max(Math.min(Number(value), this.height()), 0); })); this._disposers.push(endGrip.adapters.add("y", (value) => { return Math.max(Math.min(Number(value), this.height()), 0); })); } else { startGrip._setC("y", 0); endGrip._setC("y", 0); this._disposers.push(thumb.adapters.add("x", (value) => { return Math.max(Math.min(Number(value), this.width() - thumb.width()), 0); })); this._disposers.push(thumb.adapters.add("y", (_value) => { return this.height() / 2; })); this._disposers.push(startGrip.adapters.add("y", (_value) => { return this.height() / 2; })); this._disposers.push(endGrip.adapters.add("y", (_value) => { return this.height() / 2; })); this._disposers.push(startGrip.adapters.add("x", (value) => { return Math.max(Math.min(Number(value), this.width()), 0); })); this._disposers.push(endGrip.adapters.add("x", (value) => { return Math.max(Math.min(Number(value), this.width()), 0); })); } } _updateChildren() { super._updateChildren(); if (this.isDirty("end") || this.isDirty("start") || this._sizeDirty) { this.updateGrips(); } } _changed() { super._changed(); if (this.isDirty("start") || this.isDirty("end")) { const eventType = "rangechanged"; if (this.events.isEnabled(eventType)) { this.events.dispatch(eventType, { type: eventType, target: this, start: this.get("start", 0), end: this.get("end", 1), grip: this._gripDown }); } } } _released() { const eventType = "released"; if (this.events.isEnabled(eventType)) { this.events.dispatch(eventType, { type: eventType, target: this }); } } /** * @ignore */ updateGrips() { const startGrip = this.startGrip; const endGrip = this.endGrip; const orientation = this.get("orientation"); const height = this.height(); const width = this.width(); if (orientation == "vertical") { startGrip._setC("y", height * this.get("start", 0)); endGrip._setC("y", height * this.get("end", 1)); } else { startGrip._setC("x", width * this.get("start", 0)); endGrip._setC("x", width * this.get("end", 1)); } const valueFunction = this.getPrivate("positionTextFunction"); const from = Math.round(this.get("start", 0) * 100); const to = Math.round(this.get("end", 0) * 100); let fromValue; let toValue; if (valueFunction) { fromValue = valueFunction.call(this, this.get("start", 0)); toValue = valueFunction.call(this, this.get("end", 0)); } else { fromValue = from + "%"; toValue = to + "%"; } startGrip._setC("ariaLabel", this._t("From %1", undefined, fromValue)); startGrip._setC("ariaValueNow", "" + from); startGrip._setC("ariaValueText", from + "%"); startGrip._setC("ariaValueMin", "0"); startGrip._setC("ariaValueMax", "100"); endGrip._setC("ariaLabel", this._t("To %1", undefined, toValue)); endGrip._setC("ariaValueNow", "" + to); endGrip._setC("ariaValueText", to + "%"); endGrip._setC("ariaValueMin", "0"); endGrip._setC("ariaValueMax", "100"); } _updateThumb() { const thumb = this.thumb; const startGrip = this.startGrip; const endGrip = this.endGrip; const height = this.height(); const width = this.width(); let x0 = startGrip.x(); let x1 = endGrip.x(); let y0 = startGrip.y(); let y1 = endGrip.y(); let start = 0; let end = 1; if (this.get("orientation") == "vertical") { if ($type.isNumber(y0) && $type.isNumber(y1)) { if (!this._thumbBusy && !thumb.isDragging()) { thumb._setC("height", y1 - y0); thumb._setC("y", y0); } start = y0 / height; end = y1 / height; } } else { if ($type.isNumber(x0) && $type.isNumber(x1)) { if (!this._thumbBusy && !thumb.isDragging()) { thumb._setC("width", x1 - x0); thumb._setC("x", x0); } start = x0 / width; end = x1 / width; } } if (this.getPrivate("isBusy") && (this.get("start") != start || this.get("end") != end)) { this._setC("start", start); this._setC("end", end); } const valueFunction = this.getPrivate("positionTextFunction"); const from = Math.round(this.get("start", 0) * 100); const to = Math.round(this.get("end", 0) * 100); let fromValue; let toValue; if (valueFunction) { fromValue = valueFunction.call(this, this.get("start", 0)); toValue = valueFunction.call(this, this.get("end", 0)); } else { fromValue = from + "%"; toValue = to + "%"; } thumb._setC("ariaLabel", this._t("From %1 to %2", undefined, fromValue, toValue)); thumb._setC("ariaValueNow", "" + from); thumb._setC("ariaValueText", from + "%"); } _updateGripsByThumb() { const thumb = this.thumb; const startGrip = this.startGrip; const endGrip = this.endGrip; if (this.get("orientation") == "vertical") { const thumbSize = thumb.height(); startGrip._setC("y", thumb.y()); endGrip._setC("y", thumb.y() + thumbSize); } else { const thumbSize = thumb.width(); startGrip._setC("x", thumb.x()); endGrip._setC("x", thumb.x() + thumbSize); } } } Scrollbar.className = "Scrollbar"; Scrollbar.classNames = Container.classNames.concat([Scrollbar.className]); //# sourceMappingURL=Scrollbar.js.map