UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

166 lines 6.13 kB
import { CanvasPanel, CanvasPanelView } from "./canvas_panel"; import { CategoricalScale } from "../scales/categorical_scale"; import { LogScale } from "../scales/log_scale"; import { Scale } from "../scales/scale"; import { LinearScale } from "../scales/linear_scale"; import { Range } from "../ranges/range"; import { Range1d } from "../ranges/range1d"; import { DataRange1d } from "../ranges/data_range1d"; import { FactorRange } from "../ranges/factor_range"; import { entries } from "../../core/util/object"; import { assert } from "../../core/util/assert"; import * as css from "../../styles/cartesian_frame.css"; export class CartesianFrameView extends CanvasPanelView { static __name__ = "CartesianFrameView"; initialize() { super.initialize(); this._configure_scales(); } remove() { this._unregister_frame(); super.remove(); } stylesheets() { return [...super.stylesheets(), css.default]; } connect_signals() { super.connect_signals(); const { x_range, y_range, x_scale, y_scale, extra_x_ranges, extra_y_ranges, extra_x_scales, extra_y_scales } = this.model.properties; this.on_change([x_range, y_range, x_scale, y_scale, extra_x_ranges, extra_y_ranges, extra_x_scales, extra_y_scales], () => { this._configure_scales(); }); } _x_target; _y_target; _x_ranges = new Map(); _y_ranges = new Map(); _x_scales = new Map(); _y_scales = new Map(); _x_scale; _y_scale; _get_ranges(range, extra_ranges) { return new Map([...entries(extra_ranges), ["default", range]]); } _get_scales(scale, extra_scales, ranges, frame_range) { const in_scales = new Map([...entries(extra_scales), ["default", scale]]); const scales = new Map(); for (const [name, range] of ranges) { const factor_range = range instanceof FactorRange; const categorical_scale = scale instanceof CategoricalScale; if (factor_range != categorical_scale) { throw new Error(`'${range.type}' is incompatible '${scale.type}'`); } if (scale instanceof LogScale && range instanceof DataRange1d) { range.scale_hint = "log"; } const base_scale = in_scales.get(name) ?? scale; const derived_scale = base_scale.clone(); derived_scale.setv({ source_range: range, target_range: frame_range }); scales.set(name, derived_scale); } return scales; } _configure_ranges() { // data to/from screen space transform (left-bottom <-> left-top origin) const { bbox } = this; this._x_target = new Range1d({ start: bbox.left, end: bbox.right }); this._y_target = new Range1d({ start: bbox.bottom, end: bbox.top }); } _configure_scales() { const { x_range, y_range, extra_x_ranges, extra_y_ranges } = this.model; const { x_scale, y_scale, extra_x_scales, extra_y_scales } = this.model; assert(x_scale.properties.source_range.is_unset && x_scale.properties.target_range.is_unset); assert(y_scale.properties.source_range.is_unset && y_scale.properties.target_range.is_unset); this._configure_ranges(); this._unregister_frame(); this._x_ranges = this._get_ranges(x_range, extra_x_ranges); this._y_ranges = this._get_ranges(y_range, extra_y_ranges); this._register_frame(); this._x_scales = this._get_scales(x_scale, extra_x_scales, this._x_ranges, this._x_target); this._y_scales = this._get_scales(y_scale, extra_y_scales, this._y_ranges, this._y_target); this._x_scale = this._x_scales.get("default"); this._y_scale = this._y_scales.get("default"); this.mark_finished(); } _update_scales() { this._configure_ranges(); for (const [, scale] of this._x_scales) { scale.target_range = this._x_target; } for (const [, scale] of this._y_scales) { scale.target_range = this._y_target; } } _register_frame() { for (const range of this.ranges.values()) { range.frames.add(this); } } _unregister_frame() { for (const range of this.ranges.values()) { range.frames.delete(this); } } set_geometry(bbox) { super.set_geometry(bbox); this._update_scales(); } get x_range() { return this.model.x_range; } get y_range() { return this.model.y_range; } get x_target() { return this._x_target; } get y_target() { return this._y_target; } get x_ranges() { return this._x_ranges; } get y_ranges() { return this._y_ranges; } get ranges() { return new Set([...this.x_ranges.values(), ...this.y_ranges.values()]); } get x_scales() { return this._x_scales; } get y_scales() { return this._y_scales; } get scales() { return new Set([...this.x_scales.values(), ...this.y_scales.values()]); } get x_scale() { return this._x_scale; } get y_scale() { return this._y_scale; } } export class CartesianFrame extends CanvasPanel { static __name__ = "CartesianFrame"; constructor(attrs) { super(attrs); } static { this.prototype.default_view = CartesianFrameView; this.define(({ Bool, Float, Dict, Ref }) => ({ x_range: [Ref(Range), () => new DataRange1d()], y_range: [Ref(Range), () => new DataRange1d()], x_scale: [Ref(Scale), () => new LinearScale()], y_scale: [Ref(Scale), () => new LinearScale()], extra_x_ranges: [Dict(Ref(Range)), {}], extra_y_ranges: [Dict(Ref(Range)), {}], extra_x_scales: [Dict(Ref(Scale)), {}], extra_y_scales: [Dict(Ref(Scale)), {}], match_aspect: [Bool, false], aspect_scale: [Float, 1], })); } } //# sourceMappingURL=cartesian_frame.js.map