UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

161 lines 6.26 kB
import noUiSlider from "nouislider"; import * as p from "../../../core/properties"; import { div, span, empty } from "../../../core/dom"; import { repeat } from "../../../core/util/array"; import { color2css } from "../../../core/util/color"; import { OrientedControl, OrientedControlView } from "../oriented_control"; import sliders_css, * as sliders from "../../../styles/widgets/sliders.css"; import nouislider_css from "../../../styles/widgets/nouislider.css"; import * as inputs from "../../../styles/widgets/inputs.css"; export class AbstractSliderView extends OrientedControlView { static __name__ = "AbstractSliderView"; behaviour; connected = false; group_el; slider_el; title_el; _auto_width = "auto"; _auto_height = "auto"; *controls() { yield this.slider_el; } _noUiSlider; get _steps() { return this._noUiSlider.steps; } _update_slider() { this._noUiSlider.updateOptions(this._calc_to(), true); } connect_signals() { super.connect_signals(); const { direction, orientation, tooltips } = this.model.properties; this.on_change([direction, orientation, tooltips], () => this.rerender()); const { bar_color } = this.model.properties; this.on_change(bar_color, () => { this._set_bar_color(); }); const { value, title, show_value } = this.model.properties; this.on_change([value, title, show_value], () => this._update_title()); this.on_change(value, () => this._update_slider()); } stylesheets() { return [...super.stylesheets(), nouislider_css, sliders_css]; } _update_title() { empty(this.title_el); const hide_header = this.model.title == null || (this.model.title.length == 0 && !this.model.show_value); this.title_el.style.display = hide_header ? "none" : ""; if (!hide_header) { const { title } = this.model; if (title != null && title.length > 0) { if (this.contains_tex_string(title)) { this.title_el.innerHTML = `${this.process_tex(title)}: `; } else { this.title_el.textContent = `${title}: `; } } if (this.model.show_value) { const { start } = this._calc_to(); const pretty = start.map((v) => this.pretty(v)).join(" .. "); this.title_el.appendChild(span({ class: sliders.slider_value }, pretty)); } } } _set_bar_color() { if (this.connected !== false && !this.model.disabled && this.slider_el != null) { const connect_el = this.slider_el.querySelector(".noUi-connect"); connect_el.style.backgroundColor = color2css(this.model.bar_color); } } render() { super.render(); let tooltips; if (this.model.tooltips) { const formatter = { to: (value) => this.pretty(value), }; const { start } = this._calc_to(); tooltips = repeat(formatter, start.length); } else { tooltips = null; } if (this.slider_el == null) { this.slider_el = div(); this._noUiSlider = noUiSlider.create(this.slider_el, { ...this._calc_to(), behaviour: this.behaviour, connect: this.connected, tooltips: tooltips ?? false, orientation: this.model.orientation, direction: this.model.direction, }); this._noUiSlider.on("slide", (_, __, values) => this._slide(values)); this._noUiSlider.on("change", (_, __, values) => this._change(values)); const toggle_tooltip = (i, show) => { if (tooltips == null || this.slider_el == null) { return; } const handle = this.slider_el.querySelectorAll(".noUi-handle")[i]; const tooltip = handle.querySelector(".noUi-tooltip"); tooltip.style.display = show ? "block" : ""; }; this._noUiSlider.on("start", () => this._toggle_user_select(false)); this._noUiSlider.on("end", () => this._toggle_user_select(true)); this._noUiSlider.on("start", (_, i) => toggle_tooltip(i, true)); this._noUiSlider.on("end", (_, i) => toggle_tooltip(i, false)); } else { this._update_slider(); } this._set_bar_color(); if (this.model.disabled) { this.slider_el.setAttribute("disabled", "true"); } else { this.slider_el.removeAttribute("disabled"); } this.title_el = div({ class: sliders.slider_title }); this._update_title(); this.group_el = div({ class: inputs.input_group }, this.title_el, this.slider_el); this.shadow_el.appendChild(this.group_el); this._has_finished = true; } _toggle_user_select(enable) { const { style } = document.body; const value = enable ? "" : "none"; style.userSelect = value; style.webkitUserSelect = value; } _slide(values) { this.model.value = this._calc_from(values); } _change(values) { const value = this._calc_from(values); this.model.setv({ value, value_throttled: value }); } } export class AbstractSlider extends OrientedControl { static __name__ = "AbstractSlider"; constructor(attrs) { super(attrs); } static { this.define(({ Unknown, Bool, Str, Color, Enum, Nullable }) => { return { title: [Nullable(Str), ""], show_value: [Bool, true], value: [Unknown], value_throttled: [Unknown, p.unset, { readonly: true }], direction: [Enum("ltr", "rtl"), "ltr"], tooltips: [Bool, true], bar_color: [Color, "#e6e6e6"], }; }); this.override({ width: 300, // sliders don't have any intrinsic width }); } } //# sourceMappingURL=abstract_slider.js.map