UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

146 lines 5.3 kB
import { Model } from "../../model"; import { View } from "../../core/view"; import { Indices } from "../../core/types"; import { Filter } from "../filters/filter"; import { AllIndices } from "../filters/all_indices"; import { IntersectionFilter } from "../filters/intersection_filter"; export class CDSViewView extends View { static __name__ = "CDSViewView"; initialize() { super.initialize(); this.compute_indices(); } connect_signals() { super.connect_signals(); const compute_indices = () => { this.compute_indices(); }; const connect_filter = (filter) => { this.connect(filter.change, compute_indices); }; const disconnect_filter = (filter) => { this.disconnect(filter.change, compute_indices); }; let { filter } = this.model; connect_filter(filter); this.on_change(this.model.properties.filter, () => { disconnect_filter(filter); filter = this.model.filter; connect_filter(filter); compute_indices(); }); const connect_data_source = (data_source) => { this.connect(data_source.change, compute_indices); this.connect(data_source.streaming, compute_indices); this.connect(data_source.patching, compute_indices); this.connect(data_source.properties.data.change, compute_indices); }; const disconnect_data_source = (data_source) => { this.disconnect(data_source.change, compute_indices); this.disconnect(data_source.streaming, compute_indices); this.disconnect(data_source.patching, compute_indices); this.disconnect(data_source.properties.data.change, compute_indices); }; let data_source = this.parent.data_source.get_value(); connect_data_source(data_source); this.on_change(this.parent.data_source, () => { disconnect_data_source(data_source); data_source = this.parent.data_source.get_value(); connect_data_source(data_source); compute_indices(); }); } compute_indices() { // XXX: if the data source is empty, there still may be one // index originating from glyph's scalar values. const source = this.parent.data_source.get_value(); const size = source.get_length() ?? 1; const indices = Indices.all_set(size); const filtered = this.model.filter.compute_indices(source); indices.intersect(filtered); this.model.indices = indices; this.model._indices_map_to_subset(); } } export class CDSView extends Model { static __name__ = "CDSView"; constructor(attrs) { super(attrs); } static { this.prototype.default_view = CDSViewView; this.define(({ Ref }) => ({ filter: [Ref(Filter), () => new AllIndices()], })); this.internal(({ Ref, Int, Arrayable, Nullable }) => ({ indices: [Ref(Indices)], indices_map: [Arrayable(Int), []], masked: [Nullable(Ref(Indices)), null], })); } _indices; _indices_map_to_subset() { this._indices = this.indices.ones(); const { _indices } = this; // _indices are sorted thus we can use the last value const n_map = _indices.length > 0 ? _indices.at(-1) + 1 : 0; const indices_map = new Array(n_map).fill(-1); const n = _indices.length; for (let i = 0; i < n; i++) { indices_map[_indices[i]] = i; } this.indices_map = indices_map; } get_subset_index(index) { const subset_index = this.indices_map[index]; return subset_index !== undefined && subset_index != -1 ? subset_index : undefined; } has_subset_index(index) { return this.get_subset_index(index) !== undefined; } convert_selection_from_subset(selection_subset) { return selection_subset.map((i) => this._indices[i]); } convert_selection_to_subset(selection_full) { return selection_full.map((i) => this.get_subset_index(i)); // XXX ?? NaN } convert_indices_from_subset(indices) { return indices.map((i) => this._indices[i]); } get_reference_point(array, value) { const { _indices } = this; const n = _indices.length; for (let i = 0; i < n; i++) { if (array[_indices[i]] == value) { return this.get_subset_index(_indices[i]); } } return null; } /** @deprecated */ get filters() { const { filter } = this; if (filter instanceof IntersectionFilter) { return filter.operands; } else if (filter instanceof AllIndices) { return []; } else { return [filter]; } } /** @deprecated */ set filters(filters) { if (filters.length == 0) { this.filter = new AllIndices(); } else if (filters.length == 1) { this.filter = filters[0]; } else { this.filter = new IntersectionFilter({ operands: filters }); } } } //# sourceMappingURL=cds_view.js.map