@bokeh/bokehjs
Version:
Interactive, novel data visualization
126 lines • 4.55 kB
JavaScript
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(({ Int, Mapping, Ref, Nullable }) => ({
indices: [Ref(Indices)],
indices_map: [Mapping(Int, Int), new Map()],
masked: [Nullable(Ref(Indices)), null],
}));
}
_indices;
_indices_map_to_subset() {
this._indices = [...this.indices];
this.indices_map = new Map();
const { _indices, indices_map } = this;
const n = _indices.length;
for (let i = 0; i < n; i++) {
indices_map.set(_indices[i], i);
}
}
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.indices_map.get(i)); // XXX ?? NaN
}
convert_indices_from_subset(indices) {
return indices.map((i) => this._indices[i]);
}
/** @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