206 lines
6.6 KiB
JavaScript
206 lines
6.6 KiB
JavaScript
var DataRange, DataRange1d, _, bbox, logger, p,
|
|
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
|
hasProp = {}.hasOwnProperty;
|
|
|
|
_ = require("underscore");
|
|
|
|
DataRange = require("./data_range");
|
|
|
|
logger = require("../../core/logging").logger;
|
|
|
|
p = require("../../core/properties");
|
|
|
|
bbox = require("../../core/util/bbox");
|
|
|
|
DataRange1d = (function(superClass) {
|
|
extend(DataRange1d, superClass);
|
|
|
|
function DataRange1d() {
|
|
return DataRange1d.__super__.constructor.apply(this, arguments);
|
|
}
|
|
|
|
DataRange1d.prototype.type = 'DataRange1d';
|
|
|
|
DataRange1d.define({
|
|
start: [p.Number],
|
|
end: [p.Number],
|
|
range_padding: [p.Number, 0.1],
|
|
flipped: [p.Bool, false],
|
|
follow: [p.String],
|
|
follow_interval: [p.Number],
|
|
default_span: [p.Number, 2],
|
|
bounds: [p.Any],
|
|
min_interval: [p.Any],
|
|
max_interval: [p.Any]
|
|
});
|
|
|
|
DataRange1d.prototype.initialize = function(attrs, options) {
|
|
DataRange1d.__super__.initialize.call(this, attrs, options);
|
|
this.define_computed_property('min', function() {
|
|
return Math.min(this.get('start'), this.get('end'));
|
|
}, true);
|
|
this.add_dependencies('min', this, ['start', 'end']);
|
|
this.define_computed_property('max', function() {
|
|
return Math.max(this.get('start'), this.get('end'));
|
|
}, true);
|
|
this.add_dependencies('max', this, ['start', 'end']);
|
|
this.plot_bounds = {};
|
|
this.have_updated_interactively = false;
|
|
this._initial_start = this.get('start');
|
|
this._initial_end = this.get('end');
|
|
this._initial_range_padding = this.get('range_padding');
|
|
this._initial_follow = this.get('follow');
|
|
this._initial_follow_interval = this.get('follow_interval');
|
|
return this._initial_default_span = this.get('default_span');
|
|
};
|
|
|
|
DataRange1d.prototype.computed_renderers = function() {
|
|
var all_renderers, i, j, len, len1, names, plot, r, ref, renderers, rs;
|
|
names = this.get('names');
|
|
renderers = this.get('renderers');
|
|
if (renderers.length === 0) {
|
|
ref = this.get('plots');
|
|
for (i = 0, len = ref.length; i < len; i++) {
|
|
plot = ref[i];
|
|
all_renderers = plot.get('renderers');
|
|
rs = (function() {
|
|
var j, len1, results;
|
|
results = [];
|
|
for (j = 0, len1 = all_renderers.length; j < len1; j++) {
|
|
r = all_renderers[j];
|
|
if (r.type === "GlyphRenderer") {
|
|
results.push(r);
|
|
}
|
|
}
|
|
return results;
|
|
})();
|
|
renderers = renderers.concat(rs);
|
|
}
|
|
}
|
|
if (names.length > 0) {
|
|
renderers = (function() {
|
|
var j, len1, results;
|
|
results = [];
|
|
for (j = 0, len1 = renderers.length; j < len1; j++) {
|
|
r = renderers[j];
|
|
if (names.indexOf(r.get('name')) >= 0) {
|
|
results.push(r);
|
|
}
|
|
}
|
|
return results;
|
|
})();
|
|
}
|
|
logger.debug("computed " + renderers.length + " renderers for DataRange1d " + this.id);
|
|
for (j = 0, len1 = renderers.length; j < len1; j++) {
|
|
r = renderers[j];
|
|
logger.trace(" - " + r.type + " " + r.id);
|
|
}
|
|
return renderers;
|
|
};
|
|
|
|
DataRange1d.prototype._compute_plot_bounds = function(renderers, bounds) {
|
|
var i, len, r, result;
|
|
result = bbox.empty();
|
|
for (i = 0, len = renderers.length; i < len; i++) {
|
|
r = renderers[i];
|
|
if (bounds[r.id] != null) {
|
|
result = bbox.union(result, bounds[r.id]);
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
|
|
DataRange1d.prototype._compute_min_max = function(plot_bounds, dimension) {
|
|
var k, max, min, overall, ref, ref1, v;
|
|
overall = bbox.empty();
|
|
for (k in plot_bounds) {
|
|
v = plot_bounds[k];
|
|
overall = bbox.union(overall, v);
|
|
}
|
|
if (dimension === 0) {
|
|
ref = [overall.minX, overall.maxX], min = ref[0], max = ref[1];
|
|
} else {
|
|
ref1 = [overall.minY, overall.maxY], min = ref1[0], max = ref1[1];
|
|
}
|
|
return [min, max];
|
|
};
|
|
|
|
DataRange1d.prototype._compute_range = function(min, max) {
|
|
var center, end, follow_interval, follow_sign, range_padding, ref, ref1, ref2, span, start;
|
|
range_padding = this.get('range_padding');
|
|
if ((range_padding != null) && range_padding > 0) {
|
|
if (max === min) {
|
|
span = this.get('default_span');
|
|
} else {
|
|
span = (max - min) * (1 + range_padding);
|
|
}
|
|
center = (max + min) / 2.0;
|
|
ref = [center - span / 2.0, center + span / 2.0], start = ref[0], end = ref[1];
|
|
} else {
|
|
ref1 = [min, max], start = ref1[0], end = ref1[1];
|
|
}
|
|
follow_sign = +1;
|
|
if (this.get('flipped')) {
|
|
ref2 = [end, start], start = ref2[0], end = ref2[1];
|
|
follow_sign = -1;
|
|
}
|
|
follow_interval = this.get('follow_interval');
|
|
if ((follow_interval != null) && Math.abs(start - end) > follow_interval) {
|
|
if (this.get('follow') === 'start') {
|
|
end = start + follow_sign * follow_interval;
|
|
} else if (this.get('follow') === 'end') {
|
|
start = end - follow_sign * follow_interval;
|
|
}
|
|
}
|
|
return [start, end];
|
|
};
|
|
|
|
DataRange1d.prototype.update = function(bounds, dimension, bounds_id) {
|
|
var _end, _start, end, max, min, new_range, ref, ref1, ref2, renderers, start;
|
|
if (this.have_updated_interactively) {
|
|
return;
|
|
}
|
|
renderers = this.computed_renderers();
|
|
this.plot_bounds[bounds_id] = this._compute_plot_bounds(renderers, bounds);
|
|
ref = this._compute_min_max(this.plot_bounds, dimension), min = ref[0], max = ref[1];
|
|
ref1 = this._compute_range(min, max), start = ref1[0], end = ref1[1];
|
|
if (this._initial_start != null) {
|
|
start = this._initial_start;
|
|
}
|
|
if (this._initial_end != null) {
|
|
end = this._initial_end;
|
|
}
|
|
ref2 = [this.get('start'), this.get('end')], _start = ref2[0], _end = ref2[1];
|
|
if (start !== _start || end !== _end) {
|
|
new_range = {};
|
|
if (start !== _start) {
|
|
new_range.start = start;
|
|
}
|
|
if (end !== _end) {
|
|
new_range.end = end;
|
|
}
|
|
this.set(new_range);
|
|
}
|
|
if (this.get('bounds') === 'auto') {
|
|
return this.set('bounds', [start, end]);
|
|
}
|
|
};
|
|
|
|
DataRange1d.prototype.reset = function() {
|
|
this.have_updated_interactively = false;
|
|
return this.set({
|
|
range_padding: this._initial_range_padding,
|
|
follow: this._initial_follow,
|
|
follow_interval: this._initial_follow_interval,
|
|
default_span: this._initial_default_span
|
|
});
|
|
};
|
|
|
|
return DataRange1d;
|
|
|
|
})(DataRange.Model);
|
|
|
|
module.exports = {
|
|
Model: DataRange1d
|
|
};
|