You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
40809 lines
1.7 MiB
40809 lines
1.7 MiB
/*!
|
|
* Copyright (c) 2012 - 2018, Anaconda, Inc., and Bokeh Contributors
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
*
|
|
* Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* Neither the name of Anaconda nor the names of any contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
(function(root, factory) {
|
|
// if(typeof exports === 'object' && typeof module === 'object')
|
|
// module.exports = factory();
|
|
// else if(typeof define === 'function' && define.amd)
|
|
// define("Bokeh", [], factory);
|
|
// else if(typeof exports === 'object')
|
|
// exports["Bokeh"] = factory();
|
|
// else
|
|
root["Bokeh"] = factory();
|
|
})(this, function() {
|
|
var define;
|
|
return (function(modules, aliases, entry, parent_require) {
|
|
var cache = {};
|
|
|
|
var normalize = function(name) {
|
|
if (typeof name === "number")
|
|
return name;
|
|
|
|
if (name === "bokehjs")
|
|
return entry;
|
|
|
|
var prefix = "@bokehjs/"
|
|
if (name.slice(0, prefix.length) === prefix)
|
|
name = name.slice(prefix.length)
|
|
|
|
var alias = aliases[name]
|
|
if (alias != null)
|
|
return alias;
|
|
|
|
var trailing = name.length > 0 && name[name.lenght-1] === "/";
|
|
var index = aliases[name + (trailing ? "" : "/") + "index"];
|
|
if (index != null)
|
|
return index;
|
|
|
|
return name;
|
|
}
|
|
|
|
var require = function(name) {
|
|
var mod = cache[name];
|
|
if (!mod) {
|
|
var id = normalize(name);
|
|
|
|
mod = cache[id];
|
|
if (!mod) {
|
|
if (!modules[id]) {
|
|
if (parent_require)
|
|
return parent_require(id);
|
|
|
|
var err = new Error("Cannot find module '" + name + "'");
|
|
err.code = 'MODULE_NOT_FOUND';
|
|
throw err;
|
|
}
|
|
|
|
mod = {exports: {}};
|
|
cache[id] = mod;
|
|
cache[name] = mod;
|
|
modules[id].call(mod.exports, require, mod, mod.exports);
|
|
} else
|
|
cache[name] = mod;
|
|
}
|
|
|
|
return mod.exports;
|
|
}
|
|
|
|
var main = require(entry);
|
|
main.require = require;
|
|
|
|
main.register_plugin = function(plugin_modules, plugin_aliases, plugin_entry) {
|
|
for (var name in plugin_modules) {
|
|
modules[name] = plugin_modules[name];
|
|
}
|
|
|
|
for (var name in plugin_aliases) {
|
|
aliases[name] = plugin_aliases[name];
|
|
}
|
|
|
|
var plugin = require(plugin_entry);
|
|
|
|
for (var name in plugin) {
|
|
main[name] = plugin[name];
|
|
}
|
|
|
|
return plugin;
|
|
}
|
|
|
|
return main;
|
|
})
|
|
([
|
|
/* base */ function _(require, module, exports) {
|
|
var models = require(157) /* ./models/index */;
|
|
var object_1 = require(35) /* ./core/util/object */;
|
|
exports.overrides = {};
|
|
var _all_models = object_1.clone(models);
|
|
exports.Models = (function (name) {
|
|
var model = exports.overrides[name] || _all_models[name];
|
|
if (model == null) {
|
|
throw new Error("Model '" + name + "' does not exist. This could be due to a widget\n or a custom model not being registered before first usage.");
|
|
}
|
|
return model;
|
|
});
|
|
exports.Models.register = function (name, model) {
|
|
exports.overrides[name] = model;
|
|
};
|
|
exports.Models.unregister = function (name) {
|
|
delete exports.overrides[name];
|
|
};
|
|
exports.Models.register_models = function (models, force, errorFn) {
|
|
if (force === void 0) {
|
|
force = false;
|
|
}
|
|
if (models == null)
|
|
return;
|
|
for (var name_1 in models) {
|
|
var model = models[name_1];
|
|
if (force || !_all_models.hasOwnProperty(name_1))
|
|
_all_models[name_1] = model;
|
|
else if (errorFn != null)
|
|
errorFn(name_1);
|
|
else
|
|
console.warn("Model '" + name_1 + "' was already registered");
|
|
}
|
|
};
|
|
exports.register_models = exports.Models.register_models;
|
|
exports.Models.registered_names = function () { return Object.keys(_all_models); };
|
|
}
|
|
,
|
|
/* client/connection */ function _(require, module, exports) {
|
|
var logging_1 = require(17) /* ../core/logging */;
|
|
var document_1 = require(54) /* ../document */;
|
|
var message_1 = require(292) /* ../protocol/message */;
|
|
var receiver_1 = require(293) /* ../protocol/receiver */;
|
|
var session_1 = require(2) /* ./session */;
|
|
exports.DEFAULT_SERVER_WEBSOCKET_URL = "ws://localhost:5006/ws";
|
|
exports.DEFAULT_SESSION_ID = "default";
|
|
var _connection_count = 0;
|
|
var ClientConnection = /** @class */ (function () {
|
|
function ClientConnection(url, id, args_string, _on_have_session_hook, _on_closed_permanently_hook) {
|
|
if (url === void 0) {
|
|
url = exports.DEFAULT_SERVER_WEBSOCKET_URL;
|
|
}
|
|
if (id === void 0) {
|
|
id = exports.DEFAULT_SESSION_ID;
|
|
}
|
|
if (args_string === void 0) {
|
|
args_string = null;
|
|
}
|
|
if (_on_have_session_hook === void 0) {
|
|
_on_have_session_hook = null;
|
|
}
|
|
if (_on_closed_permanently_hook === void 0) {
|
|
_on_closed_permanently_hook = null;
|
|
}
|
|
this.url = url;
|
|
this.id = id;
|
|
this.args_string = args_string;
|
|
this._on_have_session_hook = _on_have_session_hook;
|
|
this._on_closed_permanently_hook = _on_closed_permanently_hook;
|
|
this._number = _connection_count++;
|
|
this.socket = null;
|
|
this.session = null;
|
|
this.closed_permanently = false;
|
|
this._current_handler = null;
|
|
this._pending_ack = null; // null or [resolve,reject]
|
|
this._pending_replies = {}; // map reqid to [resolve,reject]
|
|
this._receiver = new receiver_1.Receiver();
|
|
logging_1.logger.debug("Creating websocket " + this._number + " to '" + this.url + "' session '" + this.id + "'");
|
|
}
|
|
ClientConnection.prototype.connect = function () {
|
|
var _this = this;
|
|
if (this.closed_permanently)
|
|
return Promise.reject(new Error("Cannot connect() a closed ClientConnection"));
|
|
if (this.socket != null)
|
|
return Promise.reject(new Error("Already connected"));
|
|
this._pending_replies = {};
|
|
this._current_handler = null;
|
|
try {
|
|
var versioned_url = this.url + "?bokeh-protocol-version=1.0&bokeh-session-id=" + this.id;
|
|
if (this.args_string != null && this.args_string.length > 0)
|
|
versioned_url += "&" + this.args_string;
|
|
this.socket = new WebSocket(versioned_url);
|
|
return new Promise(function (resolve, reject) {
|
|
// "arraybuffer" gives us binary data we can look at;
|
|
// if we just needed an opaque blob we could use "blob"
|
|
_this.socket.binaryType = "arraybuffer";
|
|
_this.socket.onopen = function () { return _this._on_open(resolve, reject); };
|
|
_this.socket.onmessage = function (event) { return _this._on_message(event); };
|
|
_this.socket.onclose = function (event) { return _this._on_close(event); };
|
|
_this.socket.onerror = function () { return _this._on_error(reject); };
|
|
});
|
|
}
|
|
catch (error) {
|
|
logging_1.logger.error("websocket creation failed to url: " + this.url);
|
|
logging_1.logger.error(" - " + error);
|
|
return Promise.reject(error);
|
|
}
|
|
};
|
|
ClientConnection.prototype.close = function () {
|
|
if (!this.closed_permanently) {
|
|
logging_1.logger.debug("Permanently closing websocket connection " + this._number);
|
|
this.closed_permanently = true;
|
|
if (this.socket != null)
|
|
this.socket.close(1000, "close method called on ClientConnection " + this._number);
|
|
this.session._connection_closed();
|
|
if (this._on_closed_permanently_hook != null) {
|
|
this._on_closed_permanently_hook();
|
|
this._on_closed_permanently_hook = null;
|
|
}
|
|
}
|
|
};
|
|
ClientConnection.prototype._schedule_reconnect = function (milliseconds) {
|
|
var _this = this;
|
|
var retry = function () {
|
|
// TODO commented code below until we fix reconnection to repull
|
|
// the document when required. Otherwise, we get a lot of
|
|
// confusing errors that are causing trouble when debugging.
|
|
/*
|
|
if (this.closed_permanently) {
|
|
*/
|
|
if (!_this.closed_permanently)
|
|
logging_1.logger.info("Websocket connection " + _this._number + " disconnected, will not attempt to reconnect");
|
|
return;
|
|
/*
|
|
} else {
|
|
logger.debug(`Attempting to reconnect websocket ${this._number}`)
|
|
this.connect()
|
|
}
|
|
*/
|
|
};
|
|
setTimeout(retry, milliseconds);
|
|
};
|
|
ClientConnection.prototype.send = function (message) {
|
|
if (this.socket == null)
|
|
throw new Error("not connected so cannot send " + message);
|
|
message.send(this.socket);
|
|
};
|
|
ClientConnection.prototype.send_with_reply = function (message) {
|
|
var _this = this;
|
|
var promise = new Promise(function (resolve, reject) {
|
|
_this._pending_replies[message.msgid()] = [resolve, reject];
|
|
_this.send(message);
|
|
});
|
|
return promise.then(function (message) {
|
|
if (message.msgtype() === "ERROR")
|
|
throw new Error("Error reply " + message.content.text);
|
|
else
|
|
return message;
|
|
}, function (error) {
|
|
throw error;
|
|
});
|
|
};
|
|
ClientConnection.prototype._pull_doc_json = function () {
|
|
var message = message_1.Message.create("PULL-DOC-REQ", {});
|
|
var promise = this.send_with_reply(message);
|
|
return promise.then(function (reply) {
|
|
if (!('doc' in reply.content))
|
|
throw new Error("No 'doc' field in PULL-DOC-REPLY");
|
|
return reply.content.doc;
|
|
}, function (error) {
|
|
throw error;
|
|
});
|
|
};
|
|
ClientConnection.prototype._repull_session_doc = function () {
|
|
var _this = this;
|
|
if (this.session == null)
|
|
logging_1.logger.debug("Pulling session for first time");
|
|
else
|
|
logging_1.logger.debug("Repulling session");
|
|
this._pull_doc_json().then(function (doc_json) {
|
|
if (_this.session == null) {
|
|
if (_this.closed_permanently)
|
|
logging_1.logger.debug("Got new document after connection was already closed");
|
|
else {
|
|
var document_2 = document_1.Document.from_json(doc_json);
|
|
// Constructing models changes some of their attributes, we deal with that
|
|
// here. This happens when models set attributes during construction
|
|
// or initialization.
|
|
var patch = document_1.Document._compute_patch_since_json(doc_json, document_2);
|
|
if (patch.events.length > 0) {
|
|
logging_1.logger.debug("Sending " + patch.events.length + " changes from model construction back to server");
|
|
var patch_message = message_1.Message.create('PATCH-DOC', {}, patch);
|
|
_this.send(patch_message);
|
|
}
|
|
_this.session = new session_1.ClientSession(_this, document_2, _this.id);
|
|
logging_1.logger.debug("Created a new session from new pulled doc");
|
|
if (_this._on_have_session_hook != null) {
|
|
_this._on_have_session_hook(_this.session);
|
|
_this._on_have_session_hook = null;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
_this.session.document.replace_with_json(doc_json);
|
|
logging_1.logger.debug("Updated existing session with new pulled doc");
|
|
}
|
|
}, function (error) {
|
|
// handling the error here is useless because we wouldn't
|
|
// get errors from the resolve handler above, so see
|
|
// the catch below instead
|
|
throw error;
|
|
}).catch(function (error) {
|
|
if (console.trace != null)
|
|
console.trace(error);
|
|
logging_1.logger.error("Failed to repull session " + error);
|
|
});
|
|
};
|
|
ClientConnection.prototype._on_open = function (resolve, reject) {
|
|
var _this = this;
|
|
logging_1.logger.info("Websocket connection " + this._number + " is now open");
|
|
this._pending_ack = [resolve, reject];
|
|
this._current_handler = function (message) {
|
|
_this._awaiting_ack_handler(message);
|
|
};
|
|
};
|
|
ClientConnection.prototype._on_message = function (event) {
|
|
if (this._current_handler == null)
|
|
logging_1.logger.error("Got a message with no current handler set");
|
|
try {
|
|
this._receiver.consume(event.data);
|
|
}
|
|
catch (e) {
|
|
this._close_bad_protocol(e.toString());
|
|
}
|
|
if (this._receiver.message == null)
|
|
return;
|
|
var msg = this._receiver.message;
|
|
var problem = msg.problem();
|
|
if (problem != null)
|
|
this._close_bad_protocol(problem);
|
|
this._current_handler(msg);
|
|
};
|
|
ClientConnection.prototype._on_close = function (event) {
|
|
var _this = this;
|
|
logging_1.logger.info("Lost websocket " + this._number + " connection, " + event.code + " (" + event.reason + ")");
|
|
this.socket = null;
|
|
if (this._pending_ack != null) {
|
|
this._pending_ack[1](new Error("Lost websocket connection, " + event.code + " (" + event.reason + ")"));
|
|
this._pending_ack = null;
|
|
}
|
|
var pop_pending = function () {
|
|
for (var reqid in _this._pending_replies) {
|
|
var promise_funcs_1 = _this._pending_replies[reqid];
|
|
delete _this._pending_replies[reqid];
|
|
return promise_funcs_1;
|
|
}
|
|
return null;
|
|
};
|
|
var promise_funcs = pop_pending();
|
|
while (promise_funcs != null) {
|
|
promise_funcs[1]("Disconnected");
|
|
promise_funcs = pop_pending();
|
|
}
|
|
if (!this.closed_permanently)
|
|
this._schedule_reconnect(2000);
|
|
};
|
|
ClientConnection.prototype._on_error = function (reject) {
|
|
logging_1.logger.debug("Websocket error on socket " + this._number);
|
|
reject(new Error("Could not open websocket"));
|
|
};
|
|
ClientConnection.prototype._close_bad_protocol = function (detail) {
|
|
logging_1.logger.error("Closing connection: " + detail);
|
|
if (this.socket != null)
|
|
this.socket.close(1002, detail); // 1002 = protocol error
|
|
};
|
|
ClientConnection.prototype._awaiting_ack_handler = function (message) {
|
|
var _this = this;
|
|
if (message.msgtype() === "ACK") {
|
|
this._current_handler = function (message) { return _this._steady_state_handler(message); };
|
|
// Reload any sessions
|
|
// TODO (havocp) there's a race where we might get a PATCH before
|
|
// we send and get a reply to our pulls.
|
|
this._repull_session_doc();
|
|
if (this._pending_ack != null) {
|
|
this._pending_ack[0](this);
|
|
this._pending_ack = null;
|
|
}
|
|
}
|
|
else
|
|
this._close_bad_protocol("First message was not an ACK");
|
|
};
|
|
ClientConnection.prototype._steady_state_handler = function (message) {
|
|
if (message.reqid() in this._pending_replies) {
|
|
var promise_funcs = this._pending_replies[message.reqid()];
|
|
delete this._pending_replies[message.reqid()];
|
|
promise_funcs[0](message);
|
|
}
|
|
else
|
|
this.session.handle(message);
|
|
};
|
|
return ClientConnection;
|
|
}());
|
|
exports.ClientConnection = ClientConnection;
|
|
// Returns a promise of a ClientSession
|
|
// The returned promise has a close() method in case you want to close before
|
|
// getting a session; session.close() works too once you have a session.
|
|
function pull_session(url, session_id, args_string) {
|
|
var promise = new Promise(function (resolve, reject) {
|
|
var connection = new ClientConnection(url, session_id, args_string, function (session) {
|
|
try {
|
|
resolve(session);
|
|
}
|
|
catch (error) {
|
|
logging_1.logger.error("Promise handler threw an error, closing session " + error);
|
|
session.close();
|
|
throw error;
|
|
}
|
|
}, function () {
|
|
// we rely on reject() as a no-op if we already resolved
|
|
reject(new Error("Connection was closed before we successfully pulled a session"));
|
|
});
|
|
connection.connect().then(function (_) { return undefined; }, function (error) {
|
|
logging_1.logger.error("Failed to connect to Bokeh server " + error);
|
|
throw error;
|
|
});
|
|
});
|
|
return promise;
|
|
}
|
|
exports.pull_session = pull_session;
|
|
}
|
|
,
|
|
/* client/session */ function _(require, module, exports) {
|
|
var document_1 = require(54) /* ../document */;
|
|
var message_1 = require(292) /* ../protocol/message */;
|
|
var logging_1 = require(17) /* ../core/logging */;
|
|
var ClientSession = /** @class */ (function () {
|
|
function ClientSession(_connection, document /*Document*/, id) {
|
|
var _this = this;
|
|
this._connection = _connection;
|
|
this.document = document;
|
|
this.id = id;
|
|
this._document_listener = function (event) { return _this._document_changed(event); };
|
|
this.document.on_change(this._document_listener);
|
|
this.event_manager = this.document.event_manager;
|
|
this.event_manager.session = this;
|
|
}
|
|
ClientSession.prototype.handle = function (message) {
|
|
var msgtype = message.msgtype();
|
|
if (msgtype === 'PATCH-DOC')
|
|
this._handle_patch(message);
|
|
else if (msgtype === 'OK')
|
|
this._handle_ok(message);
|
|
else if (msgtype === 'ERROR')
|
|
this._handle_error(message);
|
|
else
|
|
logging_1.logger.debug("Doing nothing with message " + message.msgtype());
|
|
};
|
|
ClientSession.prototype.close = function () {
|
|
this._connection.close();
|
|
};
|
|
ClientSession.prototype.send_event = function (event) {
|
|
var message = message_1.Message.create('EVENT', {}, JSON.stringify(event.to_json()));
|
|
this._connection.send(message);
|
|
};
|
|
/*protected*/ ClientSession.prototype._connection_closed = function () {
|
|
this.document.remove_on_change(this._document_listener);
|
|
};
|
|
// Sends a request to the server for info about the server, such as its Bokeh
|
|
// version. Returns a promise, the value of the promise is a free-form dictionary
|
|
// of server details.
|
|
ClientSession.prototype.request_server_info = function () {
|
|
var message = message_1.Message.create('SERVER-INFO-REQ', {});
|
|
var promise = this._connection.send_with_reply(message);
|
|
return promise.then(function (reply) { return reply.content; });
|
|
};
|
|
// Sends some request to the server (no guarantee about which one) and returns
|
|
// a promise which is completed when the server replies. The purpose of this
|
|
// is that if you wait for the promise to be completed, you know the server
|
|
// has processed the request. This is useful when writing tests because once
|
|
// the server has processed this request it should also have processed any
|
|
// events or requests you sent previously, which means you can check for the
|
|
// results of that processing without a race condition. (This assumes the
|
|
// server processes events in sequence, which it mostly has to semantically,
|
|
// since reordering events might change the final state.)
|
|
ClientSession.prototype.force_roundtrip = function () {
|
|
return this.request_server_info().then(function (_) { return undefined; });
|
|
};
|
|
ClientSession.prototype._document_changed = function (event) {
|
|
// Filter out events that were initiated by the ClientSession itself
|
|
if (event.setter_id === this.id)
|
|
return;
|
|
// Filter out changes to attributes that aren't server-visible
|
|
if (event instanceof document_1.ModelChangedEvent && !(event.attr in event.model.serializable_attributes()))
|
|
return;
|
|
// TODO (havocp) the connection may be closed here, which will
|
|
// cause this send to throw an error - need to deal with it more cleanly.
|
|
var message = message_1.Message.create('PATCH-DOC', {}, this.document.create_json_patch([event]));
|
|
this._connection.send(message);
|
|
};
|
|
ClientSession.prototype._handle_patch = function (message) {
|
|
this.document.apply_json_patch(message.content, message.buffers, this.id);
|
|
};
|
|
ClientSession.prototype._handle_ok = function (message) {
|
|
logging_1.logger.trace("Unhandled OK reply to " + message.reqid());
|
|
};
|
|
ClientSession.prototype._handle_error = function (message) {
|
|
logging_1.logger.error("Unhandled ERROR reply to " + message.reqid() + ": " + message.content.text);
|
|
};
|
|
return ClientSession;
|
|
}());
|
|
exports.ClientSession = ClientSession;
|
|
}
|
|
,
|
|
/* core/bokeh_events */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
function event(event_name) {
|
|
return function (cls) {
|
|
cls.prototype.event_name = event_name;
|
|
};
|
|
}
|
|
var BokehEvent = /** @class */ (function () {
|
|
function BokehEvent() {
|
|
}
|
|
BokehEvent.prototype.to_json = function () {
|
|
var event_name = this.event_name;
|
|
return { event_name: event_name, event_values: this._to_json() };
|
|
};
|
|
BokehEvent.prototype._to_json = function () {
|
|
var origin = this.origin;
|
|
return { model_id: origin != null ? origin.id : null };
|
|
};
|
|
return BokehEvent;
|
|
}());
|
|
exports.BokehEvent = BokehEvent;
|
|
var ButtonClick = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ButtonClick, _super);
|
|
function ButtonClick() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ButtonClick = tslib_1.__decorate([
|
|
event("button_click")
|
|
], ButtonClick);
|
|
return ButtonClick;
|
|
}(BokehEvent));
|
|
exports.ButtonClick = ButtonClick;
|
|
var MenuItemClick = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MenuItemClick, _super);
|
|
function MenuItemClick(item) {
|
|
var _this = _super.call(this) || this;
|
|
_this.item = item;
|
|
return _this;
|
|
}
|
|
MenuItemClick.prototype._to_json = function () {
|
|
var item = this.item;
|
|
return tslib_1.__assign({}, _super.prototype._to_json.call(this), { item: item });
|
|
};
|
|
MenuItemClick = tslib_1.__decorate([
|
|
event("menu_item_click")
|
|
], MenuItemClick);
|
|
return MenuItemClick;
|
|
}(BokehEvent));
|
|
exports.MenuItemClick = MenuItemClick;
|
|
// A UIEvent is an event originating on a canvas this includes.
|
|
// DOM events such as keystrokes as well as hammer events and LOD events.
|
|
var UIEvent = /** @class */ (function (_super) {
|
|
tslib_1.__extends(UIEvent, _super);
|
|
function UIEvent() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return UIEvent;
|
|
}(BokehEvent));
|
|
exports.UIEvent = UIEvent;
|
|
var LODStart = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LODStart, _super);
|
|
function LODStart() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
LODStart = tslib_1.__decorate([
|
|
event("lodstart")
|
|
], LODStart);
|
|
return LODStart;
|
|
}(UIEvent));
|
|
exports.LODStart = LODStart;
|
|
var LODEnd = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LODEnd, _super);
|
|
function LODEnd() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
LODEnd = tslib_1.__decorate([
|
|
event("lodend")
|
|
], LODEnd);
|
|
return LODEnd;
|
|
}(UIEvent));
|
|
exports.LODEnd = LODEnd;
|
|
var SelectionGeometry = /** @class */ (function (_super) {
|
|
tslib_1.__extends(SelectionGeometry, _super);
|
|
function SelectionGeometry(geometry, final) {
|
|
var _this = _super.call(this) || this;
|
|
_this.geometry = geometry;
|
|
_this.final = final;
|
|
return _this;
|
|
}
|
|
SelectionGeometry.prototype._to_json = function () {
|
|
var _a = this, geometry = _a.geometry, final = _a.final;
|
|
return tslib_1.__assign({}, _super.prototype._to_json.call(this), { geometry: geometry, final: final });
|
|
};
|
|
SelectionGeometry = tslib_1.__decorate([
|
|
event("selectiongeometry")
|
|
], SelectionGeometry);
|
|
return SelectionGeometry;
|
|
}(UIEvent));
|
|
exports.SelectionGeometry = SelectionGeometry;
|
|
var Reset = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Reset, _super);
|
|
function Reset() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Reset = tslib_1.__decorate([
|
|
event("reset")
|
|
], Reset);
|
|
return Reset;
|
|
}(UIEvent));
|
|
exports.Reset = Reset;
|
|
var PointEvent = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PointEvent, _super);
|
|
function PointEvent(sx, sy, x, y) {
|
|
var _this = _super.call(this) || this;
|
|
_this.sx = sx;
|
|
_this.sy = sy;
|
|
_this.x = x;
|
|
_this.y = y;
|
|
return _this;
|
|
}
|
|
PointEvent.prototype._to_json = function () {
|
|
var _a = this, sx = _a.sx, sy = _a.sy, x = _a.x, y = _a.y;
|
|
return tslib_1.__assign({}, _super.prototype._to_json.call(this), { sx: sx, sy: sy, x: x, y: y });
|
|
};
|
|
return PointEvent;
|
|
}(UIEvent));
|
|
exports.PointEvent = PointEvent;
|
|
var Pan = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Pan, _super);
|
|
function Pan(sx, sy, x, y, delta_x, delta_y) {
|
|
var _this = _super.call(this, sx, sy, x, y) || this;
|
|
_this.sx = sx;
|
|
_this.sy = sy;
|
|
_this.x = x;
|
|
_this.y = y;
|
|
_this.delta_x = delta_x;
|
|
_this.delta_y = delta_y;
|
|
return _this;
|
|
}
|
|
Pan.prototype._to_json = function () {
|
|
var _a = this, delta_x = _a.delta_x, delta_y = _a.delta_y /*, direction*/;
|
|
return tslib_1.__assign({}, _super.prototype._to_json.call(this), { delta_x: delta_x, delta_y: delta_y /*, direction*/ });
|
|
};
|
|
Pan = tslib_1.__decorate([
|
|
event("pan")
|
|
], Pan);
|
|
return Pan;
|
|
}(PointEvent));
|
|
exports.Pan = Pan;
|
|
var Pinch = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Pinch, _super);
|
|
function Pinch(sx, sy, x, y, scale) {
|
|
var _this = _super.call(this, sx, sy, x, y) || this;
|
|
_this.sx = sx;
|
|
_this.sy = sy;
|
|
_this.x = x;
|
|
_this.y = y;
|
|
_this.scale = scale;
|
|
return _this;
|
|
}
|
|
Pinch.prototype._to_json = function () {
|
|
var scale = this.scale;
|
|
return tslib_1.__assign({}, _super.prototype._to_json.call(this), { scale: scale });
|
|
};
|
|
Pinch = tslib_1.__decorate([
|
|
event("pinch")
|
|
], Pinch);
|
|
return Pinch;
|
|
}(PointEvent));
|
|
exports.Pinch = Pinch;
|
|
var MouseWheel = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MouseWheel, _super);
|
|
function MouseWheel(sx, sy, x, y, delta) {
|
|
var _this = _super.call(this, sx, sy, x, y) || this;
|
|
_this.sx = sx;
|
|
_this.sy = sy;
|
|
_this.x = x;
|
|
_this.y = y;
|
|
_this.delta = delta;
|
|
return _this;
|
|
}
|
|
MouseWheel.prototype._to_json = function () {
|
|
var delta = this.delta;
|
|
return tslib_1.__assign({}, _super.prototype._to_json.call(this), { delta: delta });
|
|
};
|
|
MouseWheel = tslib_1.__decorate([
|
|
event("wheel")
|
|
], MouseWheel);
|
|
return MouseWheel;
|
|
}(PointEvent));
|
|
exports.MouseWheel = MouseWheel;
|
|
var MouseMove = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MouseMove, _super);
|
|
function MouseMove() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
MouseMove = tslib_1.__decorate([
|
|
event("mousemove")
|
|
], MouseMove);
|
|
return MouseMove;
|
|
}(PointEvent));
|
|
exports.MouseMove = MouseMove;
|
|
var MouseEnter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MouseEnter, _super);
|
|
function MouseEnter() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
MouseEnter = tslib_1.__decorate([
|
|
event("mouseenter")
|
|
], MouseEnter);
|
|
return MouseEnter;
|
|
}(PointEvent));
|
|
exports.MouseEnter = MouseEnter;
|
|
var MouseLeave = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MouseLeave, _super);
|
|
function MouseLeave() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
MouseLeave = tslib_1.__decorate([
|
|
event("mouseleave")
|
|
], MouseLeave);
|
|
return MouseLeave;
|
|
}(PointEvent));
|
|
exports.MouseLeave = MouseLeave;
|
|
var Tap = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Tap, _super);
|
|
function Tap() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Tap = tslib_1.__decorate([
|
|
event("tap")
|
|
], Tap);
|
|
return Tap;
|
|
}(PointEvent));
|
|
exports.Tap = Tap;
|
|
var DoubleTap = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DoubleTap, _super);
|
|
function DoubleTap() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
DoubleTap = tslib_1.__decorate([
|
|
event("doubletap")
|
|
], DoubleTap);
|
|
return DoubleTap;
|
|
}(PointEvent));
|
|
exports.DoubleTap = DoubleTap;
|
|
var Press = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Press, _super);
|
|
function Press() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Press = tslib_1.__decorate([
|
|
event("press")
|
|
], Press);
|
|
return Press;
|
|
}(PointEvent));
|
|
exports.Press = Press;
|
|
var PanStart = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PanStart, _super);
|
|
function PanStart() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
PanStart = tslib_1.__decorate([
|
|
event("panstart")
|
|
], PanStart);
|
|
return PanStart;
|
|
}(PointEvent));
|
|
exports.PanStart = PanStart;
|
|
var PanEnd = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PanEnd, _super);
|
|
function PanEnd() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
PanEnd = tslib_1.__decorate([
|
|
event("panend")
|
|
], PanEnd);
|
|
return PanEnd;
|
|
}(PointEvent));
|
|
exports.PanEnd = PanEnd;
|
|
var PinchStart = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PinchStart, _super);
|
|
function PinchStart() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
PinchStart = tslib_1.__decorate([
|
|
event("pinchstart")
|
|
], PinchStart);
|
|
return PinchStart;
|
|
}(PointEvent));
|
|
exports.PinchStart = PinchStart;
|
|
var PinchEnd = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PinchEnd, _super);
|
|
function PinchEnd() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
PinchEnd = tslib_1.__decorate([
|
|
event("pinchend")
|
|
], PinchEnd);
|
|
return PinchEnd;
|
|
}(PointEvent));
|
|
exports.PinchEnd = PinchEnd;
|
|
}
|
|
,
|
|
/* core/build_views */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var array_1 = require(24) /* ./util/array */;
|
|
function build_views(view_storage, models, options, cls) {
|
|
if (cls === void 0) {
|
|
cls = function (model) { return model.default_view; };
|
|
}
|
|
var to_remove = array_1.difference(Object.keys(view_storage), models.map(function (model) { return model.id; }));
|
|
for (var _i = 0, to_remove_1 = to_remove; _i < to_remove_1.length; _i++) {
|
|
var model_id = to_remove_1[_i];
|
|
view_storage[model_id].remove();
|
|
delete view_storage[model_id];
|
|
}
|
|
var created_views = [];
|
|
var new_models = models.filter(function (model) { return view_storage[model.id] == null; });
|
|
for (var _a = 0, new_models_1 = new_models; _a < new_models_1.length; _a++) {
|
|
var model = new_models_1[_a];
|
|
var view_cls = cls(model);
|
|
var view_options = tslib_1.__assign({}, options, { model: model, connect_signals: false });
|
|
var view = new view_cls(view_options);
|
|
view_storage[model.id] = view;
|
|
created_views.push(view);
|
|
}
|
|
for (var _b = 0, created_views_1 = created_views; _b < created_views_1.length; _b++) {
|
|
var view = created_views_1[_b];
|
|
view.connect_signals();
|
|
}
|
|
return created_views;
|
|
}
|
|
exports.build_views = build_views;
|
|
function remove_views(view_storage) {
|
|
for (var id in view_storage) {
|
|
view_storage[id].remove();
|
|
delete view_storage[id];
|
|
}
|
|
}
|
|
exports.remove_views = remove_views;
|
|
}
|
|
,
|
|
/* core/dom */ function _(require, module, exports) {
|
|
var types_1 = require(46) /* ./util/types */;
|
|
var _createElement = function (tag) {
|
|
return function (attrs) {
|
|
if (attrs === void 0) {
|
|
attrs = {};
|
|
}
|
|
var children = [];
|
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
children[_i - 1] = arguments[_i];
|
|
}
|
|
var element = document.createElement(tag);
|
|
element.classList.add("bk");
|
|
for (var attr in attrs) {
|
|
var value = attrs[attr];
|
|
if (value == null || types_1.isBoolean(value) && !value)
|
|
continue;
|
|
if (attr === "class") {
|
|
if (types_1.isString(value))
|
|
value = value.split(/\s+/);
|
|
if (types_1.isArray(value)) {
|
|
for (var _a = 0, _b = value; _a < _b.length; _a++) {
|
|
var cls = _b[_a];
|
|
if (cls != null)
|
|
element.classList.add(cls);
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
if (attr === "style" && types_1.isPlainObject(value)) {
|
|
for (var prop in value) {
|
|
element.style[prop] = value[prop];
|
|
}
|
|
continue;
|
|
}
|
|
if (attr === "data" && types_1.isPlainObject(value)) {
|
|
for (var key in value) {
|
|
element.dataset[key] = value[key]; // XXX: attrs needs a better type
|
|
}
|
|
continue;
|
|
}
|
|
element.setAttribute(attr, value);
|
|
}
|
|
function append(child) {
|
|
if (child instanceof HTMLElement)
|
|
element.appendChild(child);
|
|
else if (types_1.isString(child))
|
|
element.appendChild(document.createTextNode(child));
|
|
else if (child != null && child !== false)
|
|
throw new Error("expected an HTMLElement, string, false or null, got " + JSON.stringify(child));
|
|
}
|
|
for (var _c = 0, children_1 = children; _c < children_1.length; _c++) {
|
|
var child = children_1[_c];
|
|
if (types_1.isArray(child)) {
|
|
for (var _d = 0, child_1 = child; _d < child_1.length; _d++) {
|
|
var _child = child_1[_d];
|
|
append(_child);
|
|
}
|
|
}
|
|
else
|
|
append(child);
|
|
}
|
|
return element;
|
|
};
|
|
};
|
|
function createElement(tag, attrs) {
|
|
var children = [];
|
|
for (var _i = 2; _i < arguments.length; _i++) {
|
|
children[_i - 2] = arguments[_i];
|
|
}
|
|
return _createElement(tag).apply(void 0, [attrs].concat(children));
|
|
}
|
|
exports.createElement = createElement;
|
|
exports.div = _createElement("div"), exports.span = _createElement("span"), exports.canvas = _createElement("canvas"), exports.link = _createElement("link"), exports.style = _createElement("style"), exports.a = _createElement("a"), exports.p = _createElement("p"), exports.i = _createElement("i"), exports.pre = _createElement("pre"), exports.button = _createElement("button"), exports.label = _createElement("label"), exports.input = _createElement("input"), exports.select = _createElement("select"), exports.option = _createElement("option"), exports.optgroup = _createElement("optgroup"), exports.textarea = _createElement("textarea");
|
|
function nbsp() {
|
|
return document.createTextNode("\u00a0");
|
|
}
|
|
exports.nbsp = nbsp;
|
|
function removeElement(element) {
|
|
var parent = element.parentNode;
|
|
if (parent != null) {
|
|
parent.removeChild(element);
|
|
}
|
|
}
|
|
exports.removeElement = removeElement;
|
|
function replaceWith(element, replacement) {
|
|
var parent = element.parentNode;
|
|
if (parent != null) {
|
|
parent.replaceChild(replacement, element);
|
|
}
|
|
}
|
|
exports.replaceWith = replaceWith;
|
|
function prepend(element) {
|
|
var nodes = [];
|
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
nodes[_i - 1] = arguments[_i];
|
|
}
|
|
var first = element.firstChild;
|
|
for (var _a = 0, nodes_1 = nodes; _a < nodes_1.length; _a++) {
|
|
var node = nodes_1[_a];
|
|
element.insertBefore(node, first);
|
|
}
|
|
}
|
|
exports.prepend = prepend;
|
|
function empty(element) {
|
|
var child;
|
|
while (child = element.firstChild) {
|
|
element.removeChild(child);
|
|
}
|
|
}
|
|
exports.empty = empty;
|
|
function display(element) {
|
|
element.style.display = "";
|
|
}
|
|
exports.display = display;
|
|
function undisplay(element) {
|
|
element.style.display = "none";
|
|
}
|
|
exports.undisplay = undisplay;
|
|
function show(element) {
|
|
element.style.visibility = "";
|
|
}
|
|
exports.show = show;
|
|
function hide(element) {
|
|
element.style.visibility = "hidden";
|
|
}
|
|
exports.hide = hide;
|
|
function offset(element) {
|
|
var rect = element.getBoundingClientRect();
|
|
return {
|
|
top: rect.top + window.pageYOffset - document.documentElement.clientTop,
|
|
left: rect.left + window.pageXOffset - document.documentElement.clientLeft,
|
|
};
|
|
}
|
|
exports.offset = offset;
|
|
function matches(el, selector) {
|
|
var p = Element.prototype;
|
|
var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector;
|
|
return f.call(el, selector);
|
|
}
|
|
exports.matches = matches;
|
|
function parent(el, selector) {
|
|
var node = el;
|
|
while (node = node.parentElement) {
|
|
if (matches(node, selector))
|
|
return node;
|
|
}
|
|
return null;
|
|
}
|
|
exports.parent = parent;
|
|
function num(value) {
|
|
return parseFloat(value) || 0;
|
|
}
|
|
function extents(el) {
|
|
var style = getComputedStyle(el);
|
|
return {
|
|
border: {
|
|
top: num(style.borderTopWidth),
|
|
bottom: num(style.borderBottomWidth),
|
|
left: num(style.borderLeftWidth),
|
|
right: num(style.borderRightWidth),
|
|
},
|
|
margin: {
|
|
top: num(style.marginTop),
|
|
bottom: num(style.marginBottom),
|
|
left: num(style.marginLeft),
|
|
right: num(style.marginRight),
|
|
},
|
|
padding: {
|
|
top: num(style.paddingTop),
|
|
bottom: num(style.paddingBottom),
|
|
left: num(style.paddingLeft),
|
|
right: num(style.paddingRight),
|
|
},
|
|
};
|
|
}
|
|
exports.extents = extents;
|
|
function size(el) {
|
|
var rect = el.getBoundingClientRect();
|
|
return {
|
|
width: Math.ceil(rect.width),
|
|
height: Math.ceil(rect.height),
|
|
};
|
|
}
|
|
exports.size = size;
|
|
function scroll_size(el) {
|
|
return {
|
|
width: Math.ceil(el.scrollWidth),
|
|
height: Math.ceil(el.scrollHeight),
|
|
};
|
|
}
|
|
exports.scroll_size = scroll_size;
|
|
function outer_size(el) {
|
|
var _a = extents(el).margin, left = _a.left, right = _a.right, top = _a.top, bottom = _a.bottom;
|
|
var _b = size(el), width = _b.width, height = _b.height;
|
|
return {
|
|
width: Math.ceil(width + left + right),
|
|
height: Math.ceil(height + top + bottom),
|
|
};
|
|
}
|
|
exports.outer_size = outer_size;
|
|
function content_size(el) {
|
|
var _a = el.getBoundingClientRect(), left = _a.left, top = _a.top;
|
|
var padding = extents(el).padding;
|
|
var width = 0;
|
|
var height = 0;
|
|
for (var _i = 0, _b = children(el); _i < _b.length; _i++) {
|
|
var child = _b[_i];
|
|
var rect = child.getBoundingClientRect();
|
|
width = Math.max(width, Math.ceil(rect.left - left - padding.left + rect.width));
|
|
height = Math.max(height, Math.ceil(rect.top - top - padding.top + rect.height));
|
|
}
|
|
return { width: width, height: height };
|
|
}
|
|
exports.content_size = content_size;
|
|
function position(el, box, margin) {
|
|
var style = el.style;
|
|
style.left = box.left + "px";
|
|
style.top = box.top + "px";
|
|
style.width = box.width + "px";
|
|
style.height = box.height + "px";
|
|
if (margin == null)
|
|
style.margin = "";
|
|
else {
|
|
var top_1 = margin.top, right = margin.right, bottom = margin.bottom, left = margin.left;
|
|
style.margin = top_1 + "px " + right + "px " + bottom + "px " + left + "px";
|
|
}
|
|
}
|
|
exports.position = position;
|
|
function children(el) {
|
|
return Array.from(el.children);
|
|
}
|
|
exports.children = children;
|
|
var ClassList = /** @class */ (function () {
|
|
function ClassList(el) {
|
|
this.el = el;
|
|
this.classList = el.classList;
|
|
}
|
|
Object.defineProperty(ClassList.prototype, "values", {
|
|
get: function () {
|
|
var values = [];
|
|
for (var i_1 = 0; i_1 < this.classList.length; i_1++) {
|
|
var item = this.classList.item(i_1);
|
|
if (item != null)
|
|
values.push(item);
|
|
}
|
|
return values;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
ClassList.prototype.has = function (cls) {
|
|
return this.classList.contains(cls);
|
|
};
|
|
ClassList.prototype.add = function () {
|
|
var classes = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
classes[_i] = arguments[_i];
|
|
}
|
|
for (var _a = 0, classes_1 = classes; _a < classes_1.length; _a++) {
|
|
var cls = classes_1[_a];
|
|
this.classList.add(cls);
|
|
}
|
|
return this;
|
|
};
|
|
ClassList.prototype.remove = function () {
|
|
var classes = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
classes[_i] = arguments[_i];
|
|
}
|
|
for (var _a = 0, classes_2 = classes; _a < classes_2.length; _a++) {
|
|
var cls = classes_2[_a];
|
|
this.classList.remove(cls);
|
|
}
|
|
return this;
|
|
};
|
|
ClassList.prototype.clear = function () {
|
|
for (var _i = 0, _a = this.values; _i < _a.length; _i++) {
|
|
var cls = _a[_i];
|
|
if (cls != "bk")
|
|
this.classList.remove(cls);
|
|
}
|
|
return this;
|
|
};
|
|
ClassList.prototype.toggle = function (cls, activate) {
|
|
var add = activate != null ? activate : !this.has(cls);
|
|
if (add)
|
|
this.add(cls);
|
|
else
|
|
this.remove(cls);
|
|
return this;
|
|
};
|
|
return ClassList;
|
|
}());
|
|
exports.ClassList = ClassList;
|
|
function classes(el) {
|
|
return new ClassList(el);
|
|
}
|
|
exports.classes = classes;
|
|
var Keys;
|
|
(function (Keys) {
|
|
Keys[Keys["Backspace"] = 8] = "Backspace";
|
|
Keys[Keys["Tab"] = 9] = "Tab";
|
|
Keys[Keys["Enter"] = 13] = "Enter";
|
|
Keys[Keys["Esc"] = 27] = "Esc";
|
|
Keys[Keys["PageUp"] = 33] = "PageUp";
|
|
Keys[Keys["PageDown"] = 34] = "PageDown";
|
|
Keys[Keys["Left"] = 37] = "Left";
|
|
Keys[Keys["Up"] = 38] = "Up";
|
|
Keys[Keys["Right"] = 39] = "Right";
|
|
Keys[Keys["Down"] = 40] = "Down";
|
|
Keys[Keys["Delete"] = 46] = "Delete";
|
|
})(Keys = exports.Keys || (exports.Keys = {}));
|
|
function undisplayed(el, fn) {
|
|
var display = el.style.display;
|
|
el.style.display = "none";
|
|
try {
|
|
return fn();
|
|
}
|
|
finally {
|
|
el.style.display = display;
|
|
}
|
|
}
|
|
exports.undisplayed = undisplayed;
|
|
function unsized(el, fn) {
|
|
return sized(el, {}, fn);
|
|
}
|
|
exports.unsized = unsized;
|
|
function sized(el, size, fn) {
|
|
var _a = el.style, width = _a.width, height = _a.height, position = _a.position, display = _a.display;
|
|
el.style.position = "absolute";
|
|
el.style.display = "";
|
|
el.style.width = size.width != null && size.width != Infinity ? size.width + "px" : "auto";
|
|
el.style.height = size.height != null && size.height != Infinity ? size.height + "px" : "auto";
|
|
try {
|
|
return fn();
|
|
}
|
|
finally {
|
|
el.style.position = position;
|
|
el.style.display = display;
|
|
el.style.width = width;
|
|
el.style.height = height;
|
|
}
|
|
}
|
|
exports.sized = sized;
|
|
}
|
|
,
|
|
/* core/dom_view */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var view_1 = require(50) /* ./view */;
|
|
var DOM = require(5) /* ./dom */;
|
|
var DOMView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DOMView, _super);
|
|
function DOMView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
DOMView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this._has_finished = false;
|
|
this.el = this._createElement();
|
|
};
|
|
DOMView.prototype.remove = function () {
|
|
DOM.removeElement(this.el);
|
|
_super.prototype.remove.call(this);
|
|
};
|
|
DOMView.prototype.css_classes = function () {
|
|
return [];
|
|
};
|
|
DOMView.prototype.cursor = function (_sx, _sy) {
|
|
return null;
|
|
};
|
|
DOMView.prototype.render = function () { };
|
|
DOMView.prototype.renderTo = function (element) {
|
|
element.appendChild(this.el);
|
|
this.render();
|
|
};
|
|
DOMView.prototype.has_finished = function () {
|
|
return this._has_finished;
|
|
};
|
|
Object.defineProperty(DOMView.prototype, "_root_element", {
|
|
get: function () {
|
|
return DOM.parent(this.el, ".bk-root") || document.body;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(DOMView.prototype, "is_idle", {
|
|
get: function () {
|
|
return this.has_finished();
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
DOMView.prototype._createElement = function () {
|
|
return DOM.createElement(this.tagName, { class: this.css_classes() });
|
|
};
|
|
return DOMView;
|
|
}(view_1.View));
|
|
exports.DOMView = DOMView;
|
|
DOMView.prototype.tagName = "div";
|
|
}
|
|
,
|
|
/* core/enums */ function _(require, module, exports) {
|
|
exports.Align = ["start", "center", "end"];
|
|
exports.Anchor = [
|
|
"top_left", "top_center", "top_right",
|
|
"center_left", "center", "center_right",
|
|
"bottom_left", "bottom_center", "bottom_right",
|
|
];
|
|
exports.AngleUnits = ["deg", "rad"];
|
|
exports.BoxOrigin = ["corner", "center"];
|
|
exports.ButtonType = ["default", "primary", "success", "warning", "danger"];
|
|
exports.Dimension = ["width", "height"];
|
|
exports.Dimensions = ["width", "height", "both"];
|
|
exports.Direction = ["clock", "anticlock"];
|
|
exports.Distribution = ["uniform", "normal"];
|
|
exports.FontStyle = ["normal", "italic", "bold", "bold italic"];
|
|
exports.HTTPMethod = ["POST", "GET"];
|
|
exports.HexTileOrientation = ["pointytop", "flattop"];
|
|
exports.HoverMode = ["mouse", "hline", "vline"];
|
|
exports.LatLon = ["lat", "lon"];
|
|
exports.LegendClickPolicy = ["none", "hide", "mute"];
|
|
exports.LegendLocation = exports.Anchor;
|
|
exports.LineCap = ["butt", "round", "square"];
|
|
exports.LineJoin = ["miter", "round", "bevel"];
|
|
exports.LinePolicy = ["prev", "next", "nearest", "interp", "none"];
|
|
exports.Location = ["above", "below", "left", "right"];
|
|
exports.Logo = ["normal", "grey"];
|
|
exports.MarkerType = [
|
|
"asterisk", "circle", "circle_cross", "circle_x", "cross",
|
|
"dash", "diamond", "diamond_cross", "hex", "inverted_triangle",
|
|
"square", "square_cross", "square_x", "triangle", "x",
|
|
];
|
|
exports.Orientation = ["vertical", "horizontal"];
|
|
exports.OutputBackend = ["canvas", "svg", "webgl"];
|
|
exports.PaddingUnits = ["percent", "absolute"];
|
|
exports.Place = ["above", "below", "left", "right", "center"];
|
|
exports.PointPolicy = ["snap_to_data", "follow_mouse", "none"];
|
|
exports.RadiusDimension = ["x", "y", "max", "min"];
|
|
exports.RenderLevel = ["image", "underlay", "glyph", "annotation", "overlay"];
|
|
exports.RenderMode = ["canvas", "css"];
|
|
exports.RoundingFunction = ["round", "nearest", "floor", "rounddown", "ceil", "roundup"];
|
|
exports.Side = ["above", "below", "left", "right"];
|
|
exports.SizingMode = ["stretch_width", "stretch_height", "stretch_both", "scale_width", "scale_height", "scale_both", "fixed"];
|
|
exports.SliderCallbackPolicy = ["continuous", "throttle", "mouseup"];
|
|
exports.Sort = ["ascending", "descending"];
|
|
exports.SpatialUnits = ["screen", "data"];
|
|
exports.StartEnd = ["start", "end"];
|
|
exports.StepMode = ["after", "before", "center"];
|
|
exports.TapBehavior = ["select", "inspect"];
|
|
exports.TextAlign = ["left", "right", "center"];
|
|
exports.TextBaseline = ["top", "middle", "bottom", "alphabetic", "hanging", "ideographic"];
|
|
exports.TickLabelOrientation = ["vertical", "horizontal", "parallel", "normal"];
|
|
exports.TooltipAttachment = ["horizontal", "vertical", "left", "right", "above", "below"];
|
|
exports.UpdateMode = ["replace", "append"];
|
|
exports.VerticalAlign = ["top", "middle", "bottom"];
|
|
}
|
|
,
|
|
/* core/has_props */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var signaling_1 = require(22) /* ./signaling */;
|
|
var property_mixins = require(19) /* ./property_mixins */;
|
|
var refs_1 = require(37) /* ./util/refs */;
|
|
var p = require(18) /* ./properties */;
|
|
var string_1 = require(40) /* ./util/string */;
|
|
var array_1 = require(24) /* ./util/array */;
|
|
var object_1 = require(35) /* ./util/object */;
|
|
var types_1 = require(46) /* ./util/types */;
|
|
var eq_1 = require(33) /* ./util/eq */;
|
|
var HasProps = /** @class */ (function (_super) {
|
|
tslib_1.__extends(HasProps, _super);
|
|
function HasProps(attrs) {
|
|
if (attrs === void 0) {
|
|
attrs = {};
|
|
}
|
|
var _this = _super.call(this) || this;
|
|
_this._subtype = undefined;
|
|
_this.document = null;
|
|
_this.destroyed = new signaling_1.Signal0(_this, "destroyed");
|
|
_this.change = new signaling_1.Signal0(_this, "change");
|
|
_this.transformchange = new signaling_1.Signal0(_this, "transformchange");
|
|
_this.attributes = {};
|
|
_this.properties = {};
|
|
_this._set_after_defaults = {};
|
|
_this._pending = false;
|
|
_this._changing = false;
|
|
for (var name_1 in _this.props) {
|
|
var _a = _this.props[name_1], type = _a.type, default_value = _a.default_value;
|
|
if (type != null)
|
|
_this.properties[name_1] = new type(_this, name_1, default_value);
|
|
else
|
|
throw new Error("undefined property type for " + _this.type + "." + name_1);
|
|
}
|
|
// auto generating ID
|
|
if (attrs.id == null)
|
|
_this.setv({ id: string_1.uniqueId() }, { silent: true });
|
|
var deferred = attrs.__deferred__ || false;
|
|
if (deferred) {
|
|
attrs = object_1.clone(attrs);
|
|
delete attrs.__deferred__;
|
|
}
|
|
_this.setv(attrs, { silent: true });
|
|
// allowing us to defer initialization when loading many models
|
|
// when loading a bunch of models, we want to do initialization as a second pass
|
|
// because other objects that this one depends on might not be loaded yet
|
|
if (!deferred)
|
|
_this.finalize();
|
|
return _this;
|
|
}
|
|
HasProps.initClass = function () {
|
|
this.prototype.type = "HasProps";
|
|
this.prototype.props = {};
|
|
this.prototype.mixins = [];
|
|
this.define({
|
|
id: [p.Any],
|
|
});
|
|
};
|
|
// }}}
|
|
HasProps._fix_default = function (default_value, _attr) {
|
|
if (default_value === undefined)
|
|
return undefined;
|
|
else if (types_1.isFunction(default_value))
|
|
return default_value;
|
|
else if (!types_1.isObject(default_value))
|
|
return function () { return default_value; };
|
|
else {
|
|
//logger.warn(`${this.prototype.type}.${attr} uses unwrapped non-primitive default value`)
|
|
if (types_1.isArray(default_value))
|
|
return function () { return array_1.copy(default_value); };
|
|
else
|
|
return function () { return object_1.clone(default_value); };
|
|
}
|
|
};
|
|
// TODO: don't use Partial<>, but exclude inherited properties
|
|
HasProps.define = function (obj) {
|
|
var _loop_1 = function (name_2) {
|
|
var prop = obj[name_2];
|
|
if (this_1.prototype.props[name_2] != null)
|
|
throw new Error("attempted to redefine property '" + this_1.prototype.type + "." + name_2 + "'");
|
|
if (this_1.prototype[name_2] != null)
|
|
throw new Error("attempted to redefine attribute '" + this_1.prototype.type + "." + name_2 + "'");
|
|
Object.defineProperty(this_1.prototype, name_2, {
|
|
// XXX: don't use tail calls in getters/setters due to https://bugs.webkit.org/show_bug.cgi?id=164306
|
|
get: function () {
|
|
var value = this.getv(name_2);
|
|
return value;
|
|
},
|
|
set: function (value) {
|
|
var _a;
|
|
this.setv((_a = {}, _a[name_2] = value, _a));
|
|
return this;
|
|
},
|
|
configurable: false,
|
|
enumerable: true,
|
|
});
|
|
var _a = prop, type = _a[0], default_value = _a[1], internal = _a[2];
|
|
var refined_prop = {
|
|
type: type,
|
|
default_value: this_1._fix_default(default_value, name_2),
|
|
internal: internal || false,
|
|
};
|
|
var props = object_1.clone(this_1.prototype.props);
|
|
props[name_2] = refined_prop;
|
|
this_1.prototype.props = props;
|
|
};
|
|
var this_1 = this;
|
|
for (var name_2 in obj) {
|
|
_loop_1(name_2);
|
|
}
|
|
};
|
|
HasProps.internal = function (obj) {
|
|
var _object = {};
|
|
for (var name_3 in obj) {
|
|
var prop = obj[name_3];
|
|
var type = prop[0], default_value = prop[1];
|
|
_object[name_3] = [type, default_value, true];
|
|
}
|
|
this.define(_object);
|
|
};
|
|
HasProps.mixin = function () {
|
|
var names = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
names[_i] = arguments[_i];
|
|
}
|
|
this.define(property_mixins.create(names));
|
|
var mixins = this.prototype.mixins.concat(names);
|
|
this.prototype.mixins = mixins;
|
|
};
|
|
HasProps.mixins = function (names) {
|
|
this.mixin.apply(this, names);
|
|
};
|
|
HasProps.override = function (obj) {
|
|
for (var name_4 in obj) {
|
|
var default_value = this._fix_default(obj[name_4], name_4);
|
|
var value = this.prototype.props[name_4];
|
|
if (value == null)
|
|
throw new Error("attempted to override nonexistent '" + this.prototype.type + "." + name_4 + "'");
|
|
var props = object_1.clone(this.prototype.props);
|
|
props[name_4] = tslib_1.__assign({}, value, { default_value: default_value });
|
|
this.prototype.props = props;
|
|
}
|
|
};
|
|
HasProps.prototype.toString = function () {
|
|
return this.type + "(" + this.id + ")";
|
|
};
|
|
HasProps.prototype.finalize = function () {
|
|
var _this = this;
|
|
// This is necessary because the initial creation of properties relies on
|
|
// model.get which is not usable at that point yet in the constructor. This
|
|
// initializer is called when deferred initialization happens for all models
|
|
// and insures that the Bokeh properties are initialized from Backbone
|
|
// attributes in a consistent way.
|
|
//
|
|
// TODO (bev) split property creation up into two parts so that only the
|
|
// portion of init that can be done happens in HasProps constructor and so
|
|
// that subsequent updates do not duplicate that setup work.
|
|
for (var name_5 in this.properties) {
|
|
var prop = this.properties[name_5];
|
|
prop.update();
|
|
if (prop.spec.transform != null)
|
|
this.connect(prop.spec.transform.change, function () { return _this.transformchange.emit(); });
|
|
}
|
|
this.initialize();
|
|
this.connect_signals();
|
|
};
|
|
HasProps.prototype.initialize = function () { };
|
|
HasProps.prototype.connect_signals = function () { };
|
|
HasProps.prototype.disconnect_signals = function () {
|
|
signaling_1.Signal.disconnectReceiver(this);
|
|
};
|
|
HasProps.prototype.destroy = function () {
|
|
this.disconnect_signals();
|
|
this.destroyed.emit();
|
|
};
|
|
// Create a new model with identical attributes to this one.
|
|
HasProps.prototype.clone = function () {
|
|
return new this.constructor(this.attributes);
|
|
};
|
|
// Set a hash of model attributes on the object, firing `"change"`. This is
|
|
// the core primitive operation of a model, updating the data and notifying
|
|
// anyone who needs to know about the change in state. The heart of the beast.
|
|
HasProps.prototype._setv = function (attrs, options) {
|
|
// Extract attributes and options.
|
|
var check_eq = options.check_eq;
|
|
var silent = options.silent;
|
|
var changes = [];
|
|
var changing = this._changing;
|
|
this._changing = true;
|
|
var current = this.attributes;
|
|
// For each `set` attribute, update or delete the current value.
|
|
for (var attr in attrs) {
|
|
var val = attrs[attr];
|
|
if (check_eq !== false) {
|
|
if (!eq_1.isEqual(current[attr], val))
|
|
changes.push(attr);
|
|
}
|
|
else
|
|
changes.push(attr);
|
|
current[attr] = val;
|
|
}
|
|
// Trigger all relevant attribute changes.
|
|
if (!silent) {
|
|
if (changes.length > 0)
|
|
this._pending = true;
|
|
for (var i = 0; i < changes.length; i++)
|
|
this.properties[changes[i]].change.emit();
|
|
}
|
|
// You might be wondering why there's a `while` loop here. Changes can
|
|
// be recursively nested within `"change"` events.
|
|
if (changing)
|
|
return;
|
|
if (!silent && !options.no_change) {
|
|
while (this._pending) {
|
|
this._pending = false;
|
|
this.change.emit();
|
|
}
|
|
}
|
|
this._pending = false;
|
|
this._changing = false;
|
|
};
|
|
HasProps.prototype.setv = function (attrs, options) {
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
for (var key in attrs) {
|
|
if (!attrs.hasOwnProperty(key))
|
|
continue;
|
|
var prop_name = key;
|
|
if (this.props[prop_name] == null)
|
|
throw new Error("property " + this.type + "." + prop_name + " wasn't declared");
|
|
if (!(options != null && options.defaults))
|
|
this._set_after_defaults[key] = true;
|
|
}
|
|
if (!object_1.isEmpty(attrs)) {
|
|
var old = {};
|
|
for (var key in attrs)
|
|
old[key] = this.getv(key);
|
|
this._setv(attrs, options);
|
|
var silent = options.silent;
|
|
if (silent == null || !silent) {
|
|
for (var key in attrs)
|
|
this._tell_document_about_change(key, old[key], this.getv(key), options);
|
|
}
|
|
}
|
|
};
|
|
HasProps.prototype.getv = function (prop_name) {
|
|
if (this.props[prop_name] == null)
|
|
throw new Error("property " + this.type + "." + prop_name + " wasn't declared");
|
|
else
|
|
return this.attributes[prop_name];
|
|
};
|
|
HasProps.prototype.ref = function () {
|
|
return refs_1.create_ref(this);
|
|
};
|
|
// we only keep the subtype so we match Python;
|
|
// only Python cares about this
|
|
HasProps.prototype.set_subtype = function (subtype) {
|
|
this._subtype = subtype;
|
|
};
|
|
HasProps.prototype.attribute_is_serializable = function (attr) {
|
|
var prop = this.props[attr];
|
|
if (prop == null)
|
|
throw new Error(this.type + ".attribute_is_serializable('" + attr + "'): " + attr + " wasn't declared");
|
|
else
|
|
return !prop.internal;
|
|
};
|
|
// dict of attributes that should be serialized to the server. We
|
|
// sometimes stick things in attributes that aren't part of the
|
|
// Document's models, subtypes that do that have to remove their
|
|
// extra attributes here.
|
|
HasProps.prototype.serializable_attributes = function () {
|
|
var attrs = {};
|
|
for (var name_6 in this.attributes) {
|
|
var value = this.attributes[name_6];
|
|
if (this.attribute_is_serializable(name_6))
|
|
attrs[name_6] = value;
|
|
}
|
|
return attrs;
|
|
};
|
|
HasProps._value_to_json = function (_key, value, _optional_parent_object) {
|
|
if (value instanceof HasProps)
|
|
return value.ref();
|
|
else if (types_1.isArray(value)) {
|
|
var ref_array = [];
|
|
for (var i = 0; i < value.length; i++) {
|
|
var v = value[i];
|
|
ref_array.push(HasProps._value_to_json(i.toString(), v, value));
|
|
}
|
|
return ref_array;
|
|
}
|
|
else if (types_1.isPlainObject(value)) {
|
|
var ref_obj = {};
|
|
for (var subkey in value) {
|
|
if (value.hasOwnProperty(subkey))
|
|
ref_obj[subkey] = HasProps._value_to_json(subkey, value[subkey], value);
|
|
}
|
|
return ref_obj;
|
|
}
|
|
else
|
|
return value;
|
|
};
|
|
// Convert attributes to "shallow" JSON (values which are themselves models
|
|
// are included as just references)
|
|
HasProps.prototype.attributes_as_json = function (include_defaults, value_to_json) {
|
|
if (include_defaults === void 0) {
|
|
include_defaults = true;
|
|
}
|
|
if (value_to_json === void 0) {
|
|
value_to_json = HasProps._value_to_json;
|
|
}
|
|
var serializable = this.serializable_attributes();
|
|
var attrs = {};
|
|
for (var key in serializable) {
|
|
if (serializable.hasOwnProperty(key)) {
|
|
var value = serializable[key];
|
|
if (include_defaults)
|
|
attrs[key] = value;
|
|
else if (key in this._set_after_defaults)
|
|
attrs[key] = value;
|
|
}
|
|
}
|
|
return value_to_json("attributes", attrs, this);
|
|
};
|
|
// this is like _value_record_references but expects to find refs
|
|
// instead of models, and takes a doc to look up the refs in
|
|
HasProps._json_record_references = function (doc, v, result, recurse) {
|
|
if (v == null) {
|
|
}
|
|
else if (refs_1.is_ref(v)) {
|
|
if (!(v.id in result)) {
|
|
var model = doc.get_model_by_id(v.id);
|
|
HasProps._value_record_references(model, result, recurse);
|
|
}
|
|
}
|
|
else if (types_1.isArray(v)) {
|
|
for (var _i = 0, v_1 = v; _i < v_1.length; _i++) {
|
|
var elem = v_1[_i];
|
|
HasProps._json_record_references(doc, elem, result, recurse);
|
|
}
|
|
}
|
|
else if (types_1.isPlainObject(v)) {
|
|
for (var k in v) {
|
|
if (v.hasOwnProperty(k)) {
|
|
var elem = v[k];
|
|
HasProps._json_record_references(doc, elem, result, recurse);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
// add all references from 'v' to 'result', if recurse
|
|
// is true then descend into refs, if false only
|
|
// descend into non-refs
|
|
HasProps._value_record_references = function (v, result, recurse) {
|
|
if (v == null) {
|
|
}
|
|
else if (v instanceof HasProps) {
|
|
if (!(v.id in result)) {
|
|
result[v.id] = v;
|
|
if (recurse) {
|
|
var immediate = v._immediate_references();
|
|
for (var _i = 0, immediate_1 = immediate; _i < immediate_1.length; _i++) {
|
|
var obj = immediate_1[_i];
|
|
HasProps._value_record_references(obj, result, true);
|
|
} // true=recurse
|
|
}
|
|
}
|
|
}
|
|
else if (v.buffer instanceof ArrayBuffer) {
|
|
}
|
|
else if (types_1.isArray(v)) {
|
|
for (var _a = 0, v_2 = v; _a < v_2.length; _a++) {
|
|
var elem = v_2[_a];
|
|
HasProps._value_record_references(elem, result, recurse);
|
|
}
|
|
}
|
|
else if (types_1.isPlainObject(v)) {
|
|
for (var k in v) {
|
|
if (v.hasOwnProperty(k)) {
|
|
var elem = v[k];
|
|
HasProps._value_record_references(elem, result, recurse);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
// Get models that are immediately referenced by our properties
|
|
// (do not recurse, do not include ourselves)
|
|
HasProps.prototype._immediate_references = function () {
|
|
var result = {};
|
|
var attrs = this.serializable_attributes();
|
|
for (var key in attrs) {
|
|
var value = attrs[key];
|
|
HasProps._value_record_references(value, result, false); // false = no recurse
|
|
}
|
|
return object_1.values(result);
|
|
};
|
|
HasProps.prototype.references = function () {
|
|
var references = {};
|
|
HasProps._value_record_references(this, references, true);
|
|
return object_1.values(references);
|
|
};
|
|
HasProps.prototype._doc_attached = function () { };
|
|
HasProps.prototype.attach_document = function (doc) {
|
|
// This should only be called by the Document implementation to set the document field
|
|
if (this.document != null && this.document != doc)
|
|
throw new Error("models must be owned by only a single document");
|
|
this.document = doc;
|
|
this._doc_attached();
|
|
};
|
|
HasProps.prototype.detach_document = function () {
|
|
// This should only be called by the Document implementation to unset the document field
|
|
this.document = null;
|
|
};
|
|
HasProps.prototype._tell_document_about_change = function (attr, old, new_, options) {
|
|
if (!this.attribute_is_serializable(attr))
|
|
return;
|
|
if (this.document != null) {
|
|
var new_refs = {};
|
|
HasProps._value_record_references(new_, new_refs, false);
|
|
var old_refs = {};
|
|
HasProps._value_record_references(old, old_refs, false);
|
|
var need_invalidate = false;
|
|
for (var new_id in new_refs) {
|
|
if (!(new_id in old_refs)) {
|
|
need_invalidate = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!need_invalidate) {
|
|
for (var old_id in old_refs) {
|
|
if (!(old_id in new_refs)) {
|
|
need_invalidate = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (need_invalidate)
|
|
this.document._invalidate_all_models();
|
|
this.document._notify_change(this, attr, old, new_, options);
|
|
}
|
|
};
|
|
HasProps.prototype.materialize_dataspecs = function (source) {
|
|
// Note: this should be moved to a function separate from HasProps
|
|
var data = {};
|
|
for (var name_7 in this.properties) {
|
|
var prop = this.properties[name_7];
|
|
if (!(prop instanceof p.VectorSpec))
|
|
continue;
|
|
// this skips optional properties like radius for circles
|
|
if (prop.optional && prop.spec.value == null && !(name_7 in this._set_after_defaults))
|
|
continue;
|
|
var array = prop.array(source);
|
|
data["_" + name_7] = array;
|
|
// the shapes are indexed by the column name, but when we materialize the dataspec, we should
|
|
// store under the canonical field name, e.g. _image_shape, even if the column name is "foo"
|
|
if (prop.spec.field != null && prop.spec.field in source._shapes)
|
|
data["_" + name_7 + "_shape"] = source._shapes[prop.spec.field];
|
|
if (prop instanceof p.DistanceSpec)
|
|
data["max_" + name_7] = array_1.max(array);
|
|
}
|
|
return data;
|
|
};
|
|
return HasProps;
|
|
}(signaling_1.Signalable()));
|
|
exports.HasProps = HasProps;
|
|
HasProps.initClass();
|
|
}
|
|
,
|
|
/* core/hittest */ function _(require, module, exports) {
|
|
var array_1 = require(24) /* ./util/array */;
|
|
var selection_1 = require(205) /* ../models/selections/selection */;
|
|
function point_in_poly(x, y, px, py) {
|
|
var inside = false;
|
|
var x1 = px[px.length - 1];
|
|
var y1 = py[py.length - 1];
|
|
for (var i = 0; i < px.length; i++) {
|
|
var x2 = px[i];
|
|
var y2 = py[i];
|
|
if ((y1 < y) != (y2 < y)) {
|
|
if (x1 + (y - y1) / (y2 - y1) * (x2 - x1) < x)
|
|
inside = !inside;
|
|
}
|
|
x1 = x2;
|
|
y1 = y2;
|
|
}
|
|
return inside;
|
|
}
|
|
exports.point_in_poly = point_in_poly;
|
|
function point_in_ellipse(x, y, angle, b, a, x0, y0) {
|
|
var A = (Math.pow((Math.cos(angle) / a), 2) + Math.pow((Math.sin(angle) / b), 2));
|
|
var B = 2 * Math.cos(angle) * Math.sin(angle) * (Math.pow((1 / a), 2) - Math.pow((1 / b), 2));
|
|
var C = (Math.pow((Math.cos(angle) / b), 2) + Math.pow((Math.sin(angle) / a), 2));
|
|
var eqn = A * Math.pow((x - x0), 2) + B * (x - x0) * (y - y0) + C * Math.pow((y - y0), 2);
|
|
var inside = eqn <= 1;
|
|
return inside;
|
|
}
|
|
exports.point_in_ellipse = point_in_ellipse;
|
|
function create_empty_hit_test_result() {
|
|
return new selection_1.Selection();
|
|
}
|
|
exports.create_empty_hit_test_result = create_empty_hit_test_result;
|
|
function create_hit_test_result_from_hits(hits) {
|
|
var result = new selection_1.Selection();
|
|
result.indices = array_1.sort_by(hits, function (_a) {
|
|
var _i = _a[0], dist = _a[1];
|
|
return dist;
|
|
}).map(function (_a) {
|
|
var i = _a[0], _dist = _a[1];
|
|
return i;
|
|
});
|
|
return result;
|
|
}
|
|
exports.create_hit_test_result_from_hits = create_hit_test_result_from_hits;
|
|
function validate_bbox_coords(_a, _b) {
|
|
var _c, _d;
|
|
var x0 = _a[0], x1 = _a[1];
|
|
var y0 = _b[0], y1 = _b[1];
|
|
// spatial index (flatbush) expects x0, y0 to be min, x1, y1 max
|
|
if (x0 > x1)
|
|
_c = [x1, x0], x0 = _c[0], x1 = _c[1];
|
|
if (y0 > y1)
|
|
_d = [y1, y0], y0 = _d[0], y1 = _d[1];
|
|
return { minX: x0, minY: y0, maxX: x1, maxY: y1 };
|
|
}
|
|
exports.validate_bbox_coords = validate_bbox_coords;
|
|
function sqr(x) {
|
|
return x * x;
|
|
}
|
|
function dist_2_pts(p0, p1) {
|
|
return sqr(p0.x - p1.x) + sqr(p0.y - p1.y);
|
|
}
|
|
exports.dist_2_pts = dist_2_pts;
|
|
function dist_to_segment_squared(p, v, w) {
|
|
var l2 = dist_2_pts(v, w);
|
|
if (l2 == 0)
|
|
return dist_2_pts(p, v);
|
|
var t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
|
|
if (t < 0)
|
|
return dist_2_pts(p, v);
|
|
if (t > 1)
|
|
return dist_2_pts(p, w);
|
|
var q = { x: v.x + t * (w.x - v.x), y: v.y + t * (w.y - v.y) };
|
|
return dist_2_pts(p, q);
|
|
}
|
|
exports.dist_to_segment_squared = dist_to_segment_squared;
|
|
function dist_to_segment(p, v, w) {
|
|
return Math.sqrt(dist_to_segment_squared(p, v, w));
|
|
}
|
|
exports.dist_to_segment = dist_to_segment;
|
|
function check_2_segments_intersect(l0_x0, l0_y0, l0_x1, l0_y1, l1_x0, l1_y0, l1_x1, l1_y1) {
|
|
/*
|
|
* Check if 2 segments (l0 and l1) intersect. Returns a structure with
|
|
* the following attributes:
|
|
* * hit (boolean): whether the 2 segments intersect
|
|
* * x (float): x coordinate of the intersection point
|
|
* * y (float): y coordinate of the intersection point
|
|
*/
|
|
var den = ((l1_y1 - l1_y0) * (l0_x1 - l0_x0)) - ((l1_x1 - l1_x0) * (l0_y1 - l0_y0));
|
|
if (den == 0) {
|
|
return { hit: false, x: null, y: null };
|
|
}
|
|
else {
|
|
var a = l0_y0 - l1_y0;
|
|
var b = l0_x0 - l1_x0;
|
|
var num1 = ((l1_x1 - l1_x0) * a) - ((l1_y1 - l1_y0) * b);
|
|
var num2 = ((l0_x1 - l0_x0) * a) - ((l0_y1 - l0_y0) * b);
|
|
a = num1 / den;
|
|
b = num2 / den;
|
|
var x = l0_x0 + (a * (l0_x1 - l0_x0));
|
|
var y = l0_y0 + (a * (l0_y1 - l0_y0));
|
|
return { hit: (a > 0 && a < 1) && (b > 0 && b < 1), x: x, y: y };
|
|
}
|
|
}
|
|
exports.check_2_segments_intersect = check_2_segments_intersect;
|
|
}
|
|
,
|
|
/* core/layout/alignments */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var layoutable_1 = require(14) /* ./layoutable */;
|
|
var bbox_1 = require(27) /* ../util/bbox */;
|
|
var Stack = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Stack, _super);
|
|
function Stack() {
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
_this.children = [];
|
|
return _this;
|
|
}
|
|
return Stack;
|
|
}(layoutable_1.Layoutable));
|
|
exports.Stack = Stack;
|
|
var HStack = /** @class */ (function (_super) {
|
|
tslib_1.__extends(HStack, _super);
|
|
function HStack() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
HStack.prototype._measure = function (_viewport) {
|
|
var width = 0;
|
|
var height = 0;
|
|
for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
|
|
var child = _a[_i];
|
|
var size_hint = child.measure({ width: 0, height: 0 });
|
|
width += size_hint.width;
|
|
height = Math.max(height, size_hint.height);
|
|
}
|
|
return { width: width, height: height };
|
|
};
|
|
HStack.prototype._set_geometry = function (outer, inner) {
|
|
_super.prototype._set_geometry.call(this, outer, inner);
|
|
var top = outer.top, bottom = outer.bottom;
|
|
var left = outer.left;
|
|
for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
|
|
var child = _a[_i];
|
|
var width = child.measure({ width: 0, height: 0 }).width;
|
|
child.set_geometry(new bbox_1.BBox({ left: left, width: width, top: top, bottom: bottom }));
|
|
left += width;
|
|
}
|
|
};
|
|
return HStack;
|
|
}(Stack));
|
|
exports.HStack = HStack;
|
|
var VStack = /** @class */ (function (_super) {
|
|
tslib_1.__extends(VStack, _super);
|
|
function VStack() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
VStack.prototype._measure = function (_viewport) {
|
|
var width = 0;
|
|
var height = 0;
|
|
for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
|
|
var child = _a[_i];
|
|
var size_hint = child.measure({ width: 0, height: 0 });
|
|
width = Math.max(width, size_hint.width);
|
|
height += size_hint.height;
|
|
}
|
|
return { width: width, height: height };
|
|
};
|
|
VStack.prototype._set_geometry = function (outer, inner) {
|
|
_super.prototype._set_geometry.call(this, outer, inner);
|
|
var left = outer.left, right = outer.right;
|
|
var top = outer.top;
|
|
for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
|
|
var child = _a[_i];
|
|
var height = child.measure({ width: 0, height: 0 }).height;
|
|
child.set_geometry(new bbox_1.BBox({ top: top, height: height, left: left, right: right }));
|
|
top += height;
|
|
}
|
|
};
|
|
return VStack;
|
|
}(Stack));
|
|
exports.VStack = VStack;
|
|
var AnchorLayout = /** @class */ (function (_super) {
|
|
tslib_1.__extends(AnchorLayout, _super);
|
|
function AnchorLayout() {
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
_this.children = [];
|
|
return _this;
|
|
}
|
|
AnchorLayout.prototype._measure = function (viewport) {
|
|
var width = 0;
|
|
var height = 0;
|
|
for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
|
|
var layout = _a[_i].layout;
|
|
var size_hint = layout.measure(viewport);
|
|
width = Math.max(width, size_hint.width);
|
|
height = Math.max(height, size_hint.height);
|
|
}
|
|
return { width: width, height: height };
|
|
};
|
|
AnchorLayout.prototype._set_geometry = function (outer, inner) {
|
|
_super.prototype._set_geometry.call(this, outer, inner);
|
|
for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
|
|
var _b = _a[_i], layout = _b.layout, anchor = _b.anchor, margin = _b.margin;
|
|
var left = outer.left, right = outer.right, top_1 = outer.top, bottom = outer.bottom, hcenter = outer.hcenter, vcenter = outer.vcenter;
|
|
var _c = layout.measure(outer), width = _c.width, height = _c.height;
|
|
var bbox = void 0;
|
|
switch (anchor) {
|
|
case 'top_left':
|
|
bbox = new bbox_1.BBox({ left: left + margin, top: top_1 + margin, width: width, height: height });
|
|
break;
|
|
case 'top_center':
|
|
bbox = new bbox_1.BBox({ hcenter: hcenter, top: top_1 + margin, width: width, height: height });
|
|
break;
|
|
case 'top_right':
|
|
bbox = new bbox_1.BBox({ right: right - margin, top: top_1 + margin, width: width, height: height });
|
|
break;
|
|
case 'bottom_right':
|
|
bbox = new bbox_1.BBox({ right: right - margin, bottom: bottom - margin, width: width, height: height });
|
|
break;
|
|
case 'bottom_center':
|
|
bbox = new bbox_1.BBox({ hcenter: hcenter, bottom: bottom - margin, width: width, height: height });
|
|
break;
|
|
case 'bottom_left':
|
|
bbox = new bbox_1.BBox({ left: left + margin, bottom: bottom - margin, width: width, height: height });
|
|
break;
|
|
case 'center_left':
|
|
bbox = new bbox_1.BBox({ left: left + margin, vcenter: vcenter, width: width, height: height });
|
|
break;
|
|
case 'center':
|
|
bbox = new bbox_1.BBox({ hcenter: hcenter, vcenter: vcenter, width: width, height: height });
|
|
break;
|
|
case 'center_right':
|
|
bbox = new bbox_1.BBox({ right: right - margin, vcenter: vcenter, width: width, height: height });
|
|
break;
|
|
default:
|
|
throw new Error("unreachable");
|
|
}
|
|
layout.set_geometry(bbox);
|
|
}
|
|
};
|
|
return AnchorLayout;
|
|
}(layoutable_1.Layoutable));
|
|
exports.AnchorLayout = AnchorLayout;
|
|
}
|
|
,
|
|
/* core/layout/grid */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var types_1 = require(16) /* ./types */;
|
|
var layoutable_1 = require(14) /* ./layoutable */;
|
|
var types_2 = require(46) /* ../util/types */;
|
|
var bbox_1 = require(27) /* ../util/bbox */;
|
|
var array_1 = require(24) /* ../util/array */;
|
|
var max = Math.max, round = Math.round;
|
|
var DefaultMap = /** @class */ (function () {
|
|
function DefaultMap(def) {
|
|
this.def = def;
|
|
this._map = new Map();
|
|
}
|
|
DefaultMap.prototype.get = function (key) {
|
|
var value = this._map.get(key);
|
|
if (value === undefined) {
|
|
value = this.def();
|
|
this._map.set(key, value);
|
|
}
|
|
return value;
|
|
};
|
|
DefaultMap.prototype.apply = function (key, fn) {
|
|
var value = this.get(key);
|
|
this._map.set(key, fn(value));
|
|
};
|
|
return DefaultMap;
|
|
}());
|
|
var Container = /** @class */ (function () {
|
|
function Container() {
|
|
this._items = [];
|
|
this._nrows = 0;
|
|
this._ncols = 0;
|
|
}
|
|
Object.defineProperty(Container.prototype, "nrows", {
|
|
get: function () {
|
|
return this._nrows;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(Container.prototype, "ncols", {
|
|
get: function () {
|
|
return this._ncols;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Container.prototype.add = function (span, data) {
|
|
var r1 = span.r1, c1 = span.c1;
|
|
this._nrows = max(this._nrows, r1 + 1);
|
|
this._ncols = max(this._ncols, c1 + 1);
|
|
this._items.push({ span: span, data: data });
|
|
};
|
|
Container.prototype.at = function (r, c) {
|
|
var selected = this._items.filter(function (_a) {
|
|
var span = _a.span;
|
|
return span.r0 <= r && r <= span.r1 &&
|
|
span.c0 <= c && c <= span.c1;
|
|
});
|
|
return selected.map(function (_a) {
|
|
var data = _a.data;
|
|
return data;
|
|
});
|
|
};
|
|
Container.prototype.row = function (r) {
|
|
var selected = this._items.filter(function (_a) {
|
|
var span = _a.span;
|
|
return span.r0 <= r && r <= span.r1;
|
|
});
|
|
return selected.map(function (_a) {
|
|
var data = _a.data;
|
|
return data;
|
|
});
|
|
};
|
|
Container.prototype.col = function (c) {
|
|
var selected = this._items.filter(function (_a) {
|
|
var span = _a.span;
|
|
return span.c0 <= c && c <= span.c1;
|
|
});
|
|
return selected.map(function (_a) {
|
|
var data = _a.data;
|
|
return data;
|
|
});
|
|
};
|
|
Container.prototype.foreach = function (fn) {
|
|
for (var _i = 0, _a = this._items; _i < _a.length; _i++) {
|
|
var _b = _a[_i], span = _b.span, data = _b.data;
|
|
fn(span, data);
|
|
}
|
|
};
|
|
Container.prototype.map = function (fn) {
|
|
var result = new Container();
|
|
for (var _i = 0, _a = this._items; _i < _a.length; _i++) {
|
|
var _b = _a[_i], span = _b.span, data = _b.data;
|
|
result.add(span, fn(span, data));
|
|
}
|
|
return result;
|
|
};
|
|
return Container;
|
|
}());
|
|
var Grid = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Grid, _super);
|
|
function Grid(items) {
|
|
if (items === void 0) {
|
|
items = [];
|
|
}
|
|
var _this = _super.call(this) || this;
|
|
_this.items = items;
|
|
_this.rows = "auto";
|
|
_this.cols = "auto";
|
|
_this.spacing = 0;
|
|
_this.absolute = false;
|
|
return _this;
|
|
}
|
|
Grid.prototype.is_width_expanding = function () {
|
|
if (_super.prototype.is_width_expanding.call(this))
|
|
return true;
|
|
if (this.sizing.width_policy == "fixed")
|
|
return false;
|
|
var cols = this._state.cols;
|
|
return array_1.some(cols, function (col) { return col.policy == "max"; });
|
|
};
|
|
Grid.prototype.is_height_expanding = function () {
|
|
if (_super.prototype.is_height_expanding.call(this))
|
|
return true;
|
|
if (this.sizing.height_policy == "fixed")
|
|
return false;
|
|
var rows = this._state.rows;
|
|
return array_1.some(rows, function (row) { return row.policy == "max"; });
|
|
};
|
|
Grid.prototype._init = function () {
|
|
var _this = this;
|
|
_super.prototype._init.call(this);
|
|
var items = new Container();
|
|
for (var _i = 0, _a = this.items; _i < _a.length; _i++) {
|
|
var _b = _a[_i], layout = _b.layout, row = _b.row, col = _b.col, row_span = _b.row_span, col_span = _b.col_span;
|
|
if (layout.sizing.visible) {
|
|
var r0 = row;
|
|
var c0 = col;
|
|
var r1 = row + (row_span != null ? row_span : 1) - 1;
|
|
var c1 = col + (col_span != null ? col_span : 1) - 1;
|
|
items.add({ r0: r0, c0: c0, r1: r1, c1: c1 }, layout);
|
|
}
|
|
}
|
|
var nrows = items.nrows, ncols = items.ncols;
|
|
var rows = new Array(nrows);
|
|
var _loop_1 = function (y) {
|
|
var row = (function () {
|
|
var sizing = types_2.isPlainObject(_this.rows) ? _this.rows[y] || _this.rows["*"] : _this.rows;
|
|
if (sizing == null)
|
|
return { policy: "auto" };
|
|
else if (types_2.isNumber(sizing))
|
|
return { policy: "fixed", height: sizing };
|
|
else if (types_2.isString(sizing))
|
|
return { policy: sizing };
|
|
else
|
|
return sizing;
|
|
})();
|
|
var align = row.align || "auto";
|
|
if (row.policy == "fixed")
|
|
rows[y] = { policy: "fixed", height: row.height, align: align };
|
|
else if (row.policy == "min")
|
|
rows[y] = { policy: "min", align: align };
|
|
else if (row.policy == "fit" || row.policy == "max")
|
|
rows[y] = { policy: row.policy, flex: row.flex || 1, align: align };
|
|
else if (row.policy == "auto") {
|
|
if (array_1.some(items.row(y), function (layout) { return layout.is_height_expanding(); }))
|
|
rows[y] = { policy: "max", flex: 1, align: align };
|
|
else
|
|
rows[y] = { policy: "min", align: align };
|
|
}
|
|
else
|
|
throw new Error("unrechable");
|
|
};
|
|
for (var y = 0; y < nrows; y++) {
|
|
_loop_1(y);
|
|
}
|
|
var cols = new Array(ncols);
|
|
var _loop_2 = function (x) {
|
|
var col = (function () {
|
|
var sizing = types_2.isPlainObject(_this.cols) ? _this.cols[x] || _this.cols["*"] : _this.cols;
|
|
if (sizing == null)
|
|
return { policy: "auto" };
|
|
else if (types_2.isNumber(sizing))
|
|
return { policy: "fixed", width: sizing };
|
|
else if (types_2.isString(sizing))
|
|
return { policy: sizing };
|
|
else
|
|
return sizing;
|
|
})();
|
|
var align = col.align || "auto";
|
|
if (col.policy == "fixed")
|
|
cols[x] = { policy: "fixed", width: col.width, align: align };
|
|
else if (col.policy == "min")
|
|
cols[x] = { policy: "min", align: align };
|
|
else if (col.policy == "fit" || col.policy == "max")
|
|
cols[x] = { policy: col.policy, flex: col.flex || 1, align: align };
|
|
else if (col.policy == "auto") {
|
|
if (array_1.some(items.col(x), function (layout) { return layout.is_width_expanding(); }))
|
|
cols[x] = { policy: "max", flex: 1, align: align };
|
|
else
|
|
cols[x] = { policy: "min", align: align };
|
|
}
|
|
else
|
|
throw new Error("unrechable");
|
|
};
|
|
for (var x = 0; x < ncols; x++) {
|
|
_loop_2(x);
|
|
}
|
|
var _c = types_2.isNumber(this.spacing) ? [this.spacing, this.spacing] : this.spacing, rspacing = _c[0], cspacing = _c[1];
|
|
this._state = { items: items, nrows: nrows, ncols: ncols, rows: rows, cols: cols, rspacing: rspacing, cspacing: cspacing };
|
|
};
|
|
Grid.prototype._measure_totals = function (row_heights, col_widths) {
|
|
var _a = this._state, nrows = _a.nrows, ncols = _a.ncols, rspacing = _a.rspacing, cspacing = _a.cspacing;
|
|
return {
|
|
height: array_1.sum(row_heights) + (nrows - 1) * rspacing,
|
|
width: array_1.sum(col_widths) + (ncols - 1) * cspacing,
|
|
};
|
|
};
|
|
Grid.prototype._measure_cells = function (cell_viewport) {
|
|
var _a = this._state, items = _a.items, nrows = _a.nrows, ncols = _a.ncols, rows = _a.rows, cols = _a.cols, rspacing = _a.rspacing, cspacing = _a.cspacing;
|
|
var row_heights = new Array(nrows);
|
|
for (var r = 0; r < nrows; r++) {
|
|
var row = rows[r];
|
|
row_heights[r] = row.policy == "fixed" ? row.height : 0;
|
|
}
|
|
var col_widths = new Array(ncols);
|
|
for (var c = 0; c < ncols; c++) {
|
|
var col = cols[c];
|
|
col_widths[c] = col.policy == "fixed" ? col.width : 0;
|
|
}
|
|
var size_hints = new Container();
|
|
items.foreach(function (span, layout) {
|
|
var r0 = span.r0, c0 = span.c0, r1 = span.r1, c1 = span.c1;
|
|
var rspace = (r1 - r0) * rspacing;
|
|
var cspace = (c1 - c0) * cspacing;
|
|
var height = 0;
|
|
for (var r = r0; r <= r1; r++) {
|
|
height += cell_viewport(r, c0).height;
|
|
}
|
|
height += rspace;
|
|
var width = 0;
|
|
for (var c = c0; c <= c1; c++) {
|
|
width += cell_viewport(r0, c).width;
|
|
}
|
|
width += cspace;
|
|
var size_hint = layout.measure({ width: width, height: height });
|
|
size_hints.add(span, { layout: layout, size_hint: size_hint });
|
|
var size = new types_1.Sizeable(size_hint).grow_by(layout.sizing.margin);
|
|
size.height -= rspace;
|
|
size.width -= cspace;
|
|
var radjustable = [];
|
|
for (var r = r0; r <= r1; r++) {
|
|
var row = rows[r];
|
|
if (row.policy == "fixed")
|
|
size.height -= row.height;
|
|
else
|
|
radjustable.push(r);
|
|
}
|
|
if (size.height > 0) {
|
|
var rheight = round(size.height / radjustable.length);
|
|
for (var _i = 0, radjustable_1 = radjustable; _i < radjustable_1.length; _i++) {
|
|
var r = radjustable_1[_i];
|
|
row_heights[r] = max(row_heights[r], rheight);
|
|
}
|
|
}
|
|
var cadjustable = [];
|
|
for (var c = c0; c <= c1; c++) {
|
|
var col = cols[c];
|
|
if (col.policy == "fixed")
|
|
size.width -= col.width;
|
|
else
|
|
cadjustable.push(c);
|
|
}
|
|
if (size.width > 0) {
|
|
var cwidth = round(size.width / cadjustable.length);
|
|
for (var _a = 0, cadjustable_1 = cadjustable; _a < cadjustable_1.length; _a++) {
|
|
var c = cadjustable_1[_a];
|
|
col_widths[c] = max(col_widths[c], cwidth);
|
|
}
|
|
}
|
|
});
|
|
var size = this._measure_totals(row_heights, col_widths);
|
|
return { size: size, row_heights: row_heights, col_widths: col_widths, size_hints: size_hints };
|
|
};
|
|
Grid.prototype._measure_grid = function (viewport) {
|
|
var _a = this._state, nrows = _a.nrows, ncols = _a.ncols, rows = _a.rows, cols = _a.cols, rspacing = _a.rspacing, cspacing = _a.cspacing;
|
|
var preferred = this._measure_cells(function (y, x) {
|
|
var row = rows[y];
|
|
var col = cols[x];
|
|
return {
|
|
width: col.policy == "fixed" ? col.width : Infinity,
|
|
height: row.policy == "fixed" ? row.height : Infinity,
|
|
};
|
|
});
|
|
var available_height;
|
|
if (this.sizing.height_policy == "fixed" && this.sizing.height != null)
|
|
available_height = this.sizing.height;
|
|
else if (viewport.height != Infinity && this.is_height_expanding())
|
|
available_height = viewport.height;
|
|
else
|
|
available_height = preferred.size.height;
|
|
var height_flex = 0;
|
|
for (var y = 0; y < nrows; y++) {
|
|
var row = rows[y];
|
|
if (row.policy == "fit" || row.policy == "max")
|
|
height_flex += row.flex;
|
|
else
|
|
available_height -= preferred.row_heights[y];
|
|
}
|
|
available_height -= (nrows - 1) * rspacing;
|
|
if (height_flex != 0 && available_height > 0) {
|
|
for (var y = 0; y < nrows; y++) {
|
|
var row = rows[y];
|
|
if (row.policy == "fit" || row.policy == "max") {
|
|
var height = round(available_height * (row.flex / height_flex));
|
|
available_height -= height;
|
|
preferred.row_heights[y] = height;
|
|
height_flex -= row.flex;
|
|
}
|
|
}
|
|
}
|
|
else if (available_height < 0) {
|
|
var nadjustable = 0;
|
|
for (var y = 0; y < nrows; y++) {
|
|
var row = rows[y];
|
|
if (row.policy != "fixed")
|
|
nadjustable++;
|
|
}
|
|
var overflow_height = -available_height;
|
|
for (var y = 0; y < nrows; y++) {
|
|
var row = rows[y];
|
|
if (row.policy != "fixed") {
|
|
var height = preferred.row_heights[y];
|
|
var cutoff = round(overflow_height / nadjustable);
|
|
preferred.row_heights[y] = max(height - cutoff, 0);
|
|
overflow_height -= cutoff > height ? height : cutoff;
|
|
nadjustable--;
|
|
}
|
|
}
|
|
}
|
|
var available_width;
|
|
if (this.sizing.width_policy == "fixed" && this.sizing.width != null)
|
|
available_width = this.sizing.width;
|
|
else if (viewport.width != Infinity && this.is_width_expanding())
|
|
available_width = viewport.width;
|
|
else
|
|
available_width = preferred.size.width;
|
|
var width_flex = 0;
|
|
for (var x = 0; x < ncols; x++) {
|
|
var col = cols[x];
|
|
if (col.policy == "fit" || col.policy == "max")
|
|
width_flex += col.flex;
|
|
else
|
|
available_width -= preferred.col_widths[x];
|
|
}
|
|
available_width -= (ncols - 1) * cspacing;
|
|
if (width_flex != 0 && available_width > 0) {
|
|
for (var x = 0; x < ncols; x++) {
|
|
var col = cols[x];
|
|
if (col.policy == "fit" || col.policy == "max") {
|
|
var width = round(available_width * (col.flex / width_flex));
|
|
available_width -= width;
|
|
preferred.col_widths[x] = width;
|
|
width_flex -= col.flex;
|
|
}
|
|
}
|
|
}
|
|
else if (available_width < 0) {
|
|
var nadjustable = 0;
|
|
for (var x = 0; x < ncols; x++) {
|
|
var col = cols[x];
|
|
if (col.policy != "fixed")
|
|
nadjustable++;
|
|
}
|
|
var overflow_width = -available_width;
|
|
for (var x = 0; x < ncols; x++) {
|
|
var col = cols[x];
|
|
if (col.policy != "fixed") {
|
|
var width = preferred.col_widths[x];
|
|
var cutoff = round(overflow_width / nadjustable);
|
|
preferred.col_widths[x] = max(width - cutoff, 0);
|
|
overflow_width -= cutoff > width ? width : cutoff;
|
|
nadjustable--;
|
|
}
|
|
}
|
|
}
|
|
var _b = this._measure_cells(function (y, x) {
|
|
return {
|
|
width: preferred.col_widths[x],
|
|
height: preferred.row_heights[y],
|
|
};
|
|
}), row_heights = _b.row_heights, col_widths = _b.col_widths, size_hints = _b.size_hints;
|
|
var size = this._measure_totals(row_heights, col_widths);
|
|
return { size: size, row_heights: row_heights, col_widths: col_widths, size_hints: size_hints };
|
|
};
|
|
Grid.prototype._measure = function (viewport) {
|
|
var size = this._measure_grid(viewport).size;
|
|
return size;
|
|
};
|
|
Grid.prototype._set_geometry = function (outer, inner) {
|
|
_super.prototype._set_geometry.call(this, outer, inner);
|
|
var _a = this._state, nrows = _a.nrows, ncols = _a.ncols, rspacing = _a.rspacing, cspacing = _a.cspacing;
|
|
var _b = this._measure_grid(outer), row_heights = _b.row_heights, col_widths = _b.col_widths, size_hints = _b.size_hints;
|
|
var rows = this._state.rows.map(function (row, r) {
|
|
return tslib_1.__assign({}, row, { top: 0, height: row_heights[r], get bottom() { return this.top + this.height; } });
|
|
});
|
|
var cols = this._state.cols.map(function (col, c) {
|
|
return tslib_1.__assign({}, col, { left: 0, width: col_widths[c], get right() { return this.left + this.width; } });
|
|
});
|
|
var items = size_hints.map(function (_, item) {
|
|
return tslib_1.__assign({}, item, { outer: new bbox_1.BBox(), inner: new bbox_1.BBox() });
|
|
});
|
|
for (var r = 0, top_1 = !this.absolute ? 0 : outer.top; r < nrows; r++) {
|
|
var row = rows[r];
|
|
row.top = top_1;
|
|
top_1 += row.height + rspacing;
|
|
}
|
|
for (var c = 0, left = !this.absolute ? 0 : outer.left; c < ncols; c++) {
|
|
var col = cols[c];
|
|
col.left = left;
|
|
left += col.width + cspacing;
|
|
}
|
|
function span_width(c0, c1) {
|
|
var width = (c1 - c0) * cspacing;
|
|
for (var c = c0; c <= c1; c++) {
|
|
width += cols[c].width;
|
|
}
|
|
return width;
|
|
}
|
|
function span_height(r0, r1) {
|
|
var height = (r1 - r0) * rspacing;
|
|
for (var r = r0; r <= r1; r++) {
|
|
height += rows[r].height;
|
|
}
|
|
return height;
|
|
}
|
|
items.foreach(function (_a, item) {
|
|
var r0 = _a.r0, c0 = _a.c0, r1 = _a.r1, c1 = _a.c1;
|
|
var layout = item.layout, size_hint = item.size_hint;
|
|
var sizing = layout.sizing;
|
|
var width = size_hint.width, height = size_hint.height;
|
|
var span = {
|
|
width: span_width(c0, c1),
|
|
height: span_height(r0, r1),
|
|
};
|
|
var halign = c0 == c1 && cols[c0].align != "auto" ? cols[c0].align : sizing.halign;
|
|
var valign = r0 == r1 && rows[r0].align != "auto" ? rows[r0].align : sizing.valign;
|
|
var left = cols[c0].left;
|
|
if (halign == "start")
|
|
left += sizing.margin.left;
|
|
else if (halign == "center")
|
|
left += round((span.width - width) / 2);
|
|
else if (halign == "end")
|
|
left += span.width - sizing.margin.right - width;
|
|
var top = rows[r0].top;
|
|
if (valign == "start")
|
|
top += sizing.margin.top;
|
|
else if (valign == "center")
|
|
top += round((span.height - height) / 2);
|
|
else if (valign == "end")
|
|
top += span.height - sizing.margin.bottom - height;
|
|
item.outer = new bbox_1.BBox({ left: left, top: top, width: width, height: height });
|
|
});
|
|
var row_aligns = rows.map(function () {
|
|
return {
|
|
start: new DefaultMap(function () { return 0; }),
|
|
end: new DefaultMap(function () { return 0; }),
|
|
};
|
|
});
|
|
var col_aligns = cols.map(function () {
|
|
return {
|
|
start: new DefaultMap(function () { return 0; }),
|
|
end: new DefaultMap(function () { return 0; }),
|
|
};
|
|
});
|
|
items.foreach(function (_a, _b) {
|
|
var r0 = _a.r0, c0 = _a.c0, r1 = _a.r1, c1 = _a.c1;
|
|
var size_hint = _b.size_hint, outer = _b.outer;
|
|
var inner = size_hint.inner;
|
|
if (inner != null) {
|
|
row_aligns[r0].start.apply(outer.top, function (v) { return max(v, inner.top); });
|
|
row_aligns[r1].end.apply(rows[r1].bottom - outer.bottom, function (v) { return max(v, inner.bottom); });
|
|
col_aligns[c0].start.apply(outer.left, function (v) { return max(v, inner.left); });
|
|
col_aligns[c1].end.apply(cols[c1].right - outer.right, function (v) { return max(v, inner.right); });
|
|
}
|
|
});
|
|
items.foreach(function (_a, item) {
|
|
var r0 = _a.r0, c0 = _a.c0, r1 = _a.r1, c1 = _a.c1;
|
|
var size_hint = item.size_hint, outer = item.outer;
|
|
function inner_bbox(_a) {
|
|
var left = _a.left, right = _a.right, top = _a.top, bottom = _a.bottom;
|
|
var width = outer.width - left - right;
|
|
var height = outer.height - top - bottom;
|
|
return new bbox_1.BBox({ left: left, top: top, width: width, height: height });
|
|
}
|
|
if (size_hint.inner != null) {
|
|
var inner_1 = inner_bbox(size_hint.inner);
|
|
if (size_hint.align !== false) {
|
|
var top_2 = row_aligns[r0].start.get(outer.top);
|
|
var bottom = row_aligns[r1].end.get(rows[r1].bottom - outer.bottom);
|
|
var left = col_aligns[c0].start.get(outer.left);
|
|
var right = col_aligns[c1].end.get(cols[c1].right - outer.right);
|
|
try {
|
|
inner_1 = inner_bbox({ top: top_2, bottom: bottom, left: left, right: right });
|
|
}
|
|
catch (_b) { }
|
|
}
|
|
item.inner = inner_1;
|
|
}
|
|
else
|
|
item.inner = outer;
|
|
});
|
|
items.foreach(function (_, _a) {
|
|
var layout = _a.layout, outer = _a.outer, inner = _a.inner;
|
|
layout.set_geometry(outer, inner);
|
|
});
|
|
};
|
|
return Grid;
|
|
}(layoutable_1.Layoutable));
|
|
exports.Grid = Grid;
|
|
var Row = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Row, _super);
|
|
function Row(items) {
|
|
var _this = _super.call(this) || this;
|
|
_this.items = items.map(function (item, i) { return ({ layout: item, row: 0, col: i }); });
|
|
_this.rows = "fit";
|
|
return _this;
|
|
}
|
|
return Row;
|
|
}(Grid));
|
|
exports.Row = Row;
|
|
var Column = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Column, _super);
|
|
function Column(items) {
|
|
var _this = _super.call(this) || this;
|
|
_this.items = items.map(function (item, i) { return ({ layout: item, row: i, col: 0 }); });
|
|
_this.cols = "fit";
|
|
return _this;
|
|
}
|
|
return Column;
|
|
}(Grid));
|
|
exports.Column = Column;
|
|
}
|
|
,
|
|
/* core/layout/html */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var layoutable_1 = require(14) /* ./layoutable */;
|
|
var types_1 = require(16) /* ./types */;
|
|
var dom_1 = require(5) /* ../dom */;
|
|
var ContentBox = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ContentBox, _super);
|
|
function ContentBox(el) {
|
|
var _this = _super.call(this) || this;
|
|
_this.content_size = dom_1.unsized(el, function () { return new types_1.Sizeable(dom_1.size(el)); });
|
|
return _this;
|
|
}
|
|
ContentBox.prototype._content_size = function () {
|
|
return this.content_size;
|
|
};
|
|
return ContentBox;
|
|
}(layoutable_1.ContentLayoutable));
|
|
exports.ContentBox = ContentBox;
|
|
var VariadicBox = /** @class */ (function (_super) {
|
|
tslib_1.__extends(VariadicBox, _super);
|
|
function VariadicBox(el) {
|
|
var _this = _super.call(this) || this;
|
|
_this.el = el;
|
|
return _this;
|
|
}
|
|
VariadicBox.prototype._measure = function (viewport) {
|
|
var _this = this;
|
|
var bounded = new types_1.Sizeable(viewport).bounded_to(this.sizing.size);
|
|
return dom_1.sized(this.el, bounded, function () {
|
|
var content = new types_1.Sizeable(dom_1.content_size(_this.el));
|
|
var _a = dom_1.extents(_this.el), border = _a.border, padding = _a.padding;
|
|
return content.grow_by(border).grow_by(padding).map(Math.ceil);
|
|
});
|
|
};
|
|
return VariadicBox;
|
|
}(layoutable_1.Layoutable));
|
|
exports.VariadicBox = VariadicBox;
|
|
}
|
|
,
|
|
/* core/layout/index */ function _(require, module, exports) {
|
|
var types_1 = require(16) /* ./types */;
|
|
exports.Sizeable = types_1.Sizeable;
|
|
var layoutable_1 = require(14) /* ./layoutable */;
|
|
exports.Layoutable = layoutable_1.Layoutable;
|
|
exports.LayoutItem = layoutable_1.LayoutItem;
|
|
var alignments_1 = require(10) /* ./alignments */;
|
|
exports.HStack = alignments_1.HStack;
|
|
exports.VStack = alignments_1.VStack;
|
|
exports.AnchorLayout = alignments_1.AnchorLayout;
|
|
var grid_1 = require(11) /* ./grid */;
|
|
exports.Grid = grid_1.Grid;
|
|
exports.Row = grid_1.Row;
|
|
exports.Column = grid_1.Column;
|
|
var html_1 = require(12) /* ./html */;
|
|
exports.ContentBox = html_1.ContentBox;
|
|
exports.VariadicBox = html_1.VariadicBox;
|
|
}
|
|
,
|
|
/* core/layout/layoutable */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var types_1 = require(16) /* ./types */;
|
|
var bbox_1 = require(27) /* ../util/bbox */;
|
|
var min = Math.min, max = Math.max, round = Math.round;
|
|
var Layoutable = /** @class */ (function () {
|
|
function Layoutable() {
|
|
this._bbox = new bbox_1.BBox();
|
|
this._inner_bbox = new bbox_1.BBox();
|
|
var layout = this;
|
|
this._top = { get value() { return layout.bbox.top; } };
|
|
this._left = { get value() { return layout.bbox.left; } };
|
|
this._width = { get value() { return layout.bbox.width; } };
|
|
this._height = { get value() { return layout.bbox.height; } };
|
|
this._right = { get value() { return layout.bbox.right; } };
|
|
this._bottom = { get value() { return layout.bbox.bottom; } };
|
|
this._hcenter = { get value() { return layout.bbox.hcenter; } };
|
|
this._vcenter = { get value() { return layout.bbox.vcenter; } };
|
|
}
|
|
Object.defineProperty(Layoutable.prototype, "bbox", {
|
|
get: function () {
|
|
return this._bbox;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(Layoutable.prototype, "inner_bbox", {
|
|
get: function () {
|
|
return this._inner_bbox;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(Layoutable.prototype, "sizing", {
|
|
get: function () {
|
|
return this._sizing;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Layoutable.prototype.set_sizing = function (sizing) {
|
|
var width_policy = sizing.width_policy || "fit";
|
|
var width = sizing.width;
|
|
var min_width = sizing.min_width != null ? sizing.min_width : 0;
|
|
var max_width = sizing.max_width != null ? sizing.max_width : Infinity;
|
|
var height_policy = sizing.height_policy || "fit";
|
|
var height = sizing.height;
|
|
var min_height = sizing.min_height != null ? sizing.min_height : 0;
|
|
var max_height = sizing.max_height != null ? sizing.max_height : Infinity;
|
|
var aspect = sizing.aspect;
|
|
var margin = sizing.margin || { top: 0, right: 0, bottom: 0, left: 0 };
|
|
var visible = sizing.visible !== false;
|
|
var halign = sizing.halign || "start";
|
|
var valign = sizing.valign || "start";
|
|
this._sizing = {
|
|
width_policy: width_policy, min_width: min_width, width: width, max_width: max_width,
|
|
height_policy: height_policy, min_height: min_height, height: height, max_height: max_height,
|
|
aspect: aspect,
|
|
margin: margin,
|
|
visible: visible,
|
|
halign: halign,
|
|
valign: valign,
|
|
size: { width: width, height: height },
|
|
min_size: { width: min_width, height: min_height },
|
|
max_size: { width: max_width, height: max_height },
|
|
};
|
|
this._init();
|
|
};
|
|
Layoutable.prototype._init = function () { };
|
|
Layoutable.prototype._set_geometry = function (outer, inner) {
|
|
this._bbox = outer;
|
|
this._inner_bbox = inner;
|
|
};
|
|
Layoutable.prototype.set_geometry = function (outer, inner) {
|
|
this._set_geometry(outer, inner || outer);
|
|
};
|
|
Layoutable.prototype.is_width_expanding = function () {
|
|
return this.sizing.width_policy == "max";
|
|
};
|
|
Layoutable.prototype.is_height_expanding = function () {
|
|
return this.sizing.height_policy == "max";
|
|
};
|
|
Layoutable.prototype.apply_aspect = function (viewport, _a) {
|
|
var width = _a.width, height = _a.height;
|
|
var aspect = this.sizing.aspect;
|
|
if (aspect != null) {
|
|
var _b = this.sizing, width_policy = _b.width_policy, height_policy = _b.height_policy;
|
|
var gt = function (width, height) {
|
|
var policies = { max: 4, fit: 3, min: 2, fixed: 1 };
|
|
return policies[width] > policies[height];
|
|
};
|
|
if (width_policy != "fixed" && height_policy != "fixed") {
|
|
if (width_policy == height_policy) {
|
|
var w_width = width;
|
|
var w_height = round(width / aspect);
|
|
var h_width = round(height * aspect);
|
|
var h_height = height;
|
|
var w_diff = Math.abs(viewport.width - w_width) + Math.abs(viewport.height - w_height);
|
|
var h_diff = Math.abs(viewport.width - h_width) + Math.abs(viewport.height - h_height);
|
|
if (w_diff <= h_diff) {
|
|
width = w_width;
|
|
height = w_height;
|
|
}
|
|
else {
|
|
width = h_width;
|
|
height = h_height;
|
|
}
|
|
}
|
|
else if (gt(width_policy, height_policy)) {
|
|
height = round(width / aspect);
|
|
}
|
|
else {
|
|
width = round(height * aspect);
|
|
}
|
|
}
|
|
else if (width_policy == "fixed") {
|
|
height = round(width / aspect);
|
|
}
|
|
else if (height_policy == "fixed") {
|
|
width = round(height * aspect);
|
|
}
|
|
}
|
|
return { width: width, height: height };
|
|
};
|
|
Layoutable.prototype.measure = function (viewport_size) {
|
|
var _this = this;
|
|
if (!this.sizing.visible)
|
|
return { width: 0, height: 0 };
|
|
var exact_width = function (width) {
|
|
return _this.sizing.width_policy == "fixed" && _this.sizing.width != null ? _this.sizing.width : width;
|
|
};
|
|
var exact_height = function (height) {
|
|
return _this.sizing.height_policy == "fixed" && _this.sizing.height != null ? _this.sizing.height : height;
|
|
};
|
|
var viewport = new types_1.Sizeable(viewport_size)
|
|
.shrink_by(this.sizing.margin)
|
|
.map(exact_width, exact_height);
|
|
var computed = this._measure(viewport);
|
|
var clipped = this.clip_size(computed);
|
|
var width = exact_width(clipped.width);
|
|
var height = exact_height(clipped.height);
|
|
var size = this.apply_aspect(viewport, { width: width, height: height });
|
|
return tslib_1.__assign({}, computed, size);
|
|
};
|
|
Layoutable.prototype.compute = function (viewport) {
|
|
if (viewport === void 0) {
|
|
viewport = {};
|
|
}
|
|
var size_hint = this.measure({
|
|
width: viewport.width != null && this.is_width_expanding() ? viewport.width : Infinity,
|
|
height: viewport.height != null && this.is_height_expanding() ? viewport.height : Infinity,
|
|
});
|
|
var width = size_hint.width, height = size_hint.height;
|
|
var outer = new bbox_1.BBox({ left: 0, top: 0, width: width, height: height });
|
|
var inner = undefined;
|
|
if (size_hint.inner != null) {
|
|
var _a = size_hint.inner, left = _a.left, top_1 = _a.top, right = _a.right, bottom = _a.bottom;
|
|
inner = new bbox_1.BBox({ left: left, top: top_1, right: width - right, bottom: height - bottom });
|
|
}
|
|
this.set_geometry(outer, inner);
|
|
};
|
|
Object.defineProperty(Layoutable.prototype, "xview", {
|
|
get: function () {
|
|
return this.bbox.xview;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(Layoutable.prototype, "yview", {
|
|
get: function () {
|
|
return this.bbox.yview;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Layoutable.prototype.clip_width = function (width) {
|
|
return max(this.sizing.min_width, min(width, this.sizing.max_width));
|
|
};
|
|
Layoutable.prototype.clip_height = function (height) {
|
|
return max(this.sizing.min_height, min(height, this.sizing.max_height));
|
|
};
|
|
Layoutable.prototype.clip_size = function (_a) {
|
|
var width = _a.width, height = _a.height;
|
|
return {
|
|
width: this.clip_width(width),
|
|
height: this.clip_height(height),
|
|
};
|
|
};
|
|
return Layoutable;
|
|
}());
|
|
exports.Layoutable = Layoutable;
|
|
var LayoutItem = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LayoutItem, _super);
|
|
function LayoutItem() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
/*
|
|
constructor(readonly measure_fn: (viewport: Size) => Size) {
|
|
super()
|
|
}
|
|
protected _measure(viewport: Size): SizeHint {
|
|
return this.measure_fn(viewport)
|
|
}
|
|
protected _measure(viewport: Size): SizeHint {
|
|
return {
|
|
width: viewport.width != Infinity ? viewport.width : this.sizing.min_width,
|
|
height: viewport.height != Infinity ? viewport.height : this.sizing.min_width,
|
|
}
|
|
}
|
|
*/
|
|
LayoutItem.prototype._measure = function (viewport) {
|
|
var _a = this.sizing, width_policy = _a.width_policy, height_policy = _a.height_policy;
|
|
var width;
|
|
if (viewport.width == Infinity) {
|
|
width = this.sizing.width != null ? this.sizing.width : 0;
|
|
}
|
|
else {
|
|
if (width_policy == "fixed")
|
|
width = this.sizing.width != null ? this.sizing.width : 0;
|
|
else if (width_policy == "min")
|
|
width = this.sizing.width != null ? min(viewport.width, this.sizing.width) : 0;
|
|
else if (width_policy == "fit")
|
|
width = this.sizing.width != null ? min(viewport.width, this.sizing.width) : viewport.width;
|
|
else if (width_policy == "max")
|
|
width = this.sizing.width != null ? max(viewport.width, this.sizing.width) : viewport.width;
|
|
else
|
|
throw new Error("unrechable");
|
|
}
|
|
var height;
|
|
if (viewport.height == Infinity) {
|
|
height = this.sizing.height != null ? this.sizing.height : 0;
|
|
}
|
|
else {
|
|
if (height_policy == "fixed")
|
|
height = this.sizing.height != null ? this.sizing.height : 0;
|
|
else if (height_policy == "min")
|
|
height = this.sizing.height != null ? min(viewport.height, this.sizing.height) : 0;
|
|
else if (height_policy == "fit")
|
|
height = this.sizing.height != null ? min(viewport.height, this.sizing.height) : viewport.height;
|
|
else if (height_policy == "max")
|
|
height = this.sizing.height != null ? max(viewport.height, this.sizing.height) : viewport.height;
|
|
else
|
|
throw new Error("unrechable");
|
|
}
|
|
return { width: width, height: height };
|
|
};
|
|
return LayoutItem;
|
|
}(Layoutable));
|
|
exports.LayoutItem = LayoutItem;
|
|
var ContentLayoutable = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ContentLayoutable, _super);
|
|
function ContentLayoutable() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ContentLayoutable.prototype._measure = function (viewport) {
|
|
var _this = this;
|
|
var content_size = this._content_size();
|
|
var bounds = viewport.bounded_to(this.sizing.size)
|
|
.bounded_to(content_size);
|
|
var width = (function () {
|
|
switch (_this.sizing.width_policy) {
|
|
case "fixed":
|
|
return _this.sizing.width != null ? _this.sizing.width : content_size.width;
|
|
case "min":
|
|
return content_size.width;
|
|
case "fit":
|
|
return bounds.width;
|
|
case "max":
|
|
return Math.max(content_size.width, bounds.width);
|
|
default:
|
|
throw new Error("unexpected");
|
|
}
|
|
})();
|
|
var height = (function () {
|
|
switch (_this.sizing.height_policy) {
|
|
case "fixed":
|
|
return _this.sizing.height != null ? _this.sizing.height : content_size.height;
|
|
case "min":
|
|
return content_size.height;
|
|
case "fit":
|
|
return bounds.height;
|
|
case "max":
|
|
return Math.max(content_size.height, bounds.height);
|
|
default:
|
|
throw new Error("unexpected");
|
|
}
|
|
})();
|
|
return { width: width, height: height };
|
|
};
|
|
return ContentLayoutable;
|
|
}(Layoutable));
|
|
exports.ContentLayoutable = ContentLayoutable;
|
|
}
|
|
,
|
|
/* core/layout/side_panel */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var types_1 = require(16) /* ./types */;
|
|
var layoutable_1 = require(14) /* ./layoutable */;
|
|
var types_2 = require(46) /* ../util/types */;
|
|
// This table lays out the rules for configuring the baseline, alignment, etc. of
|
|
// title text, based on it's location and orientation
|
|
//
|
|
// side orient baseline align angle normal-dist
|
|
// ------------------------------------------------------------------------------
|
|
// above parallel bottom center 0 height
|
|
// normal middle left -90 width
|
|
// horizontal bottom center 0 height
|
|
// [angle > 0] middle left width * sin + height * cos
|
|
// [angle < 0] middle right width * sin + height * cos
|
|
//
|
|
// below parallel top center 0 height
|
|
// normal middle right 90 width
|
|
// horizontal top center 0 height
|
|
// [angle > 0] middle right width * sin + height * cos
|
|
// [angle < 0] middle left width * sin + height * cos
|
|
//
|
|
// left parallel bottom center 90 height
|
|
// normal middle right 0 width
|
|
// horizontal middle right 0 width
|
|
// [angle > 0] middle right width * cos + height * sin
|
|
// [angle < 0] middle right width * cos + height + sin
|
|
//
|
|
// right parallel bottom center -90 height
|
|
// normal middle left 0 width
|
|
// horizontal middle left 0 width
|
|
// [angle > 0] middle left width * cos + height * sin
|
|
// [angle < 0] middle left width * cos + height + sin
|
|
var pi2 = Math.PI / 2;
|
|
var ALPHABETIC = 'alphabetic';
|
|
var TOP = 'top';
|
|
var BOTTOM = 'bottom';
|
|
var MIDDLE = 'middle';
|
|
var HANGING = 'hanging';
|
|
var LEFT = 'left';
|
|
var RIGHT = 'right';
|
|
var CENTER = 'center';
|
|
var _angle_lookup = {
|
|
above: {
|
|
parallel: 0,
|
|
normal: -pi2,
|
|
horizontal: 0,
|
|
vertical: -pi2,
|
|
},
|
|
below: {
|
|
parallel: 0,
|
|
normal: pi2,
|
|
horizontal: 0,
|
|
vertical: pi2,
|
|
},
|
|
left: {
|
|
parallel: -pi2,
|
|
normal: 0,
|
|
horizontal: 0,
|
|
vertical: -pi2,
|
|
},
|
|
right: {
|
|
parallel: pi2,
|
|
normal: 0,
|
|
horizontal: 0,
|
|
vertical: pi2,
|
|
},
|
|
};
|
|
var _baseline_lookup = {
|
|
above: {
|
|
justified: TOP,
|
|
parallel: ALPHABETIC,
|
|
normal: MIDDLE,
|
|
horizontal: ALPHABETIC,
|
|
vertical: MIDDLE,
|
|
},
|
|
below: {
|
|
justified: BOTTOM,
|
|
parallel: HANGING,
|
|
normal: MIDDLE,
|
|
horizontal: HANGING,
|
|
vertical: MIDDLE,
|
|
},
|
|
left: {
|
|
justified: TOP,
|
|
parallel: ALPHABETIC,
|
|
normal: MIDDLE,
|
|
horizontal: MIDDLE,
|
|
vertical: ALPHABETIC,
|
|
},
|
|
right: {
|
|
justified: TOP,
|
|
parallel: ALPHABETIC,
|
|
normal: MIDDLE,
|
|
horizontal: MIDDLE,
|
|
vertical: ALPHABETIC,
|
|
},
|
|
};
|
|
var _align_lookup = {
|
|
above: {
|
|
justified: CENTER,
|
|
parallel: CENTER,
|
|
normal: LEFT,
|
|
horizontal: CENTER,
|
|
vertical: LEFT,
|
|
},
|
|
below: {
|
|
justified: CENTER,
|
|
parallel: CENTER,
|
|
normal: LEFT,
|
|
horizontal: CENTER,
|
|
vertical: LEFT,
|
|
},
|
|
left: {
|
|
justified: CENTER,
|
|
parallel: CENTER,
|
|
normal: RIGHT,
|
|
horizontal: RIGHT,
|
|
vertical: CENTER,
|
|
},
|
|
right: {
|
|
justified: CENTER,
|
|
parallel: CENTER,
|
|
normal: LEFT,
|
|
horizontal: LEFT,
|
|
vertical: CENTER,
|
|
},
|
|
};
|
|
var _align_lookup_negative = {
|
|
above: RIGHT,
|
|
below: LEFT,
|
|
left: RIGHT,
|
|
right: LEFT,
|
|
};
|
|
var _align_lookup_positive = {
|
|
above: LEFT,
|
|
below: RIGHT,
|
|
left: RIGHT,
|
|
right: LEFT,
|
|
};
|
|
var SidePanel = /** @class */ (function (_super) {
|
|
tslib_1.__extends(SidePanel, _super);
|
|
function SidePanel(side, obj) {
|
|
var _this = _super.call(this) || this;
|
|
_this.side = side;
|
|
_this.obj = obj;
|
|
switch (_this.side) {
|
|
case "above":
|
|
_this._dim = 0;
|
|
_this._normals = [0, -1];
|
|
break;
|
|
case "below":
|
|
_this._dim = 0;
|
|
_this._normals = [0, 1];
|
|
break;
|
|
case "left":
|
|
_this._dim = 1;
|
|
_this._normals = [-1, 0];
|
|
break;
|
|
case "right":
|
|
_this._dim = 1;
|
|
_this._normals = [1, 0];
|
|
break;
|
|
default:
|
|
throw new Error("unreachable");
|
|
}
|
|
if (_this.is_horizontal)
|
|
_this.set_sizing({ width_policy: "max", height_policy: "fixed" });
|
|
else
|
|
_this.set_sizing({ width_policy: "fixed", height_policy: "max" });
|
|
return _this;
|
|
}
|
|
SidePanel.prototype._content_size = function () {
|
|
return new types_1.Sizeable(this.get_oriented_size());
|
|
};
|
|
SidePanel.prototype.get_oriented_size = function () {
|
|
var _a = this.obj.get_size(), width = _a.width, height = _a.height;
|
|
if (!this.obj.rotate || this.is_horizontal)
|
|
return { width: width, height: height };
|
|
else
|
|
return { width: height, height: width };
|
|
};
|
|
SidePanel.prototype.has_size_changed = function () {
|
|
var _a = this.get_oriented_size(), width = _a.width, height = _a.height;
|
|
if (this.is_horizontal)
|
|
return this.bbox.height != height;
|
|
else
|
|
return this.bbox.width != width;
|
|
};
|
|
Object.defineProperty(SidePanel.prototype, "dimension", {
|
|
get: function () {
|
|
return this._dim;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(SidePanel.prototype, "normals", {
|
|
get: function () {
|
|
return this._normals;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(SidePanel.prototype, "is_horizontal", {
|
|
get: function () {
|
|
return this._dim == 0;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(SidePanel.prototype, "is_vertical", {
|
|
get: function () {
|
|
return this._dim == 1;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
SidePanel.prototype.apply_label_text_heuristics = function (ctx, orient) {
|
|
var side = this.side;
|
|
var baseline;
|
|
var align;
|
|
if (types_2.isString(orient)) {
|
|
baseline = _baseline_lookup[side][orient];
|
|
align = _align_lookup[side][orient];
|
|
}
|
|
else {
|
|
if (orient === 0) {
|
|
baseline = "whatever"; // XXX: _baseline_lookup[side][orient]
|
|
align = "whatever"; // XXX: _align_lookup[side][orient]
|
|
}
|
|
else if (orient < 0) {
|
|
baseline = 'middle';
|
|
align = _align_lookup_negative[side];
|
|
}
|
|
else {
|
|
baseline = 'middle';
|
|
align = _align_lookup_positive[side];
|
|
}
|
|
}
|
|
ctx.textBaseline = baseline;
|
|
ctx.textAlign = align;
|
|
};
|
|
SidePanel.prototype.get_label_angle_heuristic = function (orient) {
|
|
return _angle_lookup[this.side][orient];
|
|
};
|
|
return SidePanel;
|
|
}(layoutable_1.ContentLayoutable));
|
|
exports.SidePanel = SidePanel;
|
|
}
|
|
,
|
|
/* core/layout/types */ function _(require, module, exports) {
|
|
var min = Math.min, max = Math.max;
|
|
var Sizeable = /** @class */ (function () {
|
|
function Sizeable(size) {
|
|
if (size === void 0) {
|
|
size = {};
|
|
}
|
|
this.width = size.width != null ? size.width : 0;
|
|
this.height = size.height != null ? size.height : 0;
|
|
}
|
|
Sizeable.prototype.bounded_to = function (_a) {
|
|
var width = _a.width, height = _a.height;
|
|
return new Sizeable({
|
|
width: this.width == Infinity && width != null ? width : this.width,
|
|
height: this.height == Infinity && height != null ? height : this.height,
|
|
});
|
|
};
|
|
Sizeable.prototype.expanded_to = function (_a) {
|
|
var width = _a.width, height = _a.height;
|
|
return new Sizeable({
|
|
width: width != Infinity ? max(this.width, width) : this.width,
|
|
height: height != Infinity ? max(this.height, height) : this.height,
|
|
});
|
|
};
|
|
Sizeable.prototype.expand_to = function (_a) {
|
|
var width = _a.width, height = _a.height;
|
|
this.width = max(this.width, width);
|
|
this.height = max(this.height, height);
|
|
};
|
|
Sizeable.prototype.narrowed_to = function (_a) {
|
|
var width = _a.width, height = _a.height;
|
|
return new Sizeable({
|
|
width: min(this.width, width),
|
|
height: min(this.height, height),
|
|
});
|
|
};
|
|
Sizeable.prototype.narrow_to = function (_a) {
|
|
var width = _a.width, height = _a.height;
|
|
this.width = min(this.width, width);
|
|
this.height = min(this.height, height);
|
|
};
|
|
Sizeable.prototype.grow_by = function (_a) {
|
|
var left = _a.left, right = _a.right, top = _a.top, bottom = _a.bottom;
|
|
var width = this.width + left + right;
|
|
var height = this.height + top + bottom;
|
|
return new Sizeable({ width: width, height: height });
|
|
};
|
|
Sizeable.prototype.shrink_by = function (_a) {
|
|
var left = _a.left, right = _a.right, top = _a.top, bottom = _a.bottom;
|
|
var width = max(this.width - left - right, 0);
|
|
var height = max(this.height - top - bottom, 0);
|
|
return new Sizeable({ width: width, height: height });
|
|
};
|
|
Sizeable.prototype.map = function (w_fn, h_fn) {
|
|
return new Sizeable({
|
|
width: w_fn(this.width),
|
|
height: (h_fn != null ? h_fn : w_fn)(this.height),
|
|
});
|
|
};
|
|
return Sizeable;
|
|
}());
|
|
exports.Sizeable = Sizeable;
|
|
}
|
|
,
|
|
/* core/logging */ function _(require, module, exports) {
|
|
var types_1 = require(46) /* ./util/types */;
|
|
var _loggers = {};
|
|
var LogLevel = /** @class */ (function () {
|
|
function LogLevel(name, level) {
|
|
this.name = name;
|
|
this.level = level;
|
|
}
|
|
return LogLevel;
|
|
}());
|
|
exports.LogLevel = LogLevel;
|
|
var Logger = /** @class */ (function () {
|
|
function Logger(name, level) {
|
|
if (level === void 0) {
|
|
level = Logger.INFO;
|
|
}
|
|
this._name = name;
|
|
this.set_level(level);
|
|
}
|
|
Object.defineProperty(Logger, "levels", {
|
|
get: function () {
|
|
return Object.keys(Logger.log_levels);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Logger.get = function (name, level) {
|
|
if (level === void 0) {
|
|
level = Logger.INFO;
|
|
}
|
|
if (name.length > 0) {
|
|
var logger_1 = _loggers[name];
|
|
if (logger_1 == null)
|
|
_loggers[name] = logger_1 = new Logger(name, level);
|
|
return logger_1;
|
|
}
|
|
else
|
|
throw new TypeError("Logger.get() expects a non-empty string name and an optional log-level");
|
|
};
|
|
Object.defineProperty(Logger.prototype, "level", {
|
|
get: function () {
|
|
return this.get_level();
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Logger.prototype.get_level = function () {
|
|
return this._log_level;
|
|
};
|
|
Logger.prototype.set_level = function (log_level) {
|
|
if (log_level instanceof LogLevel)
|
|
this._log_level = log_level;
|
|
else if (types_1.isString(log_level) && Logger.log_levels[log_level] != null)
|
|
this._log_level = Logger.log_levels[log_level];
|
|
else
|
|
throw new Error("Logger.set_level() expects a log-level object or a string name of a log-level");
|
|
var logger_name = "[" + this._name + "]";
|
|
for (var name_1 in Logger.log_levels) {
|
|
var log_level_1 = Logger.log_levels[name_1];
|
|
if (log_level_1.level < this._log_level.level || this._log_level.level === Logger.OFF.level)
|
|
this[name_1] = function () { };
|
|
else
|
|
this[name_1] = _method_factory(name_1, logger_name);
|
|
}
|
|
};
|
|
Logger.prototype.trace = function () {
|
|
var _args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
_args[_i] = arguments[_i];
|
|
}
|
|
};
|
|
Logger.prototype.debug = function () {
|
|
var _args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
_args[_i] = arguments[_i];
|
|
}
|
|
};
|
|
Logger.prototype.info = function () {
|
|
var _args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
_args[_i] = arguments[_i];
|
|
}
|
|
};
|
|
Logger.prototype.warn = function () {
|
|
var _args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
_args[_i] = arguments[_i];
|
|
}
|
|
};
|
|
Logger.prototype.error = function () {
|
|
var _args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
_args[_i] = arguments[_i];
|
|
}
|
|
};
|
|
Logger.TRACE = new LogLevel("trace", 0);
|
|
Logger.DEBUG = new LogLevel("debug", 1);
|
|
Logger.INFO = new LogLevel("info", 2);
|
|
Logger.WARN = new LogLevel("warn", 6);
|
|
Logger.ERROR = new LogLevel("error", 7);
|
|
Logger.FATAL = new LogLevel("fatal", 8);
|
|
Logger.OFF = new LogLevel("off", 9);
|
|
Logger.log_levels = {
|
|
trace: Logger.TRACE,
|
|
debug: Logger.DEBUG,
|
|
info: Logger.INFO,
|
|
warn: Logger.WARN,
|
|
error: Logger.ERROR,
|
|
fatal: Logger.FATAL,
|
|
off: Logger.OFF,
|
|
};
|
|
return Logger;
|
|
}());
|
|
exports.Logger = Logger;
|
|
function _method_factory(method_name, logger_name) {
|
|
if (console[method_name] != null)
|
|
return console[method_name].bind(console, logger_name);
|
|
else if (console.log != null)
|
|
return console.log.bind(console, logger_name);
|
|
else
|
|
return function () { };
|
|
}
|
|
exports.logger = Logger.get("bokeh");
|
|
function set_log_level(level) {
|
|
if (Logger.log_levels[level] == null) {
|
|
console.log("[bokeh] unrecognized logging level '" + level + "' passed to Bokeh.set_log_level(), ignoring");
|
|
console.log("[bokeh] valid log levels are: " + Logger.levels.join(', '));
|
|
}
|
|
else {
|
|
console.log("[bokeh] setting log level to: '" + level + "'");
|
|
exports.logger.set_level(level);
|
|
}
|
|
}
|
|
exports.set_log_level = set_log_level;
|
|
}
|
|
,
|
|
/* core/properties */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var signaling_1 = require(22) /* ./signaling */;
|
|
var enums = require(7) /* ./enums */;
|
|
var array_1 = require(24) /* ./util/array */;
|
|
var arrayable_1 = require(25) /* ./util/arrayable */;
|
|
var color_1 = require(30) /* ./util/color */;
|
|
var types_1 = require(46) /* ./util/types */;
|
|
signaling_1.Signal; // XXX: silence TS, because `Signal` appears in declarations due to Signalable
|
|
function valueToString(value) {
|
|
try {
|
|
return JSON.stringify(value);
|
|
}
|
|
catch (_a) {
|
|
return value.toString();
|
|
}
|
|
}
|
|
function isSpec(obj) {
|
|
return types_1.isPlainObject(obj) &&
|
|
((obj.value === undefined ? 0 : 1) +
|
|
(obj.field === undefined ? 0 : 1) +
|
|
(obj.expr === undefined ? 0 : 1) == 1); // garbage JS XOR
|
|
}
|
|
exports.isSpec = isSpec;
|
|
var Property = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Property, _super);
|
|
function Property(obj, attr, default_value) {
|
|
var _this = _super.call(this) || this;
|
|
_this.obj = obj;
|
|
_this.attr = attr;
|
|
_this.default_value = default_value;
|
|
_this.optional = false;
|
|
_this.change = new signaling_1.Signal0(_this.obj, "change");
|
|
_this._init();
|
|
_this.connect(_this.change, function () { return _this._init(); });
|
|
return _this;
|
|
}
|
|
Property.prototype.update = function () {
|
|
this._init();
|
|
};
|
|
// ----- customizable policies
|
|
Property.prototype.init = function () { };
|
|
Property.prototype.transform = function (values) {
|
|
return values;
|
|
};
|
|
Property.prototype.validate = function (value) {
|
|
if (!this.valid(value))
|
|
throw new Error(this.obj.type + "." + this.attr + " given invalid value: " + valueToString(value));
|
|
};
|
|
Property.prototype.valid = function (_value) {
|
|
return true;
|
|
};
|
|
// ----- property accessors
|
|
Property.prototype.value = function (do_spec_transform) {
|
|
if (do_spec_transform === void 0) {
|
|
do_spec_transform = true;
|
|
}
|
|
if (this.spec.value === undefined)
|
|
throw new Error("attempted to retrieve property value for property without value specification");
|
|
var ret = this.transform([this.spec.value])[0];
|
|
if (this.spec.transform != null && do_spec_transform)
|
|
ret = this.spec.transform.compute(ret);
|
|
return ret;
|
|
};
|
|
// ----- private methods
|
|
/*protected*/ Property.prototype._init = function () {
|
|
var _a;
|
|
var obj = this.obj;
|
|
var attr = this.attr;
|
|
var attr_value = obj.getv(attr);
|
|
if (attr_value === undefined) {
|
|
var default_value = this.default_value;
|
|
if (default_value !== undefined)
|
|
attr_value = default_value(obj);
|
|
else
|
|
attr_value = null;
|
|
obj.setv((_a = {}, _a[attr] = attr_value, _a), { silent: true, defaults: true });
|
|
}
|
|
if (types_1.isArray(attr_value))
|
|
this.spec = { value: attr_value };
|
|
else if (isSpec(attr_value))
|
|
this.spec = attr_value;
|
|
else
|
|
this.spec = { value: attr_value };
|
|
//if (this.dataspec && this.spec.field != null && !isString(this.spec.field))
|
|
// throw new Error(`field value for property '${attr}' is not a string`)
|
|
if (this.spec.value != null)
|
|
this.validate(this.spec.value);
|
|
this.init();
|
|
};
|
|
Property.prototype.toString = function () {
|
|
/*${this.name}*/
|
|
return "Prop(" + this.obj + "." + this.attr + ", spec: " + valueToString(this.spec) + ")";
|
|
};
|
|
return Property;
|
|
}(signaling_1.Signalable()));
|
|
exports.Property = Property;
|
|
//
|
|
// Primitive Properties
|
|
//
|
|
var Any = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Any, _super);
|
|
function Any() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return Any;
|
|
}(Property));
|
|
exports.Any = Any;
|
|
var Array = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Array, _super);
|
|
function Array() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Array.prototype.valid = function (value) {
|
|
return types_1.isArray(value) || value instanceof Float64Array;
|
|
};
|
|
return Array;
|
|
}(Property));
|
|
exports.Array = Array;
|
|
var Boolean = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Boolean, _super);
|
|
function Boolean() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Boolean.prototype.valid = function (value) {
|
|
return types_1.isBoolean(value);
|
|
};
|
|
return Boolean;
|
|
}(Property));
|
|
exports.Boolean = Boolean;
|
|
var Color = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Color, _super);
|
|
function Color() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Color.prototype.valid = function (value) {
|
|
return types_1.isString(value) && color_1.is_color(value);
|
|
};
|
|
return Color;
|
|
}(Property));
|
|
exports.Color = Color;
|
|
var Instance = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Instance, _super);
|
|
function Instance() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return Instance;
|
|
}(Property));
|
|
exports.Instance = Instance;
|
|
var Number = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Number, _super);
|
|
function Number() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Number.prototype.valid = function (value) {
|
|
return types_1.isNumber(value);
|
|
};
|
|
return Number;
|
|
}(Property));
|
|
exports.Number = Number;
|
|
var Int = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Int, _super);
|
|
function Int() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Int.prototype.valid = function (value) {
|
|
return types_1.isNumber(value) && (value | 0) == value;
|
|
};
|
|
return Int;
|
|
}(Number));
|
|
exports.Int = Int;
|
|
var Angle = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Angle, _super);
|
|
function Angle() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return Angle;
|
|
}(Number));
|
|
exports.Angle = Angle;
|
|
var Percent = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Percent, _super);
|
|
function Percent() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Percent.prototype.valid = function (value) {
|
|
return types_1.isNumber(value) && 0 <= value && value <= 1.0;
|
|
};
|
|
return Percent;
|
|
}(Number));
|
|
exports.Percent = Percent;
|
|
var String = /** @class */ (function (_super) {
|
|
tslib_1.__extends(String, _super);
|
|
function String() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
String.prototype.valid = function (value) {
|
|
return types_1.isString(value);
|
|
};
|
|
return String;
|
|
}(Property));
|
|
exports.String = String;
|
|
var FontSize = /** @class */ (function (_super) {
|
|
tslib_1.__extends(FontSize, _super);
|
|
function FontSize() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return FontSize;
|
|
}(String));
|
|
exports.FontSize = FontSize;
|
|
var Font = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Font, _super);
|
|
function Font() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return Font;
|
|
}(String)); // TODO (bev) don't think this exists python side
|
|
exports.Font = Font;
|
|
//
|
|
// Enum properties
|
|
//
|
|
var EnumProperty = /** @class */ (function (_super) {
|
|
tslib_1.__extends(EnumProperty, _super);
|
|
function EnumProperty() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
EnumProperty.prototype.valid = function (value) {
|
|
return types_1.isString(value) && array_1.includes(this.enum_values, value);
|
|
};
|
|
return EnumProperty;
|
|
}(Property));
|
|
exports.EnumProperty = EnumProperty;
|
|
function Enum(values) {
|
|
return /** @class */ (function (_super) {
|
|
tslib_1.__extends(class_1, _super);
|
|
function class_1() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Object.defineProperty(class_1.prototype, "enum_values", {
|
|
get: function () {
|
|
return values;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return class_1;
|
|
}(EnumProperty));
|
|
}
|
|
exports.Enum = Enum;
|
|
var Direction = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Direction, _super);
|
|
function Direction() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Object.defineProperty(Direction.prototype, "enum_values", {
|
|
get: function () {
|
|
return enums.Direction;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Direction.prototype.transform = function (values) {
|
|
var result = new Uint8Array(values.length);
|
|
for (var i = 0; i < values.length; i++) {
|
|
switch (values[i]) {
|
|
case "clock":
|
|
result[i] = 0;
|
|
break;
|
|
case "anticlock":
|
|
result[i] = 1;
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
return Direction;
|
|
}(EnumProperty));
|
|
exports.Direction = Direction;
|
|
exports.Anchor = Enum(enums.Anchor);
|
|
exports.AngleUnits = Enum(enums.AngleUnits);
|
|
exports.BoxOrigin = Enum(enums.BoxOrigin);
|
|
exports.ButtonType = Enum(enums.ButtonType);
|
|
exports.Dimension = Enum(enums.Dimension);
|
|
exports.Dimensions = Enum(enums.Dimensions);
|
|
exports.Distribution = Enum(enums.Distribution);
|
|
exports.FontStyle = Enum(enums.FontStyle);
|
|
exports.HTTPMethod = Enum(enums.HTTPMethod);
|
|
exports.HexTileOrientation = Enum(enums.HexTileOrientation);
|
|
exports.HoverMode = Enum(enums.HoverMode);
|
|
exports.LatLon = Enum(enums.LatLon);
|
|
exports.LegendClickPolicy = Enum(enums.LegendClickPolicy);
|
|
exports.LegendLocation = Enum(enums.LegendLocation);
|
|
exports.LineCap = Enum(enums.LineCap);
|
|
exports.LineJoin = Enum(enums.LineJoin);
|
|
exports.LinePolicy = Enum(enums.LinePolicy);
|
|
exports.Location = Enum(enums.Location);
|
|
exports.Logo = Enum(enums.Logo);
|
|
exports.MarkerType = Enum(enums.MarkerType);
|
|
exports.Orientation = Enum(enums.Orientation);
|
|
exports.OutputBackend = Enum(enums.OutputBackend);
|
|
exports.PaddingUnits = Enum(enums.PaddingUnits);
|
|
exports.Place = Enum(enums.Place);
|
|
exports.PointPolicy = Enum(enums.PointPolicy);
|
|
exports.RadiusDimension = Enum(enums.RadiusDimension);
|
|
exports.RenderLevel = Enum(enums.RenderLevel);
|
|
exports.RenderMode = Enum(enums.RenderMode);
|
|
exports.RoundingFunction = Enum(enums.RoundingFunction);
|
|
exports.Side = Enum(enums.Side);
|
|
exports.SizingMode = Enum(enums.SizingMode);
|
|
exports.SliderCallbackPolicy = Enum(enums.SliderCallbackPolicy);
|
|
exports.Sort = Enum(enums.Sort);
|
|
exports.SpatialUnits = Enum(enums.SpatialUnits);
|
|
exports.StartEnd = Enum(enums.StartEnd);
|
|
exports.StepMode = Enum(enums.StepMode);
|
|
exports.TapBehavior = Enum(enums.TapBehavior);
|
|
exports.TextAlign = Enum(enums.TextAlign);
|
|
exports.TextBaseline = Enum(enums.TextBaseline);
|
|
exports.TickLabelOrientation = Enum(enums.TickLabelOrientation);
|
|
exports.TooltipAttachment = Enum(enums.TooltipAttachment);
|
|
exports.UpdateMode = Enum(enums.UpdateMode);
|
|
exports.VerticalAlign = Enum(enums.VerticalAlign);
|
|
//
|
|
// DataSpec properties
|
|
//
|
|
var ScalarSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ScalarSpec, _super);
|
|
function ScalarSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return ScalarSpec;
|
|
}(Property));
|
|
exports.ScalarSpec = ScalarSpec;
|
|
var VectorSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(VectorSpec, _super);
|
|
function VectorSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
VectorSpec.prototype.array = function (source) {
|
|
var ret;
|
|
if (this.spec.field != null) {
|
|
ret = this.transform(source.get_column(this.spec.field));
|
|
if (ret == null)
|
|
throw new Error("attempted to retrieve property array for nonexistent field '" + this.spec.field + "'");
|
|
}
|
|
else if (this.spec.expr != null) {
|
|
ret = this.transform(this.spec.expr.v_compute(source));
|
|
}
|
|
else {
|
|
var length_1 = source.get_length();
|
|
if (length_1 == null)
|
|
length_1 = 1;
|
|
var value = this.value(false); // don't apply any spec transform
|
|
ret = array_1.repeat(value, length_1);
|
|
}
|
|
if (this.spec.transform != null)
|
|
ret = this.spec.transform.v_compute(ret);
|
|
return ret;
|
|
};
|
|
return VectorSpec;
|
|
}(Property));
|
|
exports.VectorSpec = VectorSpec;
|
|
var DataSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DataSpec, _super);
|
|
function DataSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return DataSpec;
|
|
}(VectorSpec));
|
|
exports.DataSpec = DataSpec;
|
|
var UnitsSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(UnitsSpec, _super);
|
|
function UnitsSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
UnitsSpec.prototype.init = function () {
|
|
if (this.spec.units == null)
|
|
this.spec.units = this.default_units;
|
|
var units = this.spec.units;
|
|
if (!array_1.includes(this.valid_units, units))
|
|
throw new Error("units must be one of " + this.valid_units.join(", ") + "; got: " + units);
|
|
};
|
|
Object.defineProperty(UnitsSpec.prototype, "units", {
|
|
get: function () {
|
|
return this.spec.units;
|
|
},
|
|
set: function (units) {
|
|
this.spec.units = units;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return UnitsSpec;
|
|
}(VectorSpec));
|
|
exports.UnitsSpec = UnitsSpec;
|
|
var AngleSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(AngleSpec, _super);
|
|
function AngleSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Object.defineProperty(AngleSpec.prototype, "default_units", {
|
|
get: function () { return "rad"; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(AngleSpec.prototype, "valid_units", {
|
|
get: function () { return enums.AngleUnits; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
AngleSpec.prototype.transform = function (values) {
|
|
if (this.spec.units == "deg")
|
|
values = arrayable_1.map(values, function (x) { return x * Math.PI / 180.0; });
|
|
values = arrayable_1.map(values, function (x) { return -x; });
|
|
return _super.prototype.transform.call(this, values);
|
|
};
|
|
return AngleSpec;
|
|
}(UnitsSpec));
|
|
exports.AngleSpec = AngleSpec;
|
|
var BooleanSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BooleanSpec, _super);
|
|
function BooleanSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return BooleanSpec;
|
|
}(DataSpec));
|
|
exports.BooleanSpec = BooleanSpec;
|
|
var ColorSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ColorSpec, _super);
|
|
function ColorSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return ColorSpec;
|
|
}(DataSpec));
|
|
exports.ColorSpec = ColorSpec;
|
|
var CoordinateSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CoordinateSpec, _super);
|
|
function CoordinateSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return CoordinateSpec;
|
|
}(DataSpec));
|
|
exports.CoordinateSpec = CoordinateSpec;
|
|
var CoordinateSeqSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CoordinateSeqSpec, _super);
|
|
function CoordinateSeqSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return CoordinateSeqSpec;
|
|
}(DataSpec));
|
|
exports.CoordinateSeqSpec = CoordinateSeqSpec;
|
|
var DistanceSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DistanceSpec, _super);
|
|
function DistanceSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Object.defineProperty(DistanceSpec.prototype, "default_units", {
|
|
get: function () { return "data"; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(DistanceSpec.prototype, "valid_units", {
|
|
get: function () { return enums.SpatialUnits; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return DistanceSpec;
|
|
}(UnitsSpec));
|
|
exports.DistanceSpec = DistanceSpec;
|
|
var FontSizeSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(FontSizeSpec, _super);
|
|
function FontSizeSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return FontSizeSpec;
|
|
}(DataSpec));
|
|
exports.FontSizeSpec = FontSizeSpec;
|
|
var MarkerSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MarkerSpec, _super);
|
|
function MarkerSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return MarkerSpec;
|
|
}(DataSpec));
|
|
exports.MarkerSpec = MarkerSpec;
|
|
var NumberSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(NumberSpec, _super);
|
|
function NumberSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return NumberSpec;
|
|
}(DataSpec));
|
|
exports.NumberSpec = NumberSpec;
|
|
var StringSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(StringSpec, _super);
|
|
function StringSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return StringSpec;
|
|
}(DataSpec));
|
|
exports.StringSpec = StringSpec;
|
|
var NullStringSpec = /** @class */ (function (_super) {
|
|
tslib_1.__extends(NullStringSpec, _super);
|
|
function NullStringSpec() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return NullStringSpec;
|
|
}(DataSpec));
|
|
exports.NullStringSpec = NullStringSpec;
|
|
}
|
|
,
|
|
/* core/property_mixins */ function _(require, module, exports) {
|
|
var p = require(18) /* ./properties */;
|
|
var object_1 = require(35) /* ./util/object */;
|
|
function _gen_mixin(mixin, prefix) {
|
|
var result = {};
|
|
for (var name_1 in mixin) {
|
|
var prop = mixin[name_1];
|
|
result[prefix + name_1] = prop;
|
|
}
|
|
return result;
|
|
}
|
|
var _line_mixin = {
|
|
line_color: [p.ColorSpec, 'black'],
|
|
line_width: [p.NumberSpec, 1],
|
|
line_alpha: [p.NumberSpec, 1.0],
|
|
line_join: [p.LineJoin, 'bevel'],
|
|
line_cap: [p.LineCap, 'butt'],
|
|
line_dash: [p.Array, []],
|
|
line_dash_offset: [p.Number, 0],
|
|
};
|
|
exports.line = function (prefix) {
|
|
if (prefix === void 0) {
|
|
prefix = "";
|
|
}
|
|
return _gen_mixin(_line_mixin, prefix);
|
|
};
|
|
var _fill_mixin = {
|
|
fill_color: [p.ColorSpec, 'gray'],
|
|
fill_alpha: [p.NumberSpec, 1.0],
|
|
};
|
|
exports.fill = function (prefix) {
|
|
if (prefix === void 0) {
|
|
prefix = "";
|
|
}
|
|
return _gen_mixin(_fill_mixin, prefix);
|
|
};
|
|
var _text_mixin = {
|
|
text_font: [p.Font, 'helvetica'],
|
|
text_font_size: [p.FontSizeSpec, '12pt'],
|
|
text_font_style: [p.FontStyle, 'normal'],
|
|
text_color: [p.ColorSpec, '#444444'],
|
|
text_alpha: [p.NumberSpec, 1.0],
|
|
text_align: [p.TextAlign, 'left'],
|
|
text_baseline: [p.TextBaseline, 'bottom'],
|
|
text_line_height: [p.Number, 1.2],
|
|
};
|
|
exports.text = function (prefix) {
|
|
if (prefix === void 0) {
|
|
prefix = "";
|
|
}
|
|
return _gen_mixin(_text_mixin, prefix);
|
|
};
|
|
function create(configs) {
|
|
var result = {};
|
|
for (var _i = 0, configs_1 = configs; _i < configs_1.length; _i++) {
|
|
var config = configs_1[_i];
|
|
var _a = config.split(":"), kind = _a[0], prefix = _a[1];
|
|
var mixin = void 0;
|
|
switch (kind) {
|
|
case "line":
|
|
mixin = exports.line;
|
|
break;
|
|
case "fill":
|
|
mixin = exports.fill;
|
|
break;
|
|
case "text":
|
|
mixin = exports.text;
|
|
break;
|
|
default:
|
|
throw new Error("Unknown property mixin kind '" + kind + "'");
|
|
}
|
|
object_1.extend(result, mixin(prefix));
|
|
}
|
|
return result;
|
|
}
|
|
exports.create = create;
|
|
}
|
|
,
|
|
/* core/selection_manager */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var has_props_1 = require(8) /* ./has_props */;
|
|
var selection_1 = require(205) /* ../models/selections/selection */;
|
|
var glyph_renderer_1 = require(193) /* ../models/renderers/glyph_renderer */;
|
|
var graph_renderer_1 = require(194) /* ../models/renderers/graph_renderer */;
|
|
var p = require(18) /* ./properties */;
|
|
var SelectionManager = /** @class */ (function (_super) {
|
|
tslib_1.__extends(SelectionManager, _super);
|
|
function SelectionManager(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.inspectors = {};
|
|
return _this;
|
|
}
|
|
SelectionManager.initClass = function () {
|
|
this.prototype.type = "SelectionManager";
|
|
this.internal({
|
|
source: [p.Any],
|
|
});
|
|
};
|
|
SelectionManager.prototype.select = function (renderer_views, geometry, final, append) {
|
|
if (append === void 0) {
|
|
append = false;
|
|
}
|
|
// divide renderers into glyph_renderers or graph_renderers
|
|
var glyph_renderer_views = [];
|
|
var graph_renderer_views = [];
|
|
for (var _i = 0, renderer_views_1 = renderer_views; _i < renderer_views_1.length; _i++) {
|
|
var r = renderer_views_1[_i];
|
|
if (r instanceof glyph_renderer_1.GlyphRendererView)
|
|
glyph_renderer_views.push(r);
|
|
else if (r instanceof graph_renderer_1.GraphRendererView)
|
|
graph_renderer_views.push(r);
|
|
}
|
|
var did_hit = false;
|
|
// graph renderer case
|
|
for (var _a = 0, graph_renderer_views_1 = graph_renderer_views; _a < graph_renderer_views_1.length; _a++) {
|
|
var r = graph_renderer_views_1[_a];
|
|
var hit_test_result = r.model.selection_policy.hit_test(geometry, r);
|
|
did_hit = did_hit || r.model.selection_policy.do_selection(hit_test_result, r.model, final, append);
|
|
}
|
|
// glyph renderers
|
|
if (glyph_renderer_views.length > 0) {
|
|
var hit_test_result = this.source.selection_policy.hit_test(geometry, glyph_renderer_views);
|
|
did_hit = did_hit || this.source.selection_policy.do_selection(hit_test_result, this.source, final, append);
|
|
}
|
|
return did_hit;
|
|
};
|
|
SelectionManager.prototype.inspect = function (renderer_view, geometry) {
|
|
var did_hit = false;
|
|
if (renderer_view instanceof glyph_renderer_1.GlyphRendererView) {
|
|
var hit_test_result = renderer_view.hit_test(geometry);
|
|
if (hit_test_result != null) {
|
|
did_hit = !hit_test_result.is_empty();
|
|
var inspection = this.get_or_create_inspector(renderer_view.model);
|
|
inspection.update(hit_test_result, true, false);
|
|
this.source.setv({ inspected: inspection }, { silent: true });
|
|
this.source.inspect.emit([renderer_view, { geometry: geometry }]);
|
|
}
|
|
}
|
|
else if (renderer_view instanceof graph_renderer_1.GraphRendererView) {
|
|
var hit_test_result = renderer_view.model.inspection_policy.hit_test(geometry, renderer_view);
|
|
did_hit = did_hit || renderer_view.model.inspection_policy.do_inspection(hit_test_result, geometry, renderer_view, false, false);
|
|
}
|
|
return did_hit;
|
|
};
|
|
SelectionManager.prototype.clear = function (rview) {
|
|
this.source.selected.clear();
|
|
if (rview != null)
|
|
this.get_or_create_inspector(rview.model).clear();
|
|
};
|
|
SelectionManager.prototype.get_or_create_inspector = function (rmodel) {
|
|
if (this.inspectors[rmodel.id] == null)
|
|
this.inspectors[rmodel.id] = new selection_1.Selection();
|
|
return this.inspectors[rmodel.id];
|
|
};
|
|
return SelectionManager;
|
|
}(has_props_1.HasProps));
|
|
exports.SelectionManager = SelectionManager;
|
|
SelectionManager.initClass();
|
|
}
|
|
,
|
|
/* core/settings */ function _(require, module, exports) {
|
|
var Settings = /** @class */ (function () {
|
|
function Settings() {
|
|
this._dev = false;
|
|
}
|
|
Object.defineProperty(Settings.prototype, "dev", {
|
|
get: function () {
|
|
return this._dev;
|
|
},
|
|
set: function (dev) {
|
|
this._dev = dev;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return Settings;
|
|
}());
|
|
exports.Settings = Settings;
|
|
exports.settings = new Settings();
|
|
}
|
|
,
|
|
/* core/signaling */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var data_structures_1 = require(32) /* ./util/data_structures */;
|
|
var callback_1 = require(28) /* ./util/callback */;
|
|
var array_1 = require(24) /* ./util/array */;
|
|
var Signal = /** @class */ (function () {
|
|
function Signal(sender, name) {
|
|
this.sender = sender;
|
|
this.name = name;
|
|
}
|
|
Signal.prototype.connect = function (slot, context) {
|
|
if (context === void 0) {
|
|
context = null;
|
|
}
|
|
if (!receiversForSender.has(this.sender)) {
|
|
receiversForSender.set(this.sender, []);
|
|
}
|
|
var receivers = receiversForSender.get(this.sender);
|
|
if (findConnection(receivers, this, slot, context) != null) {
|
|
return false;
|
|
}
|
|
var receiver = context || slot;
|
|
if (!sendersForReceiver.has(receiver)) {
|
|
sendersForReceiver.set(receiver, []);
|
|
}
|
|
var senders = sendersForReceiver.get(receiver);
|
|
var connection = { signal: this, slot: slot, context: context };
|
|
receivers.push(connection);
|
|
senders.push(connection);
|
|
return true;
|
|
};
|
|
Signal.prototype.disconnect = function (slot, context) {
|
|
if (context === void 0) {
|
|
context = null;
|
|
}
|
|
var receivers = receiversForSender.get(this.sender);
|
|
if (receivers == null || receivers.length === 0) {
|
|
return false;
|
|
}
|
|
var connection = findConnection(receivers, this, slot, context);
|
|
if (connection == null) {
|
|
return false;
|
|
}
|
|
var receiver = context || slot;
|
|
var senders = sendersForReceiver.get(receiver);
|
|
connection.signal = null;
|
|
scheduleCleanup(receivers);
|
|
scheduleCleanup(senders);
|
|
return true;
|
|
};
|
|
Signal.prototype.emit = function (args) {
|
|
var receivers = receiversForSender.get(this.sender) || [];
|
|
for (var _i = 0, receivers_1 = receivers; _i < receivers_1.length; _i++) {
|
|
var _a = receivers_1[_i], signal = _a.signal, slot = _a.slot, context = _a.context;
|
|
if (signal === this) {
|
|
slot.call(context, args, this.sender);
|
|
}
|
|
}
|
|
};
|
|
return Signal;
|
|
}());
|
|
exports.Signal = Signal;
|
|
var Signal0 = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Signal0, _super);
|
|
function Signal0() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Signal0.prototype.emit = function () {
|
|
_super.prototype.emit.call(this, undefined);
|
|
};
|
|
return Signal0;
|
|
}(Signal));
|
|
exports.Signal0 = Signal0;
|
|
(function (Signal) {
|
|
function disconnectBetween(sender, receiver) {
|
|
var receivers = receiversForSender.get(sender);
|
|
if (receivers == null || receivers.length === 0)
|
|
return;
|
|
var senders = sendersForReceiver.get(receiver);
|
|
if (senders == null || senders.length === 0)
|
|
return;
|
|
for (var _i = 0, senders_1 = senders; _i < senders_1.length; _i++) {
|
|
var connection = senders_1[_i];
|
|
if (connection.signal == null)
|
|
return;
|
|
if (connection.signal.sender === sender)
|
|
connection.signal = null;
|
|
}
|
|
scheduleCleanup(receivers);
|
|
scheduleCleanup(senders);
|
|
}
|
|
Signal.disconnectBetween = disconnectBetween;
|
|
function disconnectSender(sender) {
|
|
var receivers = receiversForSender.get(sender);
|
|
if (receivers == null || receivers.length === 0)
|
|
return;
|
|
for (var _i = 0, receivers_2 = receivers; _i < receivers_2.length; _i++) {
|
|
var connection = receivers_2[_i];
|
|
if (connection.signal == null)
|
|
return;
|
|
var receiver = connection.context || connection.slot;
|
|
connection.signal = null;
|
|
scheduleCleanup(sendersForReceiver.get(receiver));
|
|
}
|
|
scheduleCleanup(receivers);
|
|
}
|
|
Signal.disconnectSender = disconnectSender;
|
|
function disconnectReceiver(receiver) {
|
|
var senders = sendersForReceiver.get(receiver);
|
|
if (senders == null || senders.length === 0)
|
|
return;
|
|
for (var _i = 0, senders_2 = senders; _i < senders_2.length; _i++) {
|
|
var connection = senders_2[_i];
|
|
if (connection.signal == null)
|
|
return;
|
|
var sender = connection.signal.sender;
|
|
connection.signal = null;
|
|
scheduleCleanup(receiversForSender.get(sender));
|
|
}
|
|
scheduleCleanup(senders);
|
|
}
|
|
Signal.disconnectReceiver = disconnectReceiver;
|
|
function disconnectAll(obj) {
|
|
var receivers = receiversForSender.get(obj);
|
|
if (receivers != null && receivers.length !== 0) {
|
|
for (var _i = 0, receivers_3 = receivers; _i < receivers_3.length; _i++) {
|
|
var connection = receivers_3[_i];
|
|
connection.signal = null;
|
|
}
|
|
scheduleCleanup(receivers);
|
|
}
|
|
var senders = sendersForReceiver.get(obj);
|
|
if (senders != null && senders.length !== 0) {
|
|
for (var _a = 0, senders_3 = senders; _a < senders_3.length; _a++) {
|
|
var connection = senders_3[_a];
|
|
connection.signal = null;
|
|
}
|
|
scheduleCleanup(senders);
|
|
}
|
|
}
|
|
Signal.disconnectAll = disconnectAll;
|
|
})(Signal = exports.Signal || (exports.Signal = {}));
|
|
exports.Signal = Signal;
|
|
function Signalable(Base) {
|
|
// XXX: `class Foo extends Signalable(Object)` doesn't work (compiles, but fails at runtime), so
|
|
// we have to do this to allow signalable classes without an explict base class.
|
|
if (Base != null) {
|
|
return /** @class */ (function (_super) {
|
|
tslib_1.__extends(class_1, _super);
|
|
function class_1() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
class_1.prototype.connect = function (signal, slot) {
|
|
return signal.connect(slot, this);
|
|
};
|
|
return class_1;
|
|
}(Base));
|
|
}
|
|
else {
|
|
return /** @class */ (function () {
|
|
function class_2() {
|
|
}
|
|
class_2.prototype.connect = function (signal, slot) {
|
|
return signal.connect(slot, this);
|
|
};
|
|
return class_2;
|
|
}());
|
|
}
|
|
}
|
|
exports.Signalable = Signalable;
|
|
var _Signalable;
|
|
(function (_Signalable) {
|
|
function connect(signal, slot) {
|
|
return signal.connect(slot, this);
|
|
}
|
|
_Signalable.connect = connect;
|
|
})(_Signalable = exports._Signalable || (exports._Signalable = {}));
|
|
var receiversForSender = new WeakMap();
|
|
var sendersForReceiver = new WeakMap();
|
|
function findConnection(conns, signal, slot, context) {
|
|
return array_1.find(conns, function (conn) { return conn.signal === signal && conn.slot === slot && conn.context === context; });
|
|
}
|
|
var dirtySet = new data_structures_1.Set();
|
|
function scheduleCleanup(connections) {
|
|
if (dirtySet.size === 0) {
|
|
callback_1.defer(cleanupDirtySet);
|
|
}
|
|
dirtySet.add(connections);
|
|
}
|
|
function cleanupDirtySet() {
|
|
dirtySet.forEach(function (connections) {
|
|
array_1.remove_by(connections, function (connection) { return connection.signal == null; });
|
|
});
|
|
dirtySet.clear();
|
|
}
|
|
}
|
|
,
|
|
/* core/ui_events */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var Hammer = require(369) /* hammerjs */;
|
|
var signaling_1 = require(22) /* ./signaling */;
|
|
var logging_1 = require(17) /* ./logging */;
|
|
var dom_1 = require(5) /* ./dom */;
|
|
var wheel_1 = require(47) /* ./util/wheel */;
|
|
var array_1 = require(24) /* ./util/array */;
|
|
var object_1 = require(35) /* ./util/object */;
|
|
var types_1 = require(46) /* ./util/types */;
|
|
var compat_1 = require(31) /* ./util/compat */;
|
|
var events = require(3) /* ./bokeh_events */;
|
|
var UIEvents = /** @class */ (function () {
|
|
function UIEvents(plot_view, toolbar, hit_area) {
|
|
var _this = this;
|
|
this.plot_view = plot_view;
|
|
this.toolbar = toolbar;
|
|
this.hit_area = hit_area;
|
|
this.pan_start = new signaling_1.Signal(this, 'pan:start');
|
|
this.pan = new signaling_1.Signal(this, 'pan');
|
|
this.pan_end = new signaling_1.Signal(this, 'pan:end');
|
|
this.pinch_start = new signaling_1.Signal(this, 'pinch:start');
|
|
this.pinch = new signaling_1.Signal(this, 'pinch');
|
|
this.pinch_end = new signaling_1.Signal(this, 'pinch:end');
|
|
this.rotate_start = new signaling_1.Signal(this, 'rotate:start');
|
|
this.rotate = new signaling_1.Signal(this, 'rotate');
|
|
this.rotate_end = new signaling_1.Signal(this, 'rotate:end');
|
|
this.tap = new signaling_1.Signal(this, 'tap');
|
|
this.doubletap = new signaling_1.Signal(this, 'doubletap');
|
|
this.press = new signaling_1.Signal(this, 'press');
|
|
this.move_enter = new signaling_1.Signal(this, 'move:enter');
|
|
this.move = new signaling_1.Signal(this, 'move');
|
|
this.move_exit = new signaling_1.Signal(this, 'move:exit');
|
|
this.scroll = new signaling_1.Signal(this, 'scroll');
|
|
this.keydown = new signaling_1.Signal(this, 'keydown');
|
|
this.keyup = new signaling_1.Signal(this, 'keyup');
|
|
this.hammer = new Hammer(this.hit_area);
|
|
this._configure_hammerjs();
|
|
// Mouse & keyboard events not handled through hammerjs
|
|
// We can 'add and forget' these event listeners because this.hit_area is a DOM element
|
|
// that will be thrown away when the view is removed
|
|
this.hit_area.addEventListener("mousemove", function (e) { return _this._mouse_move(e); });
|
|
this.hit_area.addEventListener("mouseenter", function (e) { return _this._mouse_enter(e); });
|
|
this.hit_area.addEventListener("mouseleave", function (e) { return _this._mouse_exit(e); });
|
|
this.hit_area.addEventListener("wheel", function (e) { return _this._mouse_wheel(e); });
|
|
// But we MUST remove listeners registered on document or we'll leak memory: register
|
|
// 'this' as the listener (it implements the event listener interface, i.e. handleEvent)
|
|
// instead of an anonymous function so we can easily refer back to it for removing
|
|
document.addEventListener("keydown", this);
|
|
document.addEventListener("keyup", this);
|
|
}
|
|
UIEvents.prototype.destroy = function () {
|
|
this.hammer.destroy();
|
|
document.removeEventListener("keydown", this);
|
|
document.removeEventListener("keyup", this);
|
|
};
|
|
UIEvents.prototype.handleEvent = function (e) {
|
|
if (e.type == "keydown")
|
|
this._key_down(e);
|
|
else if (e.type == "keyup")
|
|
this._key_up(e);
|
|
};
|
|
UIEvents.prototype._configure_hammerjs = function () {
|
|
var _this = this;
|
|
// This is to be able to distinguish double taps from single taps
|
|
this.hammer.get('doubletap').recognizeWith('tap');
|
|
this.hammer.get('tap').requireFailure('doubletap');
|
|
this.hammer.get('doubletap').dropRequireFailure('tap');
|
|
this.hammer.on('doubletap', function (e) { return _this._doubletap(e); });
|
|
this.hammer.on('tap', function (e) { return _this._tap(e); });
|
|
this.hammer.on('press', function (e) { return _this._press(e); });
|
|
this.hammer.get('pan').set({ direction: Hammer.DIRECTION_ALL });
|
|
this.hammer.on('panstart', function (e) { return _this._pan_start(e); });
|
|
this.hammer.on('pan', function (e) { return _this._pan(e); });
|
|
this.hammer.on('panend', function (e) { return _this._pan_end(e); });
|
|
this.hammer.get('pinch').set({ enable: true });
|
|
this.hammer.on('pinchstart', function (e) { return _this._pinch_start(e); });
|
|
this.hammer.on('pinch', function (e) { return _this._pinch(e); });
|
|
this.hammer.on('pinchend', function (e) { return _this._pinch_end(e); });
|
|
this.hammer.get('rotate').set({ enable: true });
|
|
this.hammer.on('rotatestart', function (e) { return _this._rotate_start(e); });
|
|
this.hammer.on('rotate', function (e) { return _this._rotate(e); });
|
|
this.hammer.on('rotateend', function (e) { return _this._rotate_end(e); });
|
|
};
|
|
UIEvents.prototype.register_tool = function (tool_view) {
|
|
var _this = this;
|
|
var et = tool_view.model.event_type;
|
|
if (et != null) {
|
|
if (types_1.isString(et))
|
|
this._register_tool(tool_view, et);
|
|
else {
|
|
// Multi-tools should only registered shared events once
|
|
et.forEach(function (e, index) { return _this._register_tool(tool_view, e, index < 1); });
|
|
}
|
|
}
|
|
};
|
|
UIEvents.prototype._register_tool = function (tool_view, et, shared) {
|
|
if (shared === void 0) {
|
|
shared = true;
|
|
}
|
|
var v = tool_view;
|
|
var id = v.model.id;
|
|
var conditionally = function (fn) {
|
|
return function (arg) {
|
|
if (arg.id == id)
|
|
fn(arg.e);
|
|
};
|
|
};
|
|
var unconditionally = function (fn) {
|
|
return function (arg) {
|
|
fn(arg.e);
|
|
};
|
|
};
|
|
switch (et) {
|
|
case "pan": {
|
|
if (v._pan_start != null)
|
|
v.connect(this.pan_start, conditionally(v._pan_start.bind(v)));
|
|
if (v._pan != null)
|
|
v.connect(this.pan, conditionally(v._pan.bind(v)));
|
|
if (v._pan_end != null)
|
|
v.connect(this.pan_end, conditionally(v._pan_end.bind(v)));
|
|
break;
|
|
}
|
|
case "pinch": {
|
|
if (v._pinch_start != null)
|
|
v.connect(this.pinch_start, conditionally(v._pinch_start.bind(v)));
|
|
if (v._pinch != null)
|
|
v.connect(this.pinch, conditionally(v._pinch.bind(v)));
|
|
if (v._pinch_end != null)
|
|
v.connect(this.pinch_end, conditionally(v._pinch_end.bind(v)));
|
|
break;
|
|
}
|
|
case "rotate": {
|
|
if (v._rotate_start != null)
|
|
v.connect(this.rotate_start, conditionally(v._rotate_start.bind(v)));
|
|
if (v._rotate != null)
|
|
v.connect(this.rotate, conditionally(v._rotate.bind(v)));
|
|
if (v._rotate_end != null)
|
|
v.connect(this.rotate_end, conditionally(v._rotate_end.bind(v)));
|
|
break;
|
|
}
|
|
case "move": {
|
|
if (v._move_enter != null)
|
|
v.connect(this.move_enter, conditionally(v._move_enter.bind(v)));
|
|
if (v._move != null)
|
|
v.connect(this.move, conditionally(v._move.bind(v)));
|
|
if (v._move_exit != null)
|
|
v.connect(this.move_exit, conditionally(v._move_exit.bind(v)));
|
|
break;
|
|
}
|
|
case "tap": {
|
|
if (v._tap != null)
|
|
v.connect(this.tap, conditionally(v._tap.bind(v)));
|
|
break;
|
|
}
|
|
case "press": {
|
|
if (v._press != null)
|
|
v.connect(this.press, conditionally(v._press.bind(v)));
|
|
break;
|
|
}
|
|
case "scroll": {
|
|
if (v._scroll != null)
|
|
v.connect(this.scroll, conditionally(v._scroll.bind(v)));
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("unsupported event_type: " + et);
|
|
}
|
|
// Skip shared events if registering multi-tool
|
|
if (!shared)
|
|
return;
|
|
if (v._doubletap != null)
|
|
v.connect(this.doubletap, unconditionally(v._doubletap.bind(v)));
|
|
if (v._keydown != null)
|
|
v.connect(this.keydown, unconditionally(v._keydown.bind(v)));
|
|
if (v._keyup != null)
|
|
v.connect(this.keyup, unconditionally(v._keyup.bind(v)));
|
|
// Dual touch hack part 1/2
|
|
// This is a hack for laptops with touch screen who may be pinching or scrolling
|
|
// in order to use the wheel zoom tool. If it's a touch screen the WheelZoomTool event
|
|
// will be linked to pinch. But we also want to trigger in the case of a scroll.
|
|
if (compat_1.is_mobile && v._scroll != null && et == 'pinch') {
|
|
logging_1.logger.debug("Registering scroll on touch screen");
|
|
v.connect(this.scroll, conditionally(v._scroll.bind(v)));
|
|
}
|
|
};
|
|
UIEvents.prototype._hit_test_renderers = function (sx, sy) {
|
|
var views = this.plot_view.get_renderer_views();
|
|
for (var _i = 0, _a = array_1.reversed(views); _i < _a.length; _i++) {
|
|
var view = _a[_i];
|
|
var level = view.model.level;
|
|
if ((level == 'annotation' || level == 'overlay') && view.interactive_hit != null) {
|
|
if (view.interactive_hit(sx, sy))
|
|
return view;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
UIEvents.prototype._hit_test_frame = function (sx, sy) {
|
|
return this.plot_view.frame.bbox.contains(sx, sy);
|
|
};
|
|
UIEvents.prototype._hit_test_canvas = function (sx, sy) {
|
|
return this.plot_view.layout.bbox.contains(sx, sy);
|
|
};
|
|
UIEvents.prototype._trigger = function (signal, e, srcEvent) {
|
|
var _this = this;
|
|
var gestures = this.toolbar.gestures;
|
|
var event_type = signal.name;
|
|
var base_type = event_type.split(":")[0];
|
|
var view = this._hit_test_renderers(e.sx, e.sy);
|
|
var on_canvas = this._hit_test_canvas(e.sx, e.sy);
|
|
switch (base_type) {
|
|
case "move": {
|
|
var active_gesture = gestures[base_type].active;
|
|
if (active_gesture != null)
|
|
this.trigger(signal, e, active_gesture.id);
|
|
var active_inspectors = this.toolbar.inspectors.filter(function (t) { return t.active; });
|
|
var cursor = "default";
|
|
// the event happened on a renderer
|
|
if (view != null) {
|
|
cursor = view.cursor(e.sx, e.sy) || cursor;
|
|
if (!object_1.isEmpty(active_inspectors)) {
|
|
// override event_type to cause inspectors to clear overlays
|
|
signal = this.move_exit; // XXX
|
|
event_type = signal.name;
|
|
}
|
|
// the event happened on the plot frame but off a renderer
|
|
}
|
|
else if (this._hit_test_frame(e.sx, e.sy)) {
|
|
if (!object_1.isEmpty(active_inspectors)) {
|
|
cursor = "crosshair";
|
|
}
|
|
}
|
|
this.plot_view.set_cursor(cursor);
|
|
this.plot_view.set_toolbar_visibility(on_canvas);
|
|
active_inspectors.map(function (inspector) { return _this.trigger(signal, e, inspector.id); });
|
|
break;
|
|
}
|
|
case "tap": {
|
|
var target = srcEvent.target;
|
|
if (target != null && target != this.hit_area)
|
|
return; // don't trigger bokeh events
|
|
if (view != null && view.on_hit != null)
|
|
view.on_hit(e.sx, e.sy);
|
|
var active_gesture = gestures[base_type].active;
|
|
if (active_gesture != null)
|
|
this.trigger(signal, e, active_gesture.id);
|
|
break;
|
|
}
|
|
case "scroll": {
|
|
// Dual touch hack part 2/2
|
|
// This is a hack for laptops with touch screen who may be pinching or scrolling
|
|
// in order to use the wheel zoom tool. If it's a touch screen the WheelZoomTool event
|
|
// will be linked to pinch. But we also want to trigger in the case of a scroll.
|
|
var base = compat_1.is_mobile ? "pinch" : "scroll";
|
|
var active_gesture = gestures[base].active;
|
|
if (active_gesture != null) {
|
|
srcEvent.preventDefault();
|
|
srcEvent.stopPropagation();
|
|
this.trigger(signal, e, active_gesture.id);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
var active_gesture = gestures[base_type].active;
|
|
if (active_gesture != null)
|
|
this.trigger(signal, e, active_gesture.id);
|
|
}
|
|
}
|
|
this._trigger_bokeh_event(e);
|
|
};
|
|
UIEvents.prototype.trigger = function (signal, e, id) {
|
|
if (id === void 0) {
|
|
id = null;
|
|
}
|
|
signal.emit({ id: id, e: e });
|
|
};
|
|
UIEvents.prototype._trigger_bokeh_event = function (e) {
|
|
var _this = this;
|
|
var ev = (function () {
|
|
var xscale = _this.plot_view.frame.xscales.default;
|
|
var yscale = _this.plot_view.frame.yscales.default;
|
|
var sx = e.sx, sy = e.sy;
|
|
var x = xscale.invert(sx);
|
|
var y = yscale.invert(sy);
|
|
switch (e.type) {
|
|
case "wheel":
|
|
return new events.MouseWheel(sx, sy, x, y, e.delta);
|
|
case "mousemove":
|
|
return new events.MouseMove(sx, sy, x, y);
|
|
case "mouseenter":
|
|
return new events.MouseEnter(sx, sy, x, y);
|
|
case "mouseleave":
|
|
return new events.MouseLeave(sx, sy, x, y);
|
|
case "tap":
|
|
return new events.Tap(sx, sy, x, y);
|
|
case "doubletap":
|
|
return new events.DoubleTap(sx, sy, x, y);
|
|
case "press":
|
|
return new events.Press(sx, sy, x, y);
|
|
case "pan":
|
|
return new events.Pan(sx, sy, x, y, e.deltaX, e.deltaY);
|
|
case "panstart":
|
|
return new events.PanStart(sx, sy, x, y);
|
|
case "panend":
|
|
return new events.PanEnd(sx, sy, x, y);
|
|
case "pinch":
|
|
return new events.Pinch(sx, sy, x, y, e.scale);
|
|
case "pinchstart":
|
|
return new events.PinchStart(sx, sy, x, y);
|
|
case "pinchend":
|
|
return new events.PinchEnd(sx, sy, x, y);
|
|
default:
|
|
throw new Error("unreachable");
|
|
}
|
|
})();
|
|
this.plot_view.model.trigger_event(ev);
|
|
};
|
|
UIEvents.prototype._get_sxy = function (event) {
|
|
// XXX: jsdom doesn't support TouchEvent constructor
|
|
function is_touch(event) {
|
|
return typeof TouchEvent !== "undefined" && event instanceof TouchEvent;
|
|
}
|
|
var _a = is_touch(event) ? (event.touches.length != 0 ? event.touches : event.changedTouches)[0] : event, pageX = _a.pageX, pageY = _a.pageY;
|
|
var _b = dom_1.offset(this.hit_area), left = _b.left, top = _b.top;
|
|
return {
|
|
sx: pageX - left,
|
|
sy: pageY - top,
|
|
};
|
|
};
|
|
UIEvents.prototype._gesture_event = function (e) {
|
|
return tslib_1.__assign({ type: e.type }, this._get_sxy(e.srcEvent), { deltaX: e.deltaX, deltaY: e.deltaY, scale: e.scale, shiftKey: e.srcEvent.shiftKey });
|
|
};
|
|
UIEvents.prototype._tap_event = function (e) {
|
|
return tslib_1.__assign({ type: e.type }, this._get_sxy(e.srcEvent), { shiftKey: e.srcEvent.shiftKey });
|
|
};
|
|
UIEvents.prototype._move_event = function (e) {
|
|
return tslib_1.__assign({ type: e.type }, this._get_sxy(e));
|
|
};
|
|
UIEvents.prototype._scroll_event = function (e) {
|
|
return tslib_1.__assign({ type: e.type }, this._get_sxy(e), { delta: wheel_1.getDeltaY(e) });
|
|
};
|
|
UIEvents.prototype._key_event = function (e) {
|
|
return {
|
|
type: e.type,
|
|
keyCode: e.keyCode,
|
|
};
|
|
};
|
|
UIEvents.prototype._pan_start = function (e) {
|
|
var ev = this._gesture_event(e);
|
|
// back out delta to get original center point
|
|
ev.sx -= e.deltaX;
|
|
ev.sy -= e.deltaY;
|
|
this._trigger(this.pan_start, ev, e.srcEvent);
|
|
};
|
|
UIEvents.prototype._pan = function (e) {
|
|
this._trigger(this.pan, this._gesture_event(e), e.srcEvent);
|
|
};
|
|
UIEvents.prototype._pan_end = function (e) {
|
|
this._trigger(this.pan_end, this._gesture_event(e), e.srcEvent);
|
|
};
|
|
UIEvents.prototype._pinch_start = function (e) {
|
|
this._trigger(this.pinch_start, this._gesture_event(e), e.srcEvent);
|
|
};
|
|
UIEvents.prototype._pinch = function (e) {
|
|
this._trigger(this.pinch, this._gesture_event(e), e.srcEvent);
|
|
};
|
|
UIEvents.prototype._pinch_end = function (e) {
|
|
this._trigger(this.pinch_end, this._gesture_event(e), e.srcEvent);
|
|
};
|
|
UIEvents.prototype._rotate_start = function (e) {
|
|
this._trigger(this.rotate_start, this._gesture_event(e), e.srcEvent);
|
|
};
|
|
UIEvents.prototype._rotate = function (e) {
|
|
this._trigger(this.rotate, this._gesture_event(e), e.srcEvent);
|
|
};
|
|
UIEvents.prototype._rotate_end = function (e) {
|
|
this._trigger(this.rotate_end, this._gesture_event(e), e.srcEvent);
|
|
};
|
|
UIEvents.prototype._tap = function (e) {
|
|
this._trigger(this.tap, this._tap_event(e), e.srcEvent);
|
|
};
|
|
UIEvents.prototype._doubletap = function (e) {
|
|
// NOTE: doubletap event triggered unconditionally
|
|
var ev = this._tap_event(e);
|
|
this._trigger_bokeh_event(ev);
|
|
this.trigger(this.doubletap, ev);
|
|
};
|
|
UIEvents.prototype._press = function (e) {
|
|
this._trigger(this.press, this._tap_event(e), e.srcEvent);
|
|
};
|
|
UIEvents.prototype._mouse_enter = function (e) {
|
|
this._trigger(this.move_enter, this._move_event(e), e);
|
|
};
|
|
UIEvents.prototype._mouse_move = function (e) {
|
|
this._trigger(this.move, this._move_event(e), e);
|
|
};
|
|
UIEvents.prototype._mouse_exit = function (e) {
|
|
this._trigger(this.move_exit, this._move_event(e), e);
|
|
};
|
|
UIEvents.prototype._mouse_wheel = function (e) {
|
|
this._trigger(this.scroll, this._scroll_event(e), e);
|
|
};
|
|
UIEvents.prototype._key_down = function (e) {
|
|
// NOTE: keyup event triggered unconditionally
|
|
this.trigger(this.keydown, this._key_event(e));
|
|
};
|
|
UIEvents.prototype._key_up = function (e) {
|
|
// NOTE: keyup event triggered unconditionally
|
|
this.trigger(this.keyup, this._key_event(e));
|
|
};
|
|
return UIEvents;
|
|
}());
|
|
exports.UIEvents = UIEvents;
|
|
}
|
|
,
|
|
/* core/util/array */ function _(require, module, exports) {
|
|
var math_1 = require(34) /* ./math */;
|
|
var assert_1 = require(26) /* ./assert */;
|
|
var arrayable_1 = require(25) /* ./arrayable */;
|
|
exports.min = arrayable_1.min;
|
|
exports.min_by = arrayable_1.min_by;
|
|
exports.max = arrayable_1.max;
|
|
exports.max_by = arrayable_1.max_by;
|
|
exports.sum = arrayable_1.sum;
|
|
exports.every = arrayable_1.every;
|
|
exports.some = arrayable_1.some;
|
|
exports.find = arrayable_1.find;
|
|
exports.find_last = arrayable_1.find_last;
|
|
exports.find_index = arrayable_1.find_index;
|
|
exports.find_last_index = arrayable_1.find_last_index;
|
|
exports.sorted_index = arrayable_1.sorted_index;
|
|
var slice = Array.prototype.slice;
|
|
function head(array) {
|
|
return array[0];
|
|
}
|
|
exports.head = head;
|
|
function tail(array) {
|
|
return array[array.length - 1];
|
|
}
|
|
exports.tail = tail;
|
|
function last(array) {
|
|
return array[array.length - 1];
|
|
}
|
|
exports.last = last;
|
|
function copy(array) {
|
|
return slice.call(array);
|
|
}
|
|
exports.copy = copy;
|
|
function concat(arrays) {
|
|
var _a;
|
|
return (_a = []).concat.apply(_a, arrays);
|
|
}
|
|
exports.concat = concat;
|
|
function includes(array, value) {
|
|
return array.indexOf(value) !== -1;
|
|
}
|
|
exports.includes = includes;
|
|
exports.contains = includes;
|
|
function nth(array, index) {
|
|
return array[index >= 0 ? index : array.length + index];
|
|
}
|
|
exports.nth = nth;
|
|
function zip() {
|
|
var arrays = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
arrays[_i] = arguments[_i];
|
|
}
|
|
if (arrays.length == 0)
|
|
return [];
|
|
var n = arrayable_1.min(arrays.map(function (a) { return a.length; }));
|
|
var k = arrays.length;
|
|
var result = new Array(n);
|
|
for (var i = 0; i < n; i++) {
|
|
result[i] = new Array(k);
|
|
for (var j = 0; j < k; j++)
|
|
result[i][j] = arrays[j][i];
|
|
}
|
|
return result;
|
|
}
|
|
exports.zip = zip;
|
|
function unzip(array) {
|
|
var n = array.length;
|
|
var k = arrayable_1.min(array.map(function (a) { return a.length; }));
|
|
var results = Array(k);
|
|
for (var j = 0; j < k; j++)
|
|
results[j] = new Array(n);
|
|
for (var i = 0; i < n; i++) {
|
|
for (var j = 0; j < k; j++)
|
|
results[j][i] = array[i][j];
|
|
}
|
|
return results;
|
|
}
|
|
exports.unzip = unzip;
|
|
function range(start, stop, step) {
|
|
if (step === void 0) {
|
|
step = 1;
|
|
}
|
|
assert_1.assert(step > 0, "'step' must be a positive number");
|
|
if (stop == null) {
|
|
stop = start;
|
|
start = 0;
|
|
}
|
|
var max = Math.max, ceil = Math.ceil, abs = Math.abs;
|
|
var delta = start <= stop ? step : -step;
|
|
var length = max(ceil(abs(stop - start) / step), 0);
|
|
var range = Array(length);
|
|
for (var i = 0; i < length; i++, start += delta) {
|
|
range[i] = start;
|
|
}
|
|
return range;
|
|
}
|
|
exports.range = range;
|
|
function linspace(start, stop, num) {
|
|
if (num === void 0) {
|
|
num = 100;
|
|
}
|
|
var step = (stop - start) / (num - 1);
|
|
var array = new Array(num);
|
|
for (var i = 0; i < num; i++) {
|
|
array[i] = start + step * i;
|
|
}
|
|
return array;
|
|
}
|
|
exports.linspace = linspace;
|
|
function transpose(array) {
|
|
var rows = array.length;
|
|
var cols = array[0].length;
|
|
var transposed = [];
|
|
for (var j = 0; j < cols; j++) {
|
|
transposed[j] = [];
|
|
for (var i = 0; i < rows; i++) {
|
|
transposed[j][i] = array[i][j];
|
|
}
|
|
}
|
|
return transposed;
|
|
}
|
|
exports.transpose = transpose;
|
|
function cumsum(array) {
|
|
var result = [];
|
|
array.reduce(function (a, b, i) { return result[i] = a + b; }, 0);
|
|
return result;
|
|
}
|
|
exports.cumsum = cumsum;
|
|
function argmin(array) {
|
|
return arrayable_1.min_by(range(array.length), function (i) { return array[i]; });
|
|
}
|
|
exports.argmin = argmin;
|
|
function argmax(array) {
|
|
return arrayable_1.max_by(range(array.length), function (i) { return array[i]; });
|
|
}
|
|
exports.argmax = argmax;
|
|
function sort_by(array, key) {
|
|
var tmp = array.map(function (value, index) {
|
|
return { value: value, index: index, key: key(value) };
|
|
});
|
|
tmp.sort(function (left, right) {
|
|
var a = left.key;
|
|
var b = right.key;
|
|
if (a !== b) {
|
|
if (a > b || a === undefined)
|
|
return 1;
|
|
if (a < b || b === undefined)
|
|
return -1;
|
|
}
|
|
return left.index - right.index;
|
|
});
|
|
return tmp.map(function (item) { return item.value; });
|
|
}
|
|
exports.sort_by = sort_by;
|
|
function uniq(array) {
|
|
var result = [];
|
|
for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
|
|
var value = array_1[_i];
|
|
if (!includes(result, value)) {
|
|
result.push(value);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
exports.uniq = uniq;
|
|
function uniq_by(array, key) {
|
|
var result = [];
|
|
var seen = [];
|
|
for (var _i = 0, array_2 = array; _i < array_2.length; _i++) {
|
|
var value = array_2[_i];
|
|
var computed = key(value);
|
|
if (!includes(seen, computed)) {
|
|
seen.push(computed);
|
|
result.push(value);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
exports.uniq_by = uniq_by;
|
|
function union() {
|
|
var arrays = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
arrays[_i] = arguments[_i];
|
|
}
|
|
return uniq(concat(arrays));
|
|
}
|
|
exports.union = union;
|
|
function intersection(array) {
|
|
var arrays = [];
|
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
arrays[_i - 1] = arguments[_i];
|
|
}
|
|
var result = [];
|
|
top: for (var _a = 0, array_3 = array; _a < array_3.length; _a++) {
|
|
var item = array_3[_a];
|
|
if (includes(result, item))
|
|
continue;
|
|
for (var _b = 0, arrays_1 = arrays; _b < arrays_1.length; _b++) {
|
|
var other = arrays_1[_b];
|
|
if (!includes(other, item))
|
|
continue top;
|
|
}
|
|
result.push(item);
|
|
}
|
|
return result;
|
|
}
|
|
exports.intersection = intersection;
|
|
function difference(array) {
|
|
var arrays = [];
|
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
arrays[_i - 1] = arguments[_i];
|
|
}
|
|
var rest = concat(arrays);
|
|
return array.filter(function (value) { return !includes(rest, value); });
|
|
}
|
|
exports.difference = difference;
|
|
function remove_at(array, i) {
|
|
var result = copy(array);
|
|
result.splice(i, 1);
|
|
return result;
|
|
}
|
|
exports.remove_at = remove_at;
|
|
function remove_by(array, key) {
|
|
for (var i = 0; i < array.length;) {
|
|
if (key(array[i]))
|
|
array.splice(i, 1);
|
|
else
|
|
i++;
|
|
}
|
|
}
|
|
exports.remove_by = remove_by;
|
|
// Shuffle a collection, using the modern version of the
|
|
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
|
|
function shuffle(array) {
|
|
var length = array.length;
|
|
var shuffled = new Array(length);
|
|
for (var i = 0; i < length; i++) {
|
|
var rand = math_1.randomIn(0, i);
|
|
if (rand !== i)
|
|
shuffled[i] = shuffled[rand];
|
|
shuffled[rand] = array[i];
|
|
}
|
|
return shuffled;
|
|
}
|
|
exports.shuffle = shuffle;
|
|
function pairwise(array, fn) {
|
|
var n = array.length;
|
|
var result = new Array(n - 1);
|
|
for (var i = 0; i < n - 1; i++) {
|
|
result[i] = fn(array[i], array[i + 1]);
|
|
}
|
|
return result;
|
|
}
|
|
exports.pairwise = pairwise;
|
|
function reversed(array) {
|
|
var n = array.length;
|
|
var result = new Array(n);
|
|
for (var i = 0; i < n; i++) {
|
|
result[n - i - 1] = array[i];
|
|
}
|
|
return result;
|
|
}
|
|
exports.reversed = reversed;
|
|
function repeat(value, n) {
|
|
var result = new Array(n);
|
|
for (var i = 0; i < n; i++) {
|
|
result[i] = value;
|
|
}
|
|
return result;
|
|
}
|
|
exports.repeat = repeat;
|
|
}
|
|
,
|
|
/* core/util/arrayable */ function _(require, module, exports) {
|
|
function splice(array, start, k) {
|
|
var items = [];
|
|
for (var _i = 3; _i < arguments.length; _i++) {
|
|
items[_i - 3] = arguments[_i];
|
|
}
|
|
var len = array.length;
|
|
if (start < 0)
|
|
start += len;
|
|
if (start < 0)
|
|
start = 0;
|
|
else if (start > len)
|
|
start = len;
|
|
if (k == null || k > len - start)
|
|
k = len - start;
|
|
else if (k < 0)
|
|
k = 0;
|
|
var n = len - k + items.length;
|
|
var result = new array.constructor(n);
|
|
var i = 0;
|
|
for (; i < start; i++) {
|
|
result[i] = array[i];
|
|
}
|
|
for (var _a = 0, items_1 = items; _a < items_1.length; _a++) {
|
|
var item = items_1[_a];
|
|
result[i++] = item;
|
|
}
|
|
for (var j = start + k; j < len; j++) {
|
|
result[i++] = array[j];
|
|
}
|
|
return result;
|
|
}
|
|
exports.splice = splice;
|
|
function insert(array, item, i) {
|
|
return splice(array, i, 0, item);
|
|
}
|
|
exports.insert = insert;
|
|
function append(array, item) {
|
|
return splice(array, array.length, 0, item);
|
|
}
|
|
exports.append = append;
|
|
function prepend(array, item) {
|
|
return splice(array, 0, 0, item);
|
|
}
|
|
exports.prepend = prepend;
|
|
function indexOf(array, item) {
|
|
for (var i = 0, n = array.length; i < n; i++) {
|
|
if (array[i] === item)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
exports.indexOf = indexOf;
|
|
function map(array, fn) {
|
|
var n = array.length;
|
|
var result = new array.constructor(n);
|
|
for (var i = 0; i < n; i++) {
|
|
result[i] = fn(array[i], i, array);
|
|
}
|
|
return result;
|
|
}
|
|
exports.map = map;
|
|
function min(array) {
|
|
var value;
|
|
var result = Infinity;
|
|
for (var i = 0, length_1 = array.length; i < length_1; i++) {
|
|
value = array[i];
|
|
if (value < result) {
|
|
result = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
exports.min = min;
|
|
function min_by(array, key) {
|
|
if (array.length == 0)
|
|
throw new Error("min_by() called with an empty array");
|
|
var result = array[0];
|
|
var resultComputed = key(result);
|
|
for (var i = 1, length_2 = array.length; i < length_2; i++) {
|
|
var value = array[i];
|
|
var computed = key(value);
|
|
if (computed < resultComputed) {
|
|
result = value;
|
|
resultComputed = computed;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
exports.min_by = min_by;
|
|
function max(array) {
|
|
var value;
|
|
var result = -Infinity;
|
|
for (var i = 0, length_3 = array.length; i < length_3; i++) {
|
|
value = array[i];
|
|
if (value > result) {
|
|
result = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
exports.max = max;
|
|
function max_by(array, key) {
|
|
if (array.length == 0)
|
|
throw new Error("max_by() called with an empty array");
|
|
var result = array[0];
|
|
var resultComputed = key(result);
|
|
for (var i = 1, length_4 = array.length; i < length_4; i++) {
|
|
var value = array[i];
|
|
var computed = key(value);
|
|
if (computed > resultComputed) {
|
|
result = value;
|
|
resultComputed = computed;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
exports.max_by = max_by;
|
|
function sum(array) {
|
|
var result = 0;
|
|
for (var i = 0, n = array.length; i < n; i++) {
|
|
result += array[i];
|
|
}
|
|
return result;
|
|
}
|
|
exports.sum = sum;
|
|
function every(array, predicate) {
|
|
for (var i = 0, length_5 = array.length; i < length_5; i++) {
|
|
if (!predicate(array[i]))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
exports.every = every;
|
|
function some(array, predicate) {
|
|
for (var i = 0, length_6 = array.length; i < length_6; i++) {
|
|
if (predicate(array[i]))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
exports.some = some;
|
|
function index_of(array, value) {
|
|
for (var i = 0, length_7 = array.length; i < length_7; i++) {
|
|
if (array[i] === value)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
exports.index_of = index_of;
|
|
function _find_index(dir) {
|
|
return function (array, predicate) {
|
|
var length = array.length;
|
|
var index = dir > 0 ? 0 : length - 1;
|
|
for (; index >= 0 && index < length; index += dir) {
|
|
if (predicate(array[index]))
|
|
return index;
|
|
}
|
|
return -1;
|
|
};
|
|
}
|
|
exports.find_index = _find_index(1);
|
|
exports.find_last_index = _find_index(-1);
|
|
function find(array, predicate) {
|
|
var index = exports.find_index(array, predicate);
|
|
return index == -1 ? undefined : array[index];
|
|
}
|
|
exports.find = find;
|
|
function find_last(array, predicate) {
|
|
var index = exports.find_last_index(array, predicate);
|
|
return index == -1 ? undefined : array[index];
|
|
}
|
|
exports.find_last = find_last;
|
|
function sorted_index(array, value) {
|
|
var low = 0;
|
|
var high = array.length;
|
|
while (low < high) {
|
|
var mid = Math.floor((low + high) / 2);
|
|
if (array[mid] < value)
|
|
low = mid + 1;
|
|
else
|
|
high = mid;
|
|
}
|
|
return low;
|
|
}
|
|
exports.sorted_index = sorted_index;
|
|
}
|
|
,
|
|
/* core/util/assert */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var AssertionError = /** @class */ (function (_super) {
|
|
tslib_1.__extends(AssertionError, _super);
|
|
function AssertionError() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return AssertionError;
|
|
}(Error));
|
|
exports.AssertionError = AssertionError;
|
|
function assert(condition, message) {
|
|
if (condition === true || (condition !== false && condition()))
|
|
return;
|
|
throw new AssertionError(message || "Assertion failed");
|
|
}
|
|
exports.assert = assert;
|
|
}
|
|
,
|
|
/* core/util/bbox */ function _(require, module, exports) {
|
|
var min = Math.min, max = Math.max;
|
|
function empty() {
|
|
return {
|
|
minX: Infinity,
|
|
minY: Infinity,
|
|
maxX: -Infinity,
|
|
maxY: -Infinity,
|
|
};
|
|
}
|
|
exports.empty = empty;
|
|
function positive_x() {
|
|
return {
|
|
minX: Number.MIN_VALUE,
|
|
minY: -Infinity,
|
|
maxX: Infinity,
|
|
maxY: Infinity,
|
|
};
|
|
}
|
|
exports.positive_x = positive_x;
|
|
function positive_y() {
|
|
return {
|
|
minX: -Infinity,
|
|
minY: Number.MIN_VALUE,
|
|
maxX: Infinity,
|
|
maxY: Infinity,
|
|
};
|
|
}
|
|
exports.positive_y = positive_y;
|
|
function union(a, b) {
|
|
return {
|
|
minX: min(a.minX, b.minX),
|
|
maxX: max(a.maxX, b.maxX),
|
|
minY: min(a.minY, b.minY),
|
|
maxY: max(a.maxY, b.maxY),
|
|
};
|
|
}
|
|
exports.union = union;
|
|
var BBox = /** @class */ (function () {
|
|
function BBox(box) {
|
|
if (box == null) {
|
|
this.x0 = 0;
|
|
this.y0 = 0;
|
|
this.x1 = 0;
|
|
this.y1 = 0;
|
|
}
|
|
else if ('x0' in box) {
|
|
var _a = box, x0 = _a.x0, y0 = _a.y0, x1 = _a.x1, y1 = _a.y1;
|
|
if (!(x0 <= x1 && y0 <= y1))
|
|
throw new Error("invalid bbox {x0: " + x0 + ", y0: " + y0 + ", x1: " + x1 + ", y1: " + y1 + "}");
|
|
this.x0 = x0;
|
|
this.y0 = y0;
|
|
this.x1 = x1;
|
|
this.y1 = y1;
|
|
}
|
|
else if ("x" in box) {
|
|
var _b = box, left = _b.left, top_1 = _b.top, width = _b.width, height = _b.height;
|
|
if (!(width >= 0 && height >= 0))
|
|
throw new Error("invalid bbox {left: " + left + ", top: " + top_1 + ", width: " + width + ", height: " + height + "}");
|
|
this.x0 = left;
|
|
this.y0 = top_1;
|
|
this.x1 = left + width;
|
|
this.y1 = top_1 + height;
|
|
}
|
|
else {
|
|
var left = void 0, right = void 0;
|
|
var top_2, bottom = void 0;
|
|
if ("width" in box) {
|
|
if ("left" in box) {
|
|
left = box.left;
|
|
right = left + box.width;
|
|
}
|
|
else if ("right" in box) {
|
|
right = box.right;
|
|
left = right - box.width;
|
|
}
|
|
else {
|
|
var w2 = box.width / 2;
|
|
left = box.hcenter - w2;
|
|
right = box.hcenter + w2;
|
|
}
|
|
}
|
|
else {
|
|
left = box.left;
|
|
right = box.right;
|
|
}
|
|
if ("height" in box) {
|
|
if ("top" in box) {
|
|
top_2 = box.top;
|
|
bottom = top_2 + box.height;
|
|
}
|
|
else if ("bottom" in box) {
|
|
bottom = box.bottom;
|
|
top_2 = bottom - box.height;
|
|
}
|
|
else {
|
|
var h2 = box.height / 2;
|
|
top_2 = box.vcenter - h2;
|
|
bottom = box.vcenter + h2;
|
|
}
|
|
}
|
|
else {
|
|
top_2 = box.top;
|
|
bottom = box.bottom;
|
|
}
|
|
if (!(left <= right && top_2 <= bottom))
|
|
throw new Error("invalid bbox {left: " + left + ", top: " + top_2 + ", right: " + right + ", bottom: " + bottom + "}");
|
|
this.x0 = left;
|
|
this.y0 = top_2;
|
|
this.x1 = right;
|
|
this.y1 = bottom;
|
|
}
|
|
}
|
|
BBox.prototype.toString = function () {
|
|
return "BBox({left: " + this.left + ", top: " + this.top + ", width: " + this.width + ", height: " + this.height + "})";
|
|
};
|
|
Object.defineProperty(BBox.prototype, "minX", {
|
|
get: function () { return this.x0; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "minY", {
|
|
get: function () { return this.y0; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "maxX", {
|
|
get: function () { return this.x1; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "maxY", {
|
|
get: function () { return this.y1; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "left", {
|
|
get: function () { return this.x0; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "top", {
|
|
get: function () { return this.y0; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "right", {
|
|
get: function () { return this.x1; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "bottom", {
|
|
get: function () { return this.y1; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "p0", {
|
|
get: function () { return [this.x0, this.y0]; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "p1", {
|
|
get: function () { return [this.x1, this.y1]; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "x", {
|
|
get: function () { return this.x0; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "y", {
|
|
get: function () { return this.y0; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "width", {
|
|
get: function () { return this.x1 - this.x0; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "height", {
|
|
get: function () { return this.y1 - this.y0; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "rect", {
|
|
get: function () { return { left: this.left, top: this.top, width: this.width, height: this.height }; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "h_range", {
|
|
get: function () { return { start: this.x0, end: this.x1 }; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "v_range", {
|
|
get: function () { return { start: this.y0, end: this.y1 }; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "ranges", {
|
|
get: function () { return [this.h_range, this.v_range]; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "aspect", {
|
|
get: function () { return this.width / this.height; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "hcenter", {
|
|
get: function () { return (this.left + this.right) / 2; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "vcenter", {
|
|
get: function () { return (this.top + this.bottom) / 2; },
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
BBox.prototype.contains = function (x, y) {
|
|
return x >= this.x0 && x <= this.x1 && y >= this.y0 && y <= this.y1;
|
|
};
|
|
BBox.prototype.clip = function (x, y) {
|
|
if (x < this.x0)
|
|
x = this.x0;
|
|
else if (x > this.x1)
|
|
x = this.x1;
|
|
if (y < this.y0)
|
|
y = this.y0;
|
|
else if (y > this.y1)
|
|
y = this.y1;
|
|
return [x, y];
|
|
};
|
|
BBox.prototype.union = function (that) {
|
|
return new BBox({
|
|
x0: min(this.x0, that.x0),
|
|
y0: min(this.y0, that.y0),
|
|
x1: max(this.x1, that.x1),
|
|
y1: max(this.y1, that.y1),
|
|
});
|
|
};
|
|
BBox.prototype.equals = function (that) {
|
|
return this.x0 == that.x0 && this.y0 == that.y0 && this.x1 == that.x1 && this.y1 == that.y1;
|
|
};
|
|
Object.defineProperty(BBox.prototype, "xview", {
|
|
get: function () {
|
|
var _this = this;
|
|
return {
|
|
compute: function (x) {
|
|
return _this.left + x;
|
|
},
|
|
v_compute: function (xx) {
|
|
var _xx = new Float64Array(xx.length);
|
|
var left = _this.left;
|
|
for (var i = 0; i < xx.length; i++) {
|
|
_xx[i] = left + xx[i];
|
|
}
|
|
return _xx;
|
|
},
|
|
};
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BBox.prototype, "yview", {
|
|
get: function () {
|
|
var _this = this;
|
|
return {
|
|
compute: function (y) {
|
|
return _this.bottom - y;
|
|
},
|
|
v_compute: function (yy) {
|
|
var _yy = new Float64Array(yy.length);
|
|
var bottom = _this.bottom;
|
|
for (var i = 0; i < yy.length; i++) {
|
|
_yy[i] = bottom - yy[i];
|
|
}
|
|
return _yy;
|
|
},
|
|
};
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return BBox;
|
|
}());
|
|
exports.BBox = BBox;
|
|
}
|
|
,
|
|
/* core/util/callback */ function _(require, module, exports) {
|
|
function delay(func, wait) {
|
|
return setTimeout(func, wait);
|
|
}
|
|
exports.delay = delay;
|
|
var _defer = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setImmediate;
|
|
function defer(func) {
|
|
return _defer(func);
|
|
}
|
|
exports.defer = defer;
|
|
function throttle(func, wait, options) {
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
var context, args, result;
|
|
var timeout = null;
|
|
var previous = 0;
|
|
var later = function () {
|
|
previous = options.leading === false ? 0 : Date.now();
|
|
timeout = null;
|
|
result = func.apply(context, args);
|
|
if (!timeout)
|
|
context = args = null;
|
|
};
|
|
return function () {
|
|
var now = Date.now();
|
|
if (!previous && options.leading === false)
|
|
previous = now;
|
|
var remaining = wait - (now - previous);
|
|
context = this;
|
|
args = arguments;
|
|
if (remaining <= 0 || remaining > wait) {
|
|
if (timeout) {
|
|
clearTimeout(timeout);
|
|
timeout = null;
|
|
}
|
|
previous = now;
|
|
result = func.apply(context, args);
|
|
if (!timeout)
|
|
context = args = null;
|
|
}
|
|
else if (!timeout && options.trailing !== false) {
|
|
timeout = setTimeout(later, remaining);
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
exports.throttle = throttle;
|
|
function once(func) {
|
|
var done = false;
|
|
var memo;
|
|
return function () {
|
|
if (!done) {
|
|
done = true;
|
|
memo = func();
|
|
}
|
|
return memo;
|
|
};
|
|
}
|
|
exports.once = once;
|
|
}
|
|
,
|
|
/* core/util/canvas */ function _(require, module, exports) {
|
|
function fixup_line_dash(ctx) {
|
|
if (!ctx.setLineDash) {
|
|
ctx.setLineDash = function (dash) {
|
|
ctx.mozDash = dash;
|
|
ctx.webkitLineDash = dash;
|
|
};
|
|
}
|
|
if (!ctx.getLineDash) {
|
|
ctx.getLineDash = function () {
|
|
return ctx.mozDash;
|
|
};
|
|
}
|
|
}
|
|
function fixup_line_dash_offset(ctx) {
|
|
ctx.setLineDashOffset = function (offset) {
|
|
ctx.lineDashOffset = offset;
|
|
ctx.mozDashOffset = offset;
|
|
ctx.webkitLineDashOffset = offset;
|
|
};
|
|
ctx.getLineDashOffset = function () {
|
|
return ctx.mozDashOffset;
|
|
};
|
|
}
|
|
function fixup_image_smoothing(ctx) {
|
|
ctx.setImageSmoothingEnabled = function (value) {
|
|
ctx.imageSmoothingEnabled = value;
|
|
ctx.mozImageSmoothingEnabled = value;
|
|
ctx.oImageSmoothingEnabled = value;
|
|
ctx.webkitImageSmoothingEnabled = value;
|
|
ctx.msImageSmoothingEnabled = value;
|
|
};
|
|
ctx.getImageSmoothingEnabled = function () {
|
|
var val = ctx.imageSmoothingEnabled;
|
|
return val != null ? val : true;
|
|
};
|
|
}
|
|
function fixup_measure_text(ctx) {
|
|
if (ctx.measureText && ctx.html5MeasureText == null) {
|
|
ctx.html5MeasureText = ctx.measureText;
|
|
ctx.measureText = function (text) {
|
|
var textMetrics = ctx.html5MeasureText(text);
|
|
// fake it til you make it
|
|
textMetrics.ascent = ctx.html5MeasureText("m").width * 1.6;
|
|
return textMetrics;
|
|
};
|
|
}
|
|
}
|
|
function fixup_ellipse(ctx) {
|
|
// implementing the ctx.ellipse function with bezier curves
|
|
// we don't implement the startAngle, endAngle and anticlockwise arguments.
|
|
function ellipse_bezier(x, y, radiusX, radiusY, rotation, _startAngle, _endAngle, anticlockwise) {
|
|
if (anticlockwise === void 0) {
|
|
anticlockwise = false;
|
|
}
|
|
var c = 0.551784; // see http://www.tinaja.com/glib/ellipse4.pdf
|
|
ctx.translate(x, y);
|
|
ctx.rotate(rotation);
|
|
var rx = radiusX;
|
|
var ry = radiusY;
|
|
if (anticlockwise) {
|
|
rx = -radiusX;
|
|
ry = -radiusY;
|
|
}
|
|
ctx.moveTo(-rx, 0); // start point of first curve
|
|
ctx.bezierCurveTo(-rx, ry * c, -rx * c, ry, 0, ry);
|
|
ctx.bezierCurveTo(rx * c, ry, rx, ry * c, rx, 0);
|
|
ctx.bezierCurveTo(rx, -ry * c, rx * c, -ry, 0, -ry);
|
|
ctx.bezierCurveTo(-rx * c, -ry, -rx, -ry * c, -rx, 0);
|
|
ctx.rotate(-rotation);
|
|
ctx.translate(-x, -y);
|
|
}
|
|
if (!ctx.ellipse)
|
|
ctx.ellipse = ellipse_bezier;
|
|
}
|
|
function fixup_ctx(ctx) {
|
|
fixup_line_dash(ctx);
|
|
fixup_line_dash_offset(ctx);
|
|
fixup_image_smoothing(ctx);
|
|
fixup_measure_text(ctx);
|
|
fixup_ellipse(ctx);
|
|
}
|
|
exports.fixup_ctx = fixup_ctx;
|
|
function get_scale_ratio(ctx, hidpi, backend) {
|
|
if (backend == "svg")
|
|
return 1;
|
|
else if (hidpi) {
|
|
var devicePixelRatio_1 = window.devicePixelRatio || 1;
|
|
var backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
|
|
ctx.mozBackingStorePixelRatio ||
|
|
ctx.msBackingStorePixelRatio ||
|
|
ctx.oBackingStorePixelRatio ||
|
|
ctx.backingStorePixelRatio || 1;
|
|
return devicePixelRatio_1 / backingStoreRatio;
|
|
}
|
|
else
|
|
return 1;
|
|
}
|
|
exports.get_scale_ratio = get_scale_ratio;
|
|
}
|
|
,
|
|
/* core/util/color */ function _(require, module, exports) {
|
|
var svg_colors_1 = require(41) /* ./svg_colors */;
|
|
var array_1 = require(24) /* ./array */;
|
|
function is_color(value) {
|
|
return svg_colors_1.is_svg_color(value.toLowerCase()) || value.substring(0, 1) == "#" || valid_rgb(value);
|
|
}
|
|
exports.is_color = is_color;
|
|
function _component2hex(v) {
|
|
var h = Number(v).toString(16);
|
|
return h.length == 1 ? "0" + h : h;
|
|
}
|
|
function rgb2hex(r, g, b) {
|
|
var R = _component2hex(r & 0xFF);
|
|
var G = _component2hex(g & 0xFF);
|
|
var B = _component2hex(b & 0xFF);
|
|
return "#" + R + G + B;
|
|
}
|
|
exports.rgb2hex = rgb2hex;
|
|
function color2hex(color) {
|
|
color = color + '';
|
|
if (color.indexOf('#') == 0)
|
|
return color;
|
|
else if (svg_colors_1.is_svg_color(color))
|
|
return svg_colors_1.svg_colors[color];
|
|
else if (color.indexOf('rgb') == 0) {
|
|
var rgb = color.replace(/^rgba?\(|\s+|\)$/g, '').split(',');
|
|
var hex = rgb.slice(0, 3).map(_component2hex).join('');
|
|
if (rgb.length == 4)
|
|
hex += _component2hex(Math.floor(parseFloat(rgb[3]) * 255));
|
|
return "#" + hex.slice(0, 8); // can also be rgba
|
|
}
|
|
else
|
|
return color;
|
|
}
|
|
exports.color2hex = color2hex;
|
|
function color2rgba(color, alpha) {
|
|
if (alpha === void 0) {
|
|
alpha = 1.0;
|
|
}
|
|
if (!color) // NaN, null, '', etc.
|
|
return [0, 0, 0, 0]; // transparent
|
|
// Convert to hex and then to clean version of 6 or 8 chars
|
|
var hex = color2hex(color);
|
|
hex = hex.replace(/ |#/g, '');
|
|
if (hex.length <= 4) {
|
|
hex = hex.replace(/(.)/g, '$1$1');
|
|
}
|
|
// Convert pairs to numbers
|
|
var rgba = hex.match(/../g).map(function (i) { return parseInt(i, 16) / 255; });
|
|
// Ensure correct length, add alpha if necessary
|
|
while (rgba.length < 3)
|
|
rgba.push(0);
|
|
if (rgba.length < 4)
|
|
rgba.push(alpha);
|
|
return rgba.slice(0, 4);
|
|
}
|
|
exports.color2rgba = color2rgba;
|
|
function valid_rgb(value) {
|
|
var params;
|
|
switch (value.substring(0, 4)) {
|
|
case "rgba": {
|
|
params = { start: "rgba(", len: 4, alpha: true };
|
|
break;
|
|
}
|
|
case "rgb(": {
|
|
params = { start: "rgb(", len: 3, alpha: false };
|
|
break;
|
|
}
|
|
default:
|
|
return false;
|
|
}
|
|
// if '.' and then ',' found, we know decimals are used on rgb
|
|
if (new RegExp(".*?(\\.).*(,)").test(value))
|
|
throw new Error("color expects integers for rgb in rgb/rgba tuple, received " + value);
|
|
// extract the numerical values from inside parens
|
|
var contents = value.replace(params.start, "").replace(")", "").split(',').map(parseFloat);
|
|
// check length of array based on rgb/rgba
|
|
if (contents.length != params.len)
|
|
throw new Error("color expects rgba " + params.len + "-tuple, received " + value);
|
|
// check for valid numerical values for rgba
|
|
if (params.alpha && !(0 <= contents[3] && contents[3] <= 1))
|
|
throw new Error("color expects rgba 4-tuple to have alpha value between 0 and 1");
|
|
if (array_1.includes(contents.slice(0, 3).map(function (rgb) { return 0 <= rgb && rgb <= 255; }), false))
|
|
throw new Error("color expects rgb to have value between 0 and 255");
|
|
return true;
|
|
}
|
|
exports.valid_rgb = valid_rgb;
|
|
}
|
|
,
|
|
/* core/util/compat */ function _(require, module, exports) {
|
|
exports.is_ie = (function () {
|
|
var ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
|
|
return ua.indexOf('MSIE') >= 0 || ua.indexOf('Trident') > 0 || ua.indexOf('Edge') > 0;
|
|
})();
|
|
exports.is_mobile = (function () {
|
|
return typeof window !== "undefined" && ("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
})();
|
|
exports.is_little_endian = (function () {
|
|
var buf = new ArrayBuffer(4);
|
|
var buf8 = new Uint8Array(buf);
|
|
var buf32 = new Uint32Array(buf);
|
|
buf32[1] = 0x0a0b0c0d;
|
|
var little_endian = true;
|
|
if (buf8[4] == 0x0a && buf8[5] == 0x0b && buf8[6] == 0x0c && buf8[7] == 0x0d) {
|
|
little_endian = false;
|
|
}
|
|
return little_endian;
|
|
})();
|
|
}
|
|
,
|
|
/* core/util/data_structures */ function _(require, module, exports) {
|
|
var array_1 = require(24) /* ./array */;
|
|
var eq_1 = require(33) /* ./eq */;
|
|
var types_1 = require(46) /* ./types */;
|
|
var MultiDict = /** @class */ (function () {
|
|
function MultiDict() {
|
|
this._dict = {};
|
|
}
|
|
MultiDict.prototype._existing = function (key) {
|
|
if (key in this._dict)
|
|
return this._dict[key];
|
|
else
|
|
return null;
|
|
};
|
|
MultiDict.prototype.add_value = function (key, value) {
|
|
/*
|
|
if value == null
|
|
throw new Error("Can't put null in this dict")
|
|
if isArray(value)
|
|
throw new Error("Can't put arrays in this dict")
|
|
*/
|
|
var existing = this._existing(key);
|
|
if (existing == null) {
|
|
this._dict[key] = value;
|
|
}
|
|
else if (types_1.isArray(existing)) {
|
|
existing.push(value);
|
|
}
|
|
else {
|
|
this._dict[key] = [existing, value];
|
|
}
|
|
};
|
|
MultiDict.prototype.remove_value = function (key, value) {
|
|
var existing = this._existing(key);
|
|
if (types_1.isArray(existing)) {
|
|
var new_array = array_1.difference(existing, [value]);
|
|
if (new_array.length > 0)
|
|
this._dict[key] = new_array;
|
|
else
|
|
delete this._dict[key];
|
|
}
|
|
else if (eq_1.isEqual(existing, value)) {
|
|
delete this._dict[key];
|
|
}
|
|
};
|
|
MultiDict.prototype.get_one = function (key, duplicate_error) {
|
|
var existing = this._existing(key);
|
|
if (types_1.isArray(existing)) {
|
|
if (existing.length === 1)
|
|
return existing[0];
|
|
else
|
|
throw new Error(duplicate_error);
|
|
}
|
|
else
|
|
return existing;
|
|
};
|
|
return MultiDict;
|
|
}());
|
|
exports.MultiDict = MultiDict;
|
|
var Set = /** @class */ (function () {
|
|
function Set(obj) {
|
|
if (obj == null)
|
|
this._values = [];
|
|
else if (obj instanceof Set)
|
|
this._values = array_1.copy(obj._values);
|
|
else {
|
|
this._values = [];
|
|
for (var _i = 0, obj_1 = obj; _i < obj_1.length; _i++) {
|
|
var item = obj_1[_i];
|
|
this.add(item);
|
|
}
|
|
}
|
|
}
|
|
Object.defineProperty(Set.prototype, "values", {
|
|
get: function () {
|
|
return array_1.copy(this._values).sort();
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Set.prototype.toString = function () {
|
|
return "Set([" + this.values.join(",") + "])";
|
|
};
|
|
Object.defineProperty(Set.prototype, "size", {
|
|
get: function () {
|
|
return this._values.length;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Set.prototype.has = function (item) {
|
|
return this._values.indexOf(item) !== -1;
|
|
};
|
|
Set.prototype.add = function (item) {
|
|
if (!this.has(item))
|
|
this._values.push(item);
|
|
};
|
|
Set.prototype.remove = function (item) {
|
|
var i = this._values.indexOf(item);
|
|
if (i !== -1)
|
|
this._values.splice(i, 1);
|
|
};
|
|
Set.prototype.toggle = function (item) {
|
|
var i = this._values.indexOf(item);
|
|
if (i === -1)
|
|
this._values.push(item);
|
|
else
|
|
this._values.splice(i, 1);
|
|
};
|
|
Set.prototype.clear = function () {
|
|
this._values = [];
|
|
};
|
|
Set.prototype.union = function (input) {
|
|
input = new Set(input);
|
|
return new Set(this._values.concat(input._values));
|
|
};
|
|
Set.prototype.intersect = function (input) {
|
|
input = new Set(input);
|
|
var output = new Set();
|
|
for (var _i = 0, _a = input._values; _i < _a.length; _i++) {
|
|
var item = _a[_i];
|
|
if (this.has(item) && input.has(item))
|
|
output.add(item);
|
|
}
|
|
return output;
|
|
};
|
|
Set.prototype.diff = function (input) {
|
|
input = new Set(input);
|
|
var output = new Set();
|
|
for (var _i = 0, _a = this._values; _i < _a.length; _i++) {
|
|
var item = _a[_i];
|
|
if (!input.has(item))
|
|
output.add(item);
|
|
}
|
|
return output;
|
|
};
|
|
Set.prototype.forEach = function (fn, thisArg) {
|
|
for (var _i = 0, _a = this._values; _i < _a.length; _i++) {
|
|
var value = _a[_i];
|
|
fn.call(thisArg || this, value, value, this);
|
|
}
|
|
};
|
|
return Set;
|
|
}());
|
|
exports.Set = Set;
|
|
var Matrix = /** @class */ (function () {
|
|
function Matrix(nrows, ncols, init) {
|
|
this.nrows = nrows;
|
|
this.ncols = ncols;
|
|
this._matrix = new Array(nrows);
|
|
for (var y = 0; y < nrows; y++) {
|
|
this._matrix[y] = new Array(ncols);
|
|
for (var x = 0; x < ncols; x++) {
|
|
this._matrix[y][x] = init(y, x);
|
|
}
|
|
}
|
|
}
|
|
Matrix.prototype.at = function (row, col) {
|
|
return this._matrix[row][col];
|
|
};
|
|
Matrix.prototype.map = function (fn) {
|
|
var _this = this;
|
|
return new Matrix(this.nrows, this.ncols, function (row, col) { return fn(_this.at(row, col), row, col); });
|
|
};
|
|
Matrix.prototype.apply = function (obj) {
|
|
var _this = this;
|
|
var fn = Matrix.from(obj);
|
|
var _a = this, nrows = _a.nrows, ncols = _a.ncols;
|
|
if (nrows == fn.nrows && ncols == fn.ncols)
|
|
return new Matrix(nrows, ncols, function (row, col) { return fn.at(row, col)(_this.at(row, col), row, col); });
|
|
else
|
|
throw new Error("dimensions don't match");
|
|
};
|
|
Matrix.prototype.to_sparse = function () {
|
|
var items = [];
|
|
for (var y = 0; y < this.nrows; y++) {
|
|
for (var x = 0; x < this.ncols; x++) {
|
|
var value = this._matrix[y][x];
|
|
items.push([value, y, x]);
|
|
}
|
|
}
|
|
return items;
|
|
};
|
|
Matrix.from = function (obj) {
|
|
if (obj instanceof Matrix)
|
|
return obj;
|
|
else {
|
|
var nrows = obj.length;
|
|
var ncols = array_1.min(obj.map(function (row) { return row.length; }));
|
|
return new Matrix(nrows, ncols, function (row, col) { return obj[row][col]; });
|
|
}
|
|
};
|
|
return Matrix;
|
|
}());
|
|
exports.Matrix = Matrix;
|
|
}
|
|
,
|
|
/* core/util/eq */ function _(require, module, exports) {
|
|
var types_1 = require(46) /* ./types */;
|
|
var toString = Object.prototype.toString;
|
|
// Internal recursive comparison function for `isEqual`.
|
|
function eq(a, b, aStack, bStack) {
|
|
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
|
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
|
|
if (a === b)
|
|
return a !== 0 || 1 / a === 1 / b;
|
|
// A strict comparison is necessary because `null == undefined`.
|
|
if (a == null || b == null)
|
|
return a === b;
|
|
// Compare `[[Class]]` names.
|
|
var className = toString.call(a);
|
|
if (className !== toString.call(b))
|
|
return false;
|
|
switch (className) {
|
|
// Strings, numbers, regular expressions, dates, and booleans are compared by value.
|
|
case '[object RegExp]':
|
|
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
|
|
case '[object String]':
|
|
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
|
|
// equivalent to `new String("5")`.
|
|
return '' + a === '' + b;
|
|
case '[object Number]':
|
|
// `NaN`s are equivalent, but non-reflexive.
|
|
// Object(NaN) is equivalent to NaN
|
|
if (+a !== +a)
|
|
return +b !== +b;
|
|
// An `egal` comparison is performed for other numeric values.
|
|
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
|
|
case '[object Date]':
|
|
case '[object Boolean]':
|
|
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
|
|
// millisecond representations. Note that invalid dates with millisecond representations
|
|
// of `NaN` are not equivalent.
|
|
return +a === +b;
|
|
}
|
|
var areArrays = className === '[object Array]';
|
|
if (!areArrays) {
|
|
if (typeof a != 'object' || typeof b != 'object')
|
|
return false;
|
|
// Objects with different constructors are not equivalent, but `Object`s or `Array`s
|
|
// from different frames are.
|
|
var aCtor = a.constructor, bCtor = b.constructor;
|
|
if (aCtor !== bCtor && !(types_1.isFunction(aCtor) && aCtor instanceof aCtor &&
|
|
types_1.isFunction(bCtor) && bCtor instanceof bCtor)
|
|
&& ('constructor' in a && 'constructor' in b)) {
|
|
return false;
|
|
}
|
|
}
|
|
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
|
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
|
// Initializing stack of traversed objects.
|
|
// It's done here since we only need them for objects and arrays comparison.
|
|
aStack = aStack || [];
|
|
bStack = bStack || [];
|
|
var length = aStack.length;
|
|
while (length--) {
|
|
// Linear search. Performance is inversely proportional to the number of
|
|
// unique nested structures.
|
|
if (aStack[length] === a)
|
|
return bStack[length] === b;
|
|
}
|
|
// Add the first object to the stack of traversed objects.
|
|
aStack.push(a);
|
|
bStack.push(b);
|
|
// Recursively compare objects and arrays.
|
|
if (areArrays) {
|
|
// Compare array lengths to determine if a deep comparison is necessary.
|
|
length = a.length;
|
|
if (length !== b.length)
|
|
return false;
|
|
// Deep compare the contents, ignoring non-numeric properties.
|
|
while (length--) {
|
|
if (!eq(a[length], b[length], aStack, bStack))
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
// Deep compare objects.
|
|
var keys = Object.keys(a);
|
|
var key = void 0;
|
|
length = keys.length;
|
|
// Ensure that both objects contain the same number of properties before comparing deep equality.
|
|
if (Object.keys(b).length !== length)
|
|
return false;
|
|
while (length--) {
|
|
// Deep compare each member
|
|
key = keys[length];
|
|
if (!(b.hasOwnProperty(key) && eq(a[key], b[key], aStack, bStack)))
|
|
return false;
|
|
}
|
|
}
|
|
// Remove the first object from the stack of traversed objects.
|
|
aStack.pop();
|
|
bStack.pop();
|
|
return true;
|
|
}
|
|
// Perform a deep comparison to check if two objects are equal.
|
|
function isEqual(a, b) {
|
|
return eq(a, b);
|
|
}
|
|
exports.isEqual = isEqual;
|
|
}
|
|
,
|
|
/* core/util/math */ function _(require, module, exports) {
|
|
function angle_norm(angle) {
|
|
while (angle < 0) {
|
|
angle += 2 * Math.PI;
|
|
}
|
|
while (angle > 2 * Math.PI) {
|
|
angle -= 2 * Math.PI;
|
|
}
|
|
return angle;
|
|
}
|
|
exports.angle_norm = angle_norm;
|
|
function angle_dist(lhs, rhs) {
|
|
return Math.abs(angle_norm(lhs - rhs));
|
|
}
|
|
exports.angle_dist = angle_dist;
|
|
function angle_between(mid, lhs, rhs, direction) {
|
|
var d = angle_dist(lhs, rhs);
|
|
if (d == 0)
|
|
return false;
|
|
var norm_mid = angle_norm(mid);
|
|
var cond = angle_dist(lhs, norm_mid) <= d && angle_dist(norm_mid, rhs) <= d;
|
|
return (direction == 0 /* clock */) ? cond : !cond;
|
|
}
|
|
exports.angle_between = angle_between;
|
|
function random() {
|
|
return Math.random();
|
|
}
|
|
exports.random = random;
|
|
function randomIn(min, max) {
|
|
if (max == null) {
|
|
max = min;
|
|
min = 0;
|
|
}
|
|
return min + Math.floor(Math.random() * (max - min + 1));
|
|
}
|
|
exports.randomIn = randomIn;
|
|
function atan2(start, end) {
|
|
/*
|
|
* Calculate the angle between a line containing start and end points (composed
|
|
* of [x, y] arrays) and the positive x-axis.
|
|
*/
|
|
return Math.atan2(end[1] - start[1], end[0] - start[0]);
|
|
}
|
|
exports.atan2 = atan2;
|
|
// http://www2.econ.osaka-u.ac.jp/~tanizaki/class/2013/econome3/13.pdf (Page 432)
|
|
function rnorm(mu, sigma) {
|
|
// Generate a random normal with a mean of 0 and a sigma of 1
|
|
var r1;
|
|
var r2;
|
|
while (true) {
|
|
r1 = random();
|
|
r2 = random();
|
|
r2 = (2 * r2 - 1) * Math.sqrt(2 * (1 / Math.E));
|
|
if (-4 * r1 * r1 * Math.log(r1) >= r2 * r2)
|
|
break;
|
|
}
|
|
var rn = r2 / r1;
|
|
// Transform the standard normal to meet the characteristics that we want (mu, sigma)
|
|
rn = mu + sigma * rn;
|
|
return rn;
|
|
}
|
|
exports.rnorm = rnorm;
|
|
function clamp(val, min, max) {
|
|
if (val > max)
|
|
return max;
|
|
if (val < min)
|
|
return min;
|
|
return val;
|
|
}
|
|
exports.clamp = clamp;
|
|
}
|
|
,
|
|
/* core/util/object */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var array_1 = require(24) /* ./array */;
|
|
exports.keys = Object.keys;
|
|
function values(object) {
|
|
var keys = Object.keys(object);
|
|
var length = keys.length;
|
|
var values = new Array(length);
|
|
for (var i = 0; i < length; i++) {
|
|
values[i] = object[keys[i]];
|
|
}
|
|
return values;
|
|
}
|
|
exports.values = values;
|
|
function extend(dest, src) {
|
|
return tslib_1.__assign(dest, src);
|
|
}
|
|
exports.extend = extend;
|
|
function clone(obj) {
|
|
return extend({}, obj); // XXX: can't use {...obj} due to https://github.com/Microsoft/TypeScript/issues/14409
|
|
}
|
|
exports.clone = clone;
|
|
function merge(obj1, obj2) {
|
|
/*
|
|
* Returns an object with the array values for obj1 and obj2 unioned by key.
|
|
*/
|
|
var result = Object.create(Object.prototype);
|
|
var keys = array_1.concat([Object.keys(obj1), Object.keys(obj2)]);
|
|
for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
|
|
var key = keys_1[_i];
|
|
var arr1 = obj1.hasOwnProperty(key) ? obj1[key] : [];
|
|
var arr2 = obj2.hasOwnProperty(key) ? obj2[key] : [];
|
|
result[key] = array_1.union(arr1, arr2);
|
|
}
|
|
return result;
|
|
}
|
|
exports.merge = merge;
|
|
function size(obj) {
|
|
return Object.keys(obj).length;
|
|
}
|
|
exports.size = size;
|
|
function isEmpty(obj) {
|
|
return size(obj) === 0;
|
|
}
|
|
exports.isEmpty = isEmpty;
|
|
}
|
|
,
|
|
/* core/util/projections */ function _(require, module, exports) {
|
|
var proj4 = require(383) /* proj4/lib/core */;
|
|
var Projection = require(371) /* proj4/lib/Proj */;
|
|
var mercator = new Projection('GOOGLE');
|
|
var wgs84 = new Projection('WGS84');
|
|
exports.wgs84_mercator = proj4(wgs84, mercator);
|
|
var mercator_bounds = {
|
|
lon: [-20026376.39, 20026376.39],
|
|
lat: [-20048966.10, 20048966.10],
|
|
};
|
|
var latlon_bounds = {
|
|
lon: [-180, 180],
|
|
lat: [-85.06, 85.06],
|
|
};
|
|
function clip_mercator(low, high, dimension) {
|
|
var _a = mercator_bounds[dimension], min = _a[0], max = _a[1];
|
|
return [Math.max(low, min), Math.min(high, max)];
|
|
}
|
|
exports.clip_mercator = clip_mercator;
|
|
function in_bounds(value, dimension) {
|
|
return value > latlon_bounds[dimension][0] && value < latlon_bounds[dimension][1];
|
|
}
|
|
exports.in_bounds = in_bounds;
|
|
function project_xy(x, y) {
|
|
var n = Math.min(x.length, y.length);
|
|
var merc_x_s = new Array(n);
|
|
var merc_y_s = new Array(n);
|
|
for (var i = 0; i < n; i++) {
|
|
var _a = exports.wgs84_mercator.forward([x[i], y[i]]), merc_x = _a[0], merc_y = _a[1];
|
|
merc_x_s[i] = merc_x;
|
|
merc_y_s[i] = merc_y;
|
|
}
|
|
return [merc_x_s, merc_y_s];
|
|
}
|
|
exports.project_xy = project_xy;
|
|
function project_xsys(xs, ys) {
|
|
var n = Math.min(xs.length, ys.length);
|
|
var merc_xs_s = new Array(n);
|
|
var merc_ys_s = new Array(n);
|
|
for (var i = 0; i < n; i++) {
|
|
var _a = project_xy(xs[i], ys[i]), merc_x_s = _a[0], merc_y_s = _a[1];
|
|
merc_xs_s[i] = merc_x_s;
|
|
merc_ys_s[i] = merc_y_s;
|
|
}
|
|
return [merc_xs_s, merc_ys_s];
|
|
}
|
|
exports.project_xsys = project_xsys;
|
|
}
|
|
,
|
|
/* core/util/refs */ function _(require, module, exports) {
|
|
var types_1 = require(46) /* ./types */;
|
|
// Create a Bokeh reference from a HasProps subclass
|
|
//
|
|
// @param obj [HasProps] the object to create a reference for
|
|
// @return [Object] a Bokeh reference for `obj`
|
|
// @throw Error if `obj` is not a HasProps
|
|
//
|
|
function create_ref(obj) {
|
|
var ref = {
|
|
type: obj.type,
|
|
id: obj.id,
|
|
};
|
|
if (obj._subtype != null) {
|
|
ref.subtype = obj._subtype;
|
|
}
|
|
return ref;
|
|
}
|
|
exports.create_ref = create_ref;
|
|
// Determine whether an object has the proper format of a Bokeh reference
|
|
//
|
|
// @param arg [Object] the object to test
|
|
// @return [bool] whether the object is a refererence
|
|
//
|
|
// @note this function does not check that the id and types are valid,
|
|
// only that the format is correct (all required keys are present)
|
|
//
|
|
function is_ref(arg) {
|
|
if (types_1.isObject(arg)) {
|
|
var keys = Object.keys(arg).sort();
|
|
if (keys.length == 2)
|
|
return keys[0] == 'id' && keys[1] == 'type';
|
|
if (keys.length == 3)
|
|
return keys[0] == 'id' && keys[1] == 'subtype' && keys[2] == 'type';
|
|
}
|
|
return false;
|
|
}
|
|
exports.is_ref = is_ref;
|
|
}
|
|
,
|
|
/* core/util/serialization */ function _(require, module, exports) {
|
|
var types_1 = require(46) /* ./types */;
|
|
var compat_1 = require(31) /* ./compat */;
|
|
exports.ARRAY_TYPES = {
|
|
uint8: Uint8Array,
|
|
int8: Int8Array,
|
|
uint16: Uint16Array,
|
|
int16: Int16Array,
|
|
uint32: Uint32Array,
|
|
int32: Int32Array,
|
|
float32: Float32Array,
|
|
float64: Float64Array,
|
|
};
|
|
exports.DTYPES = {
|
|
Uint8Array: "uint8",
|
|
Int8Array: "int8",
|
|
Uint16Array: "uint16",
|
|
Int16Array: "int16",
|
|
Uint32Array: "uint32",
|
|
Int32Array: "int32",
|
|
Float32Array: "float32",
|
|
Float64Array: "float64",
|
|
};
|
|
function arrayName(array) {
|
|
if ("name" in array.constructor)
|
|
return array.constructor.name;
|
|
else {
|
|
switch (true) {
|
|
case array instanceof Uint8Array: return "Uint8Array";
|
|
case array instanceof Int8Array: return "Int8Array";
|
|
case array instanceof Uint16Array: return "Uint16Array";
|
|
case array instanceof Int16Array: return "Int16Array";
|
|
case array instanceof Uint32Array: return "Uint32Array";
|
|
case array instanceof Int32Array: return "Int32Array";
|
|
case array instanceof Float32Array: return "Float32Array";
|
|
case array instanceof Float64Array: return "Float64Array";
|
|
default:
|
|
throw new Error("unsupported typed array");
|
|
}
|
|
}
|
|
}
|
|
exports.BYTE_ORDER = compat_1.is_little_endian ? "little" : "big";
|
|
function swap16(a) {
|
|
var x = new Uint8Array(a.buffer, a.byteOffset, a.length * 2);
|
|
for (var i = 0, end = x.length; i < end; i += 2) {
|
|
var t = x[i];
|
|
x[i] = x[i + 1];
|
|
x[i + 1] = t;
|
|
}
|
|
}
|
|
exports.swap16 = swap16;
|
|
function swap32(a) {
|
|
var x = new Uint8Array(a.buffer, a.byteOffset, a.length * 4);
|
|
for (var i = 0, end = x.length; i < end; i += 4) {
|
|
var t = x[i];
|
|
x[i] = x[i + 3];
|
|
x[i + 3] = t;
|
|
t = x[i + 1];
|
|
x[i + 1] = x[i + 2];
|
|
x[i + 2] = t;
|
|
}
|
|
}
|
|
exports.swap32 = swap32;
|
|
function swap64(a) {
|
|
var x = new Uint8Array(a.buffer, a.byteOffset, a.length * 8);
|
|
for (var i = 0, end = x.length; i < end; i += 8) {
|
|
var t = x[i];
|
|
x[i] = x[i + 7];
|
|
x[i + 7] = t;
|
|
t = x[i + 1];
|
|
x[i + 1] = x[i + 6];
|
|
x[i + 6] = t;
|
|
t = x[i + 2];
|
|
x[i + 2] = x[i + 5];
|
|
x[i + 5] = t;
|
|
t = x[i + 3];
|
|
x[i + 3] = x[i + 4];
|
|
x[i + 4] = t;
|
|
}
|
|
}
|
|
exports.swap64 = swap64;
|
|
function process_buffer(specification, buffers) {
|
|
var need_swap = specification.order !== exports.BYTE_ORDER;
|
|
var shape = specification.shape;
|
|
var bytes = null;
|
|
for (var _i = 0, buffers_1 = buffers; _i < buffers_1.length; _i++) {
|
|
var buf = buffers_1[_i];
|
|
var header = JSON.parse(buf[0]);
|
|
if (header.id === specification.__buffer__) {
|
|
bytes = buf[1];
|
|
break;
|
|
}
|
|
}
|
|
var arr = new (exports.ARRAY_TYPES[specification.dtype])(bytes);
|
|
if (need_swap) {
|
|
if (arr.BYTES_PER_ELEMENT === 2) {
|
|
swap16(arr);
|
|
}
|
|
else if (arr.BYTES_PER_ELEMENT === 4) {
|
|
swap32(arr);
|
|
}
|
|
else if (arr.BYTES_PER_ELEMENT === 8) {
|
|
swap64(arr);
|
|
}
|
|
}
|
|
return [arr, shape];
|
|
}
|
|
exports.process_buffer = process_buffer;
|
|
function process_array(obj, buffers) {
|
|
if (types_1.isObject(obj) && '__ndarray__' in obj)
|
|
return decode_base64(obj);
|
|
else if (types_1.isObject(obj) && '__buffer__' in obj)
|
|
return process_buffer(obj, buffers);
|
|
else if (types_1.isArray(obj) || types_1.isTypedArray(obj))
|
|
return [obj, []];
|
|
else
|
|
return undefined;
|
|
}
|
|
exports.process_array = process_array;
|
|
function arrayBufferToBase64(buffer) {
|
|
var bytes = new Uint8Array(buffer);
|
|
var chars = Array.from(bytes).map(function (b) { return String.fromCharCode(b); });
|
|
return btoa(chars.join(""));
|
|
}
|
|
exports.arrayBufferToBase64 = arrayBufferToBase64;
|
|
function base64ToArrayBuffer(base64) {
|
|
var binary_string = atob(base64);
|
|
var len = binary_string.length;
|
|
var bytes = new Uint8Array(len);
|
|
for (var i = 0, end = len; i < end; i++) {
|
|
bytes[i] = binary_string.charCodeAt(i);
|
|
}
|
|
return bytes.buffer;
|
|
}
|
|
exports.base64ToArrayBuffer = base64ToArrayBuffer;
|
|
function decode_base64(input) {
|
|
var bytes = base64ToArrayBuffer(input.__ndarray__);
|
|
var dtype = input.dtype;
|
|
var shape = input.shape;
|
|
var array;
|
|
if (dtype in exports.ARRAY_TYPES)
|
|
array = new (exports.ARRAY_TYPES[dtype])(bytes);
|
|
else
|
|
throw new Error("unknown dtype: " + dtype);
|
|
return [array, shape];
|
|
}
|
|
exports.decode_base64 = decode_base64;
|
|
function encode_base64(array, shape) {
|
|
var b64 = arrayBufferToBase64(array.buffer);
|
|
var name = arrayName(array);
|
|
var dtype;
|
|
if (name in exports.DTYPES)
|
|
dtype = exports.DTYPES[name];
|
|
else
|
|
throw new Error("unknown array type: " + name);
|
|
var data = {
|
|
__ndarray__: b64,
|
|
shape: shape,
|
|
dtype: dtype,
|
|
};
|
|
return data;
|
|
}
|
|
exports.encode_base64 = encode_base64;
|
|
function decode_traverse_data(v, buffers) {
|
|
// v is just a regular array of scalars
|
|
if (v.length == 0 || !(types_1.isObject(v[0]) || types_1.isArray(v[0]))) {
|
|
return [v, []];
|
|
}
|
|
var arrays = [];
|
|
var shapes = [];
|
|
for (var _i = 0, v_1 = v; _i < v_1.length; _i++) {
|
|
var obj = v_1[_i];
|
|
var _a = types_1.isArray(obj) ? decode_traverse_data(obj, buffers) :
|
|
process_array(obj, buffers), arr = _a[0], shape = _a[1];
|
|
arrays.push(arr);
|
|
shapes.push(shape);
|
|
}
|
|
// If there is a list of empty lists, reduce that to just a list
|
|
var filtered_shapes = shapes.map(function (shape) { return shape.filter(function (v) { return v.length != 0; }); });
|
|
return [arrays, filtered_shapes];
|
|
}
|
|
function decode_column_data(data, buffers) {
|
|
if (buffers === void 0) {
|
|
buffers = [];
|
|
}
|
|
var new_data = {};
|
|
var new_shapes = {};
|
|
for (var k in data) {
|
|
// might be array of scalars, or might be ragged array or arrays
|
|
var v = data[k];
|
|
if (types_1.isArray(v)) {
|
|
// v is just a regular array of scalars
|
|
if (v.length == 0 || !(types_1.isObject(v[0]) || types_1.isArray(v[0]))) {
|
|
new_data[k] = v;
|
|
continue;
|
|
}
|
|
// v is a ragged array of arrays
|
|
var _a = decode_traverse_data(v, buffers), arrays = _a[0], shapes = _a[1];
|
|
new_data[k] = arrays;
|
|
new_shapes[k] = shapes;
|
|
// must be object or array (single array case)
|
|
}
|
|
else {
|
|
var _b = process_array(v, buffers), arr = _b[0], shape = _b[1];
|
|
new_data[k] = arr;
|
|
new_shapes[k] = shape;
|
|
}
|
|
}
|
|
return [new_data, new_shapes];
|
|
}
|
|
exports.decode_column_data = decode_column_data;
|
|
function encode_traverse_data(v, shapes) {
|
|
var new_array = [];
|
|
for (var i = 0, end = v.length; i < end; i++) {
|
|
var item = v[i];
|
|
if (types_1.isTypedArray(item)) {
|
|
var shape = shapes[i] ? shapes[i] : undefined;
|
|
new_array.push(encode_base64(item, shape));
|
|
}
|
|
else if (types_1.isArray(item)) {
|
|
new_array.push(encode_traverse_data(item, shapes ? shapes[i] : []));
|
|
}
|
|
else
|
|
new_array.push(item);
|
|
}
|
|
return new_array;
|
|
}
|
|
function encode_column_data(data, shapes) {
|
|
var new_data = {};
|
|
for (var k in data) {
|
|
var v = data[k];
|
|
var shapes_k = shapes != null ? shapes[k] : undefined;
|
|
var new_v = void 0;
|
|
if (types_1.isTypedArray(v)) {
|
|
new_v = encode_base64(v, shapes_k);
|
|
}
|
|
else if (types_1.isArray(v)) {
|
|
new_v = encode_traverse_data(v, shapes_k || []);
|
|
}
|
|
else
|
|
new_v = v;
|
|
new_data[k] = new_v;
|
|
}
|
|
return new_data;
|
|
}
|
|
exports.encode_column_data = encode_column_data;
|
|
}
|
|
,
|
|
/* core/util/spatial */ function _(require, module, exports) {
|
|
var FlatBush = require(368) /* flatbush */;
|
|
var bbox_1 = require(27) /* ./bbox */;
|
|
var SpatialIndex = /** @class */ (function () {
|
|
function SpatialIndex(points) {
|
|
this.points = points;
|
|
this.index = null;
|
|
if (points.length > 0) {
|
|
this.index = new FlatBush(points.length);
|
|
for (var _i = 0, points_1 = points; _i < points_1.length; _i++) {
|
|
var p = points_1[_i];
|
|
var minX = p.minX, minY = p.minY, maxX = p.maxX, maxY = p.maxY;
|
|
this.index.add(minX, minY, maxX, maxY);
|
|
}
|
|
this.index.finish();
|
|
}
|
|
}
|
|
SpatialIndex.prototype._normalize = function (rect) {
|
|
var _a, _b;
|
|
var minX = rect.minX, minY = rect.minY, maxX = rect.maxX, maxY = rect.maxY;
|
|
if (minX > maxX)
|
|
_a = [maxX, minX], minX = _a[0], maxX = _a[1];
|
|
if (minY > maxY)
|
|
_b = [maxY, minY], minY = _b[0], maxY = _b[1];
|
|
return { minX: minX, minY: minY, maxX: maxX, maxY: maxY };
|
|
};
|
|
Object.defineProperty(SpatialIndex.prototype, "bbox", {
|
|
get: function () {
|
|
if (this.index == null)
|
|
return bbox_1.empty();
|
|
else {
|
|
var _a = this.index, minX = _a.minX, minY = _a.minY, maxX = _a.maxX, maxY = _a.maxY;
|
|
return { minX: minX, minY: minY, maxX: maxX, maxY: maxY };
|
|
}
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
SpatialIndex.prototype.search = function (rect) {
|
|
var _this = this;
|
|
if (this.index == null)
|
|
return [];
|
|
else {
|
|
var _a = this._normalize(rect), minX = _a.minX, minY = _a.minY, maxX = _a.maxX, maxY = _a.maxY;
|
|
var indices = this.index.search(minX, minY, maxX, maxY);
|
|
return indices.map(function (j) { return _this.points[j]; });
|
|
}
|
|
};
|
|
SpatialIndex.prototype.indices = function (rect) {
|
|
return this.search(rect).map(function (_a) {
|
|
var i = _a.i;
|
|
return i;
|
|
});
|
|
};
|
|
return SpatialIndex;
|
|
}());
|
|
exports.SpatialIndex = SpatialIndex;
|
|
}
|
|
,
|
|
/* core/util/string */ function _(require, module, exports) {
|
|
var settings_1 = require(21) /* ../settings */;
|
|
function startsWith(str, searchString, position) {
|
|
if (position === void 0) {
|
|
position = 0;
|
|
}
|
|
return str.substr(position, searchString.length) == searchString;
|
|
}
|
|
exports.startsWith = startsWith;
|
|
function uuid4() {
|
|
// from ipython project
|
|
// http://www.ietf.org/rfc/rfc4122.txt
|
|
var s = new Array(32);
|
|
var hexDigits = "0123456789ABCDEF";
|
|
for (var i = 0; i < 32; i++) {
|
|
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
|
|
}
|
|
s[12] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
|
|
s[16] = hexDigits.substr((s[16].charCodeAt(0) & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
|
|
return s.join("");
|
|
}
|
|
exports.uuid4 = uuid4;
|
|
var counter = 1000;
|
|
function uniqueId(prefix) {
|
|
var id = settings_1.settings.dev ? "j" + counter++ : uuid4();
|
|
if (prefix != null)
|
|
return prefix + "-" + id;
|
|
else
|
|
return id;
|
|
}
|
|
exports.uniqueId = uniqueId;
|
|
function escape(s) {
|
|
return s.replace(/(?:[&<>"'`])/g, function (ch) {
|
|
switch (ch) {
|
|
case '&': return '&';
|
|
case '<': return '<';
|
|
case '>': return '>';
|
|
case '"': return '"';
|
|
case "'": return ''';
|
|
case '`': return '`';
|
|
default: return ch;
|
|
}
|
|
});
|
|
}
|
|
exports.escape = escape;
|
|
function unescape(s) {
|
|
return s.replace(/&(amp|lt|gt|quot|#x27|#x60);/g, function (_, entity) {
|
|
switch (entity) {
|
|
case 'amp': return '&';
|
|
case 'lt': return '<';
|
|
case 'gt': return '>';
|
|
case 'quot': return '"';
|
|
case '#x27': return "'";
|
|
case '#x60': return '`';
|
|
default: return entity;
|
|
}
|
|
});
|
|
}
|
|
exports.unescape = unescape;
|
|
function use_strict(code) {
|
|
return "'use strict';\n" + code;
|
|
}
|
|
exports.use_strict = use_strict;
|
|
}
|
|
,
|
|
/* core/util/svg_colors */ function _(require, module, exports) {
|
|
exports.svg_colors = {
|
|
indianred: "#CD5C5C",
|
|
lightcoral: "#F08080",
|
|
salmon: "#FA8072",
|
|
darksalmon: "#E9967A",
|
|
lightsalmon: "#FFA07A",
|
|
crimson: "#DC143C",
|
|
red: "#FF0000",
|
|
firebrick: "#B22222",
|
|
darkred: "#8B0000",
|
|
pink: "#FFC0CB",
|
|
lightpink: "#FFB6C1",
|
|
hotpink: "#FF69B4",
|
|
deeppink: "#FF1493",
|
|
mediumvioletred: "#C71585",
|
|
palevioletred: "#DB7093",
|
|
coral: "#FF7F50",
|
|
tomato: "#FF6347",
|
|
orangered: "#FF4500",
|
|
darkorange: "#FF8C00",
|
|
orange: "#FFA500",
|
|
gold: "#FFD700",
|
|
yellow: "#FFFF00",
|
|
lightyellow: "#FFFFE0",
|
|
lemonchiffon: "#FFFACD",
|
|
lightgoldenrodyellow: "#FAFAD2",
|
|
papayawhip: "#FFEFD5",
|
|
moccasin: "#FFE4B5",
|
|
peachpuff: "#FFDAB9",
|
|
palegoldenrod: "#EEE8AA",
|
|
khaki: "#F0E68C",
|
|
darkkhaki: "#BDB76B",
|
|
lavender: "#E6E6FA",
|
|
thistle: "#D8BFD8",
|
|
plum: "#DDA0DD",
|
|
violet: "#EE82EE",
|
|
orchid: "#DA70D6",
|
|
fuchsia: "#FF00FF",
|
|
magenta: "#FF00FF",
|
|
mediumorchid: "#BA55D3",
|
|
mediumpurple: "#9370DB",
|
|
blueviolet: "#8A2BE2",
|
|
darkviolet: "#9400D3",
|
|
darkorchid: "#9932CC",
|
|
darkmagenta: "#8B008B",
|
|
purple: "#800080",
|
|
indigo: "#4B0082",
|
|
slateblue: "#6A5ACD",
|
|
darkslateblue: "#483D8B",
|
|
mediumslateblue: "#7B68EE",
|
|
greenyellow: "#ADFF2F",
|
|
chartreuse: "#7FFF00",
|
|
lawngreen: "#7CFC00",
|
|
lime: "#00FF00",
|
|
limegreen: "#32CD32",
|
|
palegreen: "#98FB98",
|
|
lightgreen: "#90EE90",
|
|
mediumspringgreen: "#00FA9A",
|
|
springgreen: "#00FF7F",
|
|
mediumseagreen: "#3CB371",
|
|
seagreen: "#2E8B57",
|
|
forestgreen: "#228B22",
|
|
green: "#008000",
|
|
darkgreen: "#006400",
|
|
yellowgreen: "#9ACD32",
|
|
olivedrab: "#6B8E23",
|
|
olive: "#808000",
|
|
darkolivegreen: "#556B2F",
|
|
mediumaquamarine: "#66CDAA",
|
|
darkseagreen: "#8FBC8F",
|
|
lightseagreen: "#20B2AA",
|
|
darkcyan: "#008B8B",
|
|
teal: "#008080",
|
|
aqua: "#00FFFF",
|
|
cyan: "#00FFFF",
|
|
lightcyan: "#E0FFFF",
|
|
paleturquoise: "#AFEEEE",
|
|
aquamarine: "#7FFFD4",
|
|
turquoise: "#40E0D0",
|
|
mediumturquoise: "#48D1CC",
|
|
darkturquoise: "#00CED1",
|
|
cadetblue: "#5F9EA0",
|
|
steelblue: "#4682B4",
|
|
lightsteelblue: "#B0C4DE",
|
|
powderblue: "#B0E0E6",
|
|
lightblue: "#ADD8E6",
|
|
skyblue: "#87CEEB",
|
|
lightskyblue: "#87CEFA",
|
|
deepskyblue: "#00BFFF",
|
|
dodgerblue: "#1E90FF",
|
|
cornflowerblue: "#6495ED",
|
|
royalblue: "#4169E1",
|
|
blue: "#0000FF",
|
|
mediumblue: "#0000CD",
|
|
darkblue: "#00008B",
|
|
navy: "#000080",
|
|
midnightblue: "#191970",
|
|
cornsilk: "#FFF8DC",
|
|
blanchedalmond: "#FFEBCD",
|
|
bisque: "#FFE4C4",
|
|
navajowhite: "#FFDEAD",
|
|
wheat: "#F5DEB3",
|
|
burlywood: "#DEB887",
|
|
tan: "#D2B48C",
|
|
rosybrown: "#BC8F8F",
|
|
sandybrown: "#F4A460",
|
|
goldenrod: "#DAA520",
|
|
darkgoldenrod: "#B8860B",
|
|
peru: "#CD853F",
|
|
chocolate: "#D2691E",
|
|
saddlebrown: "#8B4513",
|
|
sienna: "#A0522D",
|
|
brown: "#A52A2A",
|
|
maroon: "#800000",
|
|
white: "#FFFFFF",
|
|
snow: "#FFFAFA",
|
|
honeydew: "#F0FFF0",
|
|
mintcream: "#F5FFFA",
|
|
azure: "#F0FFFF",
|
|
aliceblue: "#F0F8FF",
|
|
ghostwhite: "#F8F8FF",
|
|
whitesmoke: "#F5F5F5",
|
|
seashell: "#FFF5EE",
|
|
beige: "#F5F5DC",
|
|
oldlace: "#FDF5E6",
|
|
floralwhite: "#FFFAF0",
|
|
ivory: "#FFFFF0",
|
|
antiquewhite: "#FAEBD7",
|
|
linen: "#FAF0E6",
|
|
lavenderblush: "#FFF0F5",
|
|
mistyrose: "#FFE4E1",
|
|
gainsboro: "#DCDCDC",
|
|
lightgray: "#D3D3D3",
|
|
lightgrey: "#D3D3D3",
|
|
silver: "#C0C0C0",
|
|
darkgray: "#A9A9A9",
|
|
darkgrey: "#A9A9A9",
|
|
gray: "#808080",
|
|
grey: "#808080",
|
|
dimgray: "#696969",
|
|
dimgrey: "#696969",
|
|
lightslategray: "#778899",
|
|
lightslategrey: "#778899",
|
|
slategray: "#708090",
|
|
slategrey: "#708090",
|
|
darkslategray: "#2F4F4F",
|
|
darkslategrey: "#2F4F4F",
|
|
black: "#000000",
|
|
};
|
|
function is_svg_color(color) {
|
|
return color in exports.svg_colors;
|
|
}
|
|
exports.is_svg_color = is_svg_color;
|
|
}
|
|
,
|
|
/* core/util/templating */ function _(require, module, exports) {
|
|
var sprintf_js_1 = require(398) /* sprintf-js */;
|
|
var Numbro = require(370) /* numbro */;
|
|
var tz = require(399) /* timezone */;
|
|
var string_1 = require(40) /* ./string */;
|
|
var types_1 = require(46) /* ./types */;
|
|
function sprintf(format) {
|
|
var args = [];
|
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
args[_i - 1] = arguments[_i];
|
|
}
|
|
return sprintf_js_1.sprintf.apply(void 0, [format].concat(args));
|
|
}
|
|
exports.sprintf = sprintf;
|
|
exports.DEFAULT_FORMATTERS = {
|
|
numeral: function (value, format, _special_vars) { return Numbro.format(value, format); },
|
|
datetime: function (value, format, _special_vars) { return tz(value, format); },
|
|
printf: function (value, format, _special_vars) { return sprintf(format, value); },
|
|
};
|
|
function basic_formatter(value, _format, _special_vars) {
|
|
if (types_1.isNumber(value)) {
|
|
var format = (function () {
|
|
switch (false) {
|
|
case Math.floor(value) != value:
|
|
return "%d";
|
|
case !(Math.abs(value) > 0.1) || !(Math.abs(value) < 1000):
|
|
return "%0.3f";
|
|
default:
|
|
return "%0.3e";
|
|
}
|
|
})();
|
|
return sprintf(format, value);
|
|
}
|
|
else
|
|
return "" + value; // get strings for categorical types
|
|
}
|
|
exports.basic_formatter = basic_formatter;
|
|
function get_formatter(name, raw_spec, format, formatters) {
|
|
// no format, use default built in formatter
|
|
if (format == null)
|
|
return basic_formatter;
|
|
// format spec in the formatters dict, use that
|
|
if (formatters != null && (name in formatters || raw_spec in formatters)) {
|
|
// some day (Bokeh 2.0) we can get rid of the check for name, and just check the raw spec
|
|
// keep it now for compatibility but do not demonstrate it anywhere
|
|
var key = raw_spec in formatters ? raw_spec : name;
|
|
var formatter_1 = formatters[key];
|
|
if (types_1.isString(formatter_1)) {
|
|
if (formatter_1 in exports.DEFAULT_FORMATTERS)
|
|
return exports.DEFAULT_FORMATTERS[formatter_1];
|
|
else
|
|
throw new Error("Unknown tooltip field formatter type '" + formatter_1 + "'");
|
|
}
|
|
return function (value, format, special_vars) {
|
|
return formatter_1.format(value, format, special_vars);
|
|
};
|
|
}
|
|
// otherwise use "numeral" as default
|
|
return exports.DEFAULT_FORMATTERS.numeral;
|
|
}
|
|
exports.get_formatter = get_formatter;
|
|
function get_value(name, data_source, i, special_vars) {
|
|
if (name[0] == "$") {
|
|
if (name.substring(1) in special_vars)
|
|
return special_vars[name.substring(1)];
|
|
else
|
|
throw new Error("Unknown special variable '" + name + "'");
|
|
}
|
|
var column = data_source.get_column(name);
|
|
// missing column
|
|
if (column == null)
|
|
return null;
|
|
// typical (non-image) index
|
|
if (types_1.isNumber(i))
|
|
return column[i];
|
|
// image index
|
|
var data = column[i.index];
|
|
if (types_1.isTypedArray(data) || types_1.isArray(data)) {
|
|
// inspect array of arrays
|
|
if (types_1.isArray(data[0])) {
|
|
var row = data[i.dim2];
|
|
return row[i.dim1];
|
|
}
|
|
else
|
|
return data[i.flat_index]; // inspect flat array
|
|
}
|
|
else
|
|
return data; // inspect per-image scalar data
|
|
}
|
|
exports.get_value = get_value;
|
|
function replace_placeholders(str, data_source, i, formatters, special_vars) {
|
|
if (special_vars === void 0) {
|
|
special_vars = {};
|
|
}
|
|
// this extracts the $x, @x, @{x} without any trailing {format}
|
|
var raw_spec = str.replace(/(?:^|[^@])([@|\$](?:\w+|{[^{}]+}))(?:{[^{}]+})?/g, function (_match, raw_spec, _format) { return "" + raw_spec; });
|
|
// this handles the special case @$name, replacing it with an @var corresponding to special_vars.name
|
|
str = str.replace(/@\$name/g, function (_match) { return "@{" + special_vars.name + "}"; });
|
|
// this prepends special vars with "@", e.g "$x" becomes "@$x", so subsequent processing is simpler
|
|
str = str.replace(/(^|[^\$])\$(\w+)/g, function (_match, prefix, name) { return prefix + "@$" + name; });
|
|
str = str.replace(/(^|[^@])@(?:(\$?\w+)|{([^{}]+)})(?:{([^{}]+)})?/g, function (_match, prefix, name, long_name, format) {
|
|
name = long_name != null ? long_name : name;
|
|
var value = get_value(name, data_source, i, special_vars);
|
|
// missing value, return ???
|
|
if (value == null)
|
|
return "" + prefix + string_1.escape("???");
|
|
// 'safe' format, return the value as-is
|
|
if (format == 'safe')
|
|
return "" + prefix + value;
|
|
// format and escape everything else
|
|
var formatter = get_formatter(name, raw_spec, format, formatters);
|
|
return "" + prefix + string_1.escape(formatter(value, format, special_vars));
|
|
});
|
|
return str;
|
|
}
|
|
exports.replace_placeholders = replace_placeholders;
|
|
}
|
|
,
|
|
/* core/util/text */ function _(require, module, exports) {
|
|
var dom_1 = require(5) /* ../dom */;
|
|
var cache = {};
|
|
function measure_font(font) {
|
|
if (cache[font] != null)
|
|
return cache[font];
|
|
var text = dom_1.span({ style: { font: font } }, "Hg");
|
|
var block = dom_1.div({ style: { display: "inline-block", width: "1px", height: "0px" } });
|
|
var elem = dom_1.div({}, text, block);
|
|
document.body.appendChild(elem);
|
|
try {
|
|
block.style.verticalAlign = "baseline";
|
|
var ascent = dom_1.offset(block).top - dom_1.offset(text).top;
|
|
block.style.verticalAlign = "bottom";
|
|
var height = dom_1.offset(block).top - dom_1.offset(text).top;
|
|
var result = { height: height, ascent: ascent, descent: height - ascent };
|
|
cache[font] = result;
|
|
return result;
|
|
}
|
|
finally {
|
|
document.body.removeChild(elem);
|
|
}
|
|
}
|
|
exports.measure_font = measure_font;
|
|
var _cache = {};
|
|
function measure_text(text, font) {
|
|
var text_cache = _cache[font];
|
|
if (text_cache != null) {
|
|
var size = text_cache[text];
|
|
if (size != null)
|
|
return size;
|
|
}
|
|
else
|
|
_cache[font] = {};
|
|
var el = dom_1.div({ style: { display: "inline-block", "white-space": "nowrap", font: font } }, text);
|
|
document.body.appendChild(el);
|
|
try {
|
|
var _a = el.getBoundingClientRect(), width = _a.width, height = _a.height;
|
|
_cache[font][text] = { width: width, height: height };
|
|
return { width: width, height: height };
|
|
}
|
|
finally {
|
|
document.body.removeChild(el);
|
|
}
|
|
}
|
|
exports.measure_text = measure_text;
|
|
}
|
|
,
|
|
/* core/util/throttle */ function _(require, module, exports) {
|
|
function _delay_animation(callback) {
|
|
callback(Date.now()); // XXX: performance.now()
|
|
return -1;
|
|
}
|
|
var delay_animation = (typeof window !== 'undefined' ? window.requestAnimationFrame : undefined) ||
|
|
(typeof window !== 'undefined' ? window.webkitRequestAnimationFrame : undefined) ||
|
|
(typeof window !== 'undefined' ? window.mozRequestAnimationFrame : undefined) ||
|
|
(typeof window !== 'undefined' ? window.msRequestAnimationFrame : undefined) || _delay_animation;
|
|
// Returns a function, that, when invoked, will only be triggered at
|
|
// most once during a given window of time.
|
|
//
|
|
// In addition, if the browser supports requestAnimationFrame, the
|
|
// throttled function will be run no more frequently than request
|
|
// animation frame allows.
|
|
//
|
|
// @param func [function] the function to throttle
|
|
// @param wait [number] time in milliseconds to use for window
|
|
// @return [function] throttled function
|
|
//
|
|
function throttle(func, wait) {
|
|
var timeout = null;
|
|
var previous = 0;
|
|
var pending = false;
|
|
var later = function () {
|
|
previous = Date.now();
|
|
timeout = null;
|
|
pending = false;
|
|
func();
|
|
};
|
|
return function () {
|
|
var now = Date.now();
|
|
var remaining = wait - (now - previous);
|
|
if (remaining <= 0 && !pending) {
|
|
if (timeout != null)
|
|
clearTimeout(timeout);
|
|
pending = true;
|
|
delay_animation(later);
|
|
}
|
|
else if (!timeout && !pending)
|
|
timeout = setTimeout(function () { return delay_animation(later); }, remaining);
|
|
};
|
|
}
|
|
exports.throttle = throttle;
|
|
}
|
|
,
|
|
/* core/util/typed_array */ function _(require, module, exports) {
|
|
function concat(array0) {
|
|
var arrays = [];
|
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
arrays[_i - 1] = arguments[_i];
|
|
}
|
|
var n = array0.length;
|
|
for (var _a = 0, arrays_1 = arrays; _a < arrays_1.length; _a++) {
|
|
var array = arrays_1[_a];
|
|
n += array.length;
|
|
}
|
|
var result = new array0.constructor(n);
|
|
result.set(array0, 0);
|
|
var i = array0.length;
|
|
for (var _b = 0, arrays_2 = arrays; _b < arrays_2.length; _b++) {
|
|
var array = arrays_2[_b];
|
|
result.set(array, i);
|
|
i += array.length;
|
|
}
|
|
return result;
|
|
}
|
|
exports.concat = concat;
|
|
}
|
|
,
|
|
/* core/util/types */ function _(require, module, exports) {
|
|
var array_1 = require(24) /* ./array */;
|
|
var toString = Object.prototype.toString;
|
|
function isBoolean(obj) {
|
|
return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
|
|
}
|
|
exports.isBoolean = isBoolean;
|
|
function isNumber(obj) {
|
|
return toString.call(obj) === "[object Number]";
|
|
}
|
|
exports.isNumber = isNumber;
|
|
function isInteger(obj) {
|
|
return isNumber(obj) && isFinite(obj) && Math.floor(obj) === obj;
|
|
}
|
|
exports.isInteger = isInteger;
|
|
function isString(obj) {
|
|
return toString.call(obj) === "[object String]";
|
|
}
|
|
exports.isString = isString;
|
|
function isStrictNaN(obj) {
|
|
return isNumber(obj) && obj !== +obj;
|
|
}
|
|
exports.isStrictNaN = isStrictNaN;
|
|
function isFunction(obj) {
|
|
return toString.call(obj) === "[object Function]";
|
|
}
|
|
exports.isFunction = isFunction;
|
|
function isArray(obj) {
|
|
return Array.isArray(obj);
|
|
}
|
|
exports.isArray = isArray;
|
|
function isArrayOf(arr, predicate) {
|
|
return array_1.every(arr, predicate);
|
|
}
|
|
exports.isArrayOf = isArrayOf;
|
|
function isArrayableOf(arr, predicate) {
|
|
for (var i = 0, end = arr.length; i < end; i++) {
|
|
if (!predicate(arr[i]))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
exports.isArrayableOf = isArrayableOf;
|
|
function isTypedArray(obj) {
|
|
return obj != null && obj.buffer != null && obj.buffer instanceof ArrayBuffer;
|
|
}
|
|
exports.isTypedArray = isTypedArray;
|
|
function isObject(obj) {
|
|
var tp = typeof obj;
|
|
return tp === 'function' || tp === 'object' && !!obj;
|
|
}
|
|
exports.isObject = isObject;
|
|
function isPlainObject(obj) {
|
|
return isObject(obj) && (obj.constructor == null || obj.constructor === Object);
|
|
}
|
|
exports.isPlainObject = isPlainObject;
|
|
}
|
|
,
|
|
/* core/util/wheel */ function _(require, module, exports) {
|
|
function fontSize(element) {
|
|
var value = getComputedStyle(element).fontSize;
|
|
if (value != null)
|
|
return parseInt(value, 10);
|
|
return null;
|
|
}
|
|
function lineHeight(element) {
|
|
var parent = element.offsetParent || document.body;
|
|
return fontSize(parent) || fontSize(element) || 16;
|
|
}
|
|
function pageHeight(element) {
|
|
return element.clientHeight; // XXX: should be content height?
|
|
}
|
|
function getDeltaY(event) {
|
|
var deltaY = -event.deltaY;
|
|
if (event.target instanceof HTMLElement) {
|
|
switch (event.deltaMode) {
|
|
case event.DOM_DELTA_LINE:
|
|
deltaY *= lineHeight(event.target);
|
|
break;
|
|
case event.DOM_DELTA_PAGE:
|
|
deltaY *= pageHeight(event.target);
|
|
break;
|
|
}
|
|
}
|
|
return deltaY;
|
|
}
|
|
exports.getDeltaY = getDeltaY;
|
|
}
|
|
,
|
|
/* core/util/zoom */ function _(require, module, exports) {
|
|
var math_1 = require(34) /* ./math */;
|
|
// Module for zoom-related functions
|
|
function scale_highlow(range, factor, center) {
|
|
var _a = [range.start, range.end], low = _a[0], high = _a[1];
|
|
var x = center != null ? center : (high + low) / 2.0;
|
|
var x0 = low - (low - x) * factor;
|
|
var x1 = high - (high - x) * factor;
|
|
return [x0, x1];
|
|
}
|
|
exports.scale_highlow = scale_highlow;
|
|
function get_info(scales, _a) {
|
|
var sxy0 = _a[0], sxy1 = _a[1];
|
|
var info = {};
|
|
for (var name_1 in scales) {
|
|
var scale = scales[name_1];
|
|
var _b = scale.r_invert(sxy0, sxy1), start = _b[0], end = _b[1];
|
|
info[name_1] = { start: start, end: end };
|
|
}
|
|
return info;
|
|
}
|
|
exports.get_info = get_info;
|
|
function scale_range(frame, factor, h_axis, v_axis, center) {
|
|
/*
|
|
* Utility function for zoom tools to calculate/create the zoom_info object
|
|
* of the form required by ``PlotView.update_range``
|
|
*
|
|
* Parameters:
|
|
* frame : CartesianFrame
|
|
* factor : Number
|
|
* h_axis : Boolean, optional
|
|
* whether to zoom the horizontal axis (default = true)
|
|
* v_axis : Boolean, optional
|
|
* whether to zoom the horizontal axis (default = true)
|
|
* center : object, optional
|
|
* of form {'x': Number, 'y', Number}
|
|
*
|
|
* Returns:
|
|
* object:
|
|
*/
|
|
if (h_axis === void 0) {
|
|
h_axis = true;
|
|
}
|
|
if (v_axis === void 0) {
|
|
v_axis = true;
|
|
}
|
|
// clamp the magnitude of factor, if it is > 1 bad things happen
|
|
factor = math_1.clamp(factor, -0.9, 0.9);
|
|
var hfactor = h_axis ? factor : 0;
|
|
var _a = scale_highlow(frame.bbox.h_range, hfactor, center != null ? center.x : undefined), sx0 = _a[0], sx1 = _a[1];
|
|
var xrs = get_info(frame.xscales, [sx0, sx1]);
|
|
var vfactor = v_axis ? factor : 0;
|
|
var _b = scale_highlow(frame.bbox.v_range, vfactor, center != null ? center.y : undefined), sy0 = _b[0], sy1 = _b[1];
|
|
var yrs = get_info(frame.yscales, [sy0, sy1]);
|
|
// OK this sucks we can't set factor independently in each direction. It is used
|
|
// for GMap plots, and GMap plots always preserve aspect, so effective the value
|
|
// of 'dimensions' is ignored.
|
|
return { xrs: xrs, yrs: yrs, factor: factor };
|
|
}
|
|
exports.scale_range = scale_range;
|
|
}
|
|
,
|
|
/* core/vectorization */ function _(require, module, exports) {
|
|
var types_1 = require(46) /* ./util/types */;
|
|
function isValue(obj) {
|
|
return types_1.isPlainObject(obj) && "value" in obj;
|
|
}
|
|
exports.isValue = isValue;
|
|
function isField(obj) {
|
|
return types_1.isPlainObject(obj) && "field" in obj;
|
|
}
|
|
exports.isField = isField;
|
|
}
|
|
,
|
|
/* core/view */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var signaling_1 = require(22) /* ./signaling */;
|
|
var types_1 = require(46) /* ./util/types */;
|
|
var string_1 = require(40) /* ./util/string */;
|
|
var View = /** @class */ (function (_super) {
|
|
tslib_1.__extends(View, _super);
|
|
function View(options) {
|
|
var _this = _super.call(this) || this;
|
|
_this.removed = new signaling_1.Signal0(_this, "removed");
|
|
if (options.model != null)
|
|
_this.model = options.model;
|
|
else
|
|
throw new Error("model of a view wasn't configured");
|
|
_this._parent = options.parent;
|
|
_this.id = options.id || string_1.uniqueId();
|
|
_this.initialize();
|
|
if (options.connect_signals !== false)
|
|
_this.connect_signals();
|
|
return _this;
|
|
}
|
|
View.prototype.initialize = function () { };
|
|
View.prototype.remove = function () {
|
|
this._parent = undefined;
|
|
this.disconnect_signals();
|
|
this.removed.emit();
|
|
};
|
|
View.prototype.toString = function () {
|
|
return this.model.type + "View(" + this.id + ")";
|
|
};
|
|
View.prototype.serializable_state = function () {
|
|
return { type: this.model.type };
|
|
};
|
|
Object.defineProperty(View.prototype, "parent", {
|
|
get: function () {
|
|
if (this._parent !== undefined)
|
|
return this._parent;
|
|
else
|
|
throw new Error("parent of a view wasn't configured");
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(View.prototype, "is_root", {
|
|
get: function () {
|
|
return this.parent === null;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(View.prototype, "root", {
|
|
get: function () {
|
|
return this.is_root ? this : this.parent.root;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
View.prototype.assert_root = function () {
|
|
if (!this.is_root)
|
|
throw new Error(this.toString() + " is not a root layout");
|
|
};
|
|
View.prototype.connect_signals = function () { };
|
|
View.prototype.disconnect_signals = function () {
|
|
signaling_1.Signal.disconnectReceiver(this);
|
|
};
|
|
View.prototype.on_change = function (properties, fn) {
|
|
for (var _i = 0, _a = types_1.isArray(properties) ? properties : [properties]; _i < _a.length; _i++) {
|
|
var property = _a[_i];
|
|
this.connect(property.change, fn);
|
|
}
|
|
};
|
|
return View;
|
|
}(signaling_1.Signalable()));
|
|
exports.View = View;
|
|
}
|
|
,
|
|
/* core/visuals */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var mixins = require(19) /* ./property_mixins */;
|
|
var color_1 = require(30) /* ./util/color */;
|
|
var ContextProperties = /** @class */ (function () {
|
|
function ContextProperties(obj, prefix) {
|
|
if (prefix === void 0) {
|
|
prefix = "";
|
|
}
|
|
this.obj = obj;
|
|
this.prefix = prefix;
|
|
// }
|
|
this.cache = {};
|
|
for (var _i = 0, _a = this.attrs; _i < _a.length; _i++) {
|
|
var attr = _a[_i];
|
|
this[attr] = obj.properties[prefix + attr];
|
|
}
|
|
}
|
|
ContextProperties.prototype.warm_cache = function (source) {
|
|
for (var _i = 0, _a = this.attrs; _i < _a.length; _i++) {
|
|
var attr = _a[_i];
|
|
var prop = this.obj.properties[this.prefix + attr];
|
|
if (prop.spec.value !== undefined) // TODO (bev) better test?
|
|
this.cache[attr] = prop.spec.value;
|
|
else if (source != null)
|
|
this.cache[attr + "_array"] = prop.array(source);
|
|
else
|
|
throw new Error("source is required with a vectorized visual property");
|
|
}
|
|
};
|
|
ContextProperties.prototype.cache_select = function (attr, i) {
|
|
var prop = this.obj.properties[this.prefix + attr];
|
|
var value;
|
|
if (prop.spec.value !== undefined) // TODO (bev) better test?
|
|
this.cache[attr] = value = prop.spec.value;
|
|
else
|
|
this.cache[attr] = value = this.cache[attr + "_array"][i];
|
|
return value;
|
|
};
|
|
ContextProperties.prototype.set_vectorize = function (ctx, i) {
|
|
if (this.all_indices != null) // all_indices is set by a Visuals instance associated with a CDSView
|
|
this._set_vectorize(ctx, this.all_indices[i]);
|
|
else // all_indices is not set for annotations which may have vectorized visual props
|
|
this._set_vectorize(ctx, i);
|
|
};
|
|
return ContextProperties;
|
|
}());
|
|
exports.ContextProperties = ContextProperties;
|
|
var Line = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Line, _super);
|
|
function Line() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Line.prototype.set_value = function (ctx) {
|
|
ctx.strokeStyle = this.line_color.value();
|
|
ctx.globalAlpha = this.line_alpha.value();
|
|
ctx.lineWidth = this.line_width.value();
|
|
ctx.lineJoin = this.line_join.value();
|
|
ctx.lineCap = this.line_cap.value();
|
|
ctx.setLineDash(this.line_dash.value());
|
|
ctx.setLineDashOffset(this.line_dash_offset.value());
|
|
};
|
|
Object.defineProperty(Line.prototype, "doit", {
|
|
get: function () {
|
|
return !(this.line_color.spec.value === null ||
|
|
this.line_alpha.spec.value == 0 ||
|
|
this.line_width.spec.value == 0);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Line.prototype._set_vectorize = function (ctx, i) {
|
|
this.cache_select("line_color", i);
|
|
if (ctx.strokeStyle !== this.cache.line_color)
|
|
ctx.strokeStyle = this.cache.line_color;
|
|
this.cache_select("line_alpha", i);
|
|
if (ctx.globalAlpha !== this.cache.line_alpha)
|
|
ctx.globalAlpha = this.cache.line_alpha;
|
|
this.cache_select("line_width", i);
|
|
if (ctx.lineWidth !== this.cache.line_width)
|
|
ctx.lineWidth = this.cache.line_width;
|
|
this.cache_select("line_join", i);
|
|
if (ctx.lineJoin !== this.cache.line_join)
|
|
ctx.lineJoin = this.cache.line_join;
|
|
this.cache_select("line_cap", i);
|
|
if (ctx.lineCap !== this.cache.line_cap)
|
|
ctx.lineCap = this.cache.line_cap;
|
|
this.cache_select("line_dash", i);
|
|
if (ctx.getLineDash() !== this.cache.line_dash)
|
|
ctx.setLineDash(this.cache.line_dash);
|
|
this.cache_select("line_dash_offset", i);
|
|
if (ctx.getLineDashOffset() !== this.cache.line_dash_offset)
|
|
ctx.setLineDashOffset(this.cache.line_dash_offset);
|
|
};
|
|
Line.prototype.color_value = function () {
|
|
var _a = color_1.color2rgba(this.line_color.value(), this.line_alpha.value()), r = _a[0], g = _a[1], b = _a[2], a = _a[3];
|
|
return "rgba(" + r * 255 + "," + g * 255 + "," + b * 255 + "," + a + ")";
|
|
};
|
|
return Line;
|
|
}(ContextProperties));
|
|
exports.Line = Line;
|
|
Line.prototype.attrs = Object.keys(mixins.line());
|
|
var Fill = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Fill, _super);
|
|
function Fill() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Fill.prototype.set_value = function (ctx) {
|
|
ctx.fillStyle = this.fill_color.value();
|
|
ctx.globalAlpha = this.fill_alpha.value();
|
|
};
|
|
Object.defineProperty(Fill.prototype, "doit", {
|
|
get: function () {
|
|
return !(this.fill_color.spec.value === null ||
|
|
this.fill_alpha.spec.value == 0);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Fill.prototype._set_vectorize = function (ctx, i) {
|
|
this.cache_select("fill_color", i);
|
|
if (ctx.fillStyle !== this.cache.fill_color)
|
|
ctx.fillStyle = this.cache.fill_color;
|
|
this.cache_select("fill_alpha", i);
|
|
if (ctx.globalAlpha !== this.cache.fill_alpha)
|
|
ctx.globalAlpha = this.cache.fill_alpha;
|
|
};
|
|
Fill.prototype.color_value = function () {
|
|
var _a = color_1.color2rgba(this.fill_color.value(), this.fill_alpha.value()), r = _a[0], g = _a[1], b = _a[2], a = _a[3];
|
|
return "rgba(" + r * 255 + "," + g * 255 + "," + b * 255 + "," + a + ")";
|
|
};
|
|
return Fill;
|
|
}(ContextProperties));
|
|
exports.Fill = Fill;
|
|
Fill.prototype.attrs = Object.keys(mixins.fill());
|
|
var Text = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Text, _super);
|
|
function Text() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Text.prototype.cache_select = function (name, i) {
|
|
var value;
|
|
if (name == "font") {
|
|
_super.prototype.cache_select.call(this, "text_font_style", i);
|
|
_super.prototype.cache_select.call(this, "text_font_size", i);
|
|
_super.prototype.cache_select.call(this, "text_font", i);
|
|
var _a = this.cache, text_font_style = _a.text_font_style, text_font_size = _a.text_font_size, text_font = _a.text_font;
|
|
this.cache.font = value = text_font_style + " " + text_font_size + " " + text_font;
|
|
}
|
|
else
|
|
value = _super.prototype.cache_select.call(this, name, i);
|
|
return value;
|
|
};
|
|
Text.prototype.font_value = function () {
|
|
var font = this.text_font.value();
|
|
var font_size = this.text_font_size.value();
|
|
var font_style = this.text_font_style.value();
|
|
return font_style + " " + font_size + " " + font;
|
|
};
|
|
Text.prototype.color_value = function () {
|
|
var _a = color_1.color2rgba(this.text_color.value(), this.text_alpha.value()), r = _a[0], g = _a[1], b = _a[2], a = _a[3];
|
|
return "rgba(" + r * 255 + "," + g * 255 + "," + b * 255 + "," + a + ")";
|
|
};
|
|
Text.prototype.set_value = function (ctx) {
|
|
ctx.font = this.font_value();
|
|
ctx.fillStyle = this.text_color.value();
|
|
ctx.globalAlpha = this.text_alpha.value();
|
|
ctx.textAlign = this.text_align.value();
|
|
ctx.textBaseline = this.text_baseline.value();
|
|
};
|
|
Object.defineProperty(Text.prototype, "doit", {
|
|
get: function () {
|
|
return !(this.text_color.spec.value === null ||
|
|
this.text_alpha.spec.value == 0);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Text.prototype._set_vectorize = function (ctx, i) {
|
|
this.cache_select("font", i);
|
|
if (ctx.font !== this.cache.font)
|
|
ctx.font = this.cache.font;
|
|
this.cache_select("text_color", i);
|
|
if (ctx.fillStyle !== this.cache.text_color)
|
|
ctx.fillStyle = this.cache.text_color;
|
|
this.cache_select("text_alpha", i);
|
|
if (ctx.globalAlpha !== this.cache.text_alpha)
|
|
ctx.globalAlpha = this.cache.text_alpha;
|
|
this.cache_select("text_align", i);
|
|
if (ctx.textAlign !== this.cache.text_align)
|
|
ctx.textAlign = this.cache.text_align;
|
|
this.cache_select("text_baseline", i);
|
|
if (ctx.textBaseline !== this.cache.text_baseline)
|
|
ctx.textBaseline = this.cache.text_baseline;
|
|
};
|
|
return Text;
|
|
}(ContextProperties));
|
|
exports.Text = Text;
|
|
Text.prototype.attrs = Object.keys(mixins.text());
|
|
var Visuals = /** @class */ (function () {
|
|
function Visuals(model) {
|
|
for (var _i = 0, _a = model.mixins; _i < _a.length; _i++) {
|
|
var mixin = _a[_i];
|
|
var _b = mixin.split(":"), name_1 = _b[0], _c = _b[1], prefix = _c === void 0 ? "" : _c;
|
|
var cls = void 0;
|
|
switch (name_1) {
|
|
case "line":
|
|
cls = Line;
|
|
break;
|
|
case "fill":
|
|
cls = Fill;
|
|
break;
|
|
case "text":
|
|
cls = Text;
|
|
break;
|
|
default:
|
|
throw new Error("unknown visual: " + name_1);
|
|
}
|
|
this[prefix + name_1] = new cls(model, prefix);
|
|
}
|
|
}
|
|
Visuals.prototype.warm_cache = function (source) {
|
|
for (var name_2 in this) {
|
|
if (this.hasOwnProperty(name_2)) {
|
|
var prop = this[name_2];
|
|
if (prop instanceof ContextProperties)
|
|
prop.warm_cache(source);
|
|
}
|
|
}
|
|
};
|
|
Visuals.prototype.set_all_indices = function (all_indices) {
|
|
for (var name_3 in this) {
|
|
if (this.hasOwnProperty(name_3)) {
|
|
var prop = this[name_3];
|
|
if (prop instanceof ContextProperties)
|
|
prop.all_indices = all_indices;
|
|
}
|
|
}
|
|
};
|
|
return Visuals;
|
|
}());
|
|
exports.Visuals = Visuals;
|
|
}
|
|
,
|
|
/* document/document */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var base_1 = require(0) /* ../base */;
|
|
var version_1 = require(296) /* ../version */;
|
|
var logging_1 = require(17) /* ../core/logging */;
|
|
var bokeh_events_1 = require(3) /* ../core/bokeh_events */;
|
|
var has_props_1 = require(8) /* ../core/has_props */;
|
|
var signaling_1 = require(22) /* ../core/signaling */;
|
|
var refs_1 = require(37) /* ../core/util/refs */;
|
|
var serialization_1 = require(38) /* ../core/util/serialization */;
|
|
var data_structures_1 = require(32) /* ../core/util/data_structures */;
|
|
var array_1 = require(24) /* ../core/util/array */;
|
|
var object_1 = require(35) /* ../core/util/object */;
|
|
var eq_1 = require(33) /* ../core/util/eq */;
|
|
var types_1 = require(46) /* ../core/util/types */;
|
|
var layout_dom_1 = require(163) /* ../models/layouts/layout_dom */;
|
|
var column_data_source_1 = require(208) /* ../models/sources/column_data_source */;
|
|
var model_1 = require(62) /* ../model */;
|
|
var events_1 = require(53) /* ./events */;
|
|
var EventManager = /** @class */ (function () {
|
|
function EventManager(document) {
|
|
this.document = document;
|
|
// Dispatches events to the subscribed models
|
|
this.session = null;
|
|
this.subscribed_models = new data_structures_1.Set();
|
|
}
|
|
EventManager.prototype.send_event = function (event) {
|
|
if (this.session != null)
|
|
this.session.send_event(event);
|
|
};
|
|
EventManager.prototype.trigger = function (event) {
|
|
for (var _i = 0, _a = this.subscribed_models.values; _i < _a.length; _i++) {
|
|
var id = _a[_i];
|
|
if (event.origin != null && event.origin.id !== id)
|
|
continue;
|
|
var model = this.document._all_models[id];
|
|
if (model != null && model instanceof model_1.Model)
|
|
model._process_event(event);
|
|
}
|
|
};
|
|
return EventManager;
|
|
}());
|
|
exports.EventManager = EventManager;
|
|
exports.documents = [];
|
|
exports.DEFAULT_TITLE = "Bokeh Application";
|
|
// This class should match the API of the Python Document class
|
|
// as much as possible.
|
|
var Document = /** @class */ (function () {
|
|
function Document() {
|
|
exports.documents.push(this);
|
|
this._init_timestamp = Date.now();
|
|
this._title = exports.DEFAULT_TITLE;
|
|
this._roots = [];
|
|
this._all_models = {};
|
|
this._all_models_by_name = new data_structures_1.MultiDict();
|
|
this._all_models_freeze_count = 0;
|
|
this._callbacks = [];
|
|
this.event_manager = new EventManager(this);
|
|
this.idle = new signaling_1.Signal0(this, "idle");
|
|
this._idle_roots = new WeakMap(); // TODO: WeakSet would be better
|
|
this._interactive_timestamp = null;
|
|
this._interactive_plot = null;
|
|
}
|
|
Object.defineProperty(Document.prototype, "layoutables", {
|
|
get: function () {
|
|
return this._roots.filter(function (root) { return root instanceof layout_dom_1.LayoutDOM; });
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(Document.prototype, "is_idle", {
|
|
get: function () {
|
|
for (var _i = 0, _a = this.layoutables; _i < _a.length; _i++) {
|
|
var root = _a[_i];
|
|
if (!this._idle_roots.has(root))
|
|
return false;
|
|
}
|
|
return true;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Document.prototype.notify_idle = function (model) {
|
|
this._idle_roots.set(model, true);
|
|
if (this.is_idle) {
|
|
logging_1.logger.info("document idle at " + (Date.now() - this._init_timestamp) + " ms");
|
|
this.idle.emit();
|
|
}
|
|
};
|
|
Document.prototype.clear = function () {
|
|
this._push_all_models_freeze();
|
|
try {
|
|
while (this._roots.length > 0) {
|
|
this.remove_root(this._roots[0]);
|
|
}
|
|
}
|
|
finally {
|
|
this._pop_all_models_freeze();
|
|
}
|
|
};
|
|
Document.prototype.interactive_start = function (plot) {
|
|
if (this._interactive_plot == null) {
|
|
this._interactive_plot = plot;
|
|
this._interactive_plot.trigger_event(new bokeh_events_1.LODStart());
|
|
}
|
|
this._interactive_timestamp = Date.now();
|
|
};
|
|
Document.prototype.interactive_stop = function (plot) {
|
|
if (this._interactive_plot != null && this._interactive_plot.id === plot.id) {
|
|
this._interactive_plot.trigger_event(new bokeh_events_1.LODEnd());
|
|
}
|
|
this._interactive_plot = null;
|
|
this._interactive_timestamp = null;
|
|
};
|
|
Document.prototype.interactive_duration = function () {
|
|
if (this._interactive_timestamp == null)
|
|
return -1;
|
|
else
|
|
return Date.now() - this._interactive_timestamp;
|
|
};
|
|
Document.prototype.destructively_move = function (dest_doc) {
|
|
if (dest_doc === this) {
|
|
throw new Error("Attempted to overwrite a document with itself");
|
|
}
|
|
dest_doc.clear();
|
|
// we have to remove ALL roots before adding any
|
|
// to the new doc or else models referenced from multiple
|
|
// roots could be in both docs at once, which isn't allowed.
|
|
var roots = array_1.copy(this._roots);
|
|
this.clear();
|
|
for (var _i = 0, roots_1 = roots; _i < roots_1.length; _i++) {
|
|
var root = roots_1[_i];
|
|
if (root.document != null)
|
|
throw new Error("Somehow we didn't detach " + root);
|
|
}
|
|
if (Object.keys(this._all_models).length !== 0) {
|
|
throw new Error("this._all_models still had stuff in it: " + this._all_models);
|
|
}
|
|
for (var _a = 0, roots_2 = roots; _a < roots_2.length; _a++) {
|
|
var root = roots_2[_a];
|
|
dest_doc.add_root(root);
|
|
}
|
|
dest_doc.set_title(this._title);
|
|
};
|
|
// TODO other fields of doc
|
|
Document.prototype._push_all_models_freeze = function () {
|
|
this._all_models_freeze_count += 1;
|
|
};
|
|
Document.prototype._pop_all_models_freeze = function () {
|
|
this._all_models_freeze_count -= 1;
|
|
if (this._all_models_freeze_count === 0) {
|
|
this._recompute_all_models();
|
|
}
|
|
};
|
|
/*protected*/ Document.prototype._invalidate_all_models = function () {
|
|
logging_1.logger.debug("invalidating document models");
|
|
// if freeze count is > 0, we'll recompute on unfreeze
|
|
if (this._all_models_freeze_count === 0) {
|
|
this._recompute_all_models();
|
|
}
|
|
};
|
|
Document.prototype._recompute_all_models = function () {
|
|
var new_all_models_set = new data_structures_1.Set();
|
|
for (var _i = 0, _a = this._roots; _i < _a.length; _i++) {
|
|
var r = _a[_i];
|
|
new_all_models_set = new_all_models_set.union(r.references());
|
|
}
|
|
var old_all_models_set = new data_structures_1.Set(object_1.values(this._all_models));
|
|
var to_detach = old_all_models_set.diff(new_all_models_set);
|
|
var to_attach = new_all_models_set.diff(old_all_models_set);
|
|
var recomputed = {};
|
|
for (var _b = 0, _c = new_all_models_set.values; _b < _c.length; _b++) {
|
|
var m = _c[_b];
|
|
recomputed[m.id] = m;
|
|
}
|
|
for (var _d = 0, _e = to_detach.values; _d < _e.length; _d++) {
|
|
var d = _e[_d];
|
|
d.detach_document();
|
|
if (d instanceof model_1.Model && d.name != null)
|
|
this._all_models_by_name.remove_value(d.name, d);
|
|
}
|
|
for (var _f = 0, _g = to_attach.values; _f < _g.length; _f++) {
|
|
var a = _g[_f];
|
|
a.attach_document(this);
|
|
if (a instanceof model_1.Model && a.name != null)
|
|
this._all_models_by_name.add_value(a.name, a);
|
|
}
|
|
this._all_models = recomputed;
|
|
};
|
|
Document.prototype.roots = function () {
|
|
return this._roots;
|
|
};
|
|
Document.prototype.add_root = function (model, setter_id) {
|
|
logging_1.logger.debug("Adding root: " + model);
|
|
if (array_1.includes(this._roots, model))
|
|
return;
|
|
this._push_all_models_freeze();
|
|
try {
|
|
this._roots.push(model);
|
|
}
|
|
finally {
|
|
this._pop_all_models_freeze();
|
|
}
|
|
this._trigger_on_change(new events_1.RootAddedEvent(this, model, setter_id));
|
|
};
|
|
Document.prototype.remove_root = function (model, setter_id) {
|
|
var i = this._roots.indexOf(model);
|
|
if (i < 0)
|
|
return;
|
|
this._push_all_models_freeze();
|
|
try {
|
|
this._roots.splice(i, 1);
|
|
}
|
|
finally {
|
|
this._pop_all_models_freeze();
|
|
}
|
|
this._trigger_on_change(new events_1.RootRemovedEvent(this, model, setter_id));
|
|
};
|
|
Document.prototype.title = function () {
|
|
return this._title;
|
|
};
|
|
Document.prototype.set_title = function (title, setter_id) {
|
|
if (title !== this._title) {
|
|
this._title = title;
|
|
this._trigger_on_change(new events_1.TitleChangedEvent(this, title, setter_id));
|
|
}
|
|
};
|
|
Document.prototype.get_model_by_id = function (model_id) {
|
|
if (model_id in this._all_models) {
|
|
return this._all_models[model_id];
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
};
|
|
Document.prototype.get_model_by_name = function (name) {
|
|
return this._all_models_by_name.get_one(name, "Multiple models are named '" + name + "'");
|
|
};
|
|
Document.prototype.on_change = function (callback) {
|
|
if (!array_1.includes(this._callbacks, callback))
|
|
this._callbacks.push(callback);
|
|
};
|
|
Document.prototype.remove_on_change = function (callback) {
|
|
var i = this._callbacks.indexOf(callback);
|
|
if (i >= 0)
|
|
this._callbacks.splice(i, 1);
|
|
};
|
|
Document.prototype._trigger_on_change = function (event) {
|
|
for (var _i = 0, _a = this._callbacks; _i < _a.length; _i++) {
|
|
var cb = _a[_i];
|
|
cb(event);
|
|
}
|
|
};
|
|
// called by the model
|
|
Document.prototype._notify_change = function (model, attr, old, new_, options) {
|
|
if (attr === 'name') {
|
|
this._all_models_by_name.remove_value(old, model);
|
|
if (new_ != null)
|
|
this._all_models_by_name.add_value(new_, model);
|
|
}
|
|
var setter_id = options != null ? options.setter_id : void 0;
|
|
var hint = options != null ? options.hint : void 0;
|
|
this._trigger_on_change(new events_1.ModelChangedEvent(this, model, attr, old, new_, setter_id, hint));
|
|
};
|
|
Document._references_json = function (references, include_defaults) {
|
|
if (include_defaults === void 0) {
|
|
include_defaults = true;
|
|
}
|
|
var references_json = [];
|
|
for (var _i = 0, references_1 = references; _i < references_1.length; _i++) {
|
|
var r = references_1[_i];
|
|
var ref = r.ref();
|
|
ref.attributes = r.attributes_as_json(include_defaults);
|
|
// server doesn't want id in here since it's already in ref above
|
|
delete ref.attributes.id;
|
|
references_json.push(ref);
|
|
}
|
|
return references_json;
|
|
};
|
|
Document._instantiate_object = function (obj_id, obj_type, obj_attrs) {
|
|
var full_attrs = tslib_1.__assign({}, obj_attrs, { id: obj_id, __deferred__: true });
|
|
var model = base_1.Models(obj_type);
|
|
return new model(full_attrs);
|
|
};
|
|
// given a JSON representation of all models in a graph, return a
|
|
// dict of new model objects
|
|
Document._instantiate_references_json = function (references_json, existing_models) {
|
|
// Create all instances, but without setting their props
|
|
var references = {};
|
|
for (var _i = 0, references_json_1 = references_json; _i < references_json_1.length; _i++) {
|
|
var obj = references_json_1[_i];
|
|
var obj_id = obj.id;
|
|
var obj_type = obj.type;
|
|
var obj_attrs = obj.attributes || {};
|
|
var instance = void 0;
|
|
if (obj_id in existing_models)
|
|
instance = existing_models[obj_id];
|
|
else {
|
|
instance = Document._instantiate_object(obj_id, obj_type, obj_attrs);
|
|
if (obj.subtype != null)
|
|
instance.set_subtype(obj.subtype);
|
|
}
|
|
references[instance.id] = instance;
|
|
}
|
|
return references;
|
|
};
|
|
// if v looks like a ref, or a collection, resolve it, otherwise return it unchanged
|
|
// recurse into collections but not into HasProps
|
|
Document._resolve_refs = function (value, old_references, new_references) {
|
|
function resolve_ref(v) {
|
|
if (refs_1.is_ref(v)) {
|
|
if (v.id in old_references)
|
|
return old_references[v.id];
|
|
else if (v.id in new_references)
|
|
return new_references[v.id];
|
|
else
|
|
throw new Error("reference " + JSON.stringify(v) + " isn't known (not in Document?)");
|
|
}
|
|
else if (types_1.isArray(v))
|
|
return resolve_array(v);
|
|
else if (types_1.isPlainObject(v))
|
|
return resolve_dict(v);
|
|
else
|
|
return v;
|
|
}
|
|
function resolve_array(array) {
|
|
var results = [];
|
|
for (var _i = 0, array_2 = array; _i < array_2.length; _i++) {
|
|
var v = array_2[_i];
|
|
results.push(resolve_ref(v));
|
|
}
|
|
return results;
|
|
}
|
|
function resolve_dict(dict) {
|
|
var resolved = {};
|
|
for (var k in dict) {
|
|
var v = dict[k];
|
|
resolved[k] = resolve_ref(v);
|
|
}
|
|
return resolved;
|
|
}
|
|
return resolve_ref(value);
|
|
};
|
|
// given a JSON representation of all models in a graph and new
|
|
// model instances, set the properties on the models from the
|
|
// JSON
|
|
Document._initialize_references_json = function (references_json, old_references, new_references) {
|
|
var to_update = {};
|
|
for (var _i = 0, references_json_2 = references_json; _i < references_json_2.length; _i++) {
|
|
var obj = references_json_2[_i];
|
|
var obj_id = obj.id;
|
|
var obj_attrs = obj.attributes;
|
|
var was_new = !(obj_id in old_references);
|
|
var instance = !was_new ? old_references[obj_id] : new_references[obj_id];
|
|
// replace references with actual instances in obj_attrs
|
|
var resolved_attrs = Document._resolve_refs(obj_attrs, old_references, new_references);
|
|
to_update[instance.id] = [instance, resolved_attrs, was_new];
|
|
}
|
|
function foreach_depth_first(items, f) {
|
|
var already_started = {};
|
|
function foreach_value(v) {
|
|
if (v instanceof has_props_1.HasProps) {
|
|
// note that we ignore instances that aren't updated (not in to_update)
|
|
if (!(v.id in already_started) && v.id in items) {
|
|
already_started[v.id] = true;
|
|
var _a = items[v.id], attrs = _a[1], was_new = _a[2];
|
|
for (var a in attrs) {
|
|
var e = attrs[a];
|
|
foreach_value(e);
|
|
}
|
|
f(v, attrs, was_new);
|
|
}
|
|
}
|
|
else if (types_1.isArray(v)) {
|
|
for (var _i = 0, v_1 = v; _i < v_1.length; _i++) {
|
|
var e = v_1[_i];
|
|
foreach_value(e);
|
|
}
|
|
}
|
|
else if (types_1.isPlainObject(v)) {
|
|
for (var k in v) {
|
|
var e = v[k];
|
|
foreach_value(e);
|
|
}
|
|
}
|
|
}
|
|
for (var k in items) {
|
|
var _a = items[k], instance = _a[0];
|
|
foreach_value(instance);
|
|
}
|
|
}
|
|
// this first pass removes all 'refs' replacing them with real instances
|
|
foreach_depth_first(to_update, function (instance, attrs, was_new) {
|
|
if (was_new)
|
|
instance.setv(attrs, { silent: true });
|
|
});
|
|
// after removing all the refs, we can run the initialize code safely
|
|
foreach_depth_first(to_update, function (instance, _attrs, was_new) {
|
|
if (was_new)
|
|
instance.finalize();
|
|
});
|
|
};
|
|
Document._event_for_attribute_change = function (changed_obj, key, new_value, doc, value_refs) {
|
|
var changed_model = doc.get_model_by_id(changed_obj.id); // XXX!
|
|
if (!changed_model.attribute_is_serializable(key))
|
|
return null;
|
|
else {
|
|
var event_1 = {
|
|
kind: "ModelChanged",
|
|
model: {
|
|
id: changed_obj.id,
|
|
type: changed_obj.type,
|
|
},
|
|
attr: key,
|
|
new: new_value,
|
|
};
|
|
has_props_1.HasProps._json_record_references(doc, new_value, value_refs, true); // true = recurse
|
|
return event_1;
|
|
}
|
|
};
|
|
Document._events_to_sync_objects = function (from_obj, to_obj, to_doc, value_refs) {
|
|
var from_keys = Object.keys(from_obj.attributes); //XXX!
|
|
var to_keys = Object.keys(to_obj.attributes); //XXX!
|
|
var removed = array_1.difference(from_keys, to_keys);
|
|
var added = array_1.difference(to_keys, from_keys);
|
|
var shared = array_1.intersection(from_keys, to_keys);
|
|
var events = [];
|
|
for (var _i = 0, removed_1 = removed; _i < removed_1.length; _i++) {
|
|
var key = removed_1[_i];
|
|
// we don't really have a "remove" event - not sure this ever
|
|
// happens even. One way this could happen is if the server
|
|
// does include_defaults=True and we do
|
|
// include_defaults=false ... in that case it'd be best to
|
|
// just ignore this probably. Warn about it, could mean
|
|
// there's a bug if we don't have a key that the server sent.
|
|
logging_1.logger.warn("Server sent key " + key + " but we don't seem to have it in our JSON");
|
|
}
|
|
for (var _a = 0, added_1 = added; _a < added_1.length; _a++) {
|
|
var key = added_1[_a];
|
|
var new_value = to_obj.attributes[key]; // XXX!
|
|
events.push(Document._event_for_attribute_change(from_obj, key, new_value, to_doc, value_refs));
|
|
}
|
|
for (var _b = 0, shared_1 = shared; _b < shared_1.length; _b++) {
|
|
var key = shared_1[_b];
|
|
var old_value = from_obj.attributes[key]; // XXX!
|
|
var new_value = to_obj.attributes[key]; // XXX!
|
|
if (old_value == null && new_value == null) {
|
|
}
|
|
else if (old_value == null || new_value == null) {
|
|
events.push(Document._event_for_attribute_change(from_obj, key, new_value, to_doc, value_refs));
|
|
}
|
|
else {
|
|
if (!eq_1.isEqual(old_value, new_value))
|
|
events.push(Document._event_for_attribute_change(from_obj, key, new_value, to_doc, value_refs));
|
|
}
|
|
}
|
|
return events.filter(function (e) { return e != null; });
|
|
};
|
|
// we use this to detect changes during document deserialization
|
|
// (in model constructors and initializers)
|
|
Document._compute_patch_since_json = function (from_json, to_doc) {
|
|
var to_json = to_doc.to_json(false); // include_defaults=false
|
|
function refs(json) {
|
|
var result = {};
|
|
for (var _i = 0, _a = json.roots.references; _i < _a.length; _i++) {
|
|
var obj = _a[_i];
|
|
result[obj.id] = obj;
|
|
}
|
|
return result;
|
|
}
|
|
var from_references = refs(from_json);
|
|
var from_roots = {};
|
|
var from_root_ids = [];
|
|
for (var _i = 0, _a = from_json.roots.root_ids; _i < _a.length; _i++) {
|
|
var r = _a[_i];
|
|
from_roots[r] = from_references[r];
|
|
from_root_ids.push(r);
|
|
}
|
|
var to_references = refs(to_json);
|
|
var to_roots = {};
|
|
var to_root_ids = [];
|
|
for (var _b = 0, _c = to_json.roots.root_ids; _b < _c.length; _b++) {
|
|
var r = _c[_b];
|
|
to_roots[r] = to_references[r];
|
|
to_root_ids.push(r);
|
|
}
|
|
from_root_ids.sort();
|
|
to_root_ids.sort();
|
|
if (array_1.difference(from_root_ids, to_root_ids).length > 0 ||
|
|
array_1.difference(to_root_ids, from_root_ids).length > 0) {
|
|
// this would arise if someone does add_root/remove_root during
|
|
// document deserialization, hopefully they won't ever do so.
|
|
throw new Error("Not implemented: computing add/remove of document roots");
|
|
}
|
|
var value_refs = {};
|
|
var events = [];
|
|
for (var id in to_doc._all_models) {
|
|
if (id in from_references) {
|
|
var update_model_events = Document._events_to_sync_objects(from_references[id], to_references[id], to_doc, value_refs);
|
|
events = events.concat(update_model_events);
|
|
}
|
|
}
|
|
return {
|
|
references: Document._references_json(object_1.values(value_refs), false),
|
|
events: events,
|
|
};
|
|
};
|
|
Document.prototype.to_json_string = function (include_defaults) {
|
|
if (include_defaults === void 0) {
|
|
include_defaults = true;
|
|
}
|
|
return JSON.stringify(this.to_json(include_defaults));
|
|
};
|
|
Document.prototype.to_json = function (include_defaults) {
|
|
if (include_defaults === void 0) {
|
|
include_defaults = true;
|
|
}
|
|
var root_ids = this._roots.map(function (r) { return r.id; });
|
|
var root_references = object_1.values(this._all_models);
|
|
return {
|
|
version: version_1.version,
|
|
title: this._title,
|
|
roots: {
|
|
root_ids: root_ids,
|
|
references: Document._references_json(root_references, include_defaults),
|
|
},
|
|
};
|
|
};
|
|
Document.from_json_string = function (s) {
|
|
var json = JSON.parse(s);
|
|
return Document.from_json(json);
|
|
};
|
|
Document.from_json = function (json) {
|
|
logging_1.logger.debug("Creating Document from JSON");
|
|
var py_version = json.version; // XXX!
|
|
var is_dev = py_version.indexOf('+') !== -1 || py_version.indexOf('-') !== -1;
|
|
var versions_string = "Library versions: JS (" + version_1.version + ") / Python (" + py_version + ")";
|
|
if (!is_dev && version_1.version !== py_version) {
|
|
logging_1.logger.warn("JS/Python version mismatch");
|
|
logging_1.logger.warn(versions_string);
|
|
}
|
|
else
|
|
logging_1.logger.debug(versions_string);
|
|
var roots_json = json.roots;
|
|
var root_ids = roots_json.root_ids;
|
|
var references_json = roots_json.references;
|
|
var references = Document._instantiate_references_json(references_json, {});
|
|
Document._initialize_references_json(references_json, {}, references);
|
|
var doc = new Document();
|
|
for (var _i = 0, root_ids_1 = root_ids; _i < root_ids_1.length; _i++) {
|
|
var r = root_ids_1[_i];
|
|
doc.add_root(references[r]);
|
|
} // XXX: HasProps
|
|
doc.set_title(json.title); // XXX!
|
|
return doc;
|
|
};
|
|
Document.prototype.replace_with_json = function (json) {
|
|
var replacement = Document.from_json(json);
|
|
replacement.destructively_move(this);
|
|
};
|
|
Document.prototype.create_json_patch_string = function (events) {
|
|
return JSON.stringify(this.create_json_patch(events));
|
|
};
|
|
Document.prototype.create_json_patch = function (events) {
|
|
var references = {};
|
|
var json_events = [];
|
|
for (var _i = 0, events_2 = events; _i < events_2.length; _i++) {
|
|
var event_2 = events_2[_i];
|
|
if (event_2.document !== this) {
|
|
logging_1.logger.warn("Cannot create a patch using events from a different document, event had ", event_2.document, " we are ", this);
|
|
throw new Error("Cannot create a patch using events from a different document");
|
|
}
|
|
json_events.push(event_2.json(references));
|
|
}
|
|
return {
|
|
events: json_events,
|
|
references: Document._references_json(object_1.values(references)),
|
|
};
|
|
};
|
|
Document.prototype.apply_json_patch = function (patch, buffers, setter_id) {
|
|
var _a;
|
|
if (buffers === void 0) {
|
|
buffers = [];
|
|
}
|
|
var references_json = patch.references;
|
|
var events_json = patch.events;
|
|
var references = Document._instantiate_references_json(references_json, this._all_models);
|
|
// The model being changed isn't always in references so add it in
|
|
for (var _i = 0, events_json_1 = events_json; _i < events_json_1.length; _i++) {
|
|
var event_json = events_json_1[_i];
|
|
switch (event_json.kind) {
|
|
case "RootAdded":
|
|
case "RootRemoved":
|
|
case "ModelChanged": {
|
|
var model_id = event_json.model.id;
|
|
if (model_id in this._all_models) {
|
|
references[model_id] = this._all_models[model_id];
|
|
}
|
|
else {
|
|
if (!(model_id in references)) {
|
|
logging_1.logger.warn("Got an event for unknown model ", event_json.model);
|
|
throw new Error("event model wasn't known");
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// split references into old and new so we know whether to initialize or update
|
|
var old_references = {};
|
|
var new_references = {};
|
|
for (var id in references) {
|
|
var value = references[id];
|
|
if (id in this._all_models)
|
|
old_references[id] = value;
|
|
else
|
|
new_references[id] = value;
|
|
}
|
|
Document._initialize_references_json(references_json, old_references, new_references);
|
|
for (var _b = 0, events_json_2 = events_json; _b < events_json_2.length; _b++) {
|
|
var event_json = events_json_2[_b];
|
|
switch (event_json.kind) {
|
|
case 'ModelChanged': {
|
|
var patched_id = event_json.model.id;
|
|
if (!(patched_id in this._all_models)) {
|
|
throw new Error("Cannot apply patch to " + patched_id + " which is not in the document");
|
|
}
|
|
var patched_obj = this._all_models[patched_id];
|
|
var attr = event_json.attr;
|
|
var model_type = event_json.model.type;
|
|
// XXXX currently still need this first branch, some updates (initial?) go through here
|
|
if (attr === 'data' && model_type === 'ColumnDataSource') {
|
|
var _c = serialization_1.decode_column_data(event_json.new, buffers), data = _c[0], shapes = _c[1];
|
|
patched_obj.setv({ _shapes: shapes, data: data }, { setter_id: setter_id });
|
|
}
|
|
else {
|
|
var value = Document._resolve_refs(event_json.new, old_references, new_references);
|
|
patched_obj.setv((_a = {}, _a[attr] = value, _a), { setter_id: setter_id });
|
|
}
|
|
break;
|
|
}
|
|
case 'ColumnDataChanged': {
|
|
var column_source_id = event_json.column_source.id;
|
|
if (!(column_source_id in this._all_models)) {
|
|
throw new Error("Cannot stream to " + column_source_id + " which is not in the document");
|
|
}
|
|
var column_source = this._all_models[column_source_id];
|
|
var _d = serialization_1.decode_column_data(event_json.new, buffers), data = _d[0], shapes = _d[1];
|
|
if (event_json.cols != null) {
|
|
for (var k in column_source.data) {
|
|
if (!(k in data)) {
|
|
data[k] = column_source.data[k];
|
|
}
|
|
}
|
|
for (var k in column_source._shapes) {
|
|
if (!(k in shapes)) {
|
|
shapes[k] = column_source._shapes[k];
|
|
}
|
|
}
|
|
}
|
|
column_source.setv({
|
|
_shapes: shapes,
|
|
data: data,
|
|
}, {
|
|
setter_id: setter_id,
|
|
check_eq: false,
|
|
});
|
|
break;
|
|
}
|
|
case 'ColumnsStreamed': {
|
|
var column_source_id = event_json.column_source.id;
|
|
if (!(column_source_id in this._all_models)) {
|
|
throw new Error("Cannot stream to " + column_source_id + " which is not in the document");
|
|
}
|
|
var column_source = this._all_models[column_source_id];
|
|
if (!(column_source instanceof column_data_source_1.ColumnDataSource)) {
|
|
throw new Error("Cannot stream to non-ColumnDataSource");
|
|
}
|
|
var data = event_json.data;
|
|
var rollover = event_json.rollover;
|
|
column_source.stream(data, rollover, setter_id);
|
|
break;
|
|
}
|
|
case 'ColumnsPatched': {
|
|
var column_source_id = event_json.column_source.id;
|
|
if (!(column_source_id in this._all_models)) {
|
|
throw new Error("Cannot patch " + column_source_id + " which is not in the document");
|
|
}
|
|
var column_source = this._all_models[column_source_id];
|
|
if (!(column_source instanceof column_data_source_1.ColumnDataSource)) {
|
|
throw new Error("Cannot patch non-ColumnDataSource");
|
|
}
|
|
var patches = event_json.patches;
|
|
column_source.patch(patches, setter_id);
|
|
break;
|
|
}
|
|
case 'RootAdded': {
|
|
var root_id = event_json.model.id;
|
|
var root_obj = references[root_id];
|
|
this.add_root(root_obj, setter_id); // XXX: HasProps
|
|
break;
|
|
}
|
|
case 'RootRemoved': {
|
|
var root_id = event_json.model.id;
|
|
var root_obj = references[root_id];
|
|
this.remove_root(root_obj, setter_id); // XXX: HasProps
|
|
break;
|
|
}
|
|
case 'TitleChanged': {
|
|
this.set_title(event_json.title, setter_id);
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("Unknown patch event " + JSON.stringify(event_json));
|
|
}
|
|
}
|
|
};
|
|
return Document;
|
|
}());
|
|
exports.Document = Document;
|
|
}
|
|
,
|
|
/* document/events */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var has_props_1 = require(8) /* ../core/has_props */;
|
|
var DocumentChangedEvent = /** @class */ (function () {
|
|
function DocumentChangedEvent(document) {
|
|
this.document = document;
|
|
}
|
|
return DocumentChangedEvent;
|
|
}());
|
|
exports.DocumentChangedEvent = DocumentChangedEvent;
|
|
var ModelChangedEvent = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ModelChangedEvent, _super);
|
|
function ModelChangedEvent(document, model, attr, old, new_, setter_id, hint) {
|
|
var _this = _super.call(this, document) || this;
|
|
_this.model = model;
|
|
_this.attr = attr;
|
|
_this.old = old;
|
|
_this.new_ = new_;
|
|
_this.setter_id = setter_id;
|
|
_this.hint = hint;
|
|
return _this;
|
|
}
|
|
ModelChangedEvent.prototype.json = function (references) {
|
|
if (this.attr === "id") {
|
|
throw new Error("'id' field should never change, whatever code just set it is wrong");
|
|
}
|
|
if (this.hint != null)
|
|
return this.hint.json(references);
|
|
var value = this.new_;
|
|
var value_json = has_props_1.HasProps._value_to_json(this.attr, value, this.model);
|
|
var value_refs = {};
|
|
has_props_1.HasProps._value_record_references(value, value_refs, true); // true = recurse
|
|
if (this.model.id in value_refs && this.model !== value) {
|
|
// we know we don't want a whole new copy of the obj we're
|
|
// patching unless it's also the value itself
|
|
delete value_refs[this.model.id];
|
|
}
|
|
for (var id in value_refs) {
|
|
references[id] = value_refs[id];
|
|
}
|
|
return {
|
|
kind: "ModelChanged",
|
|
model: this.model.ref(),
|
|
attr: this.attr,
|
|
new: value_json,
|
|
};
|
|
};
|
|
return ModelChangedEvent;
|
|
}(DocumentChangedEvent));
|
|
exports.ModelChangedEvent = ModelChangedEvent;
|
|
var ColumnsPatchedEvent = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ColumnsPatchedEvent, _super);
|
|
function ColumnsPatchedEvent(document, column_source, patches) {
|
|
var _this = _super.call(this, document) || this;
|
|
_this.column_source = column_source;
|
|
_this.patches = patches;
|
|
return _this;
|
|
}
|
|
ColumnsPatchedEvent.prototype.json = function (_references) {
|
|
return {
|
|
kind: "ColumnsPatched",
|
|
column_source: this.column_source,
|
|
patches: this.patches,
|
|
};
|
|
};
|
|
return ColumnsPatchedEvent;
|
|
}(DocumentChangedEvent));
|
|
exports.ColumnsPatchedEvent = ColumnsPatchedEvent;
|
|
var ColumnsStreamedEvent = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ColumnsStreamedEvent, _super);
|
|
function ColumnsStreamedEvent(document, column_source, data, rollover) {
|
|
var _this = _super.call(this, document) || this;
|
|
_this.column_source = column_source;
|
|
_this.data = data;
|
|
_this.rollover = rollover;
|
|
return _this;
|
|
}
|
|
ColumnsStreamedEvent.prototype.json = function (_references) {
|
|
return {
|
|
kind: "ColumnsStreamed",
|
|
column_source: this.column_source,
|
|
data: this.data,
|
|
rollover: this.rollover,
|
|
};
|
|
};
|
|
return ColumnsStreamedEvent;
|
|
}(DocumentChangedEvent));
|
|
exports.ColumnsStreamedEvent = ColumnsStreamedEvent;
|
|
var TitleChangedEvent = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TitleChangedEvent, _super);
|
|
function TitleChangedEvent(document, title, setter_id) {
|
|
var _this = _super.call(this, document) || this;
|
|
_this.title = title;
|
|
_this.setter_id = setter_id;
|
|
return _this;
|
|
}
|
|
TitleChangedEvent.prototype.json = function (_references) {
|
|
return {
|
|
kind: "TitleChanged",
|
|
title: this.title,
|
|
};
|
|
};
|
|
return TitleChangedEvent;
|
|
}(DocumentChangedEvent));
|
|
exports.TitleChangedEvent = TitleChangedEvent;
|
|
var RootAddedEvent = /** @class */ (function (_super) {
|
|
tslib_1.__extends(RootAddedEvent, _super);
|
|
function RootAddedEvent(document, model, setter_id) {
|
|
var _this = _super.call(this, document) || this;
|
|
_this.model = model;
|
|
_this.setter_id = setter_id;
|
|
return _this;
|
|
}
|
|
RootAddedEvent.prototype.json = function (references) {
|
|
has_props_1.HasProps._value_record_references(this.model, references, true);
|
|
return {
|
|
kind: "RootAdded",
|
|
model: this.model.ref(),
|
|
};
|
|
};
|
|
return RootAddedEvent;
|
|
}(DocumentChangedEvent));
|
|
exports.RootAddedEvent = RootAddedEvent;
|
|
var RootRemovedEvent = /** @class */ (function (_super) {
|
|
tslib_1.__extends(RootRemovedEvent, _super);
|
|
function RootRemovedEvent(document, model, setter_id) {
|
|
var _this = _super.call(this, document) || this;
|
|
_this.model = model;
|
|
_this.setter_id = setter_id;
|
|
return _this;
|
|
}
|
|
RootRemovedEvent.prototype.json = function (_references) {
|
|
return {
|
|
kind: "RootRemoved",
|
|
model: this.model.ref(),
|
|
};
|
|
};
|
|
return RootRemovedEvent;
|
|
}(DocumentChangedEvent));
|
|
exports.RootRemovedEvent = RootRemovedEvent;
|
|
}
|
|
,
|
|
/* document/index */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
tslib_1.__exportStar(require(52) /* ./document */, exports);
|
|
tslib_1.__exportStar(require(53) /* ./events */, exports);
|
|
}
|
|
,
|
|
/* embed/dom */ function _(require, module, exports) {
|
|
var dom_1 = require(5) /* ../core/dom */;
|
|
// Matches Bokeh CSS class selector. Setting all Bokeh parent element class names
|
|
// with this var prevents user configurations where css styling is unset.
|
|
exports.BOKEH_ROOT = "bk-root";
|
|
function _get_element(elementid) {
|
|
var element = document.getElementById(elementid);
|
|
if (element == null)
|
|
throw new Error("Error rendering Bokeh model: could not find #" + elementid + " HTML tag");
|
|
if (!document.body.contains(element))
|
|
throw new Error("Error rendering Bokeh model: element #" + elementid + " must be under <body>");
|
|
// If autoload script, replace script tag with div for embedding.
|
|
if (element.tagName == "SCRIPT") {
|
|
var root_el = dom_1.div({ class: exports.BOKEH_ROOT });
|
|
dom_1.replaceWith(element, root_el);
|
|
element = root_el;
|
|
}
|
|
return element;
|
|
}
|
|
function _resolve_element(item) {
|
|
var elementid = item.elementid;
|
|
if (elementid != null)
|
|
return _get_element(elementid);
|
|
else
|
|
return document.body;
|
|
}
|
|
exports._resolve_element = _resolve_element;
|
|
function _resolve_root_elements(item) {
|
|
var roots = {};
|
|
if (item.roots != null) {
|
|
for (var root_id in item.roots)
|
|
roots[root_id] = _get_element(item.roots[root_id]);
|
|
}
|
|
return roots;
|
|
}
|
|
exports._resolve_root_elements = _resolve_root_elements;
|
|
}
|
|
,
|
|
/* embed/index */ function _(require, module, exports) {
|
|
var document_1 = require(54) /* ../document */;
|
|
var logging_1 = require(17) /* ../core/logging */;
|
|
var callback_1 = require(28) /* ../core/util/callback */;
|
|
var string_1 = require(40) /* ../core/util/string */;
|
|
var types_1 = require(46) /* ../core/util/types */;
|
|
var standalone_1 = require(59) /* ./standalone */;
|
|
var server_1 = require(58) /* ./server */;
|
|
var dom_1 = require(55) /* ./dom */;
|
|
var standalone_2 = require(59) /* ./standalone */;
|
|
exports.add_document_standalone = standalone_2.add_document_standalone;
|
|
exports.index = standalone_2.index;
|
|
var server_2 = require(58) /* ./server */;
|
|
exports.add_document_from_session = server_2.add_document_from_session;
|
|
var notebook_1 = require(57) /* ./notebook */;
|
|
exports.embed_items_notebook = notebook_1.embed_items_notebook;
|
|
exports.kernels = notebook_1.kernels;
|
|
var dom_2 = require(55) /* ./dom */;
|
|
exports.BOKEH_ROOT = dom_2.BOKEH_ROOT;
|
|
function embed_item(item, target_id) {
|
|
var _a;
|
|
var docs_json = {};
|
|
var doc_id = string_1.uuid4();
|
|
docs_json[doc_id] = item.doc;
|
|
if (target_id == null)
|
|
target_id = item.target_id;
|
|
var element = document.getElementById(target_id);
|
|
if (element != null)
|
|
element.classList.add(dom_1.BOKEH_ROOT);
|
|
var roots = (_a = {}, _a[item.root_id] = target_id, _a);
|
|
var render_item = { roots: roots, docid: doc_id };
|
|
callback_1.defer(function () { return _embed_items(docs_json, [render_item]); });
|
|
}
|
|
exports.embed_item = embed_item;
|
|
// TODO (bev) this is currently clunky. Standalone embeds only provide
|
|
// the first two args, whereas server provide the app_app, and *may* prove and
|
|
// absolute_url as well if non-relative links are needed for resources. This function
|
|
// should probably be split in to two pieces to reflect the different usage patterns
|
|
function embed_items(docs_json, render_items, app_path, absolute_url) {
|
|
callback_1.defer(function () { return _embed_items(docs_json, render_items, app_path, absolute_url); });
|
|
}
|
|
exports.embed_items = embed_items;
|
|
function _embed_items(docs_json, render_items, app_path, absolute_url) {
|
|
if (types_1.isString(docs_json))
|
|
docs_json = JSON.parse(string_1.unescape(docs_json));
|
|
var docs = {};
|
|
for (var docid in docs_json) {
|
|
var doc_json = docs_json[docid];
|
|
docs[docid] = document_1.Document.from_json(doc_json);
|
|
}
|
|
for (var _i = 0, render_items_1 = render_items; _i < render_items_1.length; _i++) {
|
|
var item = render_items_1[_i];
|
|
var element = dom_1._resolve_element(item);
|
|
var roots = dom_1._resolve_root_elements(item);
|
|
if (item.docid != null) {
|
|
standalone_1.add_document_standalone(docs[item.docid], element, roots, item.use_for_title);
|
|
}
|
|
else if (item.sessionid != null) {
|
|
var websocket_url = server_1._get_ws_url(app_path, absolute_url);
|
|
logging_1.logger.debug("embed: computed ws url: " + websocket_url);
|
|
var promise = server_1.add_document_from_session(websocket_url, item.sessionid, element, roots, item.use_for_title);
|
|
promise.then(function () {
|
|
console.log("Bokeh items were rendered successfully");
|
|
}, function (error) {
|
|
console.log("Error rendering Bokeh items:", error);
|
|
});
|
|
}
|
|
else
|
|
throw new Error("Error rendering Bokeh items: either 'docid' or 'sessionid' was expected.");
|
|
}
|
|
}
|
|
}
|
|
,
|
|
/* embed/notebook */ function _(require, module, exports) {
|
|
var document_1 = require(54) /* ../document */;
|
|
var receiver_1 = require(293) /* ../protocol/receiver */;
|
|
var logging_1 = require(17) /* ../core/logging */;
|
|
var object_1 = require(35) /* ../core/util/object */;
|
|
var standalone_1 = require(59) /* ./standalone */;
|
|
var dom_1 = require(55) /* ./dom */;
|
|
// This exists to allow the jupyterlab_bokeh extension to store the
|
|
// notebook kernel so that _init_comms can register the comms target.
|
|
// This has to be available at window.Bokeh.embed.kernels in JupyterLab.
|
|
exports.kernels = {};
|
|
function _handle_notebook_comms(receiver, comm_msg) {
|
|
if (comm_msg.buffers.length > 0)
|
|
receiver.consume(comm_msg.buffers[0].buffer);
|
|
else
|
|
receiver.consume(comm_msg.content.data);
|
|
var msg = receiver.message;
|
|
if (msg != null)
|
|
this.apply_json_patch(msg.content, msg.buffers);
|
|
}
|
|
function _init_comms(target, doc) {
|
|
if (typeof Jupyter !== 'undefined' && Jupyter.notebook.kernel != null) {
|
|
logging_1.logger.info("Registering Jupyter comms for target " + target);
|
|
var comm_manager = Jupyter.notebook.kernel.comm_manager;
|
|
try {
|
|
comm_manager.register_target(target, function (comm) {
|
|
logging_1.logger.info("Registering Jupyter comms for target " + target);
|
|
var r = new receiver_1.Receiver();
|
|
comm.on_msg(_handle_notebook_comms.bind(doc, r));
|
|
});
|
|
}
|
|
catch (e) {
|
|
logging_1.logger.warn("Jupyter comms failed to register. push_notebook() will not function. (exception reported: " + e + ")");
|
|
}
|
|
}
|
|
else if (doc.roots()[0].id in exports.kernels) {
|
|
logging_1.logger.info("Registering JupyterLab comms for target " + target);
|
|
var kernel = exports.kernels[doc.roots()[0].id];
|
|
try {
|
|
kernel.registerCommTarget(target, function (comm) {
|
|
logging_1.logger.info("Registering JupyterLab comms for target " + target);
|
|
var r = new receiver_1.Receiver();
|
|
comm.onMsg = _handle_notebook_comms.bind(doc, r);
|
|
});
|
|
}
|
|
catch (e) {
|
|
logging_1.logger.warn("Jupyter comms failed to register. push_notebook() will not function. (exception reported: " + e + ")");
|
|
}
|
|
}
|
|
else {
|
|
console.warn("Jupyter notebooks comms not available. push_notebook() will not function. If running JupyterLab ensure the latest jupyterlab_bokeh extension is installed. In an exported notebook this warning is expected.");
|
|
}
|
|
}
|
|
function embed_items_notebook(docs_json, render_items) {
|
|
if (object_1.size(docs_json) != 1)
|
|
throw new Error("embed_items_notebook expects exactly one document in docs_json");
|
|
var document = document_1.Document.from_json(object_1.values(docs_json)[0]);
|
|
for (var _i = 0, render_items_1 = render_items; _i < render_items_1.length; _i++) {
|
|
var item = render_items_1[_i];
|
|
if (item.notebook_comms_target != null)
|
|
_init_comms(item.notebook_comms_target, document);
|
|
var element = dom_1._resolve_element(item);
|
|
var roots = dom_1._resolve_root_elements(item);
|
|
standalone_1.add_document_standalone(document, element, roots);
|
|
}
|
|
}
|
|
exports.embed_items_notebook = embed_items_notebook;
|
|
}
|
|
,
|
|
/* embed/server */ function _(require, module, exports) {
|
|
var connection_1 = require(1) /* ../client/connection */;
|
|
var logging_1 = require(17) /* ../core/logging */;
|
|
var standalone_1 = require(59) /* ./standalone */;
|
|
// @internal
|
|
function _get_ws_url(app_path, absolute_url) {
|
|
var protocol = 'ws:';
|
|
if (window.location.protocol == 'https:')
|
|
protocol = 'wss:';
|
|
var loc;
|
|
if (absolute_url != null) {
|
|
loc = document.createElement('a');
|
|
loc.href = absolute_url;
|
|
}
|
|
else
|
|
loc = window.location;
|
|
if (app_path != null) {
|
|
if (app_path == "/")
|
|
app_path = "";
|
|
}
|
|
else
|
|
app_path = loc.pathname.replace(/\/+$/, '');
|
|
return protocol + '//' + loc.host + app_path + '/ws';
|
|
}
|
|
exports._get_ws_url = _get_ws_url;
|
|
// map { websocket url to map { session id to promise of ClientSession } }
|
|
var _sessions = {};
|
|
function _get_session(websocket_url, session_id, args_string) {
|
|
if (!(websocket_url in _sessions))
|
|
_sessions[websocket_url] = {};
|
|
var subsessions = _sessions[websocket_url];
|
|
if (!(session_id in subsessions))
|
|
subsessions[session_id] = connection_1.pull_session(websocket_url, session_id, args_string);
|
|
return subsessions[session_id];
|
|
}
|
|
// Fill element with the roots from session_id
|
|
function add_document_from_session(websocket_url, session_id, element, roots, use_for_title) {
|
|
if (roots === void 0) {
|
|
roots = {};
|
|
}
|
|
if (use_for_title === void 0) {
|
|
use_for_title = false;
|
|
}
|
|
var args_string = window.location.search.substr(1);
|
|
var promise = _get_session(websocket_url, session_id, args_string);
|
|
return promise.then(function (session) {
|
|
return standalone_1.add_document_standalone(session.document, element, roots, use_for_title);
|
|
}, function (error) {
|
|
logging_1.logger.error("Failed to load Bokeh session " + session_id + ": " + error);
|
|
throw error;
|
|
});
|
|
}
|
|
exports.add_document_from_session = add_document_from_session;
|
|
}
|
|
,
|
|
/* embed/standalone */ function _(require, module, exports) {
|
|
var document_1 = require(54) /* ../document */;
|
|
var dom_1 = require(5) /* ../core/dom */;
|
|
var dom_2 = require(55) /* ./dom */;
|
|
// A map from the root model IDs to their views.
|
|
exports.index = {};
|
|
function _create_view(model) {
|
|
var view = new model.default_view({ model: model, parent: null });
|
|
exports.index[model.id] = view;
|
|
return view;
|
|
}
|
|
function add_document_standalone(document, element, roots, use_for_title) {
|
|
if (roots === void 0) {
|
|
roots = {};
|
|
}
|
|
if (use_for_title === void 0) {
|
|
use_for_title = false;
|
|
}
|
|
// this is a LOCAL index of views used only by this particular rendering
|
|
// call, so we can remove the views we create.
|
|
var views = {};
|
|
function render_model(model) {
|
|
var root_el;
|
|
if (model.id in roots)
|
|
root_el = roots[model.id];
|
|
else if (element.classList.contains(dom_2.BOKEH_ROOT))
|
|
root_el = element;
|
|
else {
|
|
root_el = dom_1.div({ class: dom_2.BOKEH_ROOT });
|
|
element.appendChild(root_el);
|
|
}
|
|
var view = _create_view(model);
|
|
view.renderTo(root_el);
|
|
views[model.id] = view;
|
|
}
|
|
function unrender_model(model) {
|
|
var id = model.id;
|
|
if (id in views) {
|
|
var view = views[id];
|
|
view.remove();
|
|
delete views[id];
|
|
delete exports.index[id];
|
|
}
|
|
}
|
|
for (var _i = 0, _a = document.roots(); _i < _a.length; _i++) {
|
|
var model = _a[_i];
|
|
render_model(model);
|
|
}
|
|
if (use_for_title)
|
|
window.document.title = document.title();
|
|
document.on_change(function (event) {
|
|
if (event instanceof document_1.RootAddedEvent)
|
|
render_model(event.model);
|
|
else if (event instanceof document_1.RootRemovedEvent)
|
|
unrender_model(event.model);
|
|
else if (use_for_title && event instanceof document_1.TitleChangedEvent)
|
|
window.document.title = event.title;
|
|
});
|
|
return views;
|
|
}
|
|
exports.add_document_standalone = add_document_standalone;
|
|
}
|
|
,
|
|
/* index */ function _(require, module, exports) {
|
|
require(290) /* ./polyfill */;
|
|
var version_1 = require(296) /* ./version */;
|
|
exports.version = version_1.version;
|
|
var embed = require(56) /* ./embed */;
|
|
exports.embed = embed;
|
|
var embed_1 = require(56) /* ./embed */;
|
|
exports.index = embed_1.index;
|
|
var protocol = require(291) /* ./protocol */;
|
|
exports.protocol = protocol;
|
|
var _testing = require(295) /* ./testing */;
|
|
exports._testing = _testing;
|
|
var logging_1 = require(17) /* ./core/logging */;
|
|
exports.logger = logging_1.logger;
|
|
exports.set_log_level = logging_1.set_log_level;
|
|
var settings_1 = require(21) /* ./core/settings */;
|
|
exports.settings = settings_1.settings;
|
|
var base_1 = require(0) /* ./base */;
|
|
exports.Models = base_1.Models;
|
|
var document_1 = require(54) /* ./document */;
|
|
exports.documents = document_1.documents;
|
|
var safely_1 = require(294) /* ./safely */;
|
|
exports.safely = safely_1.safely;
|
|
}
|
|
,
|
|
/* main */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
tslib_1.__exportStar(require(60) /* ./index */, exports);
|
|
}
|
|
,
|
|
/* model */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var has_props_1 = require(8) /* ./core/has_props */;
|
|
var p = require(18) /* ./core/properties */;
|
|
var types_1 = require(46) /* ./core/util/types */;
|
|
var object_1 = require(35) /* ./core/util/object */;
|
|
var logging_1 = require(17) /* ./core/logging */;
|
|
var Model = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Model, _super);
|
|
function Model(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Model.initClass = function () {
|
|
this.prototype.type = "Model";
|
|
this.define({
|
|
tags: [p.Array, []],
|
|
name: [p.String],
|
|
js_property_callbacks: [p.Any, {}],
|
|
js_event_callbacks: [p.Any, {}],
|
|
subscribed_events: [p.Array, []],
|
|
});
|
|
};
|
|
Model.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
for (var base_evt in this.js_property_callbacks) {
|
|
var callbacks = this.js_property_callbacks[base_evt];
|
|
var _a = base_evt.split(':'), evt = _a[0], _b = _a[1], attr = _b === void 0 ? null : _b;
|
|
var _loop_1 = function (cb) {
|
|
var signal = attr != null ? this_1.properties[attr][evt] : this_1[evt];
|
|
this_1.connect(signal, function () { return cb.execute(_this); });
|
|
};
|
|
var this_1 = this;
|
|
for (var _i = 0, callbacks_1 = callbacks; _i < callbacks_1.length; _i++) {
|
|
var cb = callbacks_1[_i];
|
|
_loop_1(cb);
|
|
}
|
|
}
|
|
this.connect(this.properties.js_event_callbacks.change, function () { return _this._update_event_callbacks(); });
|
|
this.connect(this.properties.subscribed_events.change, function () { return _this._update_event_callbacks(); });
|
|
};
|
|
/*protected*/ Model.prototype._process_event = function (event) {
|
|
for (var _i = 0, _a = this.js_event_callbacks[event.event_name] || []; _i < _a.length; _i++) {
|
|
var callback = _a[_i];
|
|
callback.execute(event);
|
|
}
|
|
if (this.document != null && this.subscribed_events.some(function (m) { return m == event.event_name; }))
|
|
this.document.event_manager.send_event(event);
|
|
};
|
|
Model.prototype.trigger_event = function (event) {
|
|
if (this.document != null) {
|
|
event.origin = this;
|
|
this.document.event_manager.trigger(event);
|
|
}
|
|
};
|
|
Model.prototype._update_event_callbacks = function () {
|
|
if (this.document == null) {
|
|
// File an issue: SidePanel in particular seems to have this issue
|
|
logging_1.logger.warn('WARNING: Document not defined for updating event callbacks');
|
|
return;
|
|
}
|
|
this.document.event_manager.subscribed_models.add(this.id);
|
|
};
|
|
Model.prototype._doc_attached = function () {
|
|
if (!object_1.isEmpty(this.js_event_callbacks) || !object_1.isEmpty(this.subscribed_events))
|
|
this._update_event_callbacks();
|
|
};
|
|
Model.prototype.select = function (selector) {
|
|
if (types_1.isString(selector))
|
|
return this.references().filter(function (ref) { return ref instanceof Model && ref.name === selector; });
|
|
else if (selector.prototype instanceof has_props_1.HasProps)
|
|
return this.references().filter(function (ref) { return ref instanceof selector; });
|
|
else
|
|
throw new Error("invalid selector");
|
|
};
|
|
Model.prototype.select_one = function (selector) {
|
|
var result = this.select(selector);
|
|
switch (result.length) {
|
|
case 0:
|
|
return null;
|
|
case 1:
|
|
return result[0];
|
|
default:
|
|
throw new Error("found more than one object matching given selector");
|
|
}
|
|
};
|
|
return Model;
|
|
}(has_props_1.HasProps));
|
|
exports.Model = Model;
|
|
Model.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/annotation */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var proj = require(36) /* ../../core/util/projections */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var renderer_1 = require(197) /* ../renderers/renderer */;
|
|
var AnnotationView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(AnnotationView, _super);
|
|
function AnnotationView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Object.defineProperty(AnnotationView.prototype, "panel", {
|
|
get: function () {
|
|
return this.layout;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
AnnotationView.prototype.get_size = function () {
|
|
if (this.model.visible) {
|
|
var _a = this._get_size(), width = _a.width, height = _a.height;
|
|
return { width: Math.round(width), height: Math.round(height) };
|
|
}
|
|
else
|
|
return { width: 0, height: 0 };
|
|
};
|
|
AnnotationView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
var p = this.model.properties;
|
|
this.on_change(p.visible, function () { return _this.plot_view.request_layout(); });
|
|
};
|
|
AnnotationView.prototype._get_size = function () {
|
|
throw new Error("not implemented");
|
|
};
|
|
Object.defineProperty(AnnotationView.prototype, "ctx", {
|
|
get: function () {
|
|
return this.plot_view.canvas_view.ctx;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
AnnotationView.prototype.set_data = function (source) {
|
|
var _a, _b;
|
|
var data = this.model.materialize_dataspecs(source);
|
|
object_1.extend(this, data);
|
|
if (this.plot_model.use_map) {
|
|
var self_1 = this;
|
|
if (self_1._x != null)
|
|
_a = proj.project_xy(self_1._x, self_1._y), self_1._x = _a[0], self_1._y = _a[1];
|
|
if (self_1._xs != null)
|
|
_b = proj.project_xsys(self_1._xs, self_1._ys), self_1._xs = _b[0], self_1._ys = _b[1];
|
|
}
|
|
};
|
|
Object.defineProperty(AnnotationView.prototype, "needs_clip", {
|
|
get: function () {
|
|
return this.layout == null; // TODO: change this, when center layout is fully implemented
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
AnnotationView.prototype.serializable_state = function () {
|
|
var state = _super.prototype.serializable_state.call(this);
|
|
return this.layout == null ? state : tslib_1.__assign({}, state, { bbox: this.layout.bbox.rect });
|
|
};
|
|
return AnnotationView;
|
|
}(renderer_1.RendererView));
|
|
exports.AnnotationView = AnnotationView;
|
|
var Annotation = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Annotation, _super);
|
|
function Annotation(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Annotation.initClass = function () {
|
|
this.prototype.type = 'Annotation';
|
|
this.override({
|
|
level: 'annotation',
|
|
});
|
|
};
|
|
return Annotation;
|
|
}(renderer_1.Renderer));
|
|
exports.Annotation = Annotation;
|
|
Annotation.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/arrow */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
var arrow_head_1 = require(65) /* ./arrow_head */;
|
|
var column_data_source_1 = require(208) /* ../sources/column_data_source */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var math_1 = require(34) /* ../../core/util/math */;
|
|
var ArrowView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ArrowView, _super);
|
|
function ArrowView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ArrowView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
if (this.model.source == null)
|
|
this.model.source = new column_data_source_1.ColumnDataSource();
|
|
this.set_data(this.model.source);
|
|
};
|
|
ArrowView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.change, function () { return _this.set_data(_this.model.source); });
|
|
this.connect(this.model.source.streaming, function () { return _this.set_data(_this.model.source); });
|
|
this.connect(this.model.source.patching, function () { return _this.set_data(_this.model.source); });
|
|
};
|
|
ArrowView.prototype.set_data = function (source) {
|
|
_super.prototype.set_data.call(this, source);
|
|
this.visuals.warm_cache(source);
|
|
this.plot_view.request_render();
|
|
};
|
|
ArrowView.prototype._map_data = function () {
|
|
var frame = this.plot_view.frame;
|
|
var sx_start, sy_start;
|
|
if (this.model.start_units == 'data') {
|
|
sx_start = frame.xscales[this.model.x_range_name].v_compute(this._x_start);
|
|
sy_start = frame.yscales[this.model.y_range_name].v_compute(this._y_start);
|
|
}
|
|
else {
|
|
sx_start = frame.xview.v_compute(this._x_start);
|
|
sy_start = frame.yview.v_compute(this._y_start);
|
|
}
|
|
var sx_end, sy_end;
|
|
if (this.model.end_units == 'data') {
|
|
sx_end = frame.xscales[this.model.x_range_name].v_compute(this._x_end);
|
|
sy_end = frame.yscales[this.model.y_range_name].v_compute(this._y_end);
|
|
}
|
|
else {
|
|
sx_end = frame.xview.v_compute(this._x_end);
|
|
sy_end = frame.yview.v_compute(this._y_end);
|
|
}
|
|
return [[sx_start, sy_start], [sx_end, sy_end]];
|
|
};
|
|
ArrowView.prototype.render = function () {
|
|
if (!this.model.visible)
|
|
return;
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
ctx.save();
|
|
// Order in this function is important. First we draw all the arrow heads.
|
|
var _a = this._map_data(), start = _a[0], end = _a[1];
|
|
if (this.model.end != null)
|
|
this._arrow_head(ctx, "render", this.model.end, start, end);
|
|
if (this.model.start != null)
|
|
this._arrow_head(ctx, "render", this.model.start, end, start);
|
|
// Next we call .clip on all the arrow heads, inside an initial canvas sized
|
|
// rect, to create an "inverted" clip region for the arrow heads
|
|
ctx.beginPath();
|
|
var _b = this.plot_view.layout.bbox.rect, x = _b.left, y = _b.top, width = _b.width, height = _b.height;
|
|
ctx.rect(x, y, width, height);
|
|
if (this.model.end != null)
|
|
this._arrow_head(ctx, "clip", this.model.end, start, end);
|
|
if (this.model.start != null)
|
|
this._arrow_head(ctx, "clip", this.model.start, end, start);
|
|
ctx.closePath();
|
|
ctx.clip();
|
|
// Finally we draw the arrow body, with the clipping regions set up. This prevents
|
|
// "fat" arrows from overlapping the arrow head in a bad way.
|
|
this._arrow_body(ctx, start, end);
|
|
ctx.restore();
|
|
};
|
|
ArrowView.prototype._arrow_head = function (ctx, action, head, start, end) {
|
|
for (var i = 0, _end = this._x_start.length; i < _end; i++) {
|
|
// arrow head runs orthogonal to arrow body
|
|
var angle = Math.PI / 2 + math_1.atan2([start[0][i], start[1][i]], [end[0][i], end[1][i]]);
|
|
ctx.save();
|
|
ctx.translate(end[0][i], end[1][i]);
|
|
ctx.rotate(angle);
|
|
if (action == "render")
|
|
head.render(ctx, i);
|
|
else if (action == "clip")
|
|
head.clip(ctx, i);
|
|
ctx.restore();
|
|
}
|
|
};
|
|
ArrowView.prototype._arrow_body = function (ctx, start, end) {
|
|
if (!this.visuals.line.doit)
|
|
return;
|
|
for (var i = 0, n = this._x_start.length; i < n; i++) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.beginPath();
|
|
ctx.moveTo(start[0][i], start[1][i]);
|
|
ctx.lineTo(end[0][i], end[1][i]);
|
|
ctx.stroke();
|
|
}
|
|
};
|
|
return ArrowView;
|
|
}(annotation_1.AnnotationView));
|
|
exports.ArrowView = ArrowView;
|
|
var Arrow = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Arrow, _super);
|
|
function Arrow(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Arrow.initClass = function () {
|
|
this.prototype.type = 'Arrow';
|
|
this.prototype.default_view = ArrowView;
|
|
this.mixins(['line']);
|
|
this.define({
|
|
x_start: [p.NumberSpec,],
|
|
y_start: [p.NumberSpec,],
|
|
start_units: [p.SpatialUnits, 'data'],
|
|
start: [p.Instance, null],
|
|
x_end: [p.NumberSpec,],
|
|
y_end: [p.NumberSpec,],
|
|
end_units: [p.SpatialUnits, 'data'],
|
|
end: [p.Instance, function () { return new arrow_head_1.OpenHead({}); }],
|
|
source: [p.Instance],
|
|
x_range_name: [p.String, 'default'],
|
|
y_range_name: [p.String, 'default'],
|
|
});
|
|
};
|
|
return Arrow;
|
|
}(annotation_1.Annotation));
|
|
exports.Arrow = Arrow;
|
|
Arrow.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/arrow_head */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
var visuals_1 = require(51) /* ../../core/visuals */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var ArrowHead = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ArrowHead, _super);
|
|
function ArrowHead(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ArrowHead.initClass = function () {
|
|
this.prototype.type = 'ArrowHead';
|
|
this.define({
|
|
size: [p.Number, 25],
|
|
});
|
|
};
|
|
ArrowHead.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.visuals = new visuals_1.Visuals(this);
|
|
};
|
|
return ArrowHead;
|
|
}(annotation_1.Annotation));
|
|
exports.ArrowHead = ArrowHead;
|
|
ArrowHead.initClass();
|
|
var OpenHead = /** @class */ (function (_super) {
|
|
tslib_1.__extends(OpenHead, _super);
|
|
function OpenHead(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
OpenHead.initClass = function () {
|
|
this.prototype.type = 'OpenHead';
|
|
this.mixins(['line']);
|
|
};
|
|
OpenHead.prototype.clip = function (ctx, i) {
|
|
// This method should not begin or close a path
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.moveTo(0.5 * this.size, this.size);
|
|
ctx.lineTo(0.5 * this.size, -2);
|
|
ctx.lineTo(-0.5 * this.size, -2);
|
|
ctx.lineTo(-0.5 * this.size, this.size);
|
|
ctx.lineTo(0, 0);
|
|
ctx.lineTo(0.5 * this.size, this.size);
|
|
};
|
|
OpenHead.prototype.render = function (ctx, i) {
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.beginPath();
|
|
ctx.moveTo(0.5 * this.size, this.size);
|
|
ctx.lineTo(0, 0);
|
|
ctx.lineTo(-0.5 * this.size, this.size);
|
|
ctx.stroke();
|
|
}
|
|
};
|
|
return OpenHead;
|
|
}(ArrowHead));
|
|
exports.OpenHead = OpenHead;
|
|
OpenHead.initClass();
|
|
var NormalHead = /** @class */ (function (_super) {
|
|
tslib_1.__extends(NormalHead, _super);
|
|
function NormalHead(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
NormalHead.initClass = function () {
|
|
this.prototype.type = 'NormalHead';
|
|
this.mixins(['line', 'fill']);
|
|
this.override({
|
|
fill_color: 'black',
|
|
});
|
|
};
|
|
NormalHead.prototype.clip = function (ctx, i) {
|
|
// This method should not begin or close a path
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.moveTo(0.5 * this.size, this.size);
|
|
ctx.lineTo(0.5 * this.size, -2);
|
|
ctx.lineTo(-0.5 * this.size, -2);
|
|
ctx.lineTo(-0.5 * this.size, this.size);
|
|
ctx.lineTo(0.5 * this.size, this.size);
|
|
};
|
|
NormalHead.prototype.render = function (ctx, i) {
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_vectorize(ctx, i);
|
|
this._normal(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
this._normal(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
};
|
|
NormalHead.prototype._normal = function (ctx, _i) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(0.5 * this.size, this.size);
|
|
ctx.lineTo(0, 0);
|
|
ctx.lineTo(-0.5 * this.size, this.size);
|
|
ctx.closePath();
|
|
};
|
|
return NormalHead;
|
|
}(ArrowHead));
|
|
exports.NormalHead = NormalHead;
|
|
NormalHead.initClass();
|
|
var VeeHead = /** @class */ (function (_super) {
|
|
tslib_1.__extends(VeeHead, _super);
|
|
function VeeHead(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
VeeHead.initClass = function () {
|
|
this.prototype.type = 'VeeHead';
|
|
this.mixins(['line', 'fill']);
|
|
this.override({
|
|
fill_color: 'black',
|
|
});
|
|
};
|
|
VeeHead.prototype.clip = function (ctx, i) {
|
|
// This method should not begin or close a path
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.moveTo(0.5 * this.size, this.size);
|
|
ctx.lineTo(0.5 * this.size, -2);
|
|
ctx.lineTo(-0.5 * this.size, -2);
|
|
ctx.lineTo(-0.5 * this.size, this.size);
|
|
ctx.lineTo(0, 0.5 * this.size);
|
|
ctx.lineTo(0.5 * this.size, this.size);
|
|
};
|
|
VeeHead.prototype.render = function (ctx, i) {
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_vectorize(ctx, i);
|
|
this._vee(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
this._vee(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
};
|
|
VeeHead.prototype._vee = function (ctx, _i) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(0.5 * this.size, this.size);
|
|
ctx.lineTo(0, 0);
|
|
ctx.lineTo(-0.5 * this.size, this.size);
|
|
ctx.lineTo(0, 0.5 * this.size);
|
|
ctx.closePath();
|
|
};
|
|
return VeeHead;
|
|
}(ArrowHead));
|
|
exports.VeeHead = VeeHead;
|
|
VeeHead.initClass();
|
|
var TeeHead = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TeeHead, _super);
|
|
function TeeHead(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
TeeHead.initClass = function () {
|
|
this.prototype.type = 'TeeHead';
|
|
this.mixins(['line']);
|
|
};
|
|
TeeHead.prototype.render = function (ctx, i) {
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.beginPath();
|
|
ctx.moveTo(0.5 * this.size, 0);
|
|
ctx.lineTo(-0.5 * this.size, 0);
|
|
ctx.stroke();
|
|
}
|
|
};
|
|
TeeHead.prototype.clip = function (_ctx, _i) { };
|
|
return TeeHead;
|
|
}(ArrowHead));
|
|
exports.TeeHead = TeeHead;
|
|
TeeHead.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/band */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
var column_data_source_1 = require(208) /* ../sources/column_data_source */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var BandView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BandView, _super);
|
|
function BandView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
BandView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.set_data(this.model.source);
|
|
};
|
|
BandView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.source.streaming, function () { return _this.set_data(_this.model.source); });
|
|
this.connect(this.model.source.patching, function () { return _this.set_data(_this.model.source); });
|
|
this.connect(this.model.source.change, function () { return _this.set_data(_this.model.source); });
|
|
};
|
|
BandView.prototype.set_data = function (source) {
|
|
_super.prototype.set_data.call(this, source);
|
|
this.visuals.warm_cache(source);
|
|
this.plot_view.request_render();
|
|
};
|
|
BandView.prototype._map_data = function () {
|
|
var frame = this.plot_view.frame;
|
|
var dim = this.model.dimension;
|
|
var xscale = frame.xscales[this.model.x_range_name];
|
|
var yscale = frame.yscales[this.model.y_range_name];
|
|
var limit_scale = dim == "height" ? yscale : xscale;
|
|
var base_scale = dim == "height" ? xscale : yscale;
|
|
var limit_view = dim == "height" ? frame.yview : frame.xview;
|
|
var base_view = dim == "height" ? frame.xview : frame.yview;
|
|
var _lower_sx;
|
|
if (this.model.properties.lower.units == "data")
|
|
_lower_sx = limit_scale.v_compute(this._lower);
|
|
else
|
|
_lower_sx = limit_view.v_compute(this._lower);
|
|
var _upper_sx;
|
|
if (this.model.properties.upper.units == "data")
|
|
_upper_sx = limit_scale.v_compute(this._upper);
|
|
else
|
|
_upper_sx = limit_view.v_compute(this._upper);
|
|
var _base_sx;
|
|
if (this.model.properties.base.units == "data")
|
|
_base_sx = base_scale.v_compute(this._base);
|
|
else
|
|
_base_sx = base_view.v_compute(this._base);
|
|
var _a = dim == 'height' ? [1, 0] : [0, 1], i = _a[0], j = _a[1];
|
|
var _lower = [_lower_sx, _base_sx];
|
|
var _upper = [_upper_sx, _base_sx];
|
|
this._lower_sx = _lower[i];
|
|
this._lower_sy = _lower[j];
|
|
this._upper_sx = _upper[i];
|
|
this._upper_sy = _upper[j];
|
|
};
|
|
BandView.prototype.render = function () {
|
|
if (!this.model.visible)
|
|
return;
|
|
this._map_data();
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
// Draw the band body
|
|
ctx.beginPath();
|
|
ctx.moveTo(this._lower_sx[0], this._lower_sy[0]);
|
|
for (var i = 0, end = this._lower_sx.length; i < end; i++) {
|
|
ctx.lineTo(this._lower_sx[i], this._lower_sy[i]);
|
|
}
|
|
// iterate backwards so that the upper end is below the lower start
|
|
for (var start = this._upper_sx.length - 1, i = start; i >= 0; i--) {
|
|
ctx.lineTo(this._upper_sx[i], this._upper_sy[i]);
|
|
}
|
|
ctx.closePath();
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_value(ctx);
|
|
ctx.fill();
|
|
}
|
|
// Draw the lower band edge
|
|
ctx.beginPath();
|
|
ctx.moveTo(this._lower_sx[0], this._lower_sy[0]);
|
|
for (var i = 0, end = this._lower_sx.length; i < end; i++) {
|
|
ctx.lineTo(this._lower_sx[i], this._lower_sy[i]);
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_value(ctx);
|
|
ctx.stroke();
|
|
}
|
|
// Draw the upper band edge
|
|
ctx.beginPath();
|
|
ctx.moveTo(this._upper_sx[0], this._upper_sy[0]);
|
|
for (var i = 0, end = this._upper_sx.length; i < end; i++) {
|
|
ctx.lineTo(this._upper_sx[i], this._upper_sy[i]);
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_value(ctx);
|
|
ctx.stroke();
|
|
}
|
|
};
|
|
return BandView;
|
|
}(annotation_1.AnnotationView));
|
|
exports.BandView = BandView;
|
|
var Band = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Band, _super);
|
|
function Band(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Band.initClass = function () {
|
|
this.prototype.type = 'Band';
|
|
this.prototype.default_view = BandView;
|
|
this.mixins(['line', 'fill']);
|
|
this.define({
|
|
lower: [p.DistanceSpec],
|
|
upper: [p.DistanceSpec],
|
|
base: [p.DistanceSpec],
|
|
dimension: [p.Dimension, 'height'],
|
|
source: [p.Instance, function () { return new column_data_source_1.ColumnDataSource(); }],
|
|
x_range_name: [p.String, 'default'],
|
|
y_range_name: [p.String, 'default'],
|
|
});
|
|
this.override({
|
|
fill_color: "#fff9ba",
|
|
fill_alpha: 0.4,
|
|
line_color: "#cccccc",
|
|
line_alpha: 0.3,
|
|
});
|
|
};
|
|
return Band;
|
|
}(annotation_1.Annotation));
|
|
exports.Band = Band;
|
|
Band.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/box_annotation */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
var signaling_1 = require(22) /* ../../core/signaling */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var bbox_1 = require(27) /* ../../core/util/bbox */;
|
|
exports.EDGE_TOLERANCE = 2.5;
|
|
var BoxAnnotationView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BoxAnnotationView, _super);
|
|
function BoxAnnotationView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
BoxAnnotationView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.plot_view.canvas_overlays.appendChild(this.el);
|
|
this.el.classList.add("bk-shading");
|
|
dom_1.undisplay(this.el);
|
|
};
|
|
BoxAnnotationView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
// need to respond to either normal BB change events or silent
|
|
// "data only updates" that tools might want to use
|
|
if (this.model.render_mode == 'css') {
|
|
// dispatch CSS update immediately
|
|
this.connect(this.model.change, function () { return _this.render(); });
|
|
this.connect(this.model.data_update, function () { return _this.render(); });
|
|
}
|
|
else {
|
|
this.connect(this.model.change, function () { return _this.plot_view.request_render(); });
|
|
this.connect(this.model.data_update, function () { return _this.plot_view.request_render(); });
|
|
}
|
|
};
|
|
BoxAnnotationView.prototype.render = function () {
|
|
var _this = this;
|
|
if (!this.model.visible && this.model.render_mode == 'css')
|
|
dom_1.undisplay(this.el);
|
|
if (!this.model.visible)
|
|
return;
|
|
// don't render if *all* position are null
|
|
if (this.model.left == null && this.model.right == null && this.model.top == null && this.model.bottom == null) {
|
|
dom_1.undisplay(this.el);
|
|
return;
|
|
}
|
|
var frame = this.plot_view.frame;
|
|
var xscale = frame.xscales[this.model.x_range_name];
|
|
var yscale = frame.yscales[this.model.y_range_name];
|
|
var _calc_dim = function (dim, dim_units, scale, view, frame_extrema) {
|
|
var sdim;
|
|
if (dim != null) {
|
|
if (_this.model.screen)
|
|
sdim = dim;
|
|
else {
|
|
if (dim_units == 'data')
|
|
sdim = scale.compute(dim);
|
|
else
|
|
sdim = view.compute(dim);
|
|
}
|
|
}
|
|
else
|
|
sdim = frame_extrema;
|
|
return sdim;
|
|
};
|
|
this.sleft = _calc_dim(this.model.left, this.model.left_units, xscale, frame.xview, frame._left.value);
|
|
this.sright = _calc_dim(this.model.right, this.model.right_units, xscale, frame.xview, frame._right.value);
|
|
this.stop = _calc_dim(this.model.top, this.model.top_units, yscale, frame.yview, frame._top.value);
|
|
this.sbottom = _calc_dim(this.model.bottom, this.model.bottom_units, yscale, frame.yview, frame._bottom.value);
|
|
var draw = this.model.render_mode == 'css' ? this._css_box.bind(this) : this._canvas_box.bind(this);
|
|
draw(this.sleft, this.sright, this.sbottom, this.stop);
|
|
};
|
|
BoxAnnotationView.prototype._css_box = function (sleft, sright, sbottom, stop) {
|
|
var line_width = this.model.properties.line_width.value();
|
|
var sw = Math.floor(sright - sleft) - line_width;
|
|
var sh = Math.floor(sbottom - stop) - line_width;
|
|
this.el.style.left = sleft + "px";
|
|
this.el.style.width = sw + "px";
|
|
this.el.style.top = stop + "px";
|
|
this.el.style.height = sh + "px";
|
|
this.el.style.borderWidth = line_width + "px";
|
|
this.el.style.borderColor = this.model.properties.line_color.value();
|
|
this.el.style.backgroundColor = this.model.properties.fill_color.value();
|
|
this.el.style.opacity = this.model.properties.fill_alpha.value();
|
|
// try our best to honor line dashing in some way, if we can
|
|
var ld = this.model.properties.line_dash.value().length < 2 ? "solid" : "dashed";
|
|
this.el.style.borderStyle = ld;
|
|
dom_1.display(this.el);
|
|
};
|
|
BoxAnnotationView.prototype._canvas_box = function (sleft, sright, sbottom, stop) {
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
ctx.save();
|
|
ctx.beginPath();
|
|
ctx.rect(sleft, stop, sright - sleft, sbottom - stop);
|
|
this.visuals.fill.set_value(ctx);
|
|
ctx.fill();
|
|
this.visuals.line.set_value(ctx);
|
|
ctx.stroke();
|
|
ctx.restore();
|
|
};
|
|
BoxAnnotationView.prototype.interactive_bbox = function () {
|
|
var tol = this.model.properties.line_width.value() + exports.EDGE_TOLERANCE;
|
|
return new bbox_1.BBox({
|
|
x0: this.sleft - tol,
|
|
y0: this.stop - tol,
|
|
x1: this.sright + tol,
|
|
y1: this.sbottom + tol,
|
|
});
|
|
};
|
|
BoxAnnotationView.prototype.interactive_hit = function (sx, sy) {
|
|
if (this.model.in_cursor == null)
|
|
return false;
|
|
var bbox = this.interactive_bbox();
|
|
return bbox.contains(sx, sy);
|
|
};
|
|
BoxAnnotationView.prototype.cursor = function (sx, sy) {
|
|
var tol = 3;
|
|
if (Math.abs(sx - this.sleft) < tol || Math.abs(sx - this.sright) < tol)
|
|
return this.model.ew_cursor;
|
|
else if (Math.abs(sy - this.sbottom) < tol || Math.abs(sy - this.stop) < tol)
|
|
return this.model.ns_cursor;
|
|
else if (sx > this.sleft && sx < this.sright && sy > this.stop && sy < this.sbottom)
|
|
return this.model.in_cursor;
|
|
else
|
|
return null;
|
|
};
|
|
return BoxAnnotationView;
|
|
}(annotation_1.AnnotationView));
|
|
exports.BoxAnnotationView = BoxAnnotationView;
|
|
var BoxAnnotation = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BoxAnnotation, _super);
|
|
function BoxAnnotation(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
BoxAnnotation.initClass = function () {
|
|
this.prototype.type = 'BoxAnnotation';
|
|
this.prototype.default_view = BoxAnnotationView;
|
|
this.mixins(['line', 'fill']);
|
|
this.define({
|
|
render_mode: [p.RenderMode, 'canvas'],
|
|
x_range_name: [p.String, 'default'],
|
|
y_range_name: [p.String, 'default'],
|
|
top: [p.Number, null],
|
|
top_units: [p.SpatialUnits, 'data'],
|
|
bottom: [p.Number, null],
|
|
bottom_units: [p.SpatialUnits, 'data'],
|
|
left: [p.Number, null],
|
|
left_units: [p.SpatialUnits, 'data'],
|
|
right: [p.Number, null],
|
|
right_units: [p.SpatialUnits, 'data'],
|
|
});
|
|
this.internal({
|
|
screen: [p.Boolean, false],
|
|
ew_cursor: [p.String, null],
|
|
ns_cursor: [p.String, null],
|
|
in_cursor: [p.String, null],
|
|
});
|
|
this.override({
|
|
fill_color: '#fff9ba',
|
|
fill_alpha: 0.4,
|
|
line_color: '#cccccc',
|
|
line_alpha: 0.3,
|
|
});
|
|
};
|
|
BoxAnnotation.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.data_update = new signaling_1.Signal0(this, "data_update");
|
|
};
|
|
BoxAnnotation.prototype.update = function (_a) {
|
|
var left = _a.left, right = _a.right, top = _a.top, bottom = _a.bottom;
|
|
this.setv({ left: left, right: right, top: top, bottom: bottom, screen: true }, { silent: true });
|
|
this.data_update.emit();
|
|
};
|
|
return BoxAnnotation;
|
|
}(annotation_1.Annotation));
|
|
exports.BoxAnnotation = BoxAnnotation;
|
|
BoxAnnotation.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/color_bar */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
var basic_ticker_1 = require(217) /* ../tickers/basic_ticker */;
|
|
var basic_tick_formatter_1 = require(107) /* ../formatters/basic_tick_formatter */;
|
|
var linear_color_mapper_1 = require(174) /* ../mappers/linear_color_mapper */;
|
|
var linear_scale_1 = require(200) /* ../scales/linear_scale */;
|
|
var log_scale_1 = require(201) /* ../scales/log_scale */;
|
|
var range1d_1 = require(191) /* ../ranges/range1d */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var text_util = require(43) /* ../../core/util/text */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var arrayable_1 = require(25) /* ../../core/util/arrayable */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var SHORT_DIM = 25;
|
|
var LONG_DIM_MIN_SCALAR = 0.3;
|
|
var LONG_DIM_MAX_SCALAR = 0.8;
|
|
var ColorBarView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ColorBarView, _super);
|
|
function ColorBarView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ColorBarView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this._set_canvas_image();
|
|
};
|
|
ColorBarView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.properties.visible.change, function () { return _this.plot_view.request_render(); });
|
|
this.connect(this.model.ticker.change, function () { return _this.plot_view.request_render(); });
|
|
this.connect(this.model.formatter.change, function () { return _this.plot_view.request_render(); });
|
|
if (this.model.color_mapper != null) {
|
|
this.connect(this.model.color_mapper.change, function () {
|
|
_this._set_canvas_image();
|
|
_this.plot_view.request_render();
|
|
});
|
|
}
|
|
};
|
|
ColorBarView.prototype._get_size = function () {
|
|
if (this.model.color_mapper == null)
|
|
return { width: 0, height: 0 };
|
|
else {
|
|
var _a = this.compute_legend_dimensions(), width = _a.width, height = _a.height;
|
|
return { width: width, height: height };
|
|
}
|
|
};
|
|
ColorBarView.prototype._set_canvas_image = function () {
|
|
var _a, _b;
|
|
if (this.model.color_mapper == null)
|
|
return;
|
|
var palette = this.model.color_mapper.palette;
|
|
if (this.model.orientation == 'vertical')
|
|
palette = array_1.reversed(palette);
|
|
var w, h;
|
|
switch (this.model.orientation) {
|
|
case "vertical": {
|
|
_a = [1, palette.length], w = _a[0], h = _a[1];
|
|
break;
|
|
}
|
|
case "horizontal": {
|
|
_b = [palette.length, 1], w = _b[0], h = _b[1];
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("unreachable code");
|
|
}
|
|
var canvas = document.createElement('canvas');
|
|
canvas.width = w;
|
|
canvas.height = h;
|
|
var image_ctx = canvas.getContext('2d');
|
|
var image_data = image_ctx.getImageData(0, 0, w, h);
|
|
// We always want to draw the entire palette linearly, so we create a new
|
|
// LinearColorMapper instance and map a monotonic range of values with
|
|
// length = palette.length to get each palette color in order.
|
|
var cmap = new linear_color_mapper_1.LinearColorMapper({ palette: palette }).rgba_mapper;
|
|
var buf8 = cmap.v_compute(array_1.range(0, palette.length));
|
|
image_data.data.set(buf8);
|
|
image_ctx.putImageData(image_data, 0, 0);
|
|
this.image = canvas;
|
|
};
|
|
ColorBarView.prototype.compute_legend_dimensions = function () {
|
|
var image_dimensions = this._computed_image_dimensions();
|
|
var _a = [image_dimensions.height, image_dimensions.width], image_height = _a[0], image_width = _a[1];
|
|
var label_extent = this._get_label_extent();
|
|
var title_extent = this._title_extent();
|
|
var tick_extent = this._tick_extent();
|
|
var padding = this.model.padding;
|
|
var legend_height, legend_width;
|
|
switch (this.model.orientation) {
|
|
case "vertical":
|
|
legend_height = image_height + title_extent + 2 * padding;
|
|
legend_width = image_width + tick_extent + label_extent + 2 * padding;
|
|
break;
|
|
case "horizontal":
|
|
legend_height = image_height + title_extent + tick_extent + label_extent + 2 * padding;
|
|
legend_width = image_width + 2 * padding;
|
|
break;
|
|
default:
|
|
throw new Error("unreachable code");
|
|
}
|
|
return { width: legend_width, height: legend_height };
|
|
};
|
|
ColorBarView.prototype.compute_legend_location = function () {
|
|
var legend_dimensions = this.compute_legend_dimensions();
|
|
var _a = [legend_dimensions.height, legend_dimensions.width], legend_height = _a[0], legend_width = _a[1];
|
|
var legend_margin = this.model.margin;
|
|
var panel = this.panel != null ? this.panel : this.plot_view.frame;
|
|
var _b = panel.bbox.ranges, hr = _b[0], vr = _b[1];
|
|
var location = this.model.location;
|
|
var sx, sy;
|
|
if (types_1.isString(location)) {
|
|
switch (location) {
|
|
case 'top_left':
|
|
sx = hr.start + legend_margin;
|
|
sy = vr.start + legend_margin;
|
|
break;
|
|
case 'top_center':
|
|
sx = (hr.end + hr.start) / 2 - legend_width / 2;
|
|
sy = vr.start + legend_margin;
|
|
break;
|
|
case 'top_right':
|
|
sx = hr.end - legend_margin - legend_width;
|
|
sy = vr.start + legend_margin;
|
|
break;
|
|
case 'bottom_right':
|
|
sx = hr.end - legend_margin - legend_width;
|
|
sy = vr.end - legend_margin - legend_height;
|
|
break;
|
|
case 'bottom_center':
|
|
sx = (hr.end + hr.start) / 2 - legend_width / 2;
|
|
sy = vr.end - legend_margin - legend_height;
|
|
break;
|
|
case 'bottom_left':
|
|
sx = hr.start + legend_margin;
|
|
sy = vr.end - legend_margin - legend_height;
|
|
break;
|
|
case 'center_left':
|
|
sx = hr.start + legend_margin;
|
|
sy = (vr.end + vr.start) / 2 - legend_height / 2;
|
|
break;
|
|
case 'center':
|
|
sx = (hr.end + hr.start) / 2 - legend_width / 2;
|
|
sy = (vr.end + vr.start) / 2 - legend_height / 2;
|
|
break;
|
|
case 'center_right':
|
|
sx = hr.end - legend_margin - legend_width;
|
|
sy = (vr.end + vr.start) / 2 - legend_height / 2;
|
|
break;
|
|
default:
|
|
throw new Error("unreachable code");
|
|
}
|
|
}
|
|
else if (types_1.isArray(location) && location.length == 2) {
|
|
var vx = location[0], vy = location[1];
|
|
sx = panel.xview.compute(vx);
|
|
sy = panel.yview.compute(vy) - legend_height;
|
|
}
|
|
else
|
|
throw new Error("unreachable code");
|
|
return { sx: sx, sy: sy };
|
|
};
|
|
ColorBarView.prototype.render = function () {
|
|
if (!this.model.visible || this.model.color_mapper == null)
|
|
return;
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
ctx.save();
|
|
var _a = this.compute_legend_location(), sx = _a.sx, sy = _a.sy;
|
|
ctx.translate(sx, sy);
|
|
this._draw_bbox(ctx);
|
|
var image_offset = this._get_image_offset();
|
|
ctx.translate(image_offset.x, image_offset.y);
|
|
this._draw_image(ctx);
|
|
if (this.model.color_mapper.low != null && this.model.color_mapper.high != null) {
|
|
var tick_info = this.tick_info();
|
|
this._draw_major_ticks(ctx, tick_info);
|
|
this._draw_minor_ticks(ctx, tick_info);
|
|
this._draw_major_labels(ctx, tick_info);
|
|
}
|
|
if (this.model.title)
|
|
this._draw_title(ctx);
|
|
ctx.restore();
|
|
};
|
|
ColorBarView.prototype._draw_bbox = function (ctx) {
|
|
var bbox = this.compute_legend_dimensions();
|
|
ctx.save();
|
|
if (this.visuals.background_fill.doit) {
|
|
this.visuals.background_fill.set_value(ctx);
|
|
ctx.fillRect(0, 0, bbox.width, bbox.height);
|
|
}
|
|
if (this.visuals.border_line.doit) {
|
|
this.visuals.border_line.set_value(ctx);
|
|
ctx.strokeRect(0, 0, bbox.width, bbox.height);
|
|
}
|
|
ctx.restore();
|
|
};
|
|
ColorBarView.prototype._draw_image = function (ctx) {
|
|
var image = this._computed_image_dimensions();
|
|
ctx.save();
|
|
ctx.setImageSmoothingEnabled(false);
|
|
ctx.globalAlpha = this.model.scale_alpha;
|
|
ctx.drawImage(this.image, 0, 0, image.width, image.height);
|
|
if (this.visuals.bar_line.doit) {
|
|
this.visuals.bar_line.set_value(ctx);
|
|
ctx.strokeRect(0, 0, image.width, image.height);
|
|
}
|
|
ctx.restore();
|
|
};
|
|
ColorBarView.prototype._draw_major_ticks = function (ctx, tick_info) {
|
|
if (!this.visuals.major_tick_line.doit)
|
|
return;
|
|
var _a = this._normals(), nx = _a[0], ny = _a[1];
|
|
var image = this._computed_image_dimensions();
|
|
var _b = [image.width * nx, image.height * ny], x_offset = _b[0], y_offset = _b[1];
|
|
var _c = tick_info.coords.major, sx = _c[0], sy = _c[1];
|
|
var tin = this.model.major_tick_in;
|
|
var tout = this.model.major_tick_out;
|
|
ctx.save();
|
|
ctx.translate(x_offset, y_offset);
|
|
this.visuals.major_tick_line.set_value(ctx);
|
|
for (var i = 0, end = sx.length; i < end; i++) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(Math.round(sx[i] + nx * tout), Math.round(sy[i] + ny * tout));
|
|
ctx.lineTo(Math.round(sx[i] - nx * tin), Math.round(sy[i] - ny * tin));
|
|
ctx.stroke();
|
|
}
|
|
ctx.restore();
|
|
};
|
|
ColorBarView.prototype._draw_minor_ticks = function (ctx, tick_info) {
|
|
if (!this.visuals.minor_tick_line.doit)
|
|
return;
|
|
var _a = this._normals(), nx = _a[0], ny = _a[1];
|
|
var image = this._computed_image_dimensions();
|
|
var _b = [image.width * nx, image.height * ny], x_offset = _b[0], y_offset = _b[1];
|
|
var _c = tick_info.coords.minor, sx = _c[0], sy = _c[1];
|
|
var tin = this.model.minor_tick_in;
|
|
var tout = this.model.minor_tick_out;
|
|
ctx.save();
|
|
ctx.translate(x_offset, y_offset);
|
|
this.visuals.minor_tick_line.set_value(ctx);
|
|
for (var i = 0, end = sx.length; i < end; i++) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(Math.round(sx[i] + nx * tout), Math.round(sy[i] + ny * tout));
|
|
ctx.lineTo(Math.round(sx[i] - nx * tin), Math.round(sy[i] - ny * tin));
|
|
ctx.stroke();
|
|
}
|
|
ctx.restore();
|
|
};
|
|
ColorBarView.prototype._draw_major_labels = function (ctx, tick_info) {
|
|
if (!this.visuals.major_label_text.doit)
|
|
return;
|
|
var _a = this._normals(), nx = _a[0], ny = _a[1];
|
|
var image = this._computed_image_dimensions();
|
|
var _b = [image.width * nx, image.height * ny], x_offset = _b[0], y_offset = _b[1];
|
|
var standoff = (this.model.label_standoff + this._tick_extent());
|
|
var _c = [standoff * nx, standoff * ny], x_standoff = _c[0], y_standoff = _c[1];
|
|
var _d = tick_info.coords.major, sx = _d[0], sy = _d[1];
|
|
var formatted_labels = tick_info.labels.major;
|
|
this.visuals.major_label_text.set_value(ctx);
|
|
ctx.save();
|
|
ctx.translate(x_offset + x_standoff, y_offset + y_standoff);
|
|
for (var i = 0, end = sx.length; i < end; i++) {
|
|
ctx.fillText(formatted_labels[i], Math.round(sx[i] + nx * this.model.label_standoff), Math.round(sy[i] + ny * this.model.label_standoff));
|
|
}
|
|
ctx.restore();
|
|
};
|
|
ColorBarView.prototype._draw_title = function (ctx) {
|
|
if (!this.visuals.title_text.doit)
|
|
return;
|
|
ctx.save();
|
|
this.visuals.title_text.set_value(ctx);
|
|
ctx.fillText(this.model.title, 0, -this.model.title_standoff);
|
|
ctx.restore();
|
|
};
|
|
/*protected*/ ColorBarView.prototype._get_label_extent = function () {
|
|
var major_labels = this.tick_info().labels.major;
|
|
var label_extent;
|
|
if (this.model.color_mapper.low != null && this.model.color_mapper.high != null && !object_1.isEmpty(major_labels)) {
|
|
var ctx_1 = this.plot_view.canvas_view.ctx;
|
|
ctx_1.save();
|
|
this.visuals.major_label_text.set_value(ctx_1);
|
|
switch (this.model.orientation) {
|
|
case "vertical":
|
|
label_extent = array_1.max((major_labels.map(function (label) { return ctx_1.measureText(label.toString()).width; })));
|
|
break;
|
|
case "horizontal":
|
|
label_extent = text_util.measure_font(this.visuals.major_label_text.font_value()).height;
|
|
break;
|
|
default:
|
|
throw new Error("unreachable code");
|
|
}
|
|
label_extent += this.model.label_standoff;
|
|
ctx_1.restore();
|
|
}
|
|
else
|
|
label_extent = 0;
|
|
return label_extent;
|
|
};
|
|
/*protected*/ ColorBarView.prototype._get_image_offset = function () {
|
|
// Returns image offset relative to legend bounding box
|
|
var x = this.model.padding;
|
|
var y = this.model.padding + this._title_extent();
|
|
return { x: x, y: y };
|
|
};
|
|
// {{{ TODO: state
|
|
ColorBarView.prototype._normals = function () {
|
|
return this.model.orientation == 'vertical' ? [1, 0] : [0, 1];
|
|
};
|
|
ColorBarView.prototype._title_extent = function () {
|
|
var font_value = this.model.title_text_font + " " + this.model.title_text_font_size + " " + this.model.title_text_font_style;
|
|
var title_extent = this.model.title ? text_util.measure_font(font_value).height + this.model.title_standoff : 0;
|
|
return title_extent;
|
|
};
|
|
ColorBarView.prototype._tick_extent = function () {
|
|
if (this.model.color_mapper.low != null && this.model.color_mapper.high != null)
|
|
return array_1.max([this.model.major_tick_out, this.model.minor_tick_out]);
|
|
else
|
|
return 0;
|
|
};
|
|
ColorBarView.prototype._computed_image_dimensions = function () {
|
|
/*
|
|
Heuristics to determine ColorBar image dimensions if set to "auto"
|
|
|
|
Note: Returns the height/width values for the ColorBar's scale image, not
|
|
the dimensions of the entire ColorBar.
|
|
|
|
If the short dimension (the width of a vertical bar or height of a
|
|
horizontal bar) is set to "auto", the resulting dimension will be set to
|
|
25 px.
|
|
|
|
For a ColorBar in a side panel with the long dimension (the height of a
|
|
vertical bar or width of a horizontal bar) set to "auto", the
|
|
resulting dimension will be as long as the adjacent frame edge, so that the
|
|
bar "fits" to the plot.
|
|
|
|
For a ColorBar in the plot frame with the long dimension set to "auto", the
|
|
resulting dimension will be the greater of:
|
|
* The length of the color palette * 25px
|
|
* The parallel frame dimension * 0.30
|
|
(i.e the frame height for a vertical ColorBar)
|
|
But not greater than:
|
|
* The parallel frame dimension * 0.80
|
|
*/
|
|
var frame_height = this.plot_view.frame._height.value;
|
|
var frame_width = this.plot_view.frame._width.value;
|
|
var title_extent = this._title_extent();
|
|
var height, width;
|
|
switch (this.model.orientation) {
|
|
case "vertical": {
|
|
if (this.model.height == 'auto') {
|
|
if (this.panel != null)
|
|
height = frame_height - 2 * this.model.padding - title_extent;
|
|
else {
|
|
height = array_1.max([this.model.color_mapper.palette.length * SHORT_DIM, frame_height * LONG_DIM_MIN_SCALAR]);
|
|
height = array_1.min([height, frame_height * LONG_DIM_MAX_SCALAR - 2 * this.model.padding - title_extent]);
|
|
}
|
|
}
|
|
else
|
|
height = this.model.height;
|
|
width = this.model.width == 'auto' ? SHORT_DIM : this.model.width;
|
|
break;
|
|
}
|
|
case "horizontal": {
|
|
height = this.model.height == 'auto' ? SHORT_DIM : this.model.height;
|
|
if (this.model.width == 'auto') {
|
|
if (this.panel != null)
|
|
width = frame_width - 2 * this.model.padding;
|
|
else {
|
|
width = array_1.max([this.model.color_mapper.palette.length * SHORT_DIM, frame_width * LONG_DIM_MIN_SCALAR]);
|
|
width = array_1.min([width, frame_width * LONG_DIM_MAX_SCALAR - 2 * this.model.padding]);
|
|
}
|
|
}
|
|
else
|
|
width = this.model.width;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("unreachable code");
|
|
}
|
|
return { width: width, height: height };
|
|
};
|
|
/*protected*/ ColorBarView.prototype._tick_coordinate_scale = function (scale_length) {
|
|
/*
|
|
Creates and returns a scale instance that maps the `color_mapper` range
|
|
(low to high) to a screen space range equal to the length of the ColorBar's
|
|
scale image. The scale is used to calculate the tick coordinates in screen
|
|
coordinates for plotting purposes.
|
|
|
|
Note: the type of color_mapper has to match the type of scale (i.e.
|
|
a LinearColorMapper will require a corresponding LinearScale instance).
|
|
*/
|
|
var ranges = {
|
|
source_range: new range1d_1.Range1d({
|
|
start: this.model.color_mapper.low,
|
|
end: this.model.color_mapper.high,
|
|
}),
|
|
target_range: new range1d_1.Range1d({
|
|
start: 0,
|
|
end: scale_length,
|
|
}),
|
|
};
|
|
switch (this.model.color_mapper.type) {
|
|
case "LinearColorMapper": return new linear_scale_1.LinearScale(ranges);
|
|
case "LogColorMapper": return new log_scale_1.LogScale(ranges);
|
|
default:
|
|
throw new Error("unreachable code");
|
|
}
|
|
};
|
|
ColorBarView.prototype._format_major_labels = function (initial_labels, major_ticks) {
|
|
// XXX: passing null as cross_loc probably means MercatorTickFormatters, etc
|
|
// will not function properly in conjunction with colorbars
|
|
var formatted_labels = this.model.formatter.doFormat(initial_labels, null);
|
|
for (var i = 0, end = major_ticks.length; i < end; i++) {
|
|
if (major_ticks[i] in this.model.major_label_overrides)
|
|
formatted_labels[i] = this.model.major_label_overrides[major_ticks[i]];
|
|
}
|
|
return formatted_labels;
|
|
};
|
|
ColorBarView.prototype.tick_info = function () {
|
|
var image_dimensions = this._computed_image_dimensions();
|
|
var scale_length;
|
|
switch (this.model.orientation) {
|
|
case "vertical": {
|
|
scale_length = image_dimensions.height;
|
|
break;
|
|
}
|
|
case "horizontal": {
|
|
scale_length = image_dimensions.width;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("unreachable code");
|
|
}
|
|
var scale = this._tick_coordinate_scale(scale_length);
|
|
var _a = this._normals(), i = _a[0], j = _a[1];
|
|
var _b = [this.model.color_mapper.low, this.model.color_mapper.high], start = _b[0], end = _b[1];
|
|
// XXX: passing null as cross_loc probably means MercatorTickers, etc
|
|
// will not function properly in conjunction with colorbars
|
|
var ticks = this.model.ticker.get_ticks(start, end, null, null, this.model.ticker.desired_num_ticks);
|
|
var majors = ticks.major;
|
|
var minors = ticks.minor;
|
|
var major_coords = [[], []];
|
|
var minor_coords = [[], []];
|
|
for (var ii = 0, _end = majors.length; ii < _end; ii++) {
|
|
if (majors[ii] < start || majors[ii] > end)
|
|
continue;
|
|
major_coords[i].push(majors[ii]);
|
|
major_coords[j].push(0);
|
|
}
|
|
for (var ii = 0, _end = minors.length; ii < _end; ii++) {
|
|
if (minors[ii] < start || minors[ii] > end)
|
|
continue;
|
|
minor_coords[i].push(minors[ii]);
|
|
minor_coords[j].push(0);
|
|
}
|
|
var labels = { major: this._format_major_labels(major_coords[i], majors) };
|
|
var coords = {
|
|
major: [[], []],
|
|
minor: [[], []],
|
|
};
|
|
coords.major[i] = scale.v_compute(major_coords[i]);
|
|
coords.minor[i] = scale.v_compute(minor_coords[i]);
|
|
coords.major[j] = major_coords[j];
|
|
coords.minor[j] = minor_coords[j];
|
|
// Because we want the scale to be reversed
|
|
if (this.model.orientation == 'vertical') {
|
|
coords.major[i] = arrayable_1.map(coords.major[i], function (coord) { return scale_length - coord; });
|
|
coords.minor[i] = arrayable_1.map(coords.minor[i], function (coord) { return scale_length - coord; });
|
|
}
|
|
return { coords: coords, labels: labels };
|
|
};
|
|
return ColorBarView;
|
|
}(annotation_1.AnnotationView));
|
|
exports.ColorBarView = ColorBarView;
|
|
var ColorBar = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ColorBar, _super);
|
|
function ColorBar(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ColorBar.initClass = function () {
|
|
this.prototype.type = 'ColorBar';
|
|
this.prototype.default_view = ColorBarView;
|
|
this.mixins([
|
|
'text:major_label_',
|
|
'text:title_',
|
|
'line:major_tick_',
|
|
'line:minor_tick_',
|
|
'line:border_',
|
|
'line:bar_',
|
|
'fill:background_',
|
|
]);
|
|
this.define({
|
|
location: [p.Any, 'top_right'],
|
|
orientation: [p.Orientation, 'vertical'],
|
|
title: [p.String,],
|
|
title_standoff: [p.Number, 2],
|
|
width: [p.Any, 'auto'],
|
|
height: [p.Any, 'auto'],
|
|
scale_alpha: [p.Number, 1.0],
|
|
ticker: [p.Instance, function () { return new basic_ticker_1.BasicTicker(); }],
|
|
formatter: [p.Instance, function () { return new basic_tick_formatter_1.BasicTickFormatter(); }],
|
|
major_label_overrides: [p.Any, {}],
|
|
color_mapper: [p.Instance],
|
|
label_standoff: [p.Number, 5],
|
|
margin: [p.Number, 30],
|
|
padding: [p.Number, 10],
|
|
major_tick_in: [p.Number, 5],
|
|
major_tick_out: [p.Number, 0],
|
|
minor_tick_in: [p.Number, 0],
|
|
minor_tick_out: [p.Number, 0],
|
|
});
|
|
this.override({
|
|
background_fill_color: "#ffffff",
|
|
background_fill_alpha: 0.95,
|
|
bar_line_color: null,
|
|
border_line_color: null,
|
|
major_label_text_align: "center",
|
|
major_label_text_baseline: "middle",
|
|
major_label_text_font_size: "8pt",
|
|
major_tick_line_color: "#ffffff",
|
|
minor_tick_line_color: null,
|
|
title_text_font_size: "10pt",
|
|
title_text_font_style: "italic",
|
|
});
|
|
};
|
|
return ColorBar;
|
|
}(annotation_1.Annotation));
|
|
exports.ColorBar = ColorBar;
|
|
ColorBar.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/index */ function _(require, module, exports) {
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
exports.Annotation = annotation_1.Annotation;
|
|
var arrow_1 = require(64) /* ./arrow */;
|
|
exports.Arrow = arrow_1.Arrow;
|
|
var arrow_head_1 = require(65) /* ./arrow_head */;
|
|
exports.ArrowHead = arrow_head_1.ArrowHead;
|
|
var arrow_head_2 = require(65) /* ./arrow_head */;
|
|
exports.OpenHead = arrow_head_2.OpenHead;
|
|
var arrow_head_3 = require(65) /* ./arrow_head */;
|
|
exports.NormalHead = arrow_head_3.NormalHead;
|
|
var arrow_head_4 = require(65) /* ./arrow_head */;
|
|
exports.TeeHead = arrow_head_4.TeeHead;
|
|
var arrow_head_5 = require(65) /* ./arrow_head */;
|
|
exports.VeeHead = arrow_head_5.VeeHead;
|
|
var band_1 = require(66) /* ./band */;
|
|
exports.Band = band_1.Band;
|
|
var box_annotation_1 = require(67) /* ./box_annotation */;
|
|
exports.BoxAnnotation = box_annotation_1.BoxAnnotation;
|
|
var color_bar_1 = require(68) /* ./color_bar */;
|
|
exports.ColorBar = color_bar_1.ColorBar;
|
|
var label_1 = require(70) /* ./label */;
|
|
exports.Label = label_1.Label;
|
|
var label_set_1 = require(71) /* ./label_set */;
|
|
exports.LabelSet = label_set_1.LabelSet;
|
|
var legend_1 = require(72) /* ./legend */;
|
|
exports.Legend = legend_1.Legend;
|
|
var legend_item_1 = require(73) /* ./legend_item */;
|
|
exports.LegendItem = legend_item_1.LegendItem;
|
|
var poly_annotation_1 = require(74) /* ./poly_annotation */;
|
|
exports.PolyAnnotation = poly_annotation_1.PolyAnnotation;
|
|
var slope_1 = require(75) /* ./slope */;
|
|
exports.Slope = slope_1.Slope;
|
|
var span_1 = require(76) /* ./span */;
|
|
exports.Span = span_1.Span;
|
|
var text_annotation_1 = require(77) /* ./text_annotation */;
|
|
exports.TextAnnotation = text_annotation_1.TextAnnotation;
|
|
var title_1 = require(78) /* ./title */;
|
|
exports.Title = title_1.Title;
|
|
var toolbar_panel_1 = require(79) /* ./toolbar_panel */;
|
|
exports.ToolbarPanel = toolbar_panel_1.ToolbarPanel;
|
|
var tooltip_1 = require(80) /* ./tooltip */;
|
|
exports.Tooltip = tooltip_1.Tooltip;
|
|
var whisker_1 = require(81) /* ./whisker */;
|
|
exports.Whisker = whisker_1.Whisker;
|
|
}
|
|
,
|
|
/* models/annotations/label */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var text_annotation_1 = require(77) /* ./text_annotation */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var LabelView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LabelView, _super);
|
|
function LabelView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
LabelView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.visuals.warm_cache();
|
|
};
|
|
LabelView.prototype._get_size = function () {
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
this.visuals.text.set_value(ctx);
|
|
var _a = ctx.measureText(this.model.text), width = _a.width, ascent = _a.ascent;
|
|
return { width: width, height: ascent };
|
|
};
|
|
LabelView.prototype.render = function () {
|
|
if (!this.model.visible && this.model.render_mode == 'css')
|
|
dom_1.undisplay(this.el);
|
|
if (!this.model.visible)
|
|
return;
|
|
// Here because AngleSpec does units tranform and label doesn't support specs
|
|
var angle;
|
|
switch (this.model.angle_units) {
|
|
case "rad": {
|
|
angle = -this.model.angle;
|
|
break;
|
|
}
|
|
case "deg": {
|
|
angle = (-this.model.angle * Math.PI) / 180.0;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("unreachable code");
|
|
}
|
|
var panel = this.panel != null ? this.panel : this.plot_view.frame;
|
|
var xscale = this.plot_view.frame.xscales[this.model.x_range_name];
|
|
var yscale = this.plot_view.frame.yscales[this.model.y_range_name];
|
|
var sx = this.model.x_units == "data" ? xscale.compute(this.model.x) : panel.xview.compute(this.model.x);
|
|
var sy = this.model.y_units == "data" ? yscale.compute(this.model.y) : panel.yview.compute(this.model.y);
|
|
sx += this.model.x_offset;
|
|
sy -= this.model.y_offset;
|
|
var draw = this.model.render_mode == 'canvas' ? this._canvas_text.bind(this) : this._css_text.bind(this);
|
|
draw(this.plot_view.canvas_view.ctx, this.model.text, sx, sy, angle);
|
|
};
|
|
return LabelView;
|
|
}(text_annotation_1.TextAnnotationView));
|
|
exports.LabelView = LabelView;
|
|
var Label = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Label, _super);
|
|
function Label(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Label.initClass = function () {
|
|
this.prototype.type = 'Label';
|
|
this.prototype.default_view = LabelView;
|
|
this.mixins(['text', 'line:border_', 'fill:background_']);
|
|
this.define({
|
|
x: [p.Number,],
|
|
x_units: [p.SpatialUnits, 'data'],
|
|
y: [p.Number,],
|
|
y_units: [p.SpatialUnits, 'data'],
|
|
text: [p.String,],
|
|
angle: [p.Angle, 0],
|
|
angle_units: [p.AngleUnits, 'rad'],
|
|
x_offset: [p.Number, 0],
|
|
y_offset: [p.Number, 0],
|
|
x_range_name: [p.String, 'default'],
|
|
y_range_name: [p.String, 'default'],
|
|
});
|
|
this.override({
|
|
background_fill_color: null,
|
|
border_line_color: null,
|
|
});
|
|
};
|
|
return Label;
|
|
}(text_annotation_1.TextAnnotation));
|
|
exports.Label = Label;
|
|
Label.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/label_set */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var text_annotation_1 = require(77) /* ./text_annotation */;
|
|
var column_data_source_1 = require(208) /* ../sources/column_data_source */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var LabelSetView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LabelSetView, _super);
|
|
function LabelSetView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
LabelSetView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.set_data(this.model.source);
|
|
if (this.model.render_mode == 'css') {
|
|
for (var i = 0, end = this._text.length; i < end; i++) {
|
|
var el = dom_1.div({ class: 'bk-annotation-child', style: { display: "none" } });
|
|
this.el.appendChild(el);
|
|
}
|
|
}
|
|
};
|
|
LabelSetView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
if (this.model.render_mode == 'css') {
|
|
// dispatch CSS update immediately
|
|
this.connect(this.model.change, function () {
|
|
_this.set_data(_this.model.source);
|
|
_this.render();
|
|
});
|
|
this.connect(this.model.source.streaming, function () {
|
|
_this.set_data(_this.model.source);
|
|
_this.render();
|
|
});
|
|
this.connect(this.model.source.patching, function () {
|
|
_this.set_data(_this.model.source);
|
|
_this.render();
|
|
});
|
|
this.connect(this.model.source.change, function () {
|
|
_this.set_data(_this.model.source);
|
|
_this.render();
|
|
});
|
|
}
|
|
else {
|
|
this.connect(this.model.change, function () {
|
|
_this.set_data(_this.model.source);
|
|
_this.plot_view.request_render();
|
|
});
|
|
this.connect(this.model.source.streaming, function () {
|
|
_this.set_data(_this.model.source);
|
|
_this.plot_view.request_render();
|
|
});
|
|
this.connect(this.model.source.patching, function () {
|
|
_this.set_data(_this.model.source);
|
|
_this.plot_view.request_render();
|
|
});
|
|
this.connect(this.model.source.change, function () {
|
|
_this.set_data(_this.model.source);
|
|
_this.plot_view.request_render();
|
|
});
|
|
}
|
|
};
|
|
LabelSetView.prototype.set_data = function (source) {
|
|
_super.prototype.set_data.call(this, source);
|
|
this.visuals.warm_cache(source);
|
|
};
|
|
LabelSetView.prototype._map_data = function () {
|
|
var xscale = this.plot_view.frame.xscales[this.model.x_range_name];
|
|
var yscale = this.plot_view.frame.yscales[this.model.y_range_name];
|
|
var panel = this.panel != null ? this.panel : this.plot_view.frame;
|
|
var sx = this.model.x_units == "data" ? xscale.v_compute(this._x) : panel.xview.v_compute(this._x);
|
|
var sy = this.model.y_units == "data" ? yscale.v_compute(this._y) : panel.yview.v_compute(this._y);
|
|
return [sx, sy];
|
|
};
|
|
LabelSetView.prototype.render = function () {
|
|
if (!this.model.visible && this.model.render_mode == 'css')
|
|
dom_1.undisplay(this.el);
|
|
if (!this.model.visible)
|
|
return;
|
|
var draw = this.model.render_mode == 'canvas' ? this._v_canvas_text.bind(this) : this._v_css_text.bind(this);
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
var _a = this._map_data(), sx = _a[0], sy = _a[1];
|
|
for (var i = 0, end = this._text.length; i < end; i++) {
|
|
draw(ctx, i, this._text[i], sx[i] + this._x_offset[i], sy[i] - this._y_offset[i], this._angle[i]);
|
|
}
|
|
};
|
|
LabelSetView.prototype._get_size = function () {
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
this.visuals.text.set_value(ctx);
|
|
var _a = ctx.measureText(this._text[0]), width = _a.width, ascent = _a.ascent;
|
|
return { width: width, height: ascent };
|
|
};
|
|
LabelSetView.prototype._v_canvas_text = function (ctx, i, text, sx, sy, angle) {
|
|
this.visuals.text.set_vectorize(ctx, i);
|
|
var bbox_dims = this._calculate_bounding_box_dimensions(ctx, text);
|
|
ctx.save();
|
|
ctx.beginPath();
|
|
ctx.translate(sx, sy);
|
|
ctx.rotate(angle);
|
|
ctx.rect(bbox_dims[0], bbox_dims[1], bbox_dims[2], bbox_dims[3]);
|
|
if (this.visuals.background_fill.doit) {
|
|
this.visuals.background_fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (this.visuals.border_line.doit) {
|
|
this.visuals.border_line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
if (this.visuals.text.doit) {
|
|
this.visuals.text.set_vectorize(ctx, i);
|
|
ctx.fillText(text, 0, 0);
|
|
}
|
|
ctx.restore();
|
|
};
|
|
LabelSetView.prototype._v_css_text = function (ctx, i, text, sx, sy, angle) {
|
|
var el = this.el.children[i];
|
|
el.textContent = text;
|
|
this.visuals.text.set_vectorize(ctx, i);
|
|
var bbox_dims = this._calculate_bounding_box_dimensions(ctx, text);
|
|
// attempt to support vector-style ("8 4 8") line dashing for css mode
|
|
var ld = this.visuals.border_line.line_dash.value();
|
|
var line_dash = ld.length < 2 ? "solid" : "dashed";
|
|
this.visuals.border_line.set_vectorize(ctx, i);
|
|
this.visuals.background_fill.set_vectorize(ctx, i);
|
|
el.style.position = 'absolute';
|
|
el.style.left = sx + bbox_dims[0] + "px";
|
|
el.style.top = sy + bbox_dims[1] + "px";
|
|
el.style.color = "" + this.visuals.text.text_color.value();
|
|
el.style.opacity = "" + this.visuals.text.text_alpha.value();
|
|
el.style.font = "" + this.visuals.text.font_value();
|
|
el.style.lineHeight = "normal"; // needed to prevent ipynb css override
|
|
if (angle) {
|
|
el.style.transform = "rotate(" + angle + "rad)";
|
|
}
|
|
if (this.visuals.background_fill.doit) {
|
|
el.style.backgroundColor = "" + this.visuals.background_fill.color_value();
|
|
}
|
|
if (this.visuals.border_line.doit) {
|
|
el.style.borderStyle = "" + line_dash;
|
|
el.style.borderWidth = this.visuals.border_line.line_width.value() + "px";
|
|
el.style.borderColor = "" + this.visuals.border_line.color_value();
|
|
}
|
|
dom_1.display(el);
|
|
};
|
|
return LabelSetView;
|
|
}(text_annotation_1.TextAnnotationView));
|
|
exports.LabelSetView = LabelSetView;
|
|
var LabelSet = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LabelSet, _super);
|
|
function LabelSet(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
LabelSet.initClass = function () {
|
|
this.prototype.type = 'LabelSet';
|
|
this.prototype.default_view = LabelSetView;
|
|
this.mixins(['text', 'line:border_', 'fill:background_']);
|
|
this.define({
|
|
x: [p.NumberSpec],
|
|
y: [p.NumberSpec],
|
|
x_units: [p.SpatialUnits, 'data'],
|
|
y_units: [p.SpatialUnits, 'data'],
|
|
text: [p.StringSpec, { field: "text" }],
|
|
angle: [p.AngleSpec, 0],
|
|
x_offset: [p.NumberSpec, { value: 0 }],
|
|
y_offset: [p.NumberSpec, { value: 0 }],
|
|
source: [p.Instance, function () { return new column_data_source_1.ColumnDataSource(); }],
|
|
x_range_name: [p.String, 'default'],
|
|
y_range_name: [p.String, 'default'],
|
|
});
|
|
this.override({
|
|
background_fill_color: null,
|
|
border_line_color: null,
|
|
});
|
|
};
|
|
return LabelSet;
|
|
}(text_annotation_1.TextAnnotation));
|
|
exports.LabelSet = LabelSet;
|
|
LabelSet.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/legend */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var signaling_1 = require(22) /* ../../core/signaling */;
|
|
var text_1 = require(43) /* ../../core/util/text */;
|
|
var bbox_1 = require(27) /* ../../core/util/bbox */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var LegendView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LegendView, _super);
|
|
function LegendView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
LegendView.prototype.cursor = function (_sx, _sy) {
|
|
return this.model.click_policy == "none" ? null : "pointer";
|
|
};
|
|
Object.defineProperty(LegendView.prototype, "legend_padding", {
|
|
get: function () {
|
|
return this.visuals.border_line.line_color.value() != null ? this.model.padding : 0;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
LegendView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.change, function () { return _this.plot_view.request_render(); });
|
|
this.connect(this.model.item_change, function () { return _this.plot_view.request_render(); });
|
|
};
|
|
LegendView.prototype.compute_legend_bbox = function () {
|
|
var legend_names = this.model.get_legend_names();
|
|
var _a = this.model, glyph_height = _a.glyph_height, glyph_width = _a.glyph_width;
|
|
var _b = this.model, label_height = _b.label_height, label_width = _b.label_width;
|
|
this.max_label_height = array_1.max([text_1.measure_font(this.visuals.label_text.font_value()).height, label_height, glyph_height]);
|
|
// this is to measure text properties
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
ctx.save();
|
|
this.visuals.label_text.set_value(ctx);
|
|
this.text_widths = {};
|
|
for (var _i = 0, legend_names_1 = legend_names; _i < legend_names_1.length; _i++) {
|
|
var name_1 = legend_names_1[_i];
|
|
this.text_widths[name_1] = array_1.max([ctx.measureText(name_1).width, label_width]);
|
|
}
|
|
ctx.restore();
|
|
var max_label_width = Math.max(array_1.max(object_1.values(this.text_widths)), 0);
|
|
var legend_margin = this.model.margin;
|
|
var legend_padding = this.legend_padding;
|
|
var legend_spacing = this.model.spacing;
|
|
var label_standoff = this.model.label_standoff;
|
|
var legend_height, legend_width;
|
|
if (this.model.orientation == "vertical") {
|
|
legend_height = legend_names.length * this.max_label_height + Math.max(legend_names.length - 1, 0) * legend_spacing + 2 * legend_padding;
|
|
legend_width = max_label_width + glyph_width + label_standoff + 2 * legend_padding;
|
|
}
|
|
else {
|
|
legend_width = 2 * legend_padding + Math.max(legend_names.length - 1, 0) * legend_spacing;
|
|
for (var name_2 in this.text_widths) {
|
|
var width = this.text_widths[name_2];
|
|
legend_width += array_1.max([width, label_width]) + glyph_width + label_standoff;
|
|
}
|
|
legend_height = this.max_label_height + 2 * legend_padding;
|
|
}
|
|
var panel = this.panel != null ? this.panel : this.plot_view.frame;
|
|
var _c = panel.bbox.ranges, hr = _c[0], vr = _c[1];
|
|
var location = this.model.location;
|
|
var sx, sy;
|
|
if (types_1.isString(location)) {
|
|
switch (location) {
|
|
case 'top_left':
|
|
sx = hr.start + legend_margin;
|
|
sy = vr.start + legend_margin;
|
|
break;
|
|
case 'top_center':
|
|
sx = (hr.end + hr.start) / 2 - legend_width / 2;
|
|
sy = vr.start + legend_margin;
|
|
break;
|
|
case 'top_right':
|
|
sx = hr.end - legend_margin - legend_width;
|
|
sy = vr.start + legend_margin;
|
|
break;
|
|
case 'bottom_right':
|
|
sx = hr.end - legend_margin - legend_width;
|
|
sy = vr.end - legend_margin - legend_height;
|
|
break;
|
|
case 'bottom_center':
|
|
sx = (hr.end + hr.start) / 2 - legend_width / 2;
|
|
sy = vr.end - legend_margin - legend_height;
|
|
break;
|
|
case 'bottom_left':
|
|
sx = hr.start + legend_margin;
|
|
sy = vr.end - legend_margin - legend_height;
|
|
break;
|
|
case 'center_left':
|
|
sx = hr.start + legend_margin;
|
|
sy = (vr.end + vr.start) / 2 - legend_height / 2;
|
|
break;
|
|
case 'center':
|
|
sx = (hr.end + hr.start) / 2 - legend_width / 2;
|
|
sy = (vr.end + vr.start) / 2 - legend_height / 2;
|
|
break;
|
|
case 'center_right':
|
|
sx = hr.end - legend_margin - legend_width;
|
|
sy = (vr.end + vr.start) / 2 - legend_height / 2;
|
|
break;
|
|
default:
|
|
throw new Error("unreachable code");
|
|
}
|
|
}
|
|
else if (types_1.isArray(location) && location.length == 2) {
|
|
var vx = location[0], vy = location[1];
|
|
sx = panel.xview.compute(vx);
|
|
sy = panel.yview.compute(vy) - legend_height;
|
|
}
|
|
else
|
|
throw new Error("unreachable code");
|
|
return new bbox_1.BBox({ left: sx, top: sy, width: legend_width, height: legend_height });
|
|
};
|
|
LegendView.prototype.interactive_bbox = function () {
|
|
return this.compute_legend_bbox();
|
|
};
|
|
LegendView.prototype.interactive_hit = function (sx, sy) {
|
|
var bbox = this.interactive_bbox();
|
|
return bbox.contains(sx, sy);
|
|
};
|
|
LegendView.prototype.on_hit = function (sx, sy) {
|
|
var _a, _b;
|
|
var yoffset;
|
|
var glyph_width = this.model.glyph_width;
|
|
var legend_padding = this.legend_padding;
|
|
var legend_spacing = this.model.spacing;
|
|
var label_standoff = this.model.label_standoff;
|
|
var xoffset = (yoffset = legend_padding);
|
|
var legend_bbox = this.compute_legend_bbox();
|
|
var vertical = this.model.orientation == "vertical";
|
|
for (var _i = 0, _c = this.model.items; _i < _c.length; _i++) {
|
|
var item = _c[_i];
|
|
var labels = item.get_labels_list_from_label_prop();
|
|
for (var _d = 0, labels_1 = labels; _d < labels_1.length; _d++) {
|
|
var label = labels_1[_d];
|
|
var x1 = legend_bbox.x + xoffset;
|
|
var y1 = legend_bbox.y + yoffset;
|
|
var w = void 0, h = void 0;
|
|
if (vertical)
|
|
_a = [legend_bbox.width - 2 * legend_padding, this.max_label_height], w = _a[0], h = _a[1];
|
|
else
|
|
_b = [this.text_widths[label] + glyph_width + label_standoff, this.max_label_height], w = _b[0], h = _b[1];
|
|
var bbox = new bbox_1.BBox({ left: x1, top: y1, width: w, height: h });
|
|
if (bbox.contains(sx, sy)) {
|
|
switch (this.model.click_policy) {
|
|
case "hide": {
|
|
for (var _e = 0, _f = item.renderers; _e < _f.length; _e++) {
|
|
var r = _f[_e];
|
|
r.visible = !r.visible;
|
|
}
|
|
break;
|
|
}
|
|
case "mute": {
|
|
for (var _g = 0, _h = item.renderers; _g < _h.length; _g++) {
|
|
var r = _h[_g];
|
|
r.muted = !r.muted;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
if (vertical)
|
|
yoffset += this.max_label_height + legend_spacing;
|
|
else
|
|
xoffset += this.text_widths[label] + glyph_width + label_standoff + legend_spacing;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
LegendView.prototype.render = function () {
|
|
if (!this.model.visible)
|
|
return;
|
|
if (this.model.items.length == 0)
|
|
return;
|
|
// set a backref on render so that items can later signal item_change upates
|
|
// on the model to trigger a re-render
|
|
for (var _i = 0, _a = this.model.items; _i < _a.length; _i++) {
|
|
var item = _a[_i];
|
|
item.legend = this.model;
|
|
}
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
var bbox = this.compute_legend_bbox();
|
|
ctx.save();
|
|
this._draw_legend_box(ctx, bbox);
|
|
this._draw_legend_items(ctx, bbox);
|
|
ctx.restore();
|
|
};
|
|
LegendView.prototype._draw_legend_box = function (ctx, bbox) {
|
|
ctx.beginPath();
|
|
ctx.rect(bbox.x, bbox.y, bbox.width, bbox.height);
|
|
this.visuals.background_fill.set_value(ctx);
|
|
ctx.fill();
|
|
if (this.visuals.border_line.doit) {
|
|
this.visuals.border_line.set_value(ctx);
|
|
ctx.stroke();
|
|
}
|
|
};
|
|
LegendView.prototype._draw_legend_items = function (ctx, bbox) {
|
|
var _this = this;
|
|
var _a = this.model, glyph_width = _a.glyph_width, glyph_height = _a.glyph_height;
|
|
var legend_padding = this.legend_padding;
|
|
var legend_spacing = this.model.spacing;
|
|
var label_standoff = this.model.label_standoff;
|
|
var xoffset = legend_padding;
|
|
var yoffset = legend_padding;
|
|
var vertical = this.model.orientation == "vertical";
|
|
var _loop_1 = function (item) {
|
|
var _a, _b;
|
|
var labels = item.get_labels_list_from_label_prop();
|
|
var field = item.get_field_from_label_prop();
|
|
if (labels.length == 0)
|
|
return "continue";
|
|
var active = (function () {
|
|
switch (_this.model.click_policy) {
|
|
case "none": return true;
|
|
case "hide": return array_1.every(item.renderers, function (r) { return r.visible; });
|
|
case "mute": return array_1.every(item.renderers, function (r) { return !r.muted; });
|
|
}
|
|
})();
|
|
for (var _i = 0, labels_2 = labels; _i < labels_2.length; _i++) {
|
|
var label = labels_2[_i];
|
|
var x1 = bbox.x + xoffset;
|
|
var y1 = bbox.y + yoffset;
|
|
var x2 = x1 + glyph_width;
|
|
var y2 = y1 + glyph_height;
|
|
if (vertical)
|
|
yoffset += this_1.max_label_height + legend_spacing;
|
|
else
|
|
xoffset += this_1.text_widths[label] + glyph_width + label_standoff + legend_spacing;
|
|
this_1.visuals.label_text.set_value(ctx);
|
|
ctx.fillText(label, x2 + label_standoff, y1 + this_1.max_label_height / 2.0);
|
|
for (var _c = 0, _d = item.renderers; _c < _d.length; _c++) {
|
|
var r = _d[_c];
|
|
var view = this_1.plot_view.renderer_views[r.id];
|
|
view.draw_legend(ctx, x1, x2, y1, y2, field, label, item.index);
|
|
}
|
|
if (!active) {
|
|
var w = void 0, h = void 0;
|
|
if (vertical)
|
|
_a = [bbox.width - 2 * legend_padding, this_1.max_label_height], w = _a[0], h = _a[1];
|
|
else
|
|
_b = [this_1.text_widths[label] + glyph_width + label_standoff, this_1.max_label_height], w = _b[0], h = _b[1];
|
|
ctx.beginPath();
|
|
ctx.rect(x1, y1, w, h);
|
|
this_1.visuals.inactive_fill.set_value(ctx);
|
|
ctx.fill();
|
|
}
|
|
}
|
|
};
|
|
var this_1 = this;
|
|
for (var _i = 0, _b = this.model.items; _i < _b.length; _i++) {
|
|
var item = _b[_i];
|
|
_loop_1(item);
|
|
}
|
|
};
|
|
LegendView.prototype._get_size = function () {
|
|
var _a = this.compute_legend_bbox(), width = _a.width, height = _a.height;
|
|
return {
|
|
width: width + 2 * this.model.margin,
|
|
height: height + 2 * this.model.margin,
|
|
};
|
|
};
|
|
return LegendView;
|
|
}(annotation_1.AnnotationView));
|
|
exports.LegendView = LegendView;
|
|
var Legend = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Legend, _super);
|
|
function Legend(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Legend.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.item_change = new signaling_1.Signal0(this, "item_change");
|
|
};
|
|
Legend.initClass = function () {
|
|
this.prototype.type = 'Legend';
|
|
this.prototype.default_view = LegendView;
|
|
this.mixins(['text:label_', 'fill:inactive_', 'line:border_', 'fill:background_']);
|
|
this.define({
|
|
orientation: [p.Orientation, 'vertical'],
|
|
location: [p.Any, 'top_right'],
|
|
label_standoff: [p.Number, 5],
|
|
glyph_height: [p.Number, 20],
|
|
glyph_width: [p.Number, 20],
|
|
label_height: [p.Number, 20],
|
|
label_width: [p.Number, 20],
|
|
margin: [p.Number, 10],
|
|
padding: [p.Number, 10],
|
|
spacing: [p.Number, 3],
|
|
items: [p.Array, []],
|
|
click_policy: [p.Any, "none"],
|
|
});
|
|
this.override({
|
|
border_line_color: "#e5e5e5",
|
|
border_line_alpha: 0.5,
|
|
border_line_width: 1,
|
|
background_fill_color: "#ffffff",
|
|
background_fill_alpha: 0.95,
|
|
inactive_fill_color: "white",
|
|
inactive_fill_alpha: 0.7,
|
|
label_text_font_size: "10pt",
|
|
label_text_baseline: "middle",
|
|
});
|
|
};
|
|
Legend.prototype.get_legend_names = function () {
|
|
var legend_names = [];
|
|
for (var _i = 0, _a = this.items; _i < _a.length; _i++) {
|
|
var item = _a[_i];
|
|
var labels = item.get_labels_list_from_label_prop();
|
|
legend_names.push.apply(legend_names, labels);
|
|
}
|
|
return legend_names;
|
|
};
|
|
return Legend;
|
|
}(annotation_1.Annotation));
|
|
exports.Legend = Legend;
|
|
Legend.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/legend_item */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var columnar_data_source_1 = require(209) /* ../sources/columnar_data_source */;
|
|
var vectorization_1 = require(49) /* ../../core/vectorization */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var LegendItem = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LegendItem, _super);
|
|
function LegendItem(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
LegendItem.initClass = function () {
|
|
this.prototype.type = "LegendItem";
|
|
this.define({
|
|
label: [p.StringSpec, null],
|
|
renderers: [p.Array, []],
|
|
index: [p.Number, null],
|
|
});
|
|
};
|
|
/*protected*/ LegendItem.prototype._check_data_sources_on_renderers = function () {
|
|
var field = this.get_field_from_label_prop();
|
|
if (field != null) {
|
|
if (this.renderers.length < 1) {
|
|
return false;
|
|
}
|
|
var source = this.renderers[0].data_source;
|
|
if (source != null) {
|
|
for (var _i = 0, _a = this.renderers; _i < _a.length; _i++) {
|
|
var r = _a[_i];
|
|
if (r.data_source != source) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
/*protected*/ LegendItem.prototype._check_field_label_on_data_source = function () {
|
|
var field = this.get_field_from_label_prop();
|
|
if (field != null) {
|
|
if (this.renderers.length < 1) {
|
|
return false;
|
|
}
|
|
var source = this.renderers[0].data_source;
|
|
if (source != null && !array_1.includes(source.columns(), field)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
LegendItem.prototype.initialize = function () {
|
|
var _this = this;
|
|
_super.prototype.initialize.call(this);
|
|
this.legend = null;
|
|
this.connect(this.change, function () {
|
|
if (_this.legend != null)
|
|
_this.legend.item_change.emit();
|
|
});
|
|
// Validate data_sources match
|
|
var data_source_validation = this._check_data_sources_on_renderers();
|
|
if (!data_source_validation)
|
|
logging_1.logger.error("Non matching data sources on legend item renderers");
|
|
// Validate label in data_source
|
|
var field_validation = this._check_field_label_on_data_source();
|
|
if (!field_validation)
|
|
logging_1.logger.error("Bad column name on label: " + this.label);
|
|
};
|
|
LegendItem.prototype.get_field_from_label_prop = function () {
|
|
var label = this.label;
|
|
return vectorization_1.isField(label) ? label.field : null;
|
|
};
|
|
LegendItem.prototype.get_labels_list_from_label_prop = function () {
|
|
// Always return a list of the labels
|
|
if (vectorization_1.isValue(this.label)) {
|
|
var value = this.label.value;
|
|
return value != null ? [value] : [];
|
|
}
|
|
var field = this.get_field_from_label_prop();
|
|
if (field != null) {
|
|
var source = void 0;
|
|
if (this.renderers[0] && this.renderers[0].data_source != null)
|
|
source = this.renderers[0].data_source;
|
|
else
|
|
return ["No source found"];
|
|
if (source instanceof columnar_data_source_1.ColumnarDataSource) {
|
|
var data = source.get_column(field);
|
|
if (data != null)
|
|
return array_1.uniq(Array.from(data));
|
|
else
|
|
return ["Invalid field"];
|
|
}
|
|
}
|
|
return [];
|
|
};
|
|
return LegendItem;
|
|
}(model_1.Model));
|
|
exports.LegendItem = LegendItem;
|
|
LegendItem.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/poly_annotation */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
var signaling_1 = require(22) /* ../../core/signaling */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var PolyAnnotationView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PolyAnnotationView, _super);
|
|
function PolyAnnotationView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
PolyAnnotationView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
// need to respond to either normal BB change events or silent
|
|
// "data only updates" that tools might want to use
|
|
this.connect(this.model.change, function () { return _this.plot_view.request_render(); });
|
|
this.connect(this.model.data_update, function () { return _this.plot_view.request_render(); });
|
|
};
|
|
PolyAnnotationView.prototype.render = function () {
|
|
if (!this.model.visible)
|
|
return;
|
|
var _a = this.model, xs = _a.xs, ys = _a.ys;
|
|
if (xs.length != ys.length)
|
|
return;
|
|
if (xs.length < 3 || ys.length < 3)
|
|
return;
|
|
var frame = this.plot_view.frame;
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
for (var i = 0, end = xs.length; i < end; i++) {
|
|
var sx = void 0;
|
|
if (this.model.xs_units == 'screen')
|
|
sx = this.model.screen ? xs[i] : frame.xview.compute(xs[i]);
|
|
else
|
|
throw new Error("not implemented");
|
|
var sy = void 0;
|
|
if (this.model.ys_units == 'screen')
|
|
sy = this.model.screen ? ys[i] : frame.yview.compute(ys[i]);
|
|
else
|
|
throw new Error("not implemented");
|
|
if (i == 0) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(sx, sy);
|
|
}
|
|
else {
|
|
ctx.lineTo(sx, sy);
|
|
}
|
|
}
|
|
ctx.closePath();
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_value(ctx);
|
|
ctx.stroke();
|
|
}
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_value(ctx);
|
|
ctx.fill();
|
|
}
|
|
};
|
|
return PolyAnnotationView;
|
|
}(annotation_1.AnnotationView));
|
|
exports.PolyAnnotationView = PolyAnnotationView;
|
|
var PolyAnnotation = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PolyAnnotation, _super);
|
|
function PolyAnnotation(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
PolyAnnotation.initClass = function () {
|
|
this.prototype.type = "PolyAnnotation";
|
|
this.prototype.default_view = PolyAnnotationView;
|
|
this.mixins(['line', 'fill']);
|
|
this.define({
|
|
xs: [p.Array, []],
|
|
xs_units: [p.SpatialUnits, 'data'],
|
|
ys: [p.Array, []],
|
|
ys_units: [p.SpatialUnits, 'data'],
|
|
x_range_name: [p.String, 'default'],
|
|
y_range_name: [p.String, 'default'],
|
|
});
|
|
this.internal({
|
|
screen: [p.Boolean, false],
|
|
});
|
|
this.override({
|
|
fill_color: "#fff9ba",
|
|
fill_alpha: 0.4,
|
|
line_color: "#cccccc",
|
|
line_alpha: 0.3,
|
|
});
|
|
};
|
|
PolyAnnotation.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.data_update = new signaling_1.Signal0(this, "data_update");
|
|
};
|
|
PolyAnnotation.prototype.update = function (_a) {
|
|
var xs = _a.xs, ys = _a.ys;
|
|
this.setv({ xs: xs, ys: ys, screen: true }, { silent: true });
|
|
this.data_update.emit();
|
|
};
|
|
return PolyAnnotation;
|
|
}(annotation_1.Annotation));
|
|
exports.PolyAnnotation = PolyAnnotation;
|
|
PolyAnnotation.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/slope */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var SlopeView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(SlopeView, _super);
|
|
function SlopeView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
SlopeView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
};
|
|
SlopeView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.change, function () { return _this.plot_view.request_render(); });
|
|
};
|
|
SlopeView.prototype.render = function () {
|
|
if (!this.model.visible)
|
|
return;
|
|
this._draw_slope();
|
|
};
|
|
SlopeView.prototype._draw_slope = function () {
|
|
var gradient = this.model.gradient;
|
|
var y_intercept = this.model.y_intercept;
|
|
if (gradient == null || y_intercept == null) {
|
|
return;
|
|
}
|
|
var frame = this.plot_view.frame;
|
|
var xscale = frame.xscales[this.model.x_range_name];
|
|
var yscale = frame.yscales[this.model.y_range_name];
|
|
var sy_start = frame._top.value;
|
|
var sy_end = sy_start + frame._height.value;
|
|
var y_start = yscale.invert(sy_start);
|
|
var y_end = yscale.invert(sy_end);
|
|
var x_start = (y_start - y_intercept) / gradient;
|
|
var x_end = (y_end - y_intercept) / gradient;
|
|
var sx_start = xscale.compute(x_start);
|
|
var sx_end = xscale.compute(x_end);
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
ctx.save();
|
|
ctx.beginPath();
|
|
this.visuals.line.set_value(ctx);
|
|
ctx.moveTo(sx_start, sy_start);
|
|
ctx.lineTo(sx_end, sy_end);
|
|
ctx.stroke();
|
|
ctx.restore();
|
|
};
|
|
return SlopeView;
|
|
}(annotation_1.AnnotationView));
|
|
exports.SlopeView = SlopeView;
|
|
var Slope = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Slope, _super);
|
|
function Slope(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Slope.initClass = function () {
|
|
this.prototype.type = 'Slope';
|
|
this.prototype.default_view = SlopeView;
|
|
this.mixins(['line']);
|
|
this.define({
|
|
gradient: [p.Number, null],
|
|
y_intercept: [p.Number, null],
|
|
x_range_name: [p.String, 'default'],
|
|
y_range_name: [p.String, 'default'],
|
|
});
|
|
this.override({
|
|
line_color: 'black',
|
|
});
|
|
};
|
|
return Slope;
|
|
}(annotation_1.Annotation));
|
|
exports.Slope = Slope;
|
|
Slope.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/span */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var SpanView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(SpanView, _super);
|
|
function SpanView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
SpanView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.plot_view.canvas_overlays.appendChild(this.el);
|
|
this.el.style.position = "absolute";
|
|
dom_1.undisplay(this.el);
|
|
};
|
|
SpanView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
if (this.model.for_hover)
|
|
this.connect(this.model.properties.computed_location.change, function () { return _this._draw_span(); });
|
|
else {
|
|
if (this.model.render_mode == 'canvas') {
|
|
this.connect(this.model.change, function () { return _this.plot_view.request_render(); });
|
|
this.connect(this.model.properties.location.change, function () { return _this.plot_view.request_render(); });
|
|
}
|
|
else {
|
|
this.connect(this.model.change, function () { return _this.render(); });
|
|
this.connect(this.model.properties.location.change, function () { return _this._draw_span(); });
|
|
}
|
|
}
|
|
};
|
|
SpanView.prototype.render = function () {
|
|
if (!this.model.visible && this.model.render_mode == 'css')
|
|
dom_1.undisplay(this.el);
|
|
if (!this.model.visible)
|
|
return;
|
|
this._draw_span();
|
|
};
|
|
SpanView.prototype._draw_span = function () {
|
|
var _this = this;
|
|
var loc = this.model.for_hover ? this.model.computed_location : this.model.location;
|
|
if (loc == null) {
|
|
dom_1.undisplay(this.el);
|
|
return;
|
|
}
|
|
var frame = this.plot_view.frame;
|
|
var xscale = frame.xscales[this.model.x_range_name];
|
|
var yscale = frame.yscales[this.model.y_range_name];
|
|
var _calc_dim = function (scale, view) {
|
|
if (_this.model.for_hover)
|
|
return _this.model.computed_location;
|
|
else {
|
|
if (_this.model.location_units == 'data')
|
|
return scale.compute(loc);
|
|
else
|
|
return view.compute(loc);
|
|
}
|
|
};
|
|
var height, sleft, stop, width;
|
|
if (this.model.dimension == 'width') {
|
|
stop = _calc_dim(yscale, frame.yview);
|
|
sleft = frame._left.value;
|
|
width = frame._width.value;
|
|
height = this.model.properties.line_width.value();
|
|
}
|
|
else {
|
|
stop = frame._top.value;
|
|
sleft = _calc_dim(xscale, frame.xview);
|
|
width = this.model.properties.line_width.value();
|
|
height = frame._height.value;
|
|
}
|
|
if (this.model.render_mode == "css") {
|
|
this.el.style.top = stop + "px";
|
|
this.el.style.left = sleft + "px";
|
|
this.el.style.width = width + "px";
|
|
this.el.style.height = height + "px";
|
|
this.el.style.backgroundColor = this.model.properties.line_color.value();
|
|
this.el.style.opacity = this.model.properties.line_alpha.value();
|
|
dom_1.display(this.el);
|
|
}
|
|
else if (this.model.render_mode == "canvas") {
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
ctx.save();
|
|
ctx.beginPath();
|
|
this.visuals.line.set_value(ctx);
|
|
ctx.moveTo(sleft, stop);
|
|
if (this.model.dimension == "width") {
|
|
ctx.lineTo(sleft + width, stop);
|
|
}
|
|
else {
|
|
ctx.lineTo(sleft, stop + height);
|
|
}
|
|
ctx.stroke();
|
|
ctx.restore();
|
|
}
|
|
};
|
|
return SpanView;
|
|
}(annotation_1.AnnotationView));
|
|
exports.SpanView = SpanView;
|
|
var Span = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Span, _super);
|
|
function Span(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Span.initClass = function () {
|
|
this.prototype.type = 'Span';
|
|
this.prototype.default_view = SpanView;
|
|
this.mixins(['line']);
|
|
this.define({
|
|
render_mode: [p.RenderMode, 'canvas'],
|
|
x_range_name: [p.String, 'default'],
|
|
y_range_name: [p.String, 'default'],
|
|
location: [p.Number, null],
|
|
location_units: [p.SpatialUnits, 'data'],
|
|
dimension: [p.Dimension, 'width'],
|
|
});
|
|
this.override({
|
|
line_color: 'black',
|
|
});
|
|
this.internal({
|
|
for_hover: [p.Boolean, false],
|
|
computed_location: [p.Number, null],
|
|
});
|
|
};
|
|
return Span;
|
|
}(annotation_1.Annotation));
|
|
exports.Span = Span;
|
|
Span.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/text_annotation */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var text_1 = require(43) /* ../../core/util/text */;
|
|
var TextAnnotationView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TextAnnotationView, _super);
|
|
function TextAnnotationView() {
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
_this.rotate = true;
|
|
return _this;
|
|
}
|
|
TextAnnotationView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
if (this.model.render_mode == 'css') {
|
|
this.el.classList.add('bk-annotation');
|
|
this.plot_view.canvas_overlays.appendChild(this.el);
|
|
}
|
|
};
|
|
TextAnnotationView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
if (this.model.render_mode == 'css') {
|
|
// dispatch CSS update immediately
|
|
this.connect(this.model.change, function () { return _this.render(); });
|
|
}
|
|
else {
|
|
this.connect(this.model.change, function () { return _this.plot_view.request_render(); });
|
|
}
|
|
};
|
|
TextAnnotationView.prototype._calculate_text_dimensions = function (ctx, text) {
|
|
var width = ctx.measureText(text).width;
|
|
var height = text_1.measure_font(this.visuals.text.font_value()).height;
|
|
return [width, height];
|
|
};
|
|
TextAnnotationView.prototype._calculate_bounding_box_dimensions = function (ctx, text) {
|
|
var _a = this._calculate_text_dimensions(ctx, text), width = _a[0], height = _a[1];
|
|
var x_offset;
|
|
switch (ctx.textAlign) {
|
|
case 'left':
|
|
x_offset = 0;
|
|
break;
|
|
case 'center':
|
|
x_offset = -width / 2;
|
|
break;
|
|
case 'right':
|
|
x_offset = -width;
|
|
break;
|
|
default:
|
|
throw new Error("unreachable code");
|
|
}
|
|
// guestimated from https://www.w3.org/TR/2dcontext/#dom-context-2d-textbaseline
|
|
var y_offset;
|
|
switch (ctx.textBaseline) {
|
|
case 'top':
|
|
y_offset = 0.0;
|
|
break;
|
|
case 'middle':
|
|
y_offset = -0.5 * height;
|
|
break;
|
|
case 'bottom':
|
|
y_offset = -1.0 * height;
|
|
break;
|
|
case 'alphabetic':
|
|
y_offset = -0.8 * height;
|
|
break;
|
|
case 'hanging':
|
|
y_offset = -0.17 * height;
|
|
break;
|
|
case 'ideographic':
|
|
y_offset = -0.83 * height;
|
|
break;
|
|
default:
|
|
throw new Error("unreachable code");
|
|
}
|
|
return [x_offset, y_offset, width, height];
|
|
};
|
|
TextAnnotationView.prototype._canvas_text = function (ctx, text, sx, sy, angle) {
|
|
this.visuals.text.set_value(ctx);
|
|
var bbox_dims = this._calculate_bounding_box_dimensions(ctx, text);
|
|
ctx.save();
|
|
ctx.beginPath();
|
|
ctx.translate(sx, sy);
|
|
if (angle)
|
|
ctx.rotate(angle);
|
|
ctx.rect(bbox_dims[0], bbox_dims[1], bbox_dims[2], bbox_dims[3]);
|
|
if (this.visuals.background_fill.doit) {
|
|
this.visuals.background_fill.set_value(ctx);
|
|
ctx.fill();
|
|
}
|
|
if (this.visuals.border_line.doit) {
|
|
this.visuals.border_line.set_value(ctx);
|
|
ctx.stroke();
|
|
}
|
|
if (this.visuals.text.doit) {
|
|
this.visuals.text.set_value(ctx);
|
|
ctx.fillText(text, 0, 0);
|
|
}
|
|
ctx.restore();
|
|
};
|
|
TextAnnotationView.prototype._css_text = function (ctx, text, sx, sy, angle) {
|
|
dom_1.undisplay(this.el);
|
|
this.visuals.text.set_value(ctx);
|
|
var bbox_dims = this._calculate_bounding_box_dimensions(ctx, text);
|
|
// attempt to support vector string-style ("8 4 8") line dashing for css mode
|
|
var ld = this.visuals.border_line.line_dash.value();
|
|
var line_dash = ld.length < 2 ? "solid" : "dashed";
|
|
this.visuals.border_line.set_value(ctx);
|
|
this.visuals.background_fill.set_value(ctx);
|
|
this.el.style.position = 'absolute';
|
|
this.el.style.left = sx + bbox_dims[0] + "px";
|
|
this.el.style.top = sy + bbox_dims[1] + "px";
|
|
this.el.style.color = "" + this.visuals.text.text_color.value();
|
|
this.el.style.opacity = "" + this.visuals.text.text_alpha.value();
|
|
this.el.style.font = "" + this.visuals.text.font_value();
|
|
this.el.style.lineHeight = "normal"; // needed to prevent ipynb css override
|
|
if (angle) {
|
|
this.el.style.transform = "rotate(" + angle + "rad)";
|
|
}
|
|
if (this.visuals.background_fill.doit) {
|
|
this.el.style.backgroundColor = "" + this.visuals.background_fill.color_value();
|
|
}
|
|
if (this.visuals.border_line.doit) {
|
|
this.el.style.borderStyle = "" + line_dash;
|
|
this.el.style.borderWidth = this.visuals.border_line.line_width.value() + "px";
|
|
this.el.style.borderColor = "" + this.visuals.border_line.color_value();
|
|
}
|
|
this.el.textContent = text;
|
|
dom_1.display(this.el);
|
|
};
|
|
return TextAnnotationView;
|
|
}(annotation_1.AnnotationView));
|
|
exports.TextAnnotationView = TextAnnotationView;
|
|
var TextAnnotation = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TextAnnotation, _super);
|
|
function TextAnnotation(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
TextAnnotation.initClass = function () {
|
|
this.prototype.type = "TextAnnotation";
|
|
this.define({
|
|
render_mode: [p.RenderMode, "canvas"],
|
|
});
|
|
};
|
|
return TextAnnotation;
|
|
}(annotation_1.Annotation));
|
|
exports.TextAnnotation = TextAnnotation;
|
|
TextAnnotation.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/title */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var text_annotation_1 = require(77) /* ./text_annotation */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var visuals_1 = require(51) /* ../../core/visuals */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var TitleView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TitleView, _super);
|
|
function TitleView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
TitleView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.visuals.text = new visuals_1.Text(this.model);
|
|
};
|
|
TitleView.prototype._get_location = function () {
|
|
var panel = this.panel;
|
|
var hmargin = this.model.offset;
|
|
var vmargin = 5;
|
|
var sx, sy;
|
|
switch (panel.side) {
|
|
case 'above':
|
|
case 'below': {
|
|
switch (this.model.vertical_align) {
|
|
case 'top':
|
|
sy = panel._top.value + vmargin;
|
|
break;
|
|
case 'middle':
|
|
sy = panel._vcenter.value;
|
|
break;
|
|
case 'bottom':
|
|
sy = panel._bottom.value - vmargin;
|
|
break;
|
|
default: throw new Error("unreachable code");
|
|
}
|
|
switch (this.model.align) {
|
|
case 'left':
|
|
sx = panel._left.value + hmargin;
|
|
break;
|
|
case 'center':
|
|
sx = panel._hcenter.value;
|
|
break;
|
|
case 'right':
|
|
sx = panel._right.value - hmargin;
|
|
break;
|
|
default: throw new Error("unreachable code");
|
|
}
|
|
break;
|
|
}
|
|
case 'left': {
|
|
switch (this.model.vertical_align) {
|
|
case 'top':
|
|
sx = panel._left.value - vmargin;
|
|
break;
|
|
case 'middle':
|
|
sx = panel._hcenter.value;
|
|
break;
|
|
case 'bottom':
|
|
sx = panel._right.value + vmargin;
|
|
break;
|
|
default: throw new Error("unreachable code");
|
|
}
|
|
switch (this.model.align) {
|
|
case 'left':
|
|
sy = panel._bottom.value - hmargin;
|
|
break;
|
|
case 'center':
|
|
sy = panel._vcenter.value;
|
|
break;
|
|
case 'right':
|
|
sy = panel._top.value + hmargin;
|
|
break;
|
|
default: throw new Error("unreachable code");
|
|
}
|
|
break;
|
|
}
|
|
case 'right': {
|
|
switch (this.model.vertical_align) {
|
|
case 'top':
|
|
sx = panel._right.value - vmargin;
|
|
break;
|
|
case 'middle':
|
|
sx = panel._hcenter.value;
|
|
break;
|
|
case 'bottom':
|
|
sx = panel._left.value + vmargin;
|
|
break;
|
|
default: throw new Error("unreachable code");
|
|
}
|
|
switch (this.model.align) {
|
|
case 'left':
|
|
sy = panel._top.value + hmargin;
|
|
break;
|
|
case 'center':
|
|
sy = panel._vcenter.value;
|
|
break;
|
|
case 'right':
|
|
sy = panel._bottom.value - hmargin;
|
|
break;
|
|
default: throw new Error("unreachable code");
|
|
}
|
|
break;
|
|
}
|
|
default: throw new Error("unreachable code");
|
|
}
|
|
return [sx, sy];
|
|
};
|
|
TitleView.prototype.render = function () {
|
|
if (!this.model.visible) {
|
|
if (this.model.render_mode == 'css')
|
|
dom_1.undisplay(this.el);
|
|
return;
|
|
}
|
|
var text = this.model.text;
|
|
if (text == null || text.length == 0)
|
|
return;
|
|
this.model.text_baseline = this.model.vertical_align;
|
|
this.model.text_align = this.model.align;
|
|
var _a = this._get_location(), sx = _a[0], sy = _a[1];
|
|
var angle = this.panel.get_label_angle_heuristic('parallel');
|
|
var draw = this.model.render_mode == 'canvas' ? this._canvas_text.bind(this) : this._css_text.bind(this);
|
|
draw(this.plot_view.canvas_view.ctx, text, sx, sy, angle);
|
|
};
|
|
TitleView.prototype._get_size = function () {
|
|
var text = this.model.text;
|
|
if (text == null || text.length == 0)
|
|
return { width: 0, height: 0 };
|
|
else {
|
|
this.visuals.text.set_value(this.ctx);
|
|
var _a = this.ctx.measureText(text), width = _a.width, ascent = _a.ascent;
|
|
return { width: width, height: ascent + 10 };
|
|
}
|
|
};
|
|
return TitleView;
|
|
}(text_annotation_1.TextAnnotationView));
|
|
exports.TitleView = TitleView;
|
|
var Title = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Title, _super);
|
|
function Title(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Title.initClass = function () {
|
|
this.prototype.type = 'Title';
|
|
this.prototype.default_view = TitleView;
|
|
this.mixins(['line:border_', 'fill:background_']);
|
|
this.define({
|
|
text: [p.String,],
|
|
text_font: [p.Font, 'helvetica'],
|
|
text_font_size: [p.FontSizeSpec, '10pt'],
|
|
text_font_style: [p.FontStyle, 'bold'],
|
|
text_color: [p.ColorSpec, '#444444'],
|
|
text_alpha: [p.NumberSpec, 1.0],
|
|
vertical_align: [p.VerticalAlign, 'bottom'],
|
|
align: [p.TextAlign, 'left'],
|
|
offset: [p.Number, 0],
|
|
});
|
|
this.override({
|
|
background_fill_color: null,
|
|
border_line_color: null,
|
|
});
|
|
this.internal({
|
|
text_align: [p.TextAlign, 'left'],
|
|
text_baseline: [p.TextBaseline, 'bottom'],
|
|
});
|
|
};
|
|
return Title;
|
|
}(text_annotation_1.TextAnnotation));
|
|
exports.Title = Title;
|
|
Title.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/toolbar_panel */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
var build_views_1 = require(4) /* ../../core/build_views */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var ToolbarPanelView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ToolbarPanelView, _super);
|
|
function ToolbarPanelView() {
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
_this.rotate = true;
|
|
return _this;
|
|
}
|
|
ToolbarPanelView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.plot_view.canvas_events.appendChild(this.el);
|
|
this._toolbar_views = {};
|
|
build_views_1.build_views(this._toolbar_views, [this.model.toolbar], { parent: this });
|
|
var toolbar_view = this._toolbar_views[this.model.toolbar.id];
|
|
this.plot_view.visibility_callbacks.push(function (visible) { return toolbar_view.set_visibility(visible); });
|
|
};
|
|
ToolbarPanelView.prototype.remove = function () {
|
|
build_views_1.remove_views(this._toolbar_views);
|
|
_super.prototype.remove.call(this);
|
|
};
|
|
ToolbarPanelView.prototype.render = function () {
|
|
_super.prototype.render.call(this);
|
|
if (!this.model.visible) {
|
|
dom_1.undisplay(this.el);
|
|
return;
|
|
}
|
|
this.el.style.position = "absolute";
|
|
this.el.style.overflow = "hidden";
|
|
dom_1.position(this.el, this.panel.bbox);
|
|
var toolbar_view = this._toolbar_views[this.model.toolbar.id];
|
|
toolbar_view.render();
|
|
dom_1.empty(this.el);
|
|
this.el.appendChild(toolbar_view.el);
|
|
dom_1.display(this.el);
|
|
};
|
|
ToolbarPanelView.prototype._get_size = function () {
|
|
var _a = this.model.toolbar, tools = _a.tools, logo = _a.logo;
|
|
return {
|
|
width: tools.length * 30 + (logo != null ? 25 : 0),
|
|
height: 30,
|
|
};
|
|
};
|
|
return ToolbarPanelView;
|
|
}(annotation_1.AnnotationView));
|
|
exports.ToolbarPanelView = ToolbarPanelView;
|
|
var ToolbarPanel = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ToolbarPanel, _super);
|
|
function ToolbarPanel(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ToolbarPanel.initClass = function () {
|
|
this.prototype.type = 'ToolbarPanel';
|
|
this.prototype.default_view = ToolbarPanelView;
|
|
this.define({
|
|
toolbar: [p.Instance],
|
|
});
|
|
};
|
|
return ToolbarPanel;
|
|
}(annotation_1.Annotation));
|
|
exports.ToolbarPanel = ToolbarPanel;
|
|
ToolbarPanel.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/tooltip */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
function compute_side(attachment, sx, sy, hcenter, vcenter) {
|
|
var side;
|
|
switch (attachment) {
|
|
case "horizontal":
|
|
side = sx < hcenter ? 'right' : 'left';
|
|
break;
|
|
case "vertical":
|
|
side = sy < vcenter ? 'below' : 'above';
|
|
break;
|
|
default:
|
|
side = attachment;
|
|
}
|
|
return side;
|
|
}
|
|
exports.compute_side = compute_side;
|
|
var TooltipView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TooltipView, _super);
|
|
function TooltipView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
TooltipView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
// TODO (bev) really probably need multiple divs
|
|
this.plot_view.canvas_overlays.appendChild(this.el);
|
|
dom_1.undisplay(this.el);
|
|
};
|
|
TooltipView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.properties.data.change, function () { return _this._draw_tips(); });
|
|
};
|
|
TooltipView.prototype.css_classes = function () {
|
|
return _super.prototype.css_classes.call(this).concat("bk-tooltip");
|
|
};
|
|
TooltipView.prototype.render = function () {
|
|
if (!this.model.visible)
|
|
return;
|
|
this._draw_tips();
|
|
};
|
|
TooltipView.prototype._draw_tips = function () {
|
|
var data = this.model.data;
|
|
dom_1.empty(this.el);
|
|
dom_1.undisplay(this.el);
|
|
if (this.model.custom)
|
|
this.el.classList.add("bk-tooltip-custom");
|
|
else
|
|
this.el.classList.remove("bk-tooltip-custom");
|
|
if (data.length == 0)
|
|
return;
|
|
var frame = this.plot_view.frame;
|
|
for (var _i = 0, data_1 = data; _i < data_1.length; _i++) {
|
|
var _a = data_1[_i], sx_1 = _a[0], sy_1 = _a[1], content = _a[2];
|
|
if (this.model.inner_only && !frame.bbox.contains(sx_1, sy_1))
|
|
continue;
|
|
var tip = dom_1.div({}, content);
|
|
this.el.appendChild(tip);
|
|
}
|
|
var _b = data[data.length - 1], sx = _b[0], sy = _b[1]; // XXX: this previously depended on {sx, sy} leaking from the for-loop
|
|
var side = compute_side(this.model.attachment, sx, sy, frame._hcenter.value, frame._vcenter.value);
|
|
this.el.classList.remove("bk-right");
|
|
this.el.classList.remove("bk-left");
|
|
this.el.classList.remove("bk-above");
|
|
this.el.classList.remove("bk-below");
|
|
var arrow_size = 10; // XXX: keep in sync with less
|
|
dom_1.display(this.el); // XXX: {offset,client}Width() gives 0 when display="none"
|
|
// slightly confusing: side "left" (for example) is relative to point that
|
|
// is being annotated but CS class "bk-left" is relative to the tooltip itself
|
|
var left, top;
|
|
switch (side) {
|
|
case "right":
|
|
this.el.classList.add("bk-left");
|
|
left = sx + (this.el.offsetWidth - this.el.clientWidth) + arrow_size;
|
|
top = sy - this.el.offsetHeight / 2;
|
|
break;
|
|
case "left":
|
|
this.el.classList.add("bk-right");
|
|
left = sx - this.el.offsetWidth - arrow_size;
|
|
top = sy - this.el.offsetHeight / 2;
|
|
break;
|
|
case "below":
|
|
this.el.classList.add("bk-above");
|
|
top = sy + (this.el.offsetHeight - this.el.clientHeight) + arrow_size;
|
|
left = Math.round(sx - this.el.offsetWidth / 2);
|
|
break;
|
|
case "above":
|
|
this.el.classList.add("bk-below");
|
|
top = sy - this.el.offsetHeight - arrow_size;
|
|
left = Math.round(sx - this.el.offsetWidth / 2);
|
|
break;
|
|
default:
|
|
throw new Error("unreachable code");
|
|
}
|
|
if (this.model.show_arrow)
|
|
this.el.classList.add("bk-tooltip-arrow");
|
|
// TODO (bev) this is not currently bulletproof. If there are
|
|
// two hits, not colocated and one is off the screen, that can
|
|
// be problematic
|
|
if (this.el.childNodes.length > 0) {
|
|
this.el.style.top = top + "px";
|
|
this.el.style.left = left + "px";
|
|
}
|
|
else
|
|
dom_1.undisplay(this.el);
|
|
};
|
|
return TooltipView;
|
|
}(annotation_1.AnnotationView));
|
|
exports.TooltipView = TooltipView;
|
|
var Tooltip = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Tooltip, _super);
|
|
function Tooltip(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Tooltip.initClass = function () {
|
|
this.prototype.type = 'Tooltip';
|
|
this.prototype.default_view = TooltipView;
|
|
this.define({
|
|
attachment: [p.TooltipAttachment, 'horizontal'],
|
|
inner_only: [p.Boolean, true],
|
|
show_arrow: [p.Boolean, true],
|
|
});
|
|
this.override({
|
|
level: 'overlay',
|
|
});
|
|
this.internal({
|
|
data: [p.Any, []],
|
|
custom: [p.Any],
|
|
});
|
|
};
|
|
Tooltip.prototype.clear = function () {
|
|
this.data = [];
|
|
};
|
|
Tooltip.prototype.add = function (sx, sy, content) {
|
|
this.data = this.data.concat([[sx, sy, content]]);
|
|
};
|
|
return Tooltip;
|
|
}(annotation_1.Annotation));
|
|
exports.Tooltip = Tooltip;
|
|
Tooltip.initClass();
|
|
}
|
|
,
|
|
/* models/annotations/whisker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var annotation_1 = require(63) /* ./annotation */;
|
|
var column_data_source_1 = require(208) /* ../sources/column_data_source */;
|
|
var arrow_head_1 = require(65) /* ./arrow_head */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var WhiskerView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(WhiskerView, _super);
|
|
function WhiskerView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
WhiskerView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.set_data(this.model.source);
|
|
};
|
|
WhiskerView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.source.streaming, function () { return _this.set_data(_this.model.source); });
|
|
this.connect(this.model.source.patching, function () { return _this.set_data(_this.model.source); });
|
|
this.connect(this.model.source.change, function () { return _this.set_data(_this.model.source); });
|
|
};
|
|
WhiskerView.prototype.set_data = function (source) {
|
|
_super.prototype.set_data.call(this, source);
|
|
this.visuals.warm_cache(source);
|
|
this.plot_view.request_render();
|
|
};
|
|
WhiskerView.prototype._map_data = function () {
|
|
var frame = this.plot_view.frame;
|
|
var dim = this.model.dimension;
|
|
var xscale = frame.xscales[this.model.x_range_name];
|
|
var yscale = frame.yscales[this.model.y_range_name];
|
|
var limit_scale = dim == "height" ? yscale : xscale;
|
|
var base_scale = dim == "height" ? xscale : yscale;
|
|
var limit_view = dim == "height" ? frame.yview : frame.xview;
|
|
var base_view = dim == "height" ? frame.xview : frame.yview;
|
|
var _lower_sx;
|
|
if (this.model.properties.lower.units == "data")
|
|
_lower_sx = limit_scale.v_compute(this._lower);
|
|
else
|
|
_lower_sx = limit_view.v_compute(this._lower);
|
|
var _upper_sx;
|
|
if (this.model.properties.upper.units == "data")
|
|
_upper_sx = limit_scale.v_compute(this._upper);
|
|
else
|
|
_upper_sx = limit_view.v_compute(this._upper);
|
|
var _base_sx;
|
|
if (this.model.properties.base.units == "data")
|
|
_base_sx = base_scale.v_compute(this._base);
|
|
else
|
|
_base_sx = base_view.v_compute(this._base);
|
|
var _a = dim == 'height' ? [1, 0] : [0, 1], i = _a[0], j = _a[1];
|
|
var _lower = [_lower_sx, _base_sx];
|
|
var _upper = [_upper_sx, _base_sx];
|
|
this._lower_sx = _lower[i];
|
|
this._lower_sy = _lower[j];
|
|
this._upper_sx = _upper[i];
|
|
this._upper_sy = _upper[j];
|
|
};
|
|
WhiskerView.prototype.render = function () {
|
|
if (!this.model.visible)
|
|
return;
|
|
this._map_data();
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
if (this.visuals.line.doit) {
|
|
for (var i = 0, end = this._lower_sx.length; i < end; i++) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.beginPath();
|
|
ctx.moveTo(this._lower_sx[i], this._lower_sy[i]);
|
|
ctx.lineTo(this._upper_sx[i], this._upper_sy[i]);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
var angle = this.model.dimension == "height" ? 0 : Math.PI / 2;
|
|
if (this.model.lower_head != null) {
|
|
for (var i = 0, end = this._lower_sx.length; i < end; i++) {
|
|
ctx.save();
|
|
ctx.translate(this._lower_sx[i], this._lower_sy[i]);
|
|
ctx.rotate(angle + Math.PI);
|
|
this.model.lower_head.render(ctx, i);
|
|
ctx.restore();
|
|
}
|
|
}
|
|
if (this.model.upper_head != null) {
|
|
for (var i = 0, end = this._upper_sx.length; i < end; i++) {
|
|
ctx.save();
|
|
ctx.translate(this._upper_sx[i], this._upper_sy[i]);
|
|
ctx.rotate(angle);
|
|
this.model.upper_head.render(ctx, i);
|
|
ctx.restore();
|
|
}
|
|
}
|
|
};
|
|
return WhiskerView;
|
|
}(annotation_1.AnnotationView));
|
|
exports.WhiskerView = WhiskerView;
|
|
var Whisker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Whisker, _super);
|
|
function Whisker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Whisker.initClass = function () {
|
|
this.prototype.type = 'Whisker';
|
|
this.prototype.default_view = WhiskerView;
|
|
this.mixins(['line']);
|
|
this.define({
|
|
lower: [p.DistanceSpec],
|
|
lower_head: [p.Instance, function () { return new arrow_head_1.TeeHead({ level: "underlay", size: 10 }); }],
|
|
upper: [p.DistanceSpec],
|
|
upper_head: [p.Instance, function () { return new arrow_head_1.TeeHead({ level: "underlay", size: 10 }); }],
|
|
base: [p.DistanceSpec],
|
|
dimension: [p.Dimension, 'height'],
|
|
source: [p.Instance, function () { return new column_data_source_1.ColumnDataSource(); }],
|
|
x_range_name: [p.String, 'default'],
|
|
y_range_name: [p.String, 'default'],
|
|
});
|
|
this.override({
|
|
level: 'underlay',
|
|
});
|
|
};
|
|
return Whisker;
|
|
}(annotation_1.Annotation));
|
|
exports.Whisker = Whisker;
|
|
Whisker.initClass();
|
|
}
|
|
,
|
|
/* models/axes/axis */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var guide_renderer_1 = require(195) /* ../renderers/guide_renderer */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var factor_range_1 = require(188) /* ../ranges/factor_range */;
|
|
var abs = Math.abs, min = Math.min, max = Math.max;
|
|
var AxisView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(AxisView, _super);
|
|
function AxisView() {
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
_this.rotate = true;
|
|
return _this;
|
|
}
|
|
Object.defineProperty(AxisView.prototype, "panel", {
|
|
get: function () {
|
|
return this.layout;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
AxisView.prototype.render = function () {
|
|
if (!this.model.visible)
|
|
return;
|
|
var extents = {
|
|
tick: this._tick_extent(),
|
|
tick_label: this._tick_label_extents(),
|
|
axis_label: this._axis_label_extent(),
|
|
};
|
|
var tick_coords = this.tick_coords;
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
ctx.save();
|
|
this._draw_rule(ctx, extents);
|
|
this._draw_major_ticks(ctx, extents, tick_coords);
|
|
this._draw_minor_ticks(ctx, extents, tick_coords);
|
|
this._draw_major_labels(ctx, extents, tick_coords);
|
|
this._draw_axis_label(ctx, extents, tick_coords);
|
|
if (this._render != null)
|
|
this._render(ctx, extents, tick_coords);
|
|
ctx.restore();
|
|
};
|
|
AxisView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.change, function () { return _this.plot_view.request_paint(); });
|
|
var p = this.model.properties;
|
|
this.on_change(p.visible, function () { return _this.plot_view.request_layout(); });
|
|
};
|
|
AxisView.prototype.get_size = function () {
|
|
if (this.model.visible && this.model.fixed_location == null) {
|
|
var size = this._get_size();
|
|
return { width: 0 /* max */, height: Math.round(size) };
|
|
}
|
|
else
|
|
return { width: 0, height: 0 };
|
|
};
|
|
AxisView.prototype._get_size = function () {
|
|
return this._tick_extent() + this._tick_label_extent() + this._axis_label_extent();
|
|
};
|
|
Object.defineProperty(AxisView.prototype, "needs_clip", {
|
|
get: function () {
|
|
return this.model.fixed_location != null;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
// drawing sub functions -----------------------------------------------------
|
|
AxisView.prototype._draw_rule = function (ctx, _extents) {
|
|
if (!this.visuals.axis_line.doit)
|
|
return;
|
|
var _a = this.rule_coords, xs = _a[0], ys = _a[1];
|
|
var _b = this.plot_view.map_to_screen(xs, ys, this.model.x_range_name, this.model.y_range_name), sxs = _b[0], sys = _b[1];
|
|
var _c = this.normals, nx = _c[0], ny = _c[1];
|
|
var _d = this.offsets, xoff = _d[0], yoff = _d[1];
|
|
this.visuals.axis_line.set_value(ctx);
|
|
ctx.beginPath();
|
|
ctx.moveTo(Math.round(sxs[0] + nx * xoff), Math.round(sys[0] + ny * yoff));
|
|
for (var i = 1; i < sxs.length; i++) {
|
|
var sx = Math.round(sxs[i] + nx * xoff);
|
|
var sy = Math.round(sys[i] + ny * yoff);
|
|
ctx.lineTo(sx, sy);
|
|
}
|
|
ctx.stroke();
|
|
};
|
|
AxisView.prototype._draw_major_ticks = function (ctx, _extents, tick_coords) {
|
|
var tin = this.model.major_tick_in;
|
|
var tout = this.model.major_tick_out;
|
|
var visuals = this.visuals.major_tick_line;
|
|
this._draw_ticks(ctx, tick_coords.major, tin, tout, visuals);
|
|
};
|
|
AxisView.prototype._draw_minor_ticks = function (ctx, _extents, tick_coords) {
|
|
var tin = this.model.minor_tick_in;
|
|
var tout = this.model.minor_tick_out;
|
|
var visuals = this.visuals.minor_tick_line;
|
|
this._draw_ticks(ctx, tick_coords.minor, tin, tout, visuals);
|
|
};
|
|
AxisView.prototype._draw_major_labels = function (ctx, extents, tick_coords) {
|
|
var coords = tick_coords.major;
|
|
var labels = this.compute_labels(coords[this.dimension]);
|
|
var orient = this.model.major_label_orientation;
|
|
var standoff = extents.tick + this.model.major_label_standoff;
|
|
var visuals = this.visuals.major_label_text;
|
|
this._draw_oriented_labels(ctx, labels, coords, orient, this.panel.side, standoff, visuals);
|
|
};
|
|
AxisView.prototype._draw_axis_label = function (ctx, extents, _tick_coords) {
|
|
if (this.model.axis_label == null || this.model.axis_label.length == 0 || this.model.fixed_location != null)
|
|
return;
|
|
var sx;
|
|
var sy;
|
|
switch (this.panel.side) {
|
|
case "above":
|
|
sx = this.panel._hcenter.value;
|
|
sy = this.panel._bottom.value;
|
|
break;
|
|
case "below":
|
|
sx = this.panel._hcenter.value;
|
|
sy = this.panel._top.value;
|
|
break;
|
|
case "left":
|
|
sx = this.panel._right.value;
|
|
sy = this.panel._vcenter.value;
|
|
break;
|
|
case "right":
|
|
sx = this.panel._left.value;
|
|
sy = this.panel._vcenter.value;
|
|
break;
|
|
default:
|
|
throw new Error("unknown side: " + this.panel.side);
|
|
}
|
|
var coords = [[sx], [sy]];
|
|
var standoff = extents.tick + array_1.sum(extents.tick_label) + this.model.axis_label_standoff;
|
|
var visuals = this.visuals.axis_label_text;
|
|
this._draw_oriented_labels(ctx, [this.model.axis_label], coords, 'parallel', this.panel.side, standoff, visuals, "screen");
|
|
};
|
|
AxisView.prototype._draw_ticks = function (ctx, coords, tin, tout, visuals) {
|
|
if (!visuals.doit)
|
|
return;
|
|
var x = coords[0], y = coords[1];
|
|
var _a = this.plot_view.map_to_screen(x, y, this.model.x_range_name, this.model.y_range_name), sxs = _a[0], sys = _a[1];
|
|
var _b = this.normals, nx = _b[0], ny = _b[1];
|
|
var _c = this.offsets, xoff = _c[0], yoff = _c[1];
|
|
var _d = [nx * (xoff - tin), ny * (yoff - tin)], nxin = _d[0], nyin = _d[1];
|
|
var _e = [nx * (xoff + tout), ny * (yoff + tout)], nxout = _e[0], nyout = _e[1];
|
|
visuals.set_value(ctx);
|
|
for (var i = 0; i < sxs.length; i++) {
|
|
var sx0 = Math.round(sxs[i] + nxout);
|
|
var sy0 = Math.round(sys[i] + nyout);
|
|
var sx1 = Math.round(sxs[i] + nxin);
|
|
var sy1 = Math.round(sys[i] + nyin);
|
|
ctx.beginPath();
|
|
ctx.moveTo(sx0, sy0);
|
|
ctx.lineTo(sx1, sy1);
|
|
ctx.stroke();
|
|
}
|
|
};
|
|
AxisView.prototype._draw_oriented_labels = function (ctx, labels, coords, orient, _side, standoff, visuals, units) {
|
|
var _a, _b, _c;
|
|
if (units === void 0) {
|
|
units = "data";
|
|
}
|
|
if (!visuals.doit || labels.length == 0)
|
|
return;
|
|
var sxs, sys;
|
|
var xoff, yoff;
|
|
if (units == "screen") {
|
|
sxs = coords[0], sys = coords[1];
|
|
_a = [0, 0], xoff = _a[0], yoff = _a[1];
|
|
}
|
|
else {
|
|
var dxs = coords[0], dys = coords[1];
|
|
_b = this.plot_view.map_to_screen(dxs, dys, this.model.x_range_name, this.model.y_range_name), sxs = _b[0], sys = _b[1];
|
|
_c = this.offsets, xoff = _c[0], yoff = _c[1];
|
|
}
|
|
var _d = this.normals, nx = _d[0], ny = _d[1];
|
|
var nxd = nx * (xoff + standoff);
|
|
var nyd = ny * (yoff + standoff);
|
|
visuals.set_value(ctx);
|
|
this.panel.apply_label_text_heuristics(ctx, orient);
|
|
var angle;
|
|
if (types_1.isString(orient))
|
|
angle = this.panel.get_label_angle_heuristic(orient);
|
|
else
|
|
angle = -orient;
|
|
for (var i = 0; i < sxs.length; i++) {
|
|
var sx = Math.round(sxs[i] + nxd);
|
|
var sy = Math.round(sys[i] + nyd);
|
|
ctx.translate(sx, sy);
|
|
ctx.rotate(angle);
|
|
ctx.fillText(labels[i], 0, 0);
|
|
ctx.rotate(-angle);
|
|
ctx.translate(-sx, -sy);
|
|
}
|
|
};
|
|
// extents sub functions -----------------------------------------------------
|
|
/*protected*/ AxisView.prototype._axis_label_extent = function () {
|
|
if (this.model.axis_label == null || this.model.axis_label == "")
|
|
return 0;
|
|
var standoff = this.model.axis_label_standoff;
|
|
var visuals = this.visuals.axis_label_text;
|
|
return this._oriented_labels_extent([this.model.axis_label], "parallel", this.panel.side, standoff, visuals);
|
|
};
|
|
/*protected*/ AxisView.prototype._tick_extent = function () {
|
|
return this.model.major_tick_out;
|
|
};
|
|
/*protected*/ AxisView.prototype._tick_label_extent = function () {
|
|
return array_1.sum(this._tick_label_extents());
|
|
};
|
|
AxisView.prototype._tick_label_extents = function () {
|
|
var coords = this.tick_coords.major;
|
|
var labels = this.compute_labels(coords[this.dimension]);
|
|
var orient = this.model.major_label_orientation;
|
|
var standoff = this.model.major_label_standoff;
|
|
var visuals = this.visuals.major_label_text;
|
|
return [this._oriented_labels_extent(labels, orient, this.panel.side, standoff, visuals)];
|
|
};
|
|
AxisView.prototype._oriented_labels_extent = function (labels, orient, side, standoff, visuals) {
|
|
if (labels.length == 0)
|
|
return 0;
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
visuals.set_value(ctx);
|
|
var hscale;
|
|
var angle;
|
|
if (types_1.isString(orient)) {
|
|
hscale = 1;
|
|
angle = this.panel.get_label_angle_heuristic(orient);
|
|
}
|
|
else {
|
|
hscale = 2;
|
|
angle = -orient;
|
|
}
|
|
angle = Math.abs(angle);
|
|
var c = Math.cos(angle);
|
|
var s = Math.sin(angle);
|
|
var extent = 0;
|
|
for (var i = 0; i < labels.length; i++) {
|
|
var w = ctx.measureText(labels[i]).width * 1.1;
|
|
var h = ctx.measureText(labels[i]).ascent * 0.9;
|
|
var val = void 0;
|
|
if (side == "above" || side == "below")
|
|
val = w * s + (h / hscale) * c;
|
|
else
|
|
val = w * c + (h / hscale) * s;
|
|
// update extent if current value is larger
|
|
if (val > extent)
|
|
extent = val;
|
|
}
|
|
// only apply the standoff if we already have non-zero extent
|
|
if (extent > 0)
|
|
extent += standoff;
|
|
return extent;
|
|
};
|
|
Object.defineProperty(AxisView.prototype, "normals", {
|
|
// {{{ TODO: state
|
|
get: function () {
|
|
return this.panel.normals;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(AxisView.prototype, "dimension", {
|
|
get: function () {
|
|
return this.panel.dimension;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
AxisView.prototype.compute_labels = function (ticks) {
|
|
var labels = this.model.formatter.doFormat(ticks, this);
|
|
for (var i = 0; i < ticks.length; i++) {
|
|
if (ticks[i] in this.model.major_label_overrides)
|
|
labels[i] = this.model.major_label_overrides[ticks[i]];
|
|
}
|
|
return labels;
|
|
};
|
|
Object.defineProperty(AxisView.prototype, "offsets", {
|
|
get: function () {
|
|
// If we have a fixed_position then we should respect that exactly and
|
|
// not apply any offsets (https://github.com/bokeh/bokeh/issues/8552)
|
|
if (this.model.fixed_location != null)
|
|
return [0, 0];
|
|
var frame = this.plot_view.frame;
|
|
var _a = [0, 0], xoff = _a[0], yoff = _a[1];
|
|
switch (this.panel.side) {
|
|
case "below":
|
|
yoff = abs(this.panel._top.value - frame._bottom.value);
|
|
break;
|
|
case "above":
|
|
yoff = abs(this.panel._bottom.value - frame._top.value);
|
|
break;
|
|
case "right":
|
|
xoff = abs(this.panel._left.value - frame._right.value);
|
|
break;
|
|
case "left":
|
|
xoff = abs(this.panel._right.value - frame._left.value);
|
|
break;
|
|
}
|
|
return [xoff, yoff];
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(AxisView.prototype, "ranges", {
|
|
get: function () {
|
|
var i = this.dimension;
|
|
var j = (i + 1) % 2;
|
|
var frame = this.plot_view.frame;
|
|
var ranges = [
|
|
frame.x_ranges[this.model.x_range_name],
|
|
frame.y_ranges[this.model.y_range_name],
|
|
];
|
|
return [ranges[i], ranges[j]];
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(AxisView.prototype, "computed_bounds", {
|
|
get: function () {
|
|
var range = this.ranges[0];
|
|
var user_bounds = this.model.bounds; // XXX: ? 'auto'
|
|
var range_bounds = [range.min, range.max];
|
|
if (user_bounds == 'auto')
|
|
return [range.min, range.max];
|
|
else if (types_1.isArray(user_bounds)) {
|
|
var start = void 0;
|
|
var end = void 0;
|
|
var user_start = user_bounds[0], user_end = user_bounds[1];
|
|
var range_start = range_bounds[0], range_end = range_bounds[1];
|
|
if (abs(user_start - user_end) > abs(range_start - range_end)) {
|
|
start = max(min(user_start, user_end), range_start);
|
|
end = min(max(user_start, user_end), range_end);
|
|
}
|
|
else {
|
|
start = min(user_start, user_end);
|
|
end = max(user_start, user_end);
|
|
}
|
|
return [start, end];
|
|
}
|
|
else
|
|
throw new Error("user bounds '" + user_bounds + "' not understood");
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(AxisView.prototype, "rule_coords", {
|
|
get: function () {
|
|
var i = this.dimension;
|
|
var j = (i + 1) % 2;
|
|
var range = this.ranges[0];
|
|
var _a = this.computed_bounds, start = _a[0], end = _a[1];
|
|
var xs = new Array(2);
|
|
var ys = new Array(2);
|
|
var coords = [xs, ys];
|
|
coords[i][0] = Math.max(start, range.min);
|
|
coords[i][1] = Math.min(end, range.max);
|
|
if (coords[i][0] > coords[i][1])
|
|
coords[i][0] = coords[i][1] = NaN;
|
|
coords[j][0] = this.loc;
|
|
coords[j][1] = this.loc;
|
|
return coords;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(AxisView.prototype, "tick_coords", {
|
|
get: function () {
|
|
var i = this.dimension;
|
|
var j = (i + 1) % 2;
|
|
var range = this.ranges[0];
|
|
var _a = this.computed_bounds, start = _a[0], end = _a[1];
|
|
var ticks = this.model.ticker.get_ticks(start, end, range, this.loc, {});
|
|
var majors = ticks.major;
|
|
var minors = ticks.minor;
|
|
var xs = [];
|
|
var ys = [];
|
|
var coords = [xs, ys];
|
|
var minor_xs = [];
|
|
var minor_ys = [];
|
|
var minor_coords = [minor_xs, minor_ys];
|
|
var _b = [range.min, range.max], range_min = _b[0], range_max = _b[1];
|
|
for (var ii = 0; ii < majors.length; ii++) {
|
|
if (majors[ii] < range_min || majors[ii] > range_max)
|
|
continue;
|
|
coords[i].push(majors[ii]);
|
|
coords[j].push(this.loc);
|
|
}
|
|
for (var ii = 0; ii < minors.length; ii++) {
|
|
if (minors[ii] < range_min || minors[ii] > range_max)
|
|
continue;
|
|
minor_coords[i].push(minors[ii]);
|
|
minor_coords[j].push(this.loc);
|
|
}
|
|
return {
|
|
major: coords,
|
|
minor: minor_coords,
|
|
};
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(AxisView.prototype, "loc", {
|
|
get: function () {
|
|
var fixed_location = this.model.fixed_location;
|
|
if (fixed_location != null) {
|
|
if (types_1.isNumber(fixed_location))
|
|
return fixed_location;
|
|
var _a = this.ranges, cross_range_1 = _a[1];
|
|
if (cross_range_1 instanceof factor_range_1.FactorRange)
|
|
return cross_range_1.synthetic(fixed_location);
|
|
throw new Error("unexpected");
|
|
}
|
|
var _b = this.ranges, cross_range = _b[1];
|
|
switch (this.panel.side) {
|
|
case 'left':
|
|
case 'below':
|
|
return cross_range.start;
|
|
case 'right':
|
|
case 'above':
|
|
return cross_range.end;
|
|
}
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
// }}}
|
|
AxisView.prototype.serializable_state = function () {
|
|
return tslib_1.__assign({}, _super.prototype.serializable_state.call(this), { bbox: this.layout.bbox.rect });
|
|
};
|
|
return AxisView;
|
|
}(guide_renderer_1.GuideRendererView));
|
|
exports.AxisView = AxisView;
|
|
var Axis = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Axis, _super);
|
|
function Axis(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Axis.initClass = function () {
|
|
this.prototype.type = "Axis";
|
|
this.prototype.default_view = AxisView;
|
|
this.mixins([
|
|
'line:axis_',
|
|
'line:major_tick_',
|
|
'line:minor_tick_',
|
|
'text:major_label_',
|
|
'text:axis_label_',
|
|
]);
|
|
this.define({
|
|
bounds: [p.Any, 'auto'],
|
|
ticker: [p.Instance],
|
|
formatter: [p.Instance],
|
|
x_range_name: [p.String, 'default'],
|
|
y_range_name: [p.String, 'default'],
|
|
axis_label: [p.String, ''],
|
|
axis_label_standoff: [p.Int, 5],
|
|
major_label_standoff: [p.Int, 5],
|
|
major_label_orientation: [p.Any, "horizontal"],
|
|
major_label_overrides: [p.Any, {}],
|
|
major_tick_in: [p.Number, 2],
|
|
major_tick_out: [p.Number, 6],
|
|
minor_tick_in: [p.Number, 0],
|
|
minor_tick_out: [p.Number, 4],
|
|
fixed_location: [p.Any, null],
|
|
});
|
|
this.override({
|
|
axis_line_color: 'black',
|
|
major_tick_line_color: 'black',
|
|
minor_tick_line_color: 'black',
|
|
major_label_text_font_size: "8pt",
|
|
major_label_text_align: "center",
|
|
major_label_text_baseline: "alphabetic",
|
|
axis_label_text_font_size: "10pt",
|
|
axis_label_text_font_style: "italic",
|
|
});
|
|
};
|
|
return Axis;
|
|
}(guide_renderer_1.GuideRenderer));
|
|
exports.Axis = Axis;
|
|
Axis.initClass();
|
|
}
|
|
,
|
|
/* models/axes/categorical_axis */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var axis_1 = require(82) /* ./axis */;
|
|
var categorical_ticker_1 = require(218) /* ../tickers/categorical_ticker */;
|
|
var categorical_tick_formatter_1 = require(108) /* ../formatters/categorical_tick_formatter */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var CategoricalAxisView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CategoricalAxisView, _super);
|
|
function CategoricalAxisView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
CategoricalAxisView.prototype._render = function (ctx, extents, tick_coords) {
|
|
this._draw_group_separators(ctx, extents, tick_coords);
|
|
};
|
|
CategoricalAxisView.prototype._draw_group_separators = function (ctx, _extents, _tick_coords) {
|
|
var _a;
|
|
var range = this.ranges[0];
|
|
var _b = this.computed_bounds, start = _b[0], end = _b[1];
|
|
if (!range.tops || range.tops.length < 2 || !this.visuals.separator_line.doit)
|
|
return;
|
|
var dim = this.dimension;
|
|
var alt = (dim + 1) % 2;
|
|
var coords = [[], []];
|
|
var ind = 0;
|
|
for (var i = 0; i < range.tops.length - 1; i++) {
|
|
var first = void 0, last = void 0;
|
|
for (var j = ind; j < range.factors.length; j++) {
|
|
if (range.factors[j][0] == range.tops[i + 1]) {
|
|
_a = [range.factors[j - 1], range.factors[j]], first = _a[0], last = _a[1];
|
|
ind = j;
|
|
break;
|
|
}
|
|
}
|
|
var pt = (range.synthetic(first) + range.synthetic(last)) / 2;
|
|
if (pt > start && pt < end) {
|
|
coords[dim].push(pt);
|
|
coords[alt].push(this.loc);
|
|
}
|
|
}
|
|
var tex = this._tick_label_extent();
|
|
this._draw_ticks(ctx, coords, -3, (tex - 6), this.visuals.separator_line);
|
|
};
|
|
CategoricalAxisView.prototype._draw_major_labels = function (ctx, extents, _tick_coords) {
|
|
var info = this._get_factor_info();
|
|
var standoff = extents.tick + this.model.major_label_standoff;
|
|
for (var i = 0; i < info.length; i++) {
|
|
var _a = info[i], labels = _a[0], coords = _a[1], orient = _a[2], visuals_1 = _a[3];
|
|
this._draw_oriented_labels(ctx, labels, coords, orient, this.panel.side, standoff, visuals_1);
|
|
standoff += extents.tick_label[i];
|
|
}
|
|
};
|
|
CategoricalAxisView.prototype._tick_label_extents = function () {
|
|
var info = this._get_factor_info();
|
|
var extents = [];
|
|
for (var _i = 0, info_1 = info; _i < info_1.length; _i++) {
|
|
var _a = info_1[_i], labels = _a[0], orient = _a[2], visuals_2 = _a[3];
|
|
var extent = this._oriented_labels_extent(labels, orient, this.panel.side, this.model.major_label_standoff, visuals_2);
|
|
extents.push(extent);
|
|
}
|
|
return extents;
|
|
};
|
|
CategoricalAxisView.prototype._get_factor_info = function () {
|
|
var range = this.ranges[0];
|
|
var _a = this.computed_bounds, start = _a[0], end = _a[1];
|
|
var loc = this.loc;
|
|
var ticks = this.model.ticker.get_ticks(start, end, range, loc, {});
|
|
var coords = this.tick_coords;
|
|
var info = [];
|
|
if (range.levels == 1) {
|
|
var major = ticks.major;
|
|
var labels = this.model.formatter.doFormat(major, this);
|
|
info.push([labels, coords.major, this.model.major_label_orientation, this.visuals.major_label_text]);
|
|
}
|
|
else if (range.levels == 2) {
|
|
var major = ticks.major.map(function (x) { return x[1]; });
|
|
var labels = this.model.formatter.doFormat(major, this);
|
|
info.push([labels, coords.major, this.model.major_label_orientation, this.visuals.major_label_text]);
|
|
info.push([ticks.tops, coords.tops, this.model.group_label_orientation, this.visuals.group_text]);
|
|
}
|
|
else if (range.levels == 3) {
|
|
var major = ticks.major.map(function (x) { return x[2]; });
|
|
var labels = this.model.formatter.doFormat(major, this);
|
|
var mid_labels = ticks.mids.map(function (x) { return x[1]; });
|
|
info.push([labels, coords.major, this.model.major_label_orientation, this.visuals.major_label_text]);
|
|
info.push([mid_labels, coords.mids, this.model.subgroup_label_orientation, this.visuals.subgroup_text]);
|
|
info.push([ticks.tops, coords.tops, this.model.group_label_orientation, this.visuals.group_text]);
|
|
}
|
|
return info;
|
|
};
|
|
Object.defineProperty(CategoricalAxisView.prototype, "tick_coords", {
|
|
// {{{ TODO: state
|
|
get: function () {
|
|
var _this = this;
|
|
var i = this.dimension;
|
|
var j = (i + 1) % 2;
|
|
var range = this.ranges[0];
|
|
var _a = this.computed_bounds, start = _a[0], end = _a[1];
|
|
var ticks = this.model.ticker.get_ticks(start, end, range, this.loc, {});
|
|
var coords = {
|
|
major: [[], []],
|
|
mids: [[], []],
|
|
tops: [[], []],
|
|
minor: [[], []],
|
|
};
|
|
coords.major[i] = ticks.major;
|
|
coords.major[j] = ticks.major.map(function (_x) { return _this.loc; });
|
|
if (range.levels == 3)
|
|
coords.mids[i] = ticks.mids;
|
|
coords.mids[j] = ticks.mids.map(function (_x) { return _this.loc; });
|
|
if (range.levels > 1)
|
|
coords.tops[i] = ticks.tops;
|
|
coords.tops[j] = ticks.tops.map(function (_x) { return _this.loc; });
|
|
return coords;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return CategoricalAxisView;
|
|
}(axis_1.AxisView));
|
|
exports.CategoricalAxisView = CategoricalAxisView;
|
|
var CategoricalAxis = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CategoricalAxis, _super);
|
|
function CategoricalAxis(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CategoricalAxis.initClass = function () {
|
|
this.prototype.type = "CategoricalAxis";
|
|
this.prototype.default_view = CategoricalAxisView;
|
|
this.mixins([
|
|
"line:separator_",
|
|
"text:group_",
|
|
"text:subgroup_",
|
|
]);
|
|
this.define({
|
|
group_label_orientation: [p.Any, "parallel"],
|
|
subgroup_label_orientation: [p.Any, "parallel"],
|
|
});
|
|
this.override({
|
|
ticker: function () { return new categorical_ticker_1.CategoricalTicker(); },
|
|
formatter: function () { return new categorical_tick_formatter_1.CategoricalTickFormatter(); },
|
|
separator_line_color: "lightgrey",
|
|
separator_line_width: 2,
|
|
group_text_font_style: "bold",
|
|
group_text_font_size: "8pt",
|
|
group_text_color: "grey",
|
|
subgroup_text_font_style: "bold",
|
|
subgroup_text_font_size: "8pt",
|
|
});
|
|
};
|
|
return CategoricalAxis;
|
|
}(axis_1.Axis));
|
|
exports.CategoricalAxis = CategoricalAxis;
|
|
CategoricalAxis.initClass();
|
|
}
|
|
,
|
|
/* models/axes/continuous_axis */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var axis_1 = require(82) /* ./axis */;
|
|
var ContinuousAxis = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ContinuousAxis, _super);
|
|
function ContinuousAxis(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ContinuousAxis.initClass = function () {
|
|
this.prototype.type = "ContinuousAxis";
|
|
};
|
|
return ContinuousAxis;
|
|
}(axis_1.Axis));
|
|
exports.ContinuousAxis = ContinuousAxis;
|
|
ContinuousAxis.initClass();
|
|
}
|
|
,
|
|
/* models/axes/datetime_axis */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var linear_axis_1 = require(87) /* ./linear_axis */;
|
|
var datetime_tick_formatter_1 = require(109) /* ../formatters/datetime_tick_formatter */;
|
|
var datetime_ticker_1 = require(221) /* ../tickers/datetime_ticker */;
|
|
var DatetimeAxisView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DatetimeAxisView, _super);
|
|
function DatetimeAxisView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return DatetimeAxisView;
|
|
}(linear_axis_1.LinearAxisView));
|
|
exports.DatetimeAxisView = DatetimeAxisView;
|
|
var DatetimeAxis = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DatetimeAxis, _super);
|
|
function DatetimeAxis(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
DatetimeAxis.initClass = function () {
|
|
this.prototype.type = "DatetimeAxis";
|
|
this.prototype.default_view = DatetimeAxisView;
|
|
this.override({
|
|
ticker: function () { return new datetime_ticker_1.DatetimeTicker(); },
|
|
formatter: function () { return new datetime_tick_formatter_1.DatetimeTickFormatter(); },
|
|
});
|
|
};
|
|
return DatetimeAxis;
|
|
}(linear_axis_1.LinearAxis));
|
|
exports.DatetimeAxis = DatetimeAxis;
|
|
DatetimeAxis.initClass();
|
|
}
|
|
,
|
|
/* models/axes/index */ function _(require, module, exports) {
|
|
var axis_1 = require(82) /* ./axis */;
|
|
exports.Axis = axis_1.Axis;
|
|
var categorical_axis_1 = require(83) /* ./categorical_axis */;
|
|
exports.CategoricalAxis = categorical_axis_1.CategoricalAxis;
|
|
var continuous_axis_1 = require(84) /* ./continuous_axis */;
|
|
exports.ContinuousAxis = continuous_axis_1.ContinuousAxis;
|
|
var datetime_axis_1 = require(85) /* ./datetime_axis */;
|
|
exports.DatetimeAxis = datetime_axis_1.DatetimeAxis;
|
|
var linear_axis_1 = require(87) /* ./linear_axis */;
|
|
exports.LinearAxis = linear_axis_1.LinearAxis;
|
|
var log_axis_1 = require(88) /* ./log_axis */;
|
|
exports.LogAxis = log_axis_1.LogAxis;
|
|
var mercator_axis_1 = require(89) /* ./mercator_axis */;
|
|
exports.MercatorAxis = mercator_axis_1.MercatorAxis;
|
|
}
|
|
,
|
|
/* models/axes/linear_axis */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var axis_1 = require(82) /* ./axis */;
|
|
var continuous_axis_1 = require(84) /* ./continuous_axis */;
|
|
var basic_tick_formatter_1 = require(107) /* ../formatters/basic_tick_formatter */;
|
|
var basic_ticker_1 = require(217) /* ../tickers/basic_ticker */;
|
|
var LinearAxisView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LinearAxisView, _super);
|
|
function LinearAxisView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return LinearAxisView;
|
|
}(axis_1.AxisView));
|
|
exports.LinearAxisView = LinearAxisView;
|
|
var LinearAxis = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LinearAxis, _super);
|
|
function LinearAxis(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
LinearAxis.initClass = function () {
|
|
this.prototype.type = "LinearAxis";
|
|
this.prototype.default_view = LinearAxisView;
|
|
this.override({
|
|
ticker: function () { return new basic_ticker_1.BasicTicker(); },
|
|
formatter: function () { return new basic_tick_formatter_1.BasicTickFormatter(); },
|
|
});
|
|
};
|
|
return LinearAxis;
|
|
}(continuous_axis_1.ContinuousAxis));
|
|
exports.LinearAxis = LinearAxis;
|
|
LinearAxis.initClass();
|
|
}
|
|
,
|
|
/* models/axes/log_axis */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var axis_1 = require(82) /* ./axis */;
|
|
var continuous_axis_1 = require(84) /* ./continuous_axis */;
|
|
var log_tick_formatter_1 = require(112) /* ../formatters/log_tick_formatter */;
|
|
var log_ticker_1 = require(225) /* ../tickers/log_ticker */;
|
|
var LogAxisView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LogAxisView, _super);
|
|
function LogAxisView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return LogAxisView;
|
|
}(axis_1.AxisView));
|
|
exports.LogAxisView = LogAxisView;
|
|
var LogAxis = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LogAxis, _super);
|
|
function LogAxis(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
LogAxis.initClass = function () {
|
|
this.prototype.type = "LogAxis";
|
|
this.prototype.default_view = LogAxisView;
|
|
this.override({
|
|
ticker: function () { return new log_ticker_1.LogTicker(); },
|
|
formatter: function () { return new log_tick_formatter_1.LogTickFormatter(); },
|
|
});
|
|
};
|
|
return LogAxis;
|
|
}(continuous_axis_1.ContinuousAxis));
|
|
exports.LogAxis = LogAxis;
|
|
LogAxis.initClass();
|
|
}
|
|
,
|
|
/* models/axes/mercator_axis */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var axis_1 = require(82) /* ./axis */;
|
|
var linear_axis_1 = require(87) /* ./linear_axis */;
|
|
var mercator_tick_formatter_1 = require(113) /* ../formatters/mercator_tick_formatter */;
|
|
var mercator_ticker_1 = require(226) /* ../tickers/mercator_ticker */;
|
|
var MercatorAxisView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MercatorAxisView, _super);
|
|
function MercatorAxisView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return MercatorAxisView;
|
|
}(axis_1.AxisView));
|
|
exports.MercatorAxisView = MercatorAxisView;
|
|
var MercatorAxis = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MercatorAxis, _super);
|
|
function MercatorAxis(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
MercatorAxis.initClass = function () {
|
|
this.prototype.type = "MercatorAxis";
|
|
this.prototype.default_view = MercatorAxisView;
|
|
this.override({
|
|
ticker: function () { return new mercator_ticker_1.MercatorTicker({ dimension: "lat" }); },
|
|
formatter: function () { return new mercator_tick_formatter_1.MercatorTickFormatter({ dimension: "lat" }); },
|
|
});
|
|
};
|
|
return MercatorAxis;
|
|
}(linear_axis_1.LinearAxis));
|
|
exports.MercatorAxis = MercatorAxis;
|
|
MercatorAxis.initClass();
|
|
}
|
|
,
|
|
/* models/callbacks/callback */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var Callback = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Callback, _super);
|
|
function Callback(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Callback.initClass = function () {
|
|
this.prototype.type = 'Callback';
|
|
};
|
|
return Callback;
|
|
}(model_1.Model));
|
|
exports.Callback = Callback;
|
|
Callback.initClass();
|
|
}
|
|
,
|
|
/* models/callbacks/customjs */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var callback_1 = require(90) /* ./callback */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var string_1 = require(40) /* ../../core/util/string */;
|
|
var CustomJS = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CustomJS, _super);
|
|
function CustomJS(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CustomJS.initClass = function () {
|
|
this.prototype.type = 'CustomJS';
|
|
this.define({
|
|
args: [p.Any, {}],
|
|
code: [p.String, ''],
|
|
use_strict: [p.Boolean, false],
|
|
});
|
|
};
|
|
Object.defineProperty(CustomJS.prototype, "names", {
|
|
get: function () {
|
|
return object_1.keys(this.args);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(CustomJS.prototype, "values", {
|
|
get: function () {
|
|
return object_1.values(this.args);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(CustomJS.prototype, "func", {
|
|
get: function () {
|
|
var code = this.use_strict ? string_1.use_strict(this.code) : this.code;
|
|
return new (Function.bind.apply(Function, [void 0].concat(this.names, ["cb_obj", "cb_data", "require", "exports", code])))();
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
CustomJS.prototype.execute = function (cb_obj, cb_data) {
|
|
if (cb_data === void 0) {
|
|
cb_data = {};
|
|
}
|
|
return this.func.apply(cb_obj, this.values.concat(cb_obj, cb_data, require, {}));
|
|
};
|
|
return CustomJS;
|
|
}(callback_1.Callback));
|
|
exports.CustomJS = CustomJS;
|
|
CustomJS.initClass();
|
|
}
|
|
,
|
|
/* models/callbacks/index */ function _(require, module, exports) {
|
|
var customjs_1 = require(91) /* ./customjs */;
|
|
exports.CustomJS = customjs_1.CustomJS;
|
|
var open_url_1 = require(93) /* ./open_url */;
|
|
exports.OpenURL = open_url_1.OpenURL;
|
|
}
|
|
,
|
|
/* models/callbacks/open_url */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var callback_1 = require(90) /* ./callback */;
|
|
var templating_1 = require(42) /* ../../core/util/templating */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var OpenURL = /** @class */ (function (_super) {
|
|
tslib_1.__extends(OpenURL, _super);
|
|
function OpenURL(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
OpenURL.initClass = function () {
|
|
this.prototype.type = 'OpenURL';
|
|
this.define({
|
|
url: [p.String, 'http://'],
|
|
same_tab: [p.Boolean, false],
|
|
});
|
|
};
|
|
OpenURL.prototype.execute = function (_cb_obj, _a) {
|
|
var _this = this;
|
|
var source = _a.source;
|
|
var open_url = function (i) {
|
|
var url = templating_1.replace_placeholders(_this.url, source, i);
|
|
if (_this.same_tab)
|
|
window.location.href = url;
|
|
else
|
|
window.open(url);
|
|
};
|
|
var selected = source.selected;
|
|
for (var _i = 0, _b = selected.indices; _i < _b.length; _i++) {
|
|
var i = _b[_i];
|
|
open_url(i);
|
|
}
|
|
for (var _c = 0, _d = selected.line_indices; _c < _d.length; _c++) {
|
|
var i = _d[_c];
|
|
open_url(i);
|
|
}
|
|
// TODO: multiline_indices: {[key: string]: number[]}
|
|
};
|
|
return OpenURL;
|
|
}(callback_1.Callback));
|
|
exports.OpenURL = OpenURL;
|
|
OpenURL.initClass();
|
|
}
|
|
,
|
|
/* models/canvas/canvas */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var has_props_1 = require(8) /* ../../core/has_props */;
|
|
var dom_view_1 = require(6) /* ../../core/dom_view */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var bbox_1 = require(27) /* ../../core/util/bbox */;
|
|
var compat_1 = require(31) /* ../../core/util/compat */;
|
|
var canvas_1 = require(29) /* ../../core/util/canvas */;
|
|
// fixes up a problem with some versions of IE11
|
|
// ref: http://stackoverflow.com/questions/22062313/imagedata-set-in-internetexplorer
|
|
if (compat_1.is_ie && typeof CanvasPixelArray !== "undefined") {
|
|
CanvasPixelArray.prototype.set = function (arr) {
|
|
for (var i = 0; i < this.length; i++) {
|
|
this[i] = arr[i];
|
|
}
|
|
};
|
|
}
|
|
var canvas2svg = require(297) /* canvas2svg */;
|
|
var CanvasView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CanvasView, _super);
|
|
function CanvasView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Object.defineProperty(CanvasView.prototype, "ctx", {
|
|
get: function () {
|
|
return this._ctx;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
CanvasView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.map_el = this.model.map ? this.el.appendChild(dom_1.div({ class: "bk-canvas-map" })) : null;
|
|
var style = {
|
|
position: "absolute",
|
|
top: "0",
|
|
left: "0",
|
|
width: "100%",
|
|
height: "100%",
|
|
};
|
|
switch (this.model.output_backend) {
|
|
case "canvas":
|
|
case "webgl": {
|
|
this.canvas_el = this.el.appendChild(dom_1.canvas({ class: "bk-canvas", style: style }));
|
|
var ctx = this.canvas_el.getContext('2d');
|
|
if (ctx == null)
|
|
throw new Error("unable to obtain 2D rendering context");
|
|
this._ctx = ctx;
|
|
break;
|
|
}
|
|
case "svg": {
|
|
var ctx = new canvas2svg();
|
|
this._ctx = ctx;
|
|
this.canvas_el = this.el.appendChild(ctx.getSvg());
|
|
break;
|
|
}
|
|
}
|
|
this.overlays_el = this.el.appendChild(dom_1.div({ class: "bk-canvas-overlays", style: style }));
|
|
this.events_el = this.el.appendChild(dom_1.div({ class: "bk-canvas-events", style: style }));
|
|
canvas_1.fixup_ctx(this._ctx);
|
|
logging_1.logger.debug("CanvasView initialized");
|
|
};
|
|
CanvasView.prototype.get_canvas_element = function () {
|
|
return this.canvas_el;
|
|
};
|
|
CanvasView.prototype.prepare_canvas = function (width, height) {
|
|
// Ensure canvas has the correct size, taking HIDPI into account
|
|
this.bbox = new bbox_1.BBox({ left: 0, top: 0, width: width, height: height });
|
|
this.el.style.width = width + "px";
|
|
this.el.style.height = height + "px";
|
|
var pixel_ratio = canvas_1.get_scale_ratio(this.ctx, this.model.use_hidpi, this.model.output_backend);
|
|
this.model.pixel_ratio = pixel_ratio;
|
|
this.canvas_el.style.width = width + "px";
|
|
this.canvas_el.style.height = height + "px";
|
|
// XXX: io.export and canvas2svg don't like this
|
|
// this.canvas_el.width = width*pixel_ratio
|
|
// this.canvas_el.height = height*pixel_ratio
|
|
this.canvas_el.setAttribute("width", "" + width * pixel_ratio);
|
|
this.canvas_el.setAttribute("height", "" + height * pixel_ratio);
|
|
logging_1.logger.debug("Rendering CanvasView with width: " + width + ", height: " + height + ", pixel ratio: " + pixel_ratio);
|
|
};
|
|
return CanvasView;
|
|
}(dom_view_1.DOMView));
|
|
exports.CanvasView = CanvasView;
|
|
var Canvas = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Canvas, _super);
|
|
function Canvas(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Canvas.initClass = function () {
|
|
this.prototype.type = "Canvas";
|
|
this.prototype.default_view = CanvasView;
|
|
this.internal({
|
|
map: [p.Boolean, false],
|
|
use_hidpi: [p.Boolean, true],
|
|
pixel_ratio: [p.Number, 1],
|
|
output_backend: [p.OutputBackend, "canvas"],
|
|
});
|
|
};
|
|
return Canvas;
|
|
}(has_props_1.HasProps));
|
|
exports.Canvas = Canvas;
|
|
Canvas.initClass();
|
|
}
|
|
,
|
|
/* models/canvas/cartesian_frame */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var categorical_scale_1 = require(198) /* ../scales/categorical_scale */;
|
|
var linear_scale_1 = require(200) /* ../scales/linear_scale */;
|
|
var log_scale_1 = require(201) /* ../scales/log_scale */;
|
|
var range1d_1 = require(191) /* ../ranges/range1d */;
|
|
var data_range1d_1 = require(187) /* ../ranges/data_range1d */;
|
|
var factor_range_1 = require(188) /* ../ranges/factor_range */;
|
|
var layout_1 = require(13) /* ../../core/layout */;
|
|
var CartesianFrame = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CartesianFrame, _super);
|
|
function CartesianFrame(x_scale, y_scale, x_range, y_range, extra_x_ranges, extra_y_ranges) {
|
|
if (extra_x_ranges === void 0) {
|
|
extra_x_ranges = {};
|
|
}
|
|
if (extra_y_ranges === void 0) {
|
|
extra_y_ranges = {};
|
|
}
|
|
var _this = _super.call(this) || this;
|
|
_this.x_scale = x_scale;
|
|
_this.y_scale = y_scale;
|
|
_this.x_range = x_range;
|
|
_this.y_range = y_range;
|
|
_this.extra_x_ranges = extra_x_ranges;
|
|
_this.extra_y_ranges = extra_y_ranges;
|
|
_this._configure_scales();
|
|
return _this;
|
|
}
|
|
CartesianFrame.prototype.map_to_screen = function (x, y, x_name, y_name) {
|
|
if (x_name === void 0) {
|
|
x_name = "default";
|
|
}
|
|
if (y_name === void 0) {
|
|
y_name = "default";
|
|
}
|
|
var sx = this.xscales[x_name].v_compute(x);
|
|
var sy = this.yscales[y_name].v_compute(y);
|
|
return [sx, sy];
|
|
};
|
|
CartesianFrame.prototype._get_ranges = function (range, extra_ranges) {
|
|
var ranges = {};
|
|
ranges.default = range;
|
|
if (extra_ranges != null) {
|
|
for (var name_1 in extra_ranges)
|
|
ranges[name_1] = extra_ranges[name_1];
|
|
}
|
|
return ranges;
|
|
};
|
|
/*protected*/ CartesianFrame.prototype._get_scales = function (scale, ranges, frame_range) {
|
|
var scales = {};
|
|
for (var name_2 in ranges) {
|
|
var range = ranges[name_2];
|
|
if (range instanceof data_range1d_1.DataRange1d || range instanceof range1d_1.Range1d) {
|
|
if (!(scale instanceof log_scale_1.LogScale) && !(scale instanceof linear_scale_1.LinearScale))
|
|
throw new Error("Range " + range.type + " is incompatible is Scale " + scale.type);
|
|
// XXX: special case because CategoricalScale is a subclass of LinearScale, should be removed in future
|
|
if (scale instanceof categorical_scale_1.CategoricalScale)
|
|
throw new Error("Range " + range.type + " is incompatible is Scale " + scale.type);
|
|
}
|
|
if (range instanceof factor_range_1.FactorRange) {
|
|
if (!(scale instanceof categorical_scale_1.CategoricalScale))
|
|
throw new Error("Range " + range.type + " is incompatible is Scale " + scale.type);
|
|
}
|
|
if (scale instanceof log_scale_1.LogScale && range instanceof data_range1d_1.DataRange1d)
|
|
range.scale_hint = "log";
|
|
var s = scale.clone();
|
|
s.setv({ source_range: range, target_range: frame_range });
|
|
scales[name_2] = s;
|
|
}
|
|
return scales;
|
|
};
|
|
CartesianFrame.prototype._configure_frame_ranges = function () {
|
|
// data to/from screen space transform (left-bottom <-> left-top origin)
|
|
this._h_target = new range1d_1.Range1d({ start: this._left.value, end: this._right.value });
|
|
this._v_target = new range1d_1.Range1d({ start: this._bottom.value, end: this._top.value });
|
|
};
|
|
CartesianFrame.prototype._configure_scales = function () {
|
|
this._configure_frame_ranges();
|
|
this._x_ranges = this._get_ranges(this.x_range, this.extra_x_ranges);
|
|
this._y_ranges = this._get_ranges(this.y_range, this.extra_y_ranges);
|
|
this._xscales = this._get_scales(this.x_scale, this._x_ranges, this._h_target);
|
|
this._yscales = this._get_scales(this.y_scale, this._y_ranges, this._v_target);
|
|
};
|
|
CartesianFrame.prototype._update_scales = function () {
|
|
this._configure_frame_ranges();
|
|
for (var name_3 in this._xscales) {
|
|
var scale = this._xscales[name_3];
|
|
scale.target_range = this._h_target;
|
|
}
|
|
for (var name_4 in this._yscales) {
|
|
var scale = this._yscales[name_4];
|
|
scale.target_range = this._v_target;
|
|
}
|
|
};
|
|
CartesianFrame.prototype._set_geometry = function (outer, inner) {
|
|
_super.prototype._set_geometry.call(this, outer, inner);
|
|
this._update_scales();
|
|
};
|
|
Object.defineProperty(CartesianFrame.prototype, "x_ranges", {
|
|
get: function () {
|
|
return this._x_ranges;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(CartesianFrame.prototype, "y_ranges", {
|
|
get: function () {
|
|
return this._y_ranges;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(CartesianFrame.prototype, "xscales", {
|
|
get: function () {
|
|
return this._xscales;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(CartesianFrame.prototype, "yscales", {
|
|
get: function () {
|
|
return this._yscales;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return CartesianFrame;
|
|
}(layout_1.LayoutItem));
|
|
exports.CartesianFrame = CartesianFrame;
|
|
}
|
|
,
|
|
/* models/canvas/index */ function _(require, module, exports) {
|
|
var canvas_1 = require(94) /* ./canvas */;
|
|
exports.Canvas = canvas_1.Canvas;
|
|
var cartesian_frame_1 = require(95) /* ./cartesian_frame */;
|
|
exports.CartesianFrame = cartesian_frame_1.CartesianFrame;
|
|
}
|
|
,
|
|
/* models/expressions/cumsum */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var expression_1 = require(98) /* ./expression */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var CumSum = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CumSum, _super);
|
|
function CumSum(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CumSum.initClass = function () {
|
|
this.prototype.type = "CumSum";
|
|
this.define({
|
|
field: [p.String],
|
|
include_zero: [p.Boolean, false],
|
|
});
|
|
};
|
|
CumSum.prototype._v_compute = function (source) {
|
|
var result = new Float64Array(source.get_length() || 0);
|
|
var col = source.data[this.field];
|
|
var offset = this.include_zero ? 1 : 0;
|
|
result[0] = this.include_zero ? 0 : col[0];
|
|
for (var i = 1; i < result.length; i++) {
|
|
result[i] = result[i - 1] + col[i - offset];
|
|
}
|
|
return result;
|
|
};
|
|
return CumSum;
|
|
}(expression_1.Expression));
|
|
exports.CumSum = CumSum;
|
|
CumSum.initClass();
|
|
}
|
|
,
|
|
/* models/expressions/expression */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var Expression = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Expression, _super);
|
|
function Expression(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this._connected = {};
|
|
_this._result = {};
|
|
return _this;
|
|
}
|
|
Expression.initClass = function () {
|
|
this.prototype.type = "Expression";
|
|
};
|
|
Expression.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this._connected = {};
|
|
this._result = {};
|
|
};
|
|
Expression.prototype.v_compute = function (source) {
|
|
var _this = this;
|
|
if (this._connected[source.id] == null) {
|
|
this.connect(source.change, function () { return delete _this._result[source.id]; });
|
|
this.connect(source.patching, function () { return delete _this._result[source.id]; });
|
|
this.connect(source.streaming, function () { return delete _this._result[source.id]; });
|
|
this._connected[source.id] = true;
|
|
}
|
|
var result = this._result[source.id];
|
|
if (result == null)
|
|
this._result[source.id] = result = this._v_compute(source);
|
|
return result;
|
|
};
|
|
return Expression;
|
|
}(model_1.Model));
|
|
exports.Expression = Expression;
|
|
Expression.initClass();
|
|
}
|
|
,
|
|
/* models/expressions/index */ function _(require, module, exports) {
|
|
var expression_1 = require(98) /* ./expression */;
|
|
exports.Expression = expression_1.Expression;
|
|
var stack_1 = require(100) /* ./stack */;
|
|
exports.Stack = stack_1.Stack;
|
|
var cumsum_1 = require(97) /* ./cumsum */;
|
|
exports.CumSum = cumsum_1.CumSum;
|
|
}
|
|
,
|
|
/* models/expressions/stack */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var expression_1 = require(98) /* ./expression */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var Stack = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Stack, _super);
|
|
function Stack(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Stack.initClass = function () {
|
|
this.prototype.type = "Stack";
|
|
this.define({
|
|
fields: [p.Array, []],
|
|
});
|
|
};
|
|
Stack.prototype._v_compute = function (source) {
|
|
var result = new Float64Array(source.get_length() || 0);
|
|
for (var _i = 0, _a = this.fields; _i < _a.length; _i++) {
|
|
var f = _a[_i];
|
|
for (var i = 0; i < source.data[f].length; i++) {
|
|
var x = source.data[f][i];
|
|
result[i] += x;
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
return Stack;
|
|
}(expression_1.Expression));
|
|
exports.Stack = Stack;
|
|
Stack.initClass();
|
|
}
|
|
,
|
|
/* models/filters/boolean_filter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var filter_1 = require(103) /* ./filter */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var BooleanFilter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BooleanFilter, _super);
|
|
function BooleanFilter(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
BooleanFilter.initClass = function () {
|
|
this.prototype.type = 'BooleanFilter';
|
|
this.define({
|
|
booleans: [p.Array, null],
|
|
});
|
|
};
|
|
BooleanFilter.prototype.compute_indices = function (source) {
|
|
var booleans = this.booleans;
|
|
if (booleans != null && booleans.length > 0) {
|
|
if (array_1.every(booleans, types_1.isBoolean)) {
|
|
if (booleans.length !== source.get_length()) {
|
|
logging_1.logger.warn("BooleanFilter " + this.id + ": length of booleans doesn't match data source");
|
|
}
|
|
return array_1.range(0, booleans.length).filter(function (i) { return booleans[i] === true; });
|
|
}
|
|
else {
|
|
logging_1.logger.warn("BooleanFilter " + this.id + ": booleans should be array of booleans, defaulting to no filtering");
|
|
return null;
|
|
}
|
|
}
|
|
else {
|
|
if (booleans != null && booleans.length == 0)
|
|
logging_1.logger.warn("BooleanFilter " + this.id + ": booleans is empty, defaulting to no filtering");
|
|
else
|
|
logging_1.logger.warn("BooleanFilter " + this.id + ": booleans was not set, defaulting to no filtering");
|
|
return null;
|
|
}
|
|
};
|
|
return BooleanFilter;
|
|
}(filter_1.Filter));
|
|
exports.BooleanFilter = BooleanFilter;
|
|
BooleanFilter.initClass();
|
|
}
|
|
,
|
|
/* models/filters/customjs_filter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var filter_1 = require(103) /* ./filter */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var string_1 = require(40) /* ../../core/util/string */;
|
|
var CustomJSFilter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CustomJSFilter, _super);
|
|
function CustomJSFilter(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CustomJSFilter.initClass = function () {
|
|
this.prototype.type = 'CustomJSFilter';
|
|
this.define({
|
|
args: [p.Any, {}],
|
|
code: [p.String, ''],
|
|
use_strict: [p.Boolean, false],
|
|
});
|
|
};
|
|
Object.defineProperty(CustomJSFilter.prototype, "names", {
|
|
get: function () {
|
|
return object_1.keys(this.args);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(CustomJSFilter.prototype, "values", {
|
|
get: function () {
|
|
return object_1.values(this.args);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(CustomJSFilter.prototype, "func", {
|
|
get: function () {
|
|
var code = this.use_strict ? string_1.use_strict(this.code) : this.code;
|
|
return new (Function.bind.apply(Function, [void 0].concat(this.names, ["source", "require", "exports", code])))();
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
CustomJSFilter.prototype.compute_indices = function (source) {
|
|
this.filter = this.func.apply(this, this.values.concat([source, require, {}]));
|
|
return _super.prototype.compute_indices.call(this, source);
|
|
};
|
|
return CustomJSFilter;
|
|
}(filter_1.Filter));
|
|
exports.CustomJSFilter = CustomJSFilter;
|
|
CustomJSFilter.initClass();
|
|
}
|
|
,
|
|
/* models/filters/filter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var Filter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Filter, _super);
|
|
function Filter(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Filter.initClass = function () {
|
|
this.prototype.type = 'Filter';
|
|
this.define({
|
|
filter: [p.Array, null],
|
|
});
|
|
};
|
|
Filter.prototype.compute_indices = function (_source) {
|
|
var filter = this.filter;
|
|
if (filter != null && filter.length >= 0) {
|
|
if (types_1.isArrayOf(filter, types_1.isBoolean)) {
|
|
return array_1.range(0, filter.length).filter(function (i) { return filter[i] === true; });
|
|
}
|
|
if (types_1.isArrayOf(filter, types_1.isInteger)) {
|
|
return filter;
|
|
}
|
|
logging_1.logger.warn("Filter " + this.id + ": filter should either be array of only booleans or only integers, defaulting to no filtering");
|
|
return null;
|
|
}
|
|
else {
|
|
logging_1.logger.warn("Filter " + this.id + ": filter was not set to be an array, defaulting to no filtering");
|
|
return null;
|
|
}
|
|
};
|
|
return Filter;
|
|
}(model_1.Model));
|
|
exports.Filter = Filter;
|
|
Filter.initClass();
|
|
}
|
|
,
|
|
/* models/filters/group_filter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var filter_1 = require(103) /* ./filter */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var GroupFilter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GroupFilter, _super);
|
|
function GroupFilter(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.indices = null;
|
|
return _this;
|
|
}
|
|
GroupFilter.initClass = function () {
|
|
this.prototype.type = 'GroupFilter';
|
|
this.define({
|
|
column_name: [p.String],
|
|
group: [p.String],
|
|
});
|
|
};
|
|
GroupFilter.prototype.compute_indices = function (source) {
|
|
var _this = this;
|
|
var column = source.get_column(this.column_name);
|
|
if (column == null) {
|
|
logging_1.logger.warn("group filter: groupby column not found in data source");
|
|
return null;
|
|
}
|
|
else {
|
|
this.indices = array_1.range(0, source.get_length() || 0).filter(function (i) { return column[i] === _this.group; });
|
|
if (this.indices.length === 0) {
|
|
logging_1.logger.warn("group filter: group '" + this.group + "' did not match any values in column '" + this.column_name + "'");
|
|
}
|
|
return this.indices;
|
|
}
|
|
};
|
|
return GroupFilter;
|
|
}(filter_1.Filter));
|
|
exports.GroupFilter = GroupFilter;
|
|
GroupFilter.initClass();
|
|
}
|
|
,
|
|
/* models/filters/index */ function _(require, module, exports) {
|
|
var boolean_filter_1 = require(101) /* ./boolean_filter */;
|
|
exports.BooleanFilter = boolean_filter_1.BooleanFilter;
|
|
var customjs_filter_1 = require(102) /* ./customjs_filter */;
|
|
exports.CustomJSFilter = customjs_filter_1.CustomJSFilter;
|
|
var filter_1 = require(103) /* ./filter */;
|
|
exports.Filter = filter_1.Filter;
|
|
var group_filter_1 = require(104) /* ./group_filter */;
|
|
exports.GroupFilter = group_filter_1.GroupFilter;
|
|
var index_filter_1 = require(106) /* ./index_filter */;
|
|
exports.IndexFilter = index_filter_1.IndexFilter;
|
|
}
|
|
,
|
|
/* models/filters/index_filter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var filter_1 = require(103) /* ./filter */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var IndexFilter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(IndexFilter, _super);
|
|
function IndexFilter(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
IndexFilter.initClass = function () {
|
|
this.prototype.type = 'IndexFilter';
|
|
this.define({
|
|
indices: [p.Array, null],
|
|
});
|
|
};
|
|
IndexFilter.prototype.compute_indices = function (_source) {
|
|
if (this.indices != null && this.indices.length >= 0) {
|
|
if (array_1.every(this.indices, types_1.isInteger))
|
|
return this.indices;
|
|
else {
|
|
logging_1.logger.warn("IndexFilter " + this.id + ": indices should be array of integers, defaulting to no filtering");
|
|
return null;
|
|
}
|
|
}
|
|
else {
|
|
logging_1.logger.warn("IndexFilter " + this.id + ": indices was not set, defaulting to no filtering");
|
|
return null;
|
|
}
|
|
};
|
|
return IndexFilter;
|
|
}(filter_1.Filter));
|
|
exports.IndexFilter = IndexFilter;
|
|
IndexFilter.initClass();
|
|
}
|
|
,
|
|
/* models/formatters/basic_tick_formatter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var tick_formatter_1 = require(116) /* ./tick_formatter */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var BasicTickFormatter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BasicTickFormatter, _super);
|
|
function BasicTickFormatter(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.last_precision = 3;
|
|
return _this;
|
|
}
|
|
BasicTickFormatter.initClass = function () {
|
|
this.prototype.type = 'BasicTickFormatter';
|
|
this.define({
|
|
precision: [p.Any, 'auto'],
|
|
use_scientific: [p.Boolean, true],
|
|
power_limit_high: [p.Number, 5],
|
|
power_limit_low: [p.Number, -3],
|
|
});
|
|
};
|
|
Object.defineProperty(BasicTickFormatter.prototype, "scientific_limit_low", {
|
|
get: function () {
|
|
return Math.pow(10.0, this.power_limit_low);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(BasicTickFormatter.prototype, "scientific_limit_high", {
|
|
get: function () {
|
|
return Math.pow(10.0, this.power_limit_high);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
BasicTickFormatter.prototype.doFormat = function (ticks, _opts) {
|
|
if (ticks.length == 0)
|
|
return [];
|
|
var zero_eps = 0;
|
|
if (ticks.length >= 2)
|
|
zero_eps = Math.abs(ticks[1] - ticks[0]) / 10000;
|
|
var need_sci = false;
|
|
if (this.use_scientific) {
|
|
for (var _i = 0, ticks_1 = ticks; _i < ticks_1.length; _i++) {
|
|
var tick = ticks_1[_i];
|
|
var tick_abs = Math.abs(tick);
|
|
if (tick_abs > zero_eps && (tick_abs >= this.scientific_limit_high || tick_abs <= this.scientific_limit_low)) {
|
|
need_sci = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
var labels = new Array(ticks.length);
|
|
var precision = this.precision;
|
|
if (precision == null || types_1.isNumber(precision)) {
|
|
if (need_sci) {
|
|
for (var i = 0, end = ticks.length; i < end; i++) {
|
|
labels[i] = ticks[i].toExponential(precision || undefined);
|
|
}
|
|
}
|
|
else {
|
|
for (var i = 0, end = ticks.length; i < end; i++) {
|
|
labels[i] = ticks[i].toFixed(precision || undefined).replace(/(\.[0-9]*?)0+$/, "$1").replace(/\.$/, "");
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
for (var x = this.last_precision, asc = this.last_precision <= 15; asc ? x <= 15 : x >= 15; asc ? x++ : x--) {
|
|
var is_ok = true;
|
|
if (need_sci) {
|
|
for (var i = 0, end = ticks.length; i < end; i++) {
|
|
labels[i] = ticks[i].toExponential(x);
|
|
if (i > 0) {
|
|
if (labels[i] === labels[i - 1]) {
|
|
is_ok = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (is_ok) {
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
for (var i = 0, end = ticks.length; i < end; i++) {
|
|
labels[i] = ticks[i].toFixed(x).replace(/(\.[0-9]*?)0+$/, "$1").replace(/\.$/, "");
|
|
if (i > 0) {
|
|
if (labels[i] == labels[i - 1]) {
|
|
is_ok = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (is_ok) {
|
|
break;
|
|
}
|
|
}
|
|
if (is_ok) {
|
|
this.last_precision = x;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return labels;
|
|
};
|
|
return BasicTickFormatter;
|
|
}(tick_formatter_1.TickFormatter));
|
|
exports.BasicTickFormatter = BasicTickFormatter;
|
|
BasicTickFormatter.initClass();
|
|
}
|
|
,
|
|
/* models/formatters/categorical_tick_formatter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var tick_formatter_1 = require(116) /* ./tick_formatter */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var CategoricalTickFormatter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CategoricalTickFormatter, _super);
|
|
function CategoricalTickFormatter(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CategoricalTickFormatter.initClass = function () {
|
|
this.prototype.type = 'CategoricalTickFormatter';
|
|
};
|
|
CategoricalTickFormatter.prototype.doFormat = function (ticks, _opts) {
|
|
return array_1.copy(ticks);
|
|
};
|
|
return CategoricalTickFormatter;
|
|
}(tick_formatter_1.TickFormatter));
|
|
exports.CategoricalTickFormatter = CategoricalTickFormatter;
|
|
CategoricalTickFormatter.initClass();
|
|
}
|
|
,
|
|
/* models/formatters/datetime_tick_formatter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var tz = require(399) /* timezone */;
|
|
var tick_formatter_1 = require(116) /* ./tick_formatter */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var templating_1 = require(42) /* ../../core/util/templating */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
function _us(t) {
|
|
// From double-precision unix (millisecond) timestamp get
|
|
// microsecond since last second. Precision seems to run
|
|
// out around the hundreds of nanoseconds scale, so rounding
|
|
// to the nearest microsecond should round to a nice
|
|
// microsecond / millisecond tick.
|
|
return Math.round(((t / 1000) % 1) * 1000000);
|
|
}
|
|
function _array(t) {
|
|
return tz(t, "%Y %m %d %H %M %S").split(/\s+/).map(function (e) { return parseInt(e, 10); });
|
|
}
|
|
function _strftime(t, format) {
|
|
if (types_1.isFunction(format)) {
|
|
return format(t);
|
|
}
|
|
else {
|
|
// Python's datetime library augments the microsecond directive %f, which is not
|
|
// supported by the javascript library timezone: http://bigeasy.github.io/timezone/.
|
|
// Use a regular expression to replace %f directive with microseconds.
|
|
// TODO: what should we do for negative microsecond strings?
|
|
var microsecond_replacement_string = templating_1.sprintf("$1%06d", _us(t));
|
|
format = format.replace(/((^|[^%])(%%)*)%f/, microsecond_replacement_string);
|
|
if (format.indexOf("%") == -1) {
|
|
// timezone seems to ignore any strings without any formatting directives,
|
|
// and just return the time argument back instead of the string argument.
|
|
// But we want the string argument, in case a user supplies a format string
|
|
// which doesn't contain a formatting directive or is only using %f.
|
|
return format;
|
|
}
|
|
return tz(t, format);
|
|
}
|
|
}
|
|
// Labels of time units, from finest to coarsest.
|
|
var format_order = [
|
|
'microseconds', 'milliseconds', 'seconds', 'minsec', 'minutes', 'hourmin', 'hours', 'days', 'months', 'years',
|
|
];
|
|
var DatetimeTickFormatter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DatetimeTickFormatter, _super);
|
|
function DatetimeTickFormatter(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
// Whether or not to strip the leading zeros on tick labels.
|
|
_this.strip_leading_zeros = true;
|
|
return _this;
|
|
}
|
|
DatetimeTickFormatter.initClass = function () {
|
|
this.prototype.type = 'DatetimeTickFormatter';
|
|
this.define({
|
|
microseconds: [p.Array, ['%fus']],
|
|
milliseconds: [p.Array, ['%3Nms', '%S.%3Ns']],
|
|
seconds: [p.Array, ['%Ss']],
|
|
minsec: [p.Array, [':%M:%S']],
|
|
minutes: [p.Array, [':%M', '%Mm']],
|
|
hourmin: [p.Array, ['%H:%M']],
|
|
hours: [p.Array, ['%Hh', '%H:%M']],
|
|
days: [p.Array, ['%m/%d', '%a%d']],
|
|
months: [p.Array, ['%m/%Y', '%b %Y']],
|
|
years: [p.Array, ['%Y']],
|
|
});
|
|
};
|
|
DatetimeTickFormatter.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
// TODO (bev) trigger update on format change
|
|
this._update_width_formats();
|
|
};
|
|
DatetimeTickFormatter.prototype._update_width_formats = function () {
|
|
var now = +tz(new Date());
|
|
var _widths = function (fmt_strings) {
|
|
var sizes = fmt_strings.map(function (fmt_string) { return _strftime(now, fmt_string).length; });
|
|
var sorted = array_1.sort_by(array_1.zip(sizes, fmt_strings), function (_a) {
|
|
var size = _a[0];
|
|
return size;
|
|
});
|
|
return array_1.unzip(sorted);
|
|
};
|
|
this._width_formats = {
|
|
microseconds: _widths(this.microseconds),
|
|
milliseconds: _widths(this.milliseconds),
|
|
seconds: _widths(this.seconds),
|
|
minsec: _widths(this.minsec),
|
|
minutes: _widths(this.minutes),
|
|
hourmin: _widths(this.hourmin),
|
|
hours: _widths(this.hours),
|
|
days: _widths(this.days),
|
|
months: _widths(this.months),
|
|
years: _widths(this.years),
|
|
};
|
|
};
|
|
// FIXME There is some unfortunate flicker when panning/zooming near the
|
|
// span boundaries.
|
|
// FIXME Rounding is weird at the 20-us scale and below.
|
|
DatetimeTickFormatter.prototype._get_resolution_str = function (resolution_secs, span_secs) {
|
|
// Our resolution boundaries should not be round numbers, because we want
|
|
// them to fall between the possible tick intervals (which *are* round
|
|
// numbers, as we've worked hard to ensure). Consequently, we adjust the
|
|
// resolution upwards a small amount (less than any possible step in
|
|
// scales) to make the effective boundaries slightly lower.
|
|
var adjusted_secs = resolution_secs * 1.1;
|
|
switch (false) {
|
|
case !(adjusted_secs < 1e-3): return "microseconds";
|
|
case !(adjusted_secs < 1.0): return "milliseconds";
|
|
case !(adjusted_secs < 60): return span_secs >= 60 ? "minsec" : "seconds";
|
|
case !(adjusted_secs < 3600): return span_secs >= 3600 ? "hourmin" : "minutes";
|
|
case !(adjusted_secs < (24 * 3600)): return "hours";
|
|
case !(adjusted_secs < (31 * 24 * 3600)): return "days";
|
|
case !(adjusted_secs < (365 * 24 * 3600)): return "months";
|
|
default: return "years";
|
|
}
|
|
};
|
|
DatetimeTickFormatter.prototype.doFormat = function (ticks, _opts) {
|
|
// In order to pick the right set of labels, we need to determine
|
|
// the resolution of the ticks. We can do this using a ticker if
|
|
// it's provided, or by computing the resolution from the actual
|
|
// ticks we've been given.
|
|
if (ticks.length == 0)
|
|
return [];
|
|
var span = Math.abs(ticks[ticks.length - 1] - ticks[0]) / 1000.0;
|
|
var r = span / (ticks.length - 1);
|
|
var resol = this._get_resolution_str(r, span);
|
|
var _a = this._width_formats[resol], format = _a[1][0];
|
|
// Apply the format to the tick values
|
|
var labels = [];
|
|
var resol_ndx = format_order.indexOf(resol);
|
|
// This dictionary maps the name of a time resolution (in @format_order)
|
|
// to its index in a time.localtime() timetuple. The default is to map
|
|
// everything to index 0, which is year. This is not ideal; it might cause
|
|
// a problem with the tick at midnight, january 1st, 0 a.d. being incorrectly
|
|
// promoted at certain tick resolutions.
|
|
var time_tuple_ndx_for_resol = {};
|
|
for (var _i = 0, format_order_1 = format_order; _i < format_order_1.length; _i++) {
|
|
var fmt = format_order_1[_i];
|
|
time_tuple_ndx_for_resol[fmt] = 0;
|
|
}
|
|
time_tuple_ndx_for_resol.seconds = 5;
|
|
time_tuple_ndx_for_resol.minsec = 4;
|
|
time_tuple_ndx_for_resol.minutes = 4;
|
|
time_tuple_ndx_for_resol.hourmin = 3;
|
|
time_tuple_ndx_for_resol.hours = 3;
|
|
// As we format each tick, check to see if we are at a boundary of the
|
|
// next higher unit of time. If so, replace the current format with one
|
|
// from that resolution. This is not the best heuristic in the world,
|
|
// but it works! There is some trickiness here due to having to deal
|
|
// with hybrid formats in a reasonable manner.
|
|
for (var _b = 0, ticks_1 = ticks; _b < ticks_1.length; _b++) {
|
|
var t = ticks_1[_b];
|
|
var s = void 0, tm = void 0;
|
|
try {
|
|
tm = _array(t);
|
|
s = _strftime(t, format);
|
|
}
|
|
catch (error) {
|
|
logging_1.logger.warn("unable to format tick for timestamp value " + t);
|
|
logging_1.logger.warn(" - " + error);
|
|
labels.push("ERR");
|
|
continue;
|
|
}
|
|
var hybrid_handled = false;
|
|
var next_ndx = resol_ndx;
|
|
// The way to check that we are at the boundary of the next unit of
|
|
// time is by checking that we have 0 units of the resolution, i.e.
|
|
// we are at zero minutes, so display hours, or we are at zero seconds,
|
|
// so display minutes (and if that is zero as well, then display hours).
|
|
while (tm[time_tuple_ndx_for_resol[format_order[next_ndx]]] == 0) {
|
|
var next_format = void 0;
|
|
next_ndx += 1;
|
|
if (next_ndx == format_order.length)
|
|
break;
|
|
if ((resol == "minsec" || resol == "hourmin") && !hybrid_handled) {
|
|
if ((resol == "minsec" && tm[4] == 0 && tm[5] != 0) || (resol == "hourmin" && tm[3] == 0 && tm[4] != 0)) {
|
|
next_format = this._width_formats[format_order[resol_ndx - 1]][1][0];
|
|
s = _strftime(t, next_format);
|
|
break;
|
|
}
|
|
else {
|
|
hybrid_handled = true;
|
|
}
|
|
}
|
|
next_format = this._width_formats[format_order[next_ndx]][1][0];
|
|
s = _strftime(t, next_format);
|
|
}
|
|
// TODO: should expose this in api. %H, %d, etc use leading zeros and
|
|
// users might prefer to see them lined up correctly.
|
|
if (this.strip_leading_zeros) {
|
|
var ss = s.replace(/^0+/g, "");
|
|
if (ss != s && isNaN(parseInt(ss))) {
|
|
// If the string can now be parsed as starting with an integer, then
|
|
// leave all zeros stripped, otherwise start with a zero. Hence:
|
|
// A label such as '000ms' should leave one zero.
|
|
// A label such as '001ms' or '0-1ms' should not leave a leading zero.
|
|
ss = "0" + ss;
|
|
}
|
|
labels.push(ss);
|
|
}
|
|
else
|
|
labels.push(s);
|
|
}
|
|
return labels;
|
|
};
|
|
return DatetimeTickFormatter;
|
|
}(tick_formatter_1.TickFormatter));
|
|
exports.DatetimeTickFormatter = DatetimeTickFormatter;
|
|
DatetimeTickFormatter.initClass();
|
|
}
|
|
,
|
|
/* models/formatters/func_tick_formatter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var tick_formatter_1 = require(116) /* ./tick_formatter */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var string_1 = require(40) /* ../../core/util/string */;
|
|
var FuncTickFormatter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(FuncTickFormatter, _super);
|
|
function FuncTickFormatter(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
FuncTickFormatter.initClass = function () {
|
|
this.prototype.type = 'FuncTickFormatter';
|
|
this.define({
|
|
args: [p.Any, {}],
|
|
code: [p.String, ''],
|
|
use_strict: [p.Boolean, false],
|
|
});
|
|
};
|
|
Object.defineProperty(FuncTickFormatter.prototype, "names", {
|
|
get: function () {
|
|
return object_1.keys(this.args);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(FuncTickFormatter.prototype, "values", {
|
|
get: function () {
|
|
return object_1.values(this.args);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
/*protected*/ FuncTickFormatter.prototype._make_func = function () {
|
|
var code = this.use_strict ? string_1.use_strict(this.code) : this.code;
|
|
return new (Function.bind.apply(Function, [void 0, "tick", "index", "ticks"].concat(this.names, ["require", "exports", code])))();
|
|
};
|
|
FuncTickFormatter.prototype.doFormat = function (ticks, _opts) {
|
|
var _this = this;
|
|
var cache = {};
|
|
var func = this._make_func().bind(cache);
|
|
return ticks.map(function (tick, index, ticks) { return func.apply(void 0, [tick, index, ticks].concat(_this.values, [require, {}])); });
|
|
};
|
|
return FuncTickFormatter;
|
|
}(tick_formatter_1.TickFormatter));
|
|
exports.FuncTickFormatter = FuncTickFormatter;
|
|
FuncTickFormatter.initClass();
|
|
}
|
|
,
|
|
/* models/formatters/index */ function _(require, module, exports) {
|
|
var basic_tick_formatter_1 = require(107) /* ./basic_tick_formatter */;
|
|
exports.BasicTickFormatter = basic_tick_formatter_1.BasicTickFormatter;
|
|
var categorical_tick_formatter_1 = require(108) /* ./categorical_tick_formatter */;
|
|
exports.CategoricalTickFormatter = categorical_tick_formatter_1.CategoricalTickFormatter;
|
|
var datetime_tick_formatter_1 = require(109) /* ./datetime_tick_formatter */;
|
|
exports.DatetimeTickFormatter = datetime_tick_formatter_1.DatetimeTickFormatter;
|
|
var func_tick_formatter_1 = require(110) /* ./func_tick_formatter */;
|
|
exports.FuncTickFormatter = func_tick_formatter_1.FuncTickFormatter;
|
|
var log_tick_formatter_1 = require(112) /* ./log_tick_formatter */;
|
|
exports.LogTickFormatter = log_tick_formatter_1.LogTickFormatter;
|
|
var mercator_tick_formatter_1 = require(113) /* ./mercator_tick_formatter */;
|
|
exports.MercatorTickFormatter = mercator_tick_formatter_1.MercatorTickFormatter;
|
|
var numeral_tick_formatter_1 = require(114) /* ./numeral_tick_formatter */;
|
|
exports.NumeralTickFormatter = numeral_tick_formatter_1.NumeralTickFormatter;
|
|
var printf_tick_formatter_1 = require(115) /* ./printf_tick_formatter */;
|
|
exports.PrintfTickFormatter = printf_tick_formatter_1.PrintfTickFormatter;
|
|
var tick_formatter_1 = require(116) /* ./tick_formatter */;
|
|
exports.TickFormatter = tick_formatter_1.TickFormatter;
|
|
}
|
|
,
|
|
/* models/formatters/log_tick_formatter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var tick_formatter_1 = require(116) /* ./tick_formatter */;
|
|
var basic_tick_formatter_1 = require(107) /* ./basic_tick_formatter */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var LogTickFormatter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LogTickFormatter, _super);
|
|
function LogTickFormatter(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
LogTickFormatter.initClass = function () {
|
|
this.prototype.type = 'LogTickFormatter';
|
|
this.define({
|
|
ticker: [p.Instance, null],
|
|
});
|
|
};
|
|
LogTickFormatter.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.basic_formatter = new basic_tick_formatter_1.BasicTickFormatter();
|
|
if (this.ticker == null)
|
|
logging_1.logger.warn("LogTickFormatter not configured with a ticker, using default base of 10 (labels will be incorrect if ticker base is not 10)");
|
|
};
|
|
LogTickFormatter.prototype.doFormat = function (ticks, opts) {
|
|
if (ticks.length == 0)
|
|
return [];
|
|
var base = this.ticker != null ? this.ticker.base : 10;
|
|
var small_interval = false;
|
|
var labels = new Array(ticks.length);
|
|
for (var i = 0, end = ticks.length; i < end; i++) {
|
|
labels[i] = base + "^" + Math.round(Math.log(ticks[i]) / Math.log(base));
|
|
if (i > 0 && labels[i] == labels[i - 1]) {
|
|
small_interval = true;
|
|
break;
|
|
}
|
|
}
|
|
if (small_interval)
|
|
return this.basic_formatter.doFormat(ticks, opts);
|
|
else
|
|
return labels;
|
|
};
|
|
return LogTickFormatter;
|
|
}(tick_formatter_1.TickFormatter));
|
|
exports.LogTickFormatter = LogTickFormatter;
|
|
LogTickFormatter.initClass();
|
|
}
|
|
,
|
|
/* models/formatters/mercator_tick_formatter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var basic_tick_formatter_1 = require(107) /* ./basic_tick_formatter */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var projections_1 = require(36) /* ../../core/util/projections */;
|
|
var MercatorTickFormatter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MercatorTickFormatter, _super);
|
|
function MercatorTickFormatter(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
MercatorTickFormatter.initClass = function () {
|
|
this.prototype.type = 'MercatorTickFormatter';
|
|
this.define({
|
|
dimension: [p.LatLon],
|
|
});
|
|
};
|
|
MercatorTickFormatter.prototype.doFormat = function (ticks, opts) {
|
|
if (this.dimension == null)
|
|
throw new Error("MercatorTickFormatter.dimension not configured");
|
|
if (ticks.length == 0)
|
|
return [];
|
|
var n = ticks.length;
|
|
var proj_ticks = new Array(n);
|
|
if (this.dimension == "lon") {
|
|
for (var i = 0; i < n; i++) {
|
|
var lon = projections_1.wgs84_mercator.inverse([ticks[i], opts.loc])[0];
|
|
proj_ticks[i] = lon;
|
|
}
|
|
}
|
|
else {
|
|
for (var i = 0; i < n; i++) {
|
|
var _a = projections_1.wgs84_mercator.inverse([opts.loc, ticks[i]]), lat = _a[1];
|
|
proj_ticks[i] = lat;
|
|
}
|
|
}
|
|
return _super.prototype.doFormat.call(this, proj_ticks, opts);
|
|
};
|
|
return MercatorTickFormatter;
|
|
}(basic_tick_formatter_1.BasicTickFormatter));
|
|
exports.MercatorTickFormatter = MercatorTickFormatter;
|
|
MercatorTickFormatter.initClass();
|
|
}
|
|
,
|
|
/* models/formatters/numeral_tick_formatter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var Numbro = require(370) /* numbro */;
|
|
var tick_formatter_1 = require(116) /* ./tick_formatter */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var NumeralTickFormatter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(NumeralTickFormatter, _super);
|
|
function NumeralTickFormatter(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
NumeralTickFormatter.initClass = function () {
|
|
this.prototype.type = 'NumeralTickFormatter';
|
|
this.define({
|
|
// TODO (bev) all of these could be tightened up
|
|
format: [p.String, '0,0'],
|
|
language: [p.String, 'en'],
|
|
rounding: [p.RoundingFunction, 'round'],
|
|
});
|
|
};
|
|
Object.defineProperty(NumeralTickFormatter.prototype, "_rounding_fn", {
|
|
get: function () {
|
|
switch (this.rounding) {
|
|
case "round":
|
|
case "nearest":
|
|
return Math.round;
|
|
case "floor":
|
|
case "rounddown":
|
|
return Math.floor;
|
|
case "ceil":
|
|
case "roundup":
|
|
return Math.ceil;
|
|
}
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
NumeralTickFormatter.prototype.doFormat = function (ticks, _opts) {
|
|
var _a = this, format = _a.format, language = _a.language, _rounding_fn = _a._rounding_fn;
|
|
return ticks.map(function (tick) { return Numbro.format(tick, format, language, _rounding_fn); });
|
|
};
|
|
return NumeralTickFormatter;
|
|
}(tick_formatter_1.TickFormatter));
|
|
exports.NumeralTickFormatter = NumeralTickFormatter;
|
|
NumeralTickFormatter.initClass();
|
|
}
|
|
,
|
|
/* models/formatters/printf_tick_formatter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var tick_formatter_1 = require(116) /* ./tick_formatter */;
|
|
var templating_1 = require(42) /* ../../core/util/templating */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var PrintfTickFormatter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PrintfTickFormatter, _super);
|
|
function PrintfTickFormatter(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
PrintfTickFormatter.initClass = function () {
|
|
this.prototype.type = 'PrintfTickFormatter';
|
|
this.define({
|
|
format: [p.String, '%s'],
|
|
});
|
|
};
|
|
PrintfTickFormatter.prototype.doFormat = function (ticks, _opts) {
|
|
var _this = this;
|
|
return ticks.map(function (tick) { return templating_1.sprintf(_this.format, tick); });
|
|
};
|
|
return PrintfTickFormatter;
|
|
}(tick_formatter_1.TickFormatter));
|
|
exports.PrintfTickFormatter = PrintfTickFormatter;
|
|
PrintfTickFormatter.initClass();
|
|
}
|
|
,
|
|
/* models/formatters/tick_formatter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var TickFormatter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TickFormatter, _super);
|
|
function TickFormatter(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
TickFormatter.initClass = function () {
|
|
this.prototype.type = "TickFormatter";
|
|
};
|
|
return TickFormatter;
|
|
}(model_1.Model));
|
|
exports.TickFormatter = TickFormatter;
|
|
TickFormatter.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/annular_wedge */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var math_1 = require(34) /* ../../core/util/math */;
|
|
var AnnularWedgeView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(AnnularWedgeView, _super);
|
|
function AnnularWedgeView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
AnnularWedgeView.prototype._map_data = function () {
|
|
if (this.model.properties.inner_radius.units == "data")
|
|
this.sinner_radius = this.sdist(this.renderer.xscale, this._x, this._inner_radius);
|
|
else
|
|
this.sinner_radius = this._inner_radius;
|
|
if (this.model.properties.outer_radius.units == "data")
|
|
this.souter_radius = this.sdist(this.renderer.xscale, this._x, this._outer_radius);
|
|
else
|
|
this.souter_radius = this._outer_radius;
|
|
this._angle = new Float32Array(this._start_angle.length);
|
|
for (var i = 0, end = this._start_angle.length; i < end; i++) {
|
|
this._angle[i] = this._end_angle[i] - this._start_angle[i];
|
|
}
|
|
};
|
|
AnnularWedgeView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy, _start_angle = _a._start_angle, _angle = _a._angle, sinner_radius = _a.sinner_radius, souter_radius = _a.souter_radius;
|
|
var direction = this.model.properties.direction.value();
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + sinner_radius[i] + souter_radius[i] + _start_angle[i] + _angle[i]))
|
|
continue;
|
|
ctx.translate(sx[i], sy[i]);
|
|
ctx.rotate(_start_angle[i]);
|
|
ctx.moveTo(souter_radius[i], 0);
|
|
ctx.beginPath();
|
|
ctx.arc(0, 0, souter_radius[i], 0, _angle[i], direction);
|
|
ctx.rotate(_angle[i]);
|
|
ctx.lineTo(sinner_radius[i], 0);
|
|
ctx.arc(0, 0, sinner_radius[i], 0, -_angle[i], !direction);
|
|
ctx.closePath();
|
|
ctx.rotate(-_angle[i] - _start_angle[i]);
|
|
ctx.translate(-sx[i], -sy[i]);
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
};
|
|
AnnularWedgeView.prototype._hit_point = function (geometry) {
|
|
var _a, _b;
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x = this.renderer.xscale.invert(sx);
|
|
var y = this.renderer.yscale.invert(sy);
|
|
// check radius first
|
|
var x0, y0;
|
|
var x1, y1;
|
|
if (this.model.properties.outer_radius.units == "data") {
|
|
x0 = x - this.max_outer_radius;
|
|
x1 = x + this.max_outer_radius;
|
|
y0 = y - this.max_outer_radius;
|
|
y1 = y + this.max_outer_radius;
|
|
}
|
|
else {
|
|
var sx0 = sx - this.max_outer_radius;
|
|
var sx1 = sx + this.max_outer_radius;
|
|
_a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
var sy0 = sy - this.max_outer_radius;
|
|
var sy1 = sy + this.max_outer_radius;
|
|
_b = this.renderer.yscale.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
}
|
|
var candidates = [];
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
for (var _i = 0, _c = this.index.indices(bbox); _i < _c.length; _i++) {
|
|
var i = _c[_i];
|
|
var or2 = Math.pow(this.souter_radius[i], 2);
|
|
var ir2 = Math.pow(this.sinner_radius[i], 2);
|
|
var _d = this.renderer.xscale.r_compute(x, this._x[i]), sx0 = _d[0], sx1 = _d[1];
|
|
var _e = this.renderer.yscale.r_compute(y, this._y[i]), sy0 = _e[0], sy1 = _e[1];
|
|
var dist = Math.pow(sx0 - sx1, 2) + Math.pow(sy0 - sy1, 2);
|
|
if (dist <= or2 && dist >= ir2)
|
|
candidates.push([i, dist]);
|
|
}
|
|
var direction = this.model.properties.direction.value();
|
|
var hits = [];
|
|
for (var _f = 0, candidates_1 = candidates; _f < candidates_1.length; _f++) {
|
|
var _g = candidates_1[_f], i = _g[0], dist = _g[1];
|
|
// NOTE: minus the angle because JS uses non-mathy convention for angles
|
|
var angle = Math.atan2(sy - this.sy[i], sx - this.sx[i]);
|
|
if (math_1.angle_between(-angle, -this._start_angle[i], -this._end_angle[i], direction)) {
|
|
hits.push([i, dist]);
|
|
}
|
|
}
|
|
return hittest.create_hit_test_result_from_hits(hits);
|
|
};
|
|
AnnularWedgeView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
AnnularWedgeView.prototype._scenterxy = function (i) {
|
|
var r = (this.sinner_radius[i] + this.souter_radius[i]) / 2;
|
|
var a = (this._start_angle[i] + this._end_angle[i]) / 2;
|
|
return { x: this.sx[i] + (r * Math.cos(a)), y: this.sy[i] + (r * Math.sin(a)) };
|
|
};
|
|
AnnularWedgeView.prototype.scenterx = function (i) {
|
|
return this._scenterxy(i).x;
|
|
};
|
|
AnnularWedgeView.prototype.scentery = function (i) {
|
|
return this._scenterxy(i).y;
|
|
};
|
|
return AnnularWedgeView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.AnnularWedgeView = AnnularWedgeView;
|
|
var AnnularWedge = /** @class */ (function (_super) {
|
|
tslib_1.__extends(AnnularWedge, _super);
|
|
function AnnularWedge(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
AnnularWedge.initClass = function () {
|
|
this.prototype.type = 'AnnularWedge';
|
|
this.prototype.default_view = AnnularWedgeView;
|
|
this.mixins(['line', 'fill']);
|
|
this.define({
|
|
direction: [p.Direction, 'anticlock'],
|
|
inner_radius: [p.DistanceSpec],
|
|
outer_radius: [p.DistanceSpec],
|
|
start_angle: [p.AngleSpec],
|
|
end_angle: [p.AngleSpec],
|
|
});
|
|
};
|
|
return AnnularWedge;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.AnnularWedge = AnnularWedge;
|
|
AnnularWedge.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/annulus */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var compat_1 = require(31) /* ../../core/util/compat */;
|
|
var AnnulusView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(AnnulusView, _super);
|
|
function AnnulusView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
AnnulusView.prototype._map_data = function () {
|
|
if (this.model.properties.inner_radius.units == "data")
|
|
this.sinner_radius = this.sdist(this.renderer.xscale, this._x, this._inner_radius);
|
|
else
|
|
this.sinner_radius = this._inner_radius;
|
|
if (this.model.properties.outer_radius.units == "data")
|
|
this.souter_radius = this.sdist(this.renderer.xscale, this._x, this._outer_radius);
|
|
else
|
|
this.souter_radius = this._outer_radius;
|
|
};
|
|
AnnulusView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy, sinner_radius = _a.sinner_radius, souter_radius = _a.souter_radius;
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + sinner_radius[i] + souter_radius[i]))
|
|
continue;
|
|
// Because this visual has a whole in it, it proved "challenging"
|
|
// for some browsers to render if drawn in one go --- i.e. it did not
|
|
// work on IE. If we render in two parts (upper and lower part),
|
|
// it is unambiguous what part should be filled. The line is
|
|
// better drawn in one go though, otherwise the part where the pieces
|
|
// meet will not be fully closed due to aa.
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_vectorize(ctx, i);
|
|
ctx.beginPath();
|
|
if (compat_1.is_ie) {
|
|
// Draw two halves of the donut. Works on IE, but causes an aa line on Safari.
|
|
for (var _b = 0, _c = [false, true]; _b < _c.length; _b++) {
|
|
var clockwise = _c[_b];
|
|
ctx.arc(sx[i], sy[i], sinner_radius[i], 0, Math.PI, clockwise);
|
|
ctx.arc(sx[i], sy[i], souter_radius[i], Math.PI, 0, !clockwise);
|
|
}
|
|
}
|
|
else {
|
|
// Draw donut in one go. Does not work on iE.
|
|
ctx.arc(sx[i], sy[i], sinner_radius[i], 0, 2 * Math.PI, true);
|
|
ctx.arc(sx[i], sy[i], souter_radius[i], 2 * Math.PI, 0, false);
|
|
}
|
|
ctx.fill();
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.beginPath();
|
|
ctx.arc(sx[i], sy[i], sinner_radius[i], 0, 2 * Math.PI);
|
|
ctx.moveTo(sx[i] + souter_radius[i], sy[i]);
|
|
ctx.arc(sx[i], sy[i], souter_radius[i], 0, 2 * Math.PI);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
};
|
|
AnnulusView.prototype._hit_point = function (geometry) {
|
|
var _a, _b;
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x = this.renderer.xscale.invert(sx);
|
|
var y = this.renderer.yscale.invert(sy);
|
|
var x0, y0;
|
|
var x1, y1;
|
|
if (this.model.properties.outer_radius.units == "data") {
|
|
x0 = x - this.max_outer_radius;
|
|
x1 = x + this.max_outer_radius;
|
|
y0 = y - this.max_outer_radius;
|
|
y1 = y + this.max_outer_radius;
|
|
}
|
|
else {
|
|
var sx0 = sx - this.max_outer_radius;
|
|
var sx1 = sx + this.max_outer_radius;
|
|
_a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
var sy0 = sy - this.max_outer_radius;
|
|
var sy1 = sy + this.max_outer_radius;
|
|
_b = this.renderer.yscale.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
}
|
|
var hits = [];
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
for (var _i = 0, _c = this.index.indices(bbox); _i < _c.length; _i++) {
|
|
var i = _c[_i];
|
|
var or2 = Math.pow(this.souter_radius[i], 2);
|
|
var ir2 = Math.pow(this.sinner_radius[i], 2);
|
|
var _d = this.renderer.xscale.r_compute(x, this._x[i]), sx0 = _d[0], sx1 = _d[1];
|
|
var _e = this.renderer.yscale.r_compute(y, this._y[i]), sy0 = _e[0], sy1 = _e[1];
|
|
var dist = Math.pow(sx0 - sx1, 2) + Math.pow(sy0 - sy1, 2);
|
|
if (dist <= or2 && dist >= ir2)
|
|
hits.push([i, dist]);
|
|
}
|
|
return hittest.create_hit_test_result_from_hits(hits);
|
|
};
|
|
AnnulusView.prototype.draw_legend_for_index = function (ctx, _a, index) {
|
|
var x0 = _a.x0, y0 = _a.y0, x1 = _a.x1, y1 = _a.y1;
|
|
var len = index + 1;
|
|
var sx = new Array(len);
|
|
sx[index] = (x0 + x1) / 2;
|
|
var sy = new Array(len);
|
|
sy[index] = (y0 + y1) / 2;
|
|
var r = Math.min(Math.abs(x1 - x0), Math.abs(y1 - y0)) * 0.5;
|
|
var sinner_radius = new Array(len);
|
|
sinner_radius[index] = r * 0.4;
|
|
var souter_radius = new Array(len);
|
|
souter_radius[index] = r * 0.8;
|
|
this._render(ctx, [index], { sx: sx, sy: sy, sinner_radius: sinner_radius, souter_radius: souter_radius }); // XXX
|
|
};
|
|
return AnnulusView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.AnnulusView = AnnulusView;
|
|
var Annulus = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Annulus, _super);
|
|
function Annulus(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Annulus.initClass = function () {
|
|
this.prototype.type = 'Annulus';
|
|
this.prototype.default_view = AnnulusView;
|
|
this.mixins(['line', 'fill']);
|
|
this.define({
|
|
inner_radius: [p.DistanceSpec],
|
|
outer_radius: [p.DistanceSpec],
|
|
});
|
|
};
|
|
return Annulus;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.Annulus = Annulus;
|
|
Annulus.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/arc */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var ArcView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ArcView, _super);
|
|
function ArcView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ArcView.prototype._map_data = function () {
|
|
if (this.model.properties.radius.units == "data")
|
|
this.sradius = this.sdist(this.renderer.xscale, this._x, this._radius);
|
|
else
|
|
this.sradius = this._radius;
|
|
};
|
|
ArcView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy, sradius = _a.sradius, _start_angle = _a._start_angle, _end_angle = _a._end_angle;
|
|
if (this.visuals.line.doit) {
|
|
var direction = this.model.properties.direction.value();
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + sradius[i] + _start_angle[i] + _end_angle[i]))
|
|
continue;
|
|
ctx.beginPath();
|
|
ctx.arc(sx[i], sy[i], sradius[i], _start_angle[i], _end_angle[i], direction);
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
};
|
|
ArcView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
return ArcView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.ArcView = ArcView;
|
|
var Arc = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Arc, _super);
|
|
function Arc(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Arc.initClass = function () {
|
|
this.prototype.type = 'Arc';
|
|
this.prototype.default_view = ArcView;
|
|
this.mixins(['line']);
|
|
this.define({
|
|
direction: [p.Direction, 'anticlock'],
|
|
radius: [p.DistanceSpec],
|
|
start_angle: [p.AngleSpec],
|
|
end_angle: [p.AngleSpec],
|
|
});
|
|
};
|
|
return Arc;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.Arc = Arc;
|
|
Arc.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/bezier */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var spatial_1 = require(39) /* ../../core/util/spatial */;
|
|
var glyph_1 = require(126) /* ./glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
// algorithm adapted from http://stackoverflow.com/a/14429749/3406693
|
|
function _cbb(x0, y0, x1, y1, x2, y2, x3, y3) {
|
|
var tvalues = [];
|
|
var bounds = [[], []];
|
|
for (var i = 0; i <= 2; i++) {
|
|
var a = void 0, b = void 0, c = void 0;
|
|
if (i === 0) {
|
|
b = ((6 * x0) - (12 * x1)) + (6 * x2);
|
|
a = (((-3 * x0) + (9 * x1)) - (9 * x2)) + (3 * x3);
|
|
c = (3 * x1) - (3 * x0);
|
|
}
|
|
else {
|
|
b = ((6 * y0) - (12 * y1)) + (6 * y2);
|
|
a = (((-3 * y0) + (9 * y1)) - (9 * y2)) + (3 * y3);
|
|
c = (3 * y1) - (3 * y0);
|
|
}
|
|
if (Math.abs(a) < 1e-12) { // Numerical robustness
|
|
if (Math.abs(b) < 1e-12) // Numerical robustness
|
|
continue;
|
|
var t = -c / b;
|
|
if (0 < t && t < 1)
|
|
tvalues.push(t);
|
|
continue;
|
|
}
|
|
var b2ac = (b * b) - (4 * c * a);
|
|
var sqrtb2ac = Math.sqrt(b2ac);
|
|
if (b2ac < 0)
|
|
continue;
|
|
var t1 = (-b + sqrtb2ac) / (2 * a);
|
|
if (0 < t1 && t1 < 1)
|
|
tvalues.push(t1);
|
|
var t2 = (-b - sqrtb2ac) / (2 * a);
|
|
if (0 < t2 && t2 < 1)
|
|
tvalues.push(t2);
|
|
}
|
|
var j = tvalues.length;
|
|
var jlen = j;
|
|
while (j--) {
|
|
var t = tvalues[j];
|
|
var mt = 1 - t;
|
|
var x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);
|
|
bounds[0][j] = x;
|
|
var y = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);
|
|
bounds[1][j] = y;
|
|
}
|
|
bounds[0][jlen] = x0;
|
|
bounds[1][jlen] = y0;
|
|
bounds[0][jlen + 1] = x3;
|
|
bounds[1][jlen + 1] = y3;
|
|
return [
|
|
Math.min.apply(Math, bounds[0]),
|
|
Math.max.apply(Math, bounds[1]),
|
|
Math.max.apply(Math, bounds[0]),
|
|
Math.min.apply(Math, bounds[1]),
|
|
];
|
|
}
|
|
var BezierView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BezierView, _super);
|
|
function BezierView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
BezierView.prototype._index_data = function () {
|
|
var points = [];
|
|
for (var i = 0, end = this._x0.length; i < end; i++) {
|
|
if (isNaN(this._x0[i] + this._x1[i] + this._y0[i] + this._y1[i] + this._cx0[i] + this._cy0[i] + this._cx1[i] + this._cy1[i]))
|
|
continue;
|
|
var _a = _cbb(this._x0[i], this._y0[i], this._x1[i], this._y1[i], this._cx0[i], this._cy0[i], this._cx1[i], this._cy1[i]), x0 = _a[0], y0 = _a[1], x1 = _a[2], y1 = _a[3];
|
|
points.push({ minX: x0, minY: y0, maxX: x1, maxY: y1, i: i });
|
|
}
|
|
return new spatial_1.SpatialIndex(points);
|
|
};
|
|
BezierView.prototype._render = function (ctx, indices, _a) {
|
|
var sx0 = _a.sx0, sy0 = _a.sy0, sx1 = _a.sx1, sy1 = _a.sy1, scx0 = _a.scx0, scy0 = _a.scy0, scx1 = _a.scx1, scy1 = _a.scy1;
|
|
if (this.visuals.line.doit) {
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx0[i] + sy0[i] + sx1[i] + sy1[i] + scx0[i] + scy0[i] + scx1[i] + scy1[i]))
|
|
continue;
|
|
ctx.beginPath();
|
|
ctx.moveTo(sx0[i], sy0[i]);
|
|
ctx.bezierCurveTo(scx0[i], scy0[i], scx1[i], scy1[i], sx1[i], sy1[i]);
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
};
|
|
BezierView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
BezierView.prototype.scenterx = function () {
|
|
throw new Error("not implemented");
|
|
};
|
|
BezierView.prototype.scentery = function () {
|
|
throw new Error("not implemented");
|
|
};
|
|
return BezierView;
|
|
}(glyph_1.GlyphView));
|
|
exports.BezierView = BezierView;
|
|
var Bezier = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Bezier, _super);
|
|
function Bezier(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Bezier.initClass = function () {
|
|
this.prototype.type = 'Bezier';
|
|
this.prototype.default_view = BezierView;
|
|
this.coords([['x0', 'y0'], ['x1', 'y1'], ['cx0', 'cy0'], ['cx1', 'cy1']]);
|
|
this.mixins(['line']);
|
|
};
|
|
return Bezier;
|
|
}(glyph_1.Glyph));
|
|
exports.Bezier = Bezier;
|
|
Bezier.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/box */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var spatial_1 = require(39) /* ../../core/util/spatial */;
|
|
var glyph_1 = require(126) /* ./glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var BoxView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BoxView, _super);
|
|
function BoxView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
BoxView.prototype._index_box = function (len) {
|
|
var points = [];
|
|
for (var i = 0; i < len; i++) {
|
|
var _a = this._lrtb(i), l = _a[0], r = _a[1], t = _a[2], b = _a[3];
|
|
if (isNaN(l + r + t + b) || !isFinite(l + r + t + b))
|
|
continue;
|
|
points.push({
|
|
minX: Math.min(l, r),
|
|
minY: Math.min(t, b),
|
|
maxX: Math.max(r, l),
|
|
maxY: Math.max(t, b),
|
|
i: i,
|
|
});
|
|
}
|
|
return new spatial_1.SpatialIndex(points);
|
|
};
|
|
BoxView.prototype._render = function (ctx, indices, _a) {
|
|
var sleft = _a.sleft, sright = _a.sright, stop = _a.stop, sbottom = _a.sbottom;
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sleft[i] + stop[i] + sright[i] + sbottom[i]))
|
|
continue;
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_vectorize(ctx, i);
|
|
ctx.fillRect(sleft[i], stop[i], sright[i] - sleft[i], sbottom[i] - stop[i]);
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
ctx.beginPath();
|
|
ctx.rect(sleft[i], stop[i], sright[i] - sleft[i], sbottom[i] - stop[i]);
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
};
|
|
// We need to clamp the endpoints inside the viewport, because various browser canvas
|
|
// implementations have issues drawing rects with enpoints far outside the viewport
|
|
BoxView.prototype._clamp_viewport = function () {
|
|
var hr = this.renderer.plot_view.frame.bbox.h_range;
|
|
var vr = this.renderer.plot_view.frame.bbox.v_range;
|
|
var n = this.stop.length;
|
|
for (var i = 0; i < n; i++) {
|
|
this.stop[i] = Math.max(this.stop[i], vr.start);
|
|
this.sbottom[i] = Math.min(this.sbottom[i], vr.end);
|
|
this.sleft[i] = Math.max(this.sleft[i], hr.start);
|
|
this.sright[i] = Math.min(this.sright[i], hr.end);
|
|
}
|
|
};
|
|
BoxView.prototype._hit_rect = function (geometry) {
|
|
return this._hit_rect_against_index(geometry);
|
|
};
|
|
BoxView.prototype._hit_point = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x = this.renderer.xscale.invert(sx);
|
|
var y = this.renderer.yscale.invert(sy);
|
|
var hits = this.index.indices({ minX: x, minY: y, maxX: x, maxY: y });
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
BoxView.prototype._hit_span = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var hits;
|
|
if (geometry.direction == 'v') {
|
|
var y = this.renderer.yscale.invert(sy);
|
|
var hr = this.renderer.plot_view.frame.bbox.h_range;
|
|
var _a = this.renderer.xscale.r_invert(hr.start, hr.end), minX = _a[0], maxX = _a[1];
|
|
hits = this.index.indices({ minX: minX, minY: y, maxX: maxX, maxY: y });
|
|
}
|
|
else {
|
|
var x = this.renderer.xscale.invert(sx);
|
|
var vr = this.renderer.plot_view.frame.bbox.v_range;
|
|
var _b = this.renderer.yscale.r_invert(vr.start, vr.end), minY = _b[0], maxY = _b[1];
|
|
hits = this.index.indices({ minX: x, minY: minY, maxX: x, maxY: maxY });
|
|
}
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
BoxView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
return BoxView;
|
|
}(glyph_1.GlyphView));
|
|
exports.BoxView = BoxView;
|
|
var Box = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Box, _super);
|
|
function Box(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Box.initClass = function () {
|
|
this.prototype.type = "Box";
|
|
this.mixins(['line', 'fill']);
|
|
};
|
|
return Box;
|
|
}(glyph_1.Glyph));
|
|
exports.Box = Box;
|
|
Box.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/center_rotatable */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var CenterRotatableView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CenterRotatableView, _super);
|
|
function CenterRotatableView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return CenterRotatableView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.CenterRotatableView = CenterRotatableView;
|
|
var CenterRotatable = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CenterRotatable, _super);
|
|
function CenterRotatable(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CenterRotatable.initClass = function () {
|
|
this.prototype.type = 'CenterRotatable';
|
|
this.mixins(['line', 'fill']);
|
|
this.define({
|
|
angle: [p.AngleSpec, 0],
|
|
width: [p.DistanceSpec],
|
|
height: [p.DistanceSpec],
|
|
});
|
|
};
|
|
return CenterRotatable;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.CenterRotatable = CenterRotatable;
|
|
CenterRotatable.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/circle */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var arrayable_1 = require(25) /* ../../core/util/arrayable */;
|
|
var CircleView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CircleView, _super);
|
|
function CircleView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
CircleView.prototype._map_data = function () {
|
|
// XXX: Order is important here: size is always present (at least
|
|
// a default), but radius is only present if a user specifies it.
|
|
if (this._radius != null) {
|
|
if (this.model.properties.radius.spec.units == "data") {
|
|
var rd = this.model.properties.radius_dimension.spec.value;
|
|
switch (rd) {
|
|
case "x": {
|
|
this.sradius = this.sdist(this.renderer.xscale, this._x, this._radius);
|
|
break;
|
|
}
|
|
case "y": {
|
|
this.sradius = this.sdist(this.renderer.yscale, this._y, this._radius);
|
|
break;
|
|
}
|
|
case "max": {
|
|
var sradius_x = this.sdist(this.renderer.xscale, this._x, this._radius);
|
|
var sradius_y_1 = this.sdist(this.renderer.yscale, this._y, this._radius);
|
|
this.sradius = arrayable_1.map(sradius_x, function (s, i) { return Math.max(s, sradius_y_1[i]); });
|
|
break;
|
|
}
|
|
case "min": {
|
|
var sradius_x = this.sdist(this.renderer.xscale, this._x, this._radius);
|
|
var sradius_y_2 = this.sdist(this.renderer.yscale, this._y, this._radius);
|
|
this.sradius = arrayable_1.map(sradius_x, function (s, i) { return Math.min(s, sradius_y_2[i]); });
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
this.sradius = this._radius;
|
|
this.max_size = 2 * this.max_radius;
|
|
}
|
|
}
|
|
else
|
|
this.sradius = arrayable_1.map(this._size, function (s) { return s / 2; });
|
|
};
|
|
CircleView.prototype._mask_data = function () {
|
|
var _a, _b, _c, _d;
|
|
var _e = this.renderer.plot_view.frame.bbox.ranges, hr = _e[0], vr = _e[1];
|
|
var x0, y0;
|
|
var x1, y1;
|
|
if (this._radius != null && this.model.properties.radius.units == "data") {
|
|
var sx0 = hr.start;
|
|
var sx1 = hr.end;
|
|
_a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
x0 -= this.max_radius;
|
|
x1 += this.max_radius;
|
|
var sy0 = vr.start;
|
|
var sy1 = vr.end;
|
|
_b = this.renderer.yscale.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
y0 -= this.max_radius;
|
|
y1 += this.max_radius;
|
|
}
|
|
else {
|
|
var sx0 = hr.start - this.max_size;
|
|
var sx1 = hr.end + this.max_size;
|
|
_c = this.renderer.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];
|
|
var sy0 = vr.start - this.max_size;
|
|
var sy1 = vr.end + this.max_size;
|
|
_d = this.renderer.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];
|
|
}
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
return this.index.indices(bbox);
|
|
};
|
|
CircleView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy, sradius = _a.sradius;
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + sradius[i]))
|
|
continue;
|
|
ctx.beginPath();
|
|
ctx.arc(sx[i], sy[i], sradius[i], 0, 2 * Math.PI, false);
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
};
|
|
CircleView.prototype._hit_point = function (geometry) {
|
|
var _a, _b, _c, _d, _e, _f;
|
|
var dist, r2, sx0, sx1, sy0, sy1, x0, x1, y0, y1;
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x = this.renderer.xscale.invert(sx);
|
|
var y = this.renderer.yscale.invert(sy);
|
|
// check radius first
|
|
if ((this._radius != null) && (this.model.properties.radius.units == "data")) {
|
|
x0 = x - this.max_radius;
|
|
x1 = x + this.max_radius;
|
|
y0 = y - this.max_radius;
|
|
y1 = y + this.max_radius;
|
|
}
|
|
else {
|
|
sx0 = sx - this.max_size;
|
|
sx1 = sx + this.max_size;
|
|
_a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
_b = [Math.min(x0, x1), Math.max(x0, x1)], x0 = _b[0], x1 = _b[1];
|
|
sy0 = sy - this.max_size;
|
|
sy1 = sy + this.max_size;
|
|
_c = this.renderer.yscale.r_invert(sy0, sy1), y0 = _c[0], y1 = _c[1];
|
|
_d = [Math.min(y0, y1), Math.max(y0, y1)], y0 = _d[0], y1 = _d[1];
|
|
}
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
var candidates = this.index.indices(bbox);
|
|
var hits = [];
|
|
if ((this._radius != null) && (this.model.properties.radius.units == "data")) {
|
|
for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
|
|
var i = candidates_1[_i];
|
|
r2 = Math.pow(this.sradius[i], 2);
|
|
_e = this.renderer.xscale.r_compute(x, this._x[i]), sx0 = _e[0], sx1 = _e[1];
|
|
_f = this.renderer.yscale.r_compute(y, this._y[i]), sy0 = _f[0], sy1 = _f[1];
|
|
dist = Math.pow(sx0 - sx1, 2) + Math.pow(sy0 - sy1, 2);
|
|
if (dist <= r2) {
|
|
hits.push([i, dist]);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
for (var _g = 0, candidates_2 = candidates; _g < candidates_2.length; _g++) {
|
|
var i = candidates_2[_g];
|
|
r2 = Math.pow(this.sradius[i], 2);
|
|
dist = Math.pow(this.sx[i] - sx, 2) + Math.pow(this.sy[i] - sy, 2);
|
|
if (dist <= r2) {
|
|
hits.push([i, dist]);
|
|
}
|
|
}
|
|
}
|
|
return hittest.create_hit_test_result_from_hits(hits);
|
|
};
|
|
CircleView.prototype._hit_span = function (geometry) {
|
|
var _a, _b, _c, _d;
|
|
var ms, x0, x1, y0, y1;
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var _e = this.bounds(), minX = _e.minX, minY = _e.minY, maxX = _e.maxX, maxY = _e.maxY;
|
|
var result = hittest.create_empty_hit_test_result();
|
|
if (geometry.direction == 'h') {
|
|
// use circle bounds instead of current pointer y coordinates
|
|
var sx0 = void 0, sx1 = void 0;
|
|
y0 = minY;
|
|
y1 = maxY;
|
|
if (this._radius != null && this.model.properties.radius.units == "data") {
|
|
sx0 = sx - this.max_radius;
|
|
sx1 = sx + this.max_radius;
|
|
_a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
}
|
|
else {
|
|
ms = this.max_size / 2;
|
|
sx0 = sx - ms;
|
|
sx1 = sx + ms;
|
|
_b = this.renderer.xscale.r_invert(sx0, sx1), x0 = _b[0], x1 = _b[1];
|
|
}
|
|
}
|
|
else {
|
|
// use circle bounds instead of current pointer x coordinates
|
|
var sy0 = void 0, sy1 = void 0;
|
|
x0 = minX;
|
|
x1 = maxX;
|
|
if (this._radius != null && this.model.properties.radius.units == "data") {
|
|
sy0 = sy - this.max_radius;
|
|
sy1 = sy + this.max_radius;
|
|
_c = this.renderer.yscale.r_invert(sy0, sy1), y0 = _c[0], y1 = _c[1];
|
|
}
|
|
else {
|
|
ms = this.max_size / 2;
|
|
sy0 = sy - ms;
|
|
sy1 = sy + ms;
|
|
_d = this.renderer.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];
|
|
}
|
|
}
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
var hits = this.index.indices(bbox);
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
CircleView.prototype._hit_rect = function (geometry) {
|
|
var sx0 = geometry.sx0, sx1 = geometry.sx1, sy0 = geometry.sy0, sy1 = geometry.sy1;
|
|
var _a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
var _b = this.renderer.yscale.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = this.index.indices(bbox);
|
|
return result;
|
|
};
|
|
CircleView.prototype._hit_poly = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
// TODO (bev) use spatial index to pare candidate list
|
|
var candidates = array_1.range(0, this.sx.length);
|
|
var hits = [];
|
|
for (var i = 0, end = candidates.length; i < end; i++) {
|
|
var idx = candidates[i];
|
|
if (hittest.point_in_poly(this.sx[i], this.sy[i], sx, sy)) {
|
|
hits.push(idx);
|
|
}
|
|
}
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
// circle does not inherit from marker (since it also accepts radius) so we
|
|
// must supply a draw_legend for it here
|
|
CircleView.prototype.draw_legend_for_index = function (ctx, _a, index) {
|
|
var x0 = _a.x0, y0 = _a.y0, x1 = _a.x1, y1 = _a.y1;
|
|
// using objects like this seems a little wonky, since the keys are coerced to
|
|
// stings, but it works
|
|
var len = index + 1;
|
|
var sx = new Array(len);
|
|
sx[index] = (x0 + x1) / 2;
|
|
var sy = new Array(len);
|
|
sy[index] = (y0 + y1) / 2;
|
|
var sradius = new Array(len);
|
|
sradius[index] = Math.min(Math.abs(x1 - x0), Math.abs(y1 - y0)) * 0.2;
|
|
this._render(ctx, [index], { sx: sx, sy: sy, sradius: sradius }); // XXX
|
|
};
|
|
return CircleView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.CircleView = CircleView;
|
|
var Circle = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Circle, _super);
|
|
function Circle(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Circle.initClass = function () {
|
|
this.prototype.type = 'Circle';
|
|
this.prototype.default_view = CircleView;
|
|
this.mixins(['line', 'fill']);
|
|
this.define({
|
|
angle: [p.AngleSpec, 0],
|
|
size: [p.DistanceSpec, { units: "screen", value: 4 }],
|
|
radius: [p.DistanceSpec],
|
|
radius_dimension: [p.RadiusDimension, 'x'],
|
|
});
|
|
};
|
|
Circle.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.properties.radius.optional = true;
|
|
};
|
|
return Circle;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.Circle = Circle;
|
|
Circle.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/ellipse */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var ellipse_oval_1 = require(125) /* ./ellipse_oval */;
|
|
var EllipseView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(EllipseView, _super);
|
|
function EllipseView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return EllipseView;
|
|
}(ellipse_oval_1.EllipseOvalView));
|
|
exports.EllipseView = EllipseView;
|
|
var Ellipse = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Ellipse, _super);
|
|
function Ellipse(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Ellipse.initClass = function () {
|
|
this.prototype.type = 'Ellipse';
|
|
this.prototype.default_view = EllipseView;
|
|
};
|
|
return Ellipse;
|
|
}(ellipse_oval_1.EllipseOval));
|
|
exports.Ellipse = Ellipse;
|
|
Ellipse.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/ellipse_oval */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var center_rotatable_1 = require(122) /* ./center_rotatable */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var EllipseOvalView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(EllipseOvalView, _super);
|
|
function EllipseOvalView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
EllipseOvalView.prototype._set_data = function () {
|
|
this.max_w2 = 0;
|
|
if (this.model.properties.width.units == "data")
|
|
this.max_w2 = this.max_width / 2;
|
|
this.max_h2 = 0;
|
|
if (this.model.properties.height.units == "data")
|
|
this.max_h2 = this.max_height / 2;
|
|
};
|
|
EllipseOvalView.prototype._map_data = function () {
|
|
if (this.model.properties.width.units == "data")
|
|
this.sw = this.sdist(this.renderer.xscale, this._x, this._width, 'center');
|
|
else
|
|
this.sw = this._width;
|
|
if (this.model.properties.height.units == "data")
|
|
this.sh = this.sdist(this.renderer.yscale, this._y, this._height, 'center');
|
|
else
|
|
this.sh = this._height;
|
|
};
|
|
EllipseOvalView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy, sw = _a.sw, sh = _a.sh, _angle = _a._angle;
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + sw[i] + sh[i] + _angle[i]))
|
|
continue;
|
|
ctx.beginPath();
|
|
ctx.ellipse(sx[i], sy[i], sw[i] / 2.0, sh[i] / 2.0, _angle[i], 0, 2 * Math.PI);
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
};
|
|
EllipseOvalView.prototype._hit_point = function (geometry) {
|
|
var _a, _b, _c, _d;
|
|
var x0, x1, y0, y1, cond, dist, sx0, sx1, sy0, sy1;
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x = this.renderer.xscale.invert(sx);
|
|
var y = this.renderer.yscale.invert(sy);
|
|
if (this.model.properties.width.units == "data") {
|
|
x0 = x - this.max_width;
|
|
x1 = x + this.max_width;
|
|
}
|
|
else {
|
|
sx0 = sx - this.max_width;
|
|
sx1 = sx + this.max_width;
|
|
_a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
}
|
|
if (this.model.properties.height.units == "data") {
|
|
y0 = y - this.max_height;
|
|
y1 = y + this.max_height;
|
|
}
|
|
else {
|
|
sy0 = sy - this.max_height;
|
|
sy1 = sy + this.max_height;
|
|
_b = this.renderer.yscale.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
}
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
var candidates = this.index.indices(bbox);
|
|
var hits = [];
|
|
for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
|
|
var i = candidates_1[_i];
|
|
cond = hittest.point_in_ellipse(sx, sy, this._angle[i], this.sh[i] / 2, this.sw[i] / 2, this.sx[i], this.sy[i]);
|
|
if (cond) {
|
|
_c = this.renderer.xscale.r_compute(x, this._x[i]), sx0 = _c[0], sx1 = _c[1];
|
|
_d = this.renderer.yscale.r_compute(y, this._y[i]), sy0 = _d[0], sy1 = _d[1];
|
|
dist = Math.pow(sx0 - sx1, 2) + Math.pow(sy0 - sy1, 2);
|
|
hits.push([i, dist]);
|
|
}
|
|
}
|
|
return hittest.create_hit_test_result_from_hits(hits);
|
|
};
|
|
EllipseOvalView.prototype.draw_legend_for_index = function (ctx, _a, index) {
|
|
var x0 = _a.x0, y0 = _a.y0, x1 = _a.x1, y1 = _a.y1;
|
|
var len = index + 1;
|
|
var sx = new Array(len);
|
|
sx[index] = (x0 + x1) / 2;
|
|
var sy = new Array(len);
|
|
sy[index] = (y0 + y1) / 2;
|
|
var scale = this.sw[index] / this.sh[index];
|
|
var d = Math.min(Math.abs(x1 - x0), Math.abs(y1 - y0)) * 0.8;
|
|
var sw = new Array(len);
|
|
var sh = new Array(len);
|
|
if (scale > 1) {
|
|
sw[index] = d;
|
|
sh[index] = d / scale;
|
|
}
|
|
else {
|
|
sw[index] = d * scale;
|
|
sh[index] = d;
|
|
}
|
|
this._render(ctx, [index], { sx: sx, sy: sy, sw: sw, sh: sh, _angle: [0] }); // XXX
|
|
};
|
|
EllipseOvalView.prototype._bounds = function (_a) {
|
|
var minX = _a.minX, maxX = _a.maxX, minY = _a.minY, maxY = _a.maxY;
|
|
return {
|
|
minX: minX - this.max_w2,
|
|
maxX: maxX + this.max_w2,
|
|
minY: minY - this.max_h2,
|
|
maxY: maxY + this.max_h2,
|
|
};
|
|
};
|
|
return EllipseOvalView;
|
|
}(center_rotatable_1.CenterRotatableView));
|
|
exports.EllipseOvalView = EllipseOvalView;
|
|
var EllipseOval = /** @class */ (function (_super) {
|
|
tslib_1.__extends(EllipseOval, _super);
|
|
function EllipseOval(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
EllipseOval.initClass = function () {
|
|
this.prototype.type = 'EllipseOval';
|
|
};
|
|
return EllipseOval;
|
|
}(center_rotatable_1.CenterRotatable));
|
|
exports.EllipseOval = EllipseOval;
|
|
EllipseOval.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/glyph */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var bbox = require(27) /* ../../core/util/bbox */;
|
|
var proj = require(36) /* ../../core/util/projections */;
|
|
var visuals = require(51) /* ../../core/visuals */;
|
|
var view_1 = require(50) /* ../../core/view */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var arrayable_1 = require(25) /* ../../core/util/arrayable */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var line_1 = require(134) /* ./line */;
|
|
var factor_range_1 = require(188) /* ../ranges/factor_range */;
|
|
var GlyphView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GlyphView, _super);
|
|
function GlyphView() {
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
_this._nohit_warned = {};
|
|
return _this;
|
|
}
|
|
Object.defineProperty(GlyphView.prototype, "renderer", {
|
|
get: function () {
|
|
return this.parent;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
GlyphView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this._nohit_warned = {};
|
|
this.visuals = new visuals.Visuals(this.model);
|
|
// Init gl (this should really be done anytime renderer is set,
|
|
// and not done if it isn't ever set, but for now it only
|
|
// matters in the unit tests because we build a view without a
|
|
// renderer there)
|
|
var gl = this.renderer.plot_view.gl;
|
|
if (gl != null) {
|
|
var webgl_module = null;
|
|
try {
|
|
webgl_module = require(466) /* ./webgl/index */;
|
|
}
|
|
catch (e) {
|
|
if (e.code === 'MODULE_NOT_FOUND') {
|
|
logging_1.logger.warn('WebGL was requested and is supported, but bokeh-gl(.min).js is not available, falling back to 2D rendering.');
|
|
}
|
|
else
|
|
throw e;
|
|
}
|
|
if (webgl_module != null) {
|
|
var Cls = webgl_module[this.model.type + 'GLGlyph'];
|
|
if (Cls != null)
|
|
this.glglyph = new Cls(gl.ctx, this);
|
|
}
|
|
}
|
|
};
|
|
GlyphView.prototype.set_visuals = function (source) {
|
|
this.visuals.warm_cache(source);
|
|
if (this.glglyph != null)
|
|
this.glglyph.set_visuals_changed();
|
|
};
|
|
GlyphView.prototype.render = function (ctx, indices, data) {
|
|
ctx.beginPath();
|
|
if (this.glglyph != null) {
|
|
if (this.glglyph.render(ctx, indices, data))
|
|
return;
|
|
}
|
|
this._render(ctx, indices, data);
|
|
};
|
|
GlyphView.prototype.has_finished = function () {
|
|
return true;
|
|
};
|
|
GlyphView.prototype.notify_finished = function () {
|
|
this.renderer.notify_finished();
|
|
};
|
|
GlyphView.prototype._bounds = function (bounds) {
|
|
return bounds;
|
|
};
|
|
GlyphView.prototype.bounds = function () {
|
|
return this._bounds(this.index.bbox);
|
|
};
|
|
GlyphView.prototype.log_bounds = function () {
|
|
var bb = bbox.empty();
|
|
var positive_x_bbs = this.index.search(bbox.positive_x());
|
|
for (var _i = 0, positive_x_bbs_1 = positive_x_bbs; _i < positive_x_bbs_1.length; _i++) {
|
|
var x = positive_x_bbs_1[_i];
|
|
if (x.minX < bb.minX)
|
|
bb.minX = x.minX;
|
|
if (x.maxX > bb.maxX)
|
|
bb.maxX = x.maxX;
|
|
}
|
|
var positive_y_bbs = this.index.search(bbox.positive_y());
|
|
for (var _a = 0, positive_y_bbs_1 = positive_y_bbs; _a < positive_y_bbs_1.length; _a++) {
|
|
var y = positive_y_bbs_1[_a];
|
|
if (y.minY < bb.minY)
|
|
bb.minY = y.minY;
|
|
if (y.maxY > bb.maxY)
|
|
bb.maxY = y.maxY;
|
|
}
|
|
return this._bounds(bb);
|
|
};
|
|
GlyphView.prototype.get_anchor_point = function (anchor, i, _a) {
|
|
var sx = _a[0], sy = _a[1];
|
|
switch (anchor) {
|
|
case "center": return { x: this.scenterx(i, sx, sy), y: this.scentery(i, sx, sy) };
|
|
default: return null;
|
|
}
|
|
};
|
|
GlyphView.prototype.sdist = function (scale, pts, spans, pts_location, dilate) {
|
|
if (pts_location === void 0) {
|
|
pts_location = "edge";
|
|
}
|
|
if (dilate === void 0) {
|
|
dilate = false;
|
|
}
|
|
var pt0;
|
|
var pt1;
|
|
var n = pts.length;
|
|
if (pts_location == 'center') {
|
|
var halfspan = arrayable_1.map(spans, function (d) { return d / 2; });
|
|
pt0 = new Float64Array(n);
|
|
for (var i = 0; i < n; i++) {
|
|
pt0[i] = pts[i] - halfspan[i];
|
|
}
|
|
pt1 = new Float64Array(n);
|
|
for (var i = 0; i < n; i++) {
|
|
pt1[i] = pts[i] + halfspan[i];
|
|
}
|
|
}
|
|
else {
|
|
pt0 = pts;
|
|
pt1 = new Float64Array(n);
|
|
for (var i = 0; i < n; i++) {
|
|
pt1[i] = pt0[i] + spans[i];
|
|
}
|
|
}
|
|
var spt0 = scale.v_compute(pt0);
|
|
var spt1 = scale.v_compute(pt1);
|
|
if (dilate)
|
|
return arrayable_1.map(spt0, function (_, i) { return Math.ceil(Math.abs(spt1[i] - spt0[i])); });
|
|
else
|
|
return arrayable_1.map(spt0, function (_, i) { return Math.abs(spt1[i] - spt0[i]); });
|
|
};
|
|
GlyphView.prototype.draw_legend_for_index = function (_ctx, _bbox, _index) { };
|
|
GlyphView.prototype.hit_test = function (geometry) {
|
|
var result = null;
|
|
var func = "_hit_" + geometry.type;
|
|
if (this[func] != null) {
|
|
result = this[func](geometry);
|
|
}
|
|
else if (this._nohit_warned[geometry.type] == null) {
|
|
logging_1.logger.debug("'" + geometry.type + "' selection not available for " + this.model.type);
|
|
this._nohit_warned[geometry.type] = true;
|
|
}
|
|
return result;
|
|
};
|
|
GlyphView.prototype._hit_rect_against_index = function (geometry) {
|
|
var sx0 = geometry.sx0, sx1 = geometry.sx1, sy0 = geometry.sy0, sy1 = geometry.sy1;
|
|
var _a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
var _b = this.renderer.yscale.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
var bb = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = this.index.indices(bb);
|
|
return result;
|
|
};
|
|
GlyphView.prototype.set_data = function (source, indices, indices_to_update) {
|
|
var _a, _b, _c, _d;
|
|
var data = this.model.materialize_dataspecs(source);
|
|
this.visuals.set_all_indices(indices);
|
|
if (indices && !(this instanceof line_1.LineView)) {
|
|
var data_subset = {};
|
|
var _loop_1 = function (k) {
|
|
var v = data[k];
|
|
if (k.charAt(0) === '_')
|
|
data_subset[k] = indices.map(function (i) { return v[i]; });
|
|
else
|
|
data_subset[k] = v;
|
|
};
|
|
for (var k in data) {
|
|
_loop_1(k);
|
|
}
|
|
data = data_subset;
|
|
}
|
|
var self = this;
|
|
object_1.extend(self, data);
|
|
// TODO (bev) Should really probably delegate computing projected
|
|
// coordinates to glyphs, instead of centralizing here in one place.
|
|
if (this.renderer.plot_view.model.use_map) {
|
|
if (self._x != null)
|
|
_a = proj.project_xy(self._x, self._y), self._x = _a[0], self._y = _a[1];
|
|
if (self._xs != null)
|
|
_b = proj.project_xsys(self._xs, self._ys), self._xs = _b[0], self._ys = _b[1];
|
|
if (self._x0 != null)
|
|
_c = proj.project_xy(self._x0, self._y0), self._x0 = _c[0], self._y0 = _c[1];
|
|
if (self._x1 != null)
|
|
_d = proj.project_xy(self._x1, self._y1), self._x1 = _d[0], self._y1 = _d[1];
|
|
}
|
|
// if we have any coordinates that are categorical, convert them to
|
|
// synthetic coords here
|
|
if (this.renderer.plot_view.frame.x_ranges != null) { // XXXX JUST TEMP FOR TESTS TO PASS
|
|
var xr_1 = this.renderer.plot_view.frame.x_ranges[this.model.x_range_name];
|
|
var yr_1 = this.renderer.plot_view.frame.y_ranges[this.model.y_range_name];
|
|
for (var _i = 0, _e = this.model._coords; _i < _e.length; _i++) {
|
|
var _f = _e[_i], xname = _f[0], yname = _f[1];
|
|
xname = "_" + xname;
|
|
yname = "_" + yname;
|
|
// TODO (bev) more robust detection of multi-glyph case
|
|
// hand multi glyph case
|
|
if (self._xs != null) {
|
|
if (xr_1 instanceof factor_range_1.FactorRange) {
|
|
self[xname] = arrayable_1.map(self[xname], function (arr) { return xr_1.v_synthetic(arr); });
|
|
}
|
|
if (yr_1 instanceof factor_range_1.FactorRange) {
|
|
self[yname] = arrayable_1.map(self[yname], function (arr) { return yr_1.v_synthetic(arr); });
|
|
}
|
|
}
|
|
else {
|
|
// hand standard glyph case
|
|
if (xr_1 instanceof factor_range_1.FactorRange) {
|
|
self[xname] = xr_1.v_synthetic(self[xname]);
|
|
}
|
|
if (yr_1 instanceof factor_range_1.FactorRange) {
|
|
self[yname] = yr_1.v_synthetic(self[yname]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (this.glglyph != null)
|
|
this.glglyph.set_data_changed(self._x.length);
|
|
this._set_data(indices_to_update); //TODO doesn't take subset indices into account
|
|
this.index_data();
|
|
};
|
|
GlyphView.prototype._set_data = function (_indices) { };
|
|
GlyphView.prototype.index_data = function () {
|
|
this.index = this._index_data();
|
|
};
|
|
GlyphView.prototype.mask_data = function (indices) {
|
|
// WebGL can do the clipping much more efficiently
|
|
if (this.glglyph != null || this._mask_data == null)
|
|
return indices;
|
|
else
|
|
return this._mask_data();
|
|
};
|
|
GlyphView.prototype.map_data = function () {
|
|
var _a;
|
|
// TODO: if using gl, skip this (when is this called?)
|
|
// map all the coordinate fields
|
|
var self = this;
|
|
for (var _i = 0, _b = this.model._coords; _i < _b.length; _i++) {
|
|
var _c = _b[_i], xname = _c[0], yname = _c[1];
|
|
var sxname = "s" + xname;
|
|
var syname = "s" + yname;
|
|
xname = "_" + xname;
|
|
yname = "_" + yname;
|
|
if (self[xname] != null && (types_1.isArray(self[xname][0]) || types_1.isTypedArray(self[xname][0]))) {
|
|
var n = self[xname].length;
|
|
self[sxname] = new Array(n);
|
|
self[syname] = new Array(n);
|
|
for (var i = 0; i < n; i++) {
|
|
var _d = this.map_to_screen(self[xname][i], self[yname][i]), sx = _d[0], sy = _d[1];
|
|
self[sxname][i] = sx;
|
|
self[syname][i] = sy;
|
|
}
|
|
}
|
|
else
|
|
_a = this.map_to_screen(self[xname], self[yname]), self[sxname] = _a[0], self[syname] = _a[1];
|
|
}
|
|
this._map_data();
|
|
};
|
|
// This is where specs not included in coords are computed, e.g. radius.
|
|
GlyphView.prototype._map_data = function () { };
|
|
GlyphView.prototype.map_to_screen = function (x, y) {
|
|
return this.renderer.plot_view.map_to_screen(x, y, this.model.x_range_name, this.model.y_range_name);
|
|
};
|
|
return GlyphView;
|
|
}(view_1.View));
|
|
exports.GlyphView = GlyphView;
|
|
var Glyph = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Glyph, _super);
|
|
function Glyph(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Glyph.initClass = function () {
|
|
this.prototype.type = 'Glyph';
|
|
this.prototype._coords = [];
|
|
this.internal({
|
|
x_range_name: [p.String, 'default'],
|
|
y_range_name: [p.String, 'default'],
|
|
});
|
|
};
|
|
Glyph.coords = function (coords) {
|
|
var _coords = this.prototype._coords.concat(coords);
|
|
this.prototype._coords = _coords;
|
|
var result = {};
|
|
for (var _i = 0, coords_1 = coords; _i < coords_1.length; _i++) {
|
|
var _a = coords_1[_i], x = _a[0], y = _a[1];
|
|
result[x] = [p.CoordinateSpec];
|
|
result[y] = [p.CoordinateSpec];
|
|
}
|
|
this.define(result);
|
|
};
|
|
return Glyph;
|
|
}(model_1.Model));
|
|
exports.Glyph = Glyph;
|
|
Glyph.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/hbar */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var box_1 = require(121) /* ./box */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var HBarView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(HBarView, _super);
|
|
function HBarView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
HBarView.prototype.scenterx = function (i) {
|
|
return (this.sleft[i] + this.sright[i]) / 2;
|
|
};
|
|
HBarView.prototype.scentery = function (i) {
|
|
return this.sy[i];
|
|
};
|
|
HBarView.prototype._index_data = function () {
|
|
return this._index_box(this._y.length);
|
|
};
|
|
HBarView.prototype._lrtb = function (i) {
|
|
var l = Math.min(this._left[i], this._right[i]);
|
|
var r = Math.max(this._left[i], this._right[i]);
|
|
var t = this._y[i] + 0.5 * this._height[i];
|
|
var b = this._y[i] - 0.5 * this._height[i];
|
|
return [l, r, t, b];
|
|
};
|
|
HBarView.prototype._map_data = function () {
|
|
this.sy = this.renderer.yscale.v_compute(this._y);
|
|
this.sh = this.sdist(this.renderer.yscale, this._y, this._height, "center");
|
|
this.sleft = this.renderer.xscale.v_compute(this._left);
|
|
this.sright = this.renderer.xscale.v_compute(this._right);
|
|
var n = this.sy.length;
|
|
this.stop = new Float64Array(n);
|
|
this.sbottom = new Float64Array(n);
|
|
for (var i = 0; i < n; i++) {
|
|
this.stop[i] = this.sy[i] - this.sh[i] / 2;
|
|
this.sbottom[i] = this.sy[i] + this.sh[i] / 2;
|
|
}
|
|
this._clamp_viewport();
|
|
};
|
|
return HBarView;
|
|
}(box_1.BoxView));
|
|
exports.HBarView = HBarView;
|
|
var HBar = /** @class */ (function (_super) {
|
|
tslib_1.__extends(HBar, _super);
|
|
function HBar(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
HBar.initClass = function () {
|
|
this.prototype.type = 'HBar';
|
|
this.prototype.default_view = HBarView;
|
|
this.coords([['left', 'y']]);
|
|
this.define({
|
|
height: [p.DistanceSpec],
|
|
right: [p.CoordinateSpec],
|
|
});
|
|
this.override({ left: 0 });
|
|
};
|
|
return HBar;
|
|
}(box_1.Box));
|
|
exports.HBar = HBar;
|
|
HBar.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/hex_tile */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var glyph_1 = require(126) /* ./glyph */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var spatial_1 = require(39) /* ../../core/util/spatial */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var HexTileView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(HexTileView, _super);
|
|
function HexTileView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
HexTileView.prototype.scenterx = function (i) { return this.sx[i]; };
|
|
HexTileView.prototype.scentery = function (i) { return this.sy[i]; };
|
|
HexTileView.prototype._set_data = function () {
|
|
var n = this._q.length;
|
|
var size = this.model.size;
|
|
var aspect_scale = this.model.aspect_scale;
|
|
this._x = new Float64Array(n);
|
|
this._y = new Float64Array(n);
|
|
if (this.model.orientation == "pointytop") {
|
|
for (var i = 0; i < n; i++) {
|
|
this._x[i] = size * Math.sqrt(3) * (this._q[i] + this._r[i] / 2) / aspect_scale;
|
|
this._y[i] = -size * 3 / 2 * this._r[i];
|
|
}
|
|
}
|
|
else {
|
|
for (var i = 0; i < n; i++) {
|
|
this._x[i] = size * 3 / 2 * this._q[i];
|
|
this._y[i] = -size * Math.sqrt(3) * (this._r[i] + this._q[i] / 2) * aspect_scale;
|
|
}
|
|
}
|
|
};
|
|
HexTileView.prototype._index_data = function () {
|
|
var _a;
|
|
var ysize = this.model.size;
|
|
var xsize = Math.sqrt(3) * ysize / 2;
|
|
if (this.model.orientation == "flattop") {
|
|
_a = [ysize, xsize], xsize = _a[0], ysize = _a[1];
|
|
ysize *= this.model.aspect_scale;
|
|
}
|
|
else
|
|
xsize /= this.model.aspect_scale;
|
|
var points = [];
|
|
for (var i = 0; i < this._x.length; i++) {
|
|
var x = this._x[i];
|
|
var y = this._y[i];
|
|
if (isNaN(x + y) || !isFinite(x + y))
|
|
continue;
|
|
points.push({ minX: x - xsize, minY: y - ysize, maxX: x + xsize, maxY: y + ysize, i: i });
|
|
}
|
|
return new spatial_1.SpatialIndex(points);
|
|
};
|
|
// overriding map_data instead of _map_data because the default automatic mappings
|
|
// for other glyphs (with cartesian coordinates) is not useful
|
|
HexTileView.prototype.map_data = function () {
|
|
var _a, _b;
|
|
_a = this.map_to_screen(this._x, this._y), this.sx = _a[0], this.sy = _a[1];
|
|
_b = this._get_unscaled_vertices(), this.svx = _b[0], this.svy = _b[1];
|
|
};
|
|
HexTileView.prototype._get_unscaled_vertices = function () {
|
|
var size = this.model.size;
|
|
var aspect_scale = this.model.aspect_scale;
|
|
if (this.model.orientation == "pointytop") {
|
|
var rscale = this.renderer.yscale;
|
|
var hscale = this.renderer.xscale;
|
|
var r = Math.abs(rscale.compute(0) - rscale.compute(size)); // assumes linear scale
|
|
var h = Math.sqrt(3) / 2 * Math.abs(hscale.compute(0) - hscale.compute(size)) / aspect_scale; // assumes linear scale
|
|
var r2 = r / 2.0;
|
|
var svx = [0, -h, -h, 0, h, h];
|
|
var svy = [r, r2, -r2, -r, -r2, r2];
|
|
return [svx, svy];
|
|
}
|
|
else {
|
|
var rscale = this.renderer.xscale;
|
|
var hscale = this.renderer.yscale;
|
|
var r = Math.abs(rscale.compute(0) - rscale.compute(size)); // assumes linear scale
|
|
var h = Math.sqrt(3) / 2 * Math.abs(hscale.compute(0) - hscale.compute(size)) * aspect_scale; // assumes linear scale
|
|
var r2 = r / 2.0;
|
|
var svx = [r, r2, -r2, -r, -r2, r2];
|
|
var svy = [0, -h, -h, 0, h, h];
|
|
return [svx, svy];
|
|
}
|
|
};
|
|
HexTileView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy, svx = _a.svx, svy = _a.svy, _scale = _a._scale;
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + _scale[i]))
|
|
continue;
|
|
ctx.translate(sx[i], sy[i]);
|
|
ctx.beginPath();
|
|
for (var j = 0; j < 6; j++) {
|
|
ctx.lineTo(svx[j] * _scale[i], svy[j] * _scale[i]);
|
|
}
|
|
ctx.closePath();
|
|
ctx.translate(-sx[i], -sy[i]);
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
};
|
|
HexTileView.prototype._hit_point = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x = this.renderer.xscale.invert(sx);
|
|
var y = this.renderer.yscale.invert(sy);
|
|
var candidates = this.index.indices({ minX: x, minY: y, maxX: x, maxY: y });
|
|
var hits = [];
|
|
for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
|
|
var i = candidates_1[_i];
|
|
if (hittest.point_in_poly(sx - this.sx[i], sy - this.sy[i], this.svx, this.svy)) {
|
|
hits.push(i);
|
|
}
|
|
}
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
HexTileView.prototype._hit_span = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var hits;
|
|
if (geometry.direction == 'v') {
|
|
var y = this.renderer.yscale.invert(sy);
|
|
var hr = this.renderer.plot_view.frame.bbox.h_range;
|
|
var _a = this.renderer.xscale.r_invert(hr.start, hr.end), minX = _a[0], maxX = _a[1];
|
|
hits = this.index.indices({ minX: minX, minY: y, maxX: maxX, maxY: y });
|
|
}
|
|
else {
|
|
var x = this.renderer.xscale.invert(sx);
|
|
var vr = this.renderer.plot_view.frame.bbox.v_range;
|
|
var _b = this.renderer.yscale.r_invert(vr.start, vr.end), minY = _b[0], maxY = _b[1];
|
|
hits = this.index.indices({ minX: x, minY: minY, maxX: x, maxY: maxY });
|
|
}
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
HexTileView.prototype._hit_rect = function (geometry) {
|
|
var sx0 = geometry.sx0, sx1 = geometry.sx1, sy0 = geometry.sy0, sy1 = geometry.sy1;
|
|
var _a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
var _b = this.renderer.yscale.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = this.index.indices(bbox);
|
|
return result;
|
|
};
|
|
HexTileView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
return HexTileView;
|
|
}(glyph_1.GlyphView));
|
|
exports.HexTileView = HexTileView;
|
|
var HexTile = /** @class */ (function (_super) {
|
|
tslib_1.__extends(HexTile, _super);
|
|
function HexTile(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
HexTile.initClass = function () {
|
|
this.prototype.type = 'HexTile';
|
|
this.prototype.default_view = HexTileView;
|
|
this.coords([['r', 'q']]);
|
|
this.mixins(['line', 'fill']);
|
|
this.define({
|
|
size: [p.Number, 1.0],
|
|
aspect_scale: [p.Number, 1.0],
|
|
scale: [p.NumberSpec, 1.0],
|
|
orientation: [p.HexTileOrientation, "pointytop"],
|
|
});
|
|
this.override({ line_color: null });
|
|
};
|
|
return HexTile;
|
|
}(glyph_1.Glyph));
|
|
exports.HexTile = HexTile;
|
|
HexTile.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/image */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var image_base_1 = require(130) /* ./image_base */;
|
|
var linear_color_mapper_1 = require(174) /* ../mappers/linear_color_mapper */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var ImageView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ImageView, _super);
|
|
function ImageView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ImageView.prototype.initialize = function () {
|
|
var _this = this;
|
|
_super.prototype.initialize.call(this);
|
|
this.connect(this.model.color_mapper.change, function () { return _this._update_image(); });
|
|
this.connect(this.model.properties.global_alpha.change, function () { return _this.renderer.request_render(); });
|
|
};
|
|
ImageView.prototype._update_image = function () {
|
|
// Only reset image_data if already initialized
|
|
if (this.image_data != null) {
|
|
this._set_data();
|
|
this.renderer.plot_view.request_render();
|
|
}
|
|
};
|
|
ImageView.prototype._set_data = function () {
|
|
this._set_width_heigh_data();
|
|
var cmap = this.model.color_mapper.rgba_mapper;
|
|
for (var i = 0, end = this._image.length; i < end; i++) {
|
|
var img = void 0;
|
|
if (this._image_shape != null && this._image_shape[i].length > 0) {
|
|
img = this._image[i];
|
|
var shape = this._image_shape[i];
|
|
this._height[i] = shape[0];
|
|
this._width[i] = shape[1];
|
|
}
|
|
else {
|
|
var _image = this._image[i];
|
|
img = array_1.concat(_image);
|
|
this._height[i] = _image.length;
|
|
this._width[i] = _image[0].length;
|
|
}
|
|
var buf8 = cmap.v_compute(img);
|
|
this._set_image_data_from_buffer(i, buf8);
|
|
}
|
|
};
|
|
ImageView.prototype._render = function (ctx, indices, _a) {
|
|
var image_data = _a.image_data, sx = _a.sx, sy = _a.sy, sw = _a.sw, sh = _a.sh;
|
|
var old_smoothing = ctx.getImageSmoothingEnabled();
|
|
ctx.setImageSmoothingEnabled(false);
|
|
ctx.globalAlpha = this.model.global_alpha;
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (image_data[i] == null)
|
|
continue;
|
|
if (isNaN(sx[i] + sy[i] + sw[i] + sh[i]))
|
|
continue;
|
|
var y_offset = sy[i];
|
|
ctx.translate(0, y_offset);
|
|
ctx.scale(1, -1);
|
|
ctx.translate(0, -y_offset);
|
|
ctx.drawImage(image_data[i], sx[i] | 0, sy[i] | 0, sw[i], sh[i]);
|
|
ctx.translate(0, y_offset);
|
|
ctx.scale(1, -1);
|
|
ctx.translate(0, -y_offset);
|
|
}
|
|
ctx.setImageSmoothingEnabled(old_smoothing);
|
|
};
|
|
return ImageView;
|
|
}(image_base_1.ImageBaseView));
|
|
exports.ImageView = ImageView;
|
|
// NOTE: this needs to be redefined here, because palettes are located in bokeh-api.js bundle
|
|
var Greys9 = function () { return ["#000000", "#252525", "#525252", "#737373", "#969696", "#bdbdbd", "#d9d9d9", "#f0f0f0", "#ffffff"]; };
|
|
var Image = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Image, _super);
|
|
function Image(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Image.initClass = function () {
|
|
this.prototype.type = 'Image';
|
|
this.prototype.default_view = ImageView;
|
|
this.define({
|
|
color_mapper: [p.Instance, function () { return new linear_color_mapper_1.LinearColorMapper({ palette: Greys9() }); }],
|
|
});
|
|
};
|
|
return Image;
|
|
}(image_base_1.ImageBase));
|
|
exports.Image = Image;
|
|
Image.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/image_base */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var spatial_1 = require(39) /* ../../core/util/spatial */;
|
|
var ImageBaseView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ImageBaseView, _super);
|
|
function ImageBaseView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ImageBaseView.prototype._render = function (_ctx, _indices, _data) { };
|
|
ImageBaseView.prototype._index_data = function () {
|
|
var points = [];
|
|
for (var i = 0, end = this._x.length; i < end; i++) {
|
|
var _a = this._lrtb(i), l = _a[0], r = _a[1], t = _a[2], b = _a[3];
|
|
if (isNaN(l + r + t + b) || !isFinite(l + r + t + b)) {
|
|
continue;
|
|
}
|
|
points.push({ minX: l, minY: b, maxX: r, maxY: t, i: i });
|
|
}
|
|
return new spatial_1.SpatialIndex(points);
|
|
};
|
|
ImageBaseView.prototype._lrtb = function (i) {
|
|
var xr = this.renderer.xscale.source_range;
|
|
var x1 = this._x[i];
|
|
var x2 = xr.is_reversed ? x1 - this._dw[i] : x1 + this._dw[i];
|
|
var yr = this.renderer.yscale.source_range;
|
|
var y1 = this._y[i];
|
|
var y2 = yr.is_reversed ? y1 - this._dh[i] : y1 + this._dh[i];
|
|
var _a = x1 < x2 ? [x1, x2] : [x2, x1], l = _a[0], r = _a[1];
|
|
var _b = y1 < y2 ? [y1, y2] : [y2, y1], b = _b[0], t = _b[1];
|
|
return [l, r, t, b];
|
|
};
|
|
ImageBaseView.prototype._set_width_heigh_data = function () {
|
|
if (this.image_data == null || this.image_data.length != this._image.length)
|
|
this.image_data = new Array(this._image.length);
|
|
if (this._width == null || this._width.length != this._image.length)
|
|
this._width = new Array(this._image.length);
|
|
if (this._height == null || this._height.length != this._image.length)
|
|
this._height = new Array(this._image.length);
|
|
};
|
|
ImageBaseView.prototype._get_or_create_canvas = function (i) {
|
|
var _image_data = this.image_data[i];
|
|
if (_image_data != null && _image_data.width == this._width[i] &&
|
|
_image_data.height == this._height[i])
|
|
return _image_data;
|
|
else {
|
|
var canvas = document.createElement('canvas');
|
|
canvas.width = this._width[i];
|
|
canvas.height = this._height[i];
|
|
return canvas;
|
|
}
|
|
};
|
|
ImageBaseView.prototype._set_image_data_from_buffer = function (i, buf8) {
|
|
var canvas = this._get_or_create_canvas(i);
|
|
var ctx = canvas.getContext('2d');
|
|
var image_data = ctx.getImageData(0, 0, this._width[i], this._height[i]);
|
|
image_data.data.set(buf8);
|
|
ctx.putImageData(image_data, 0, 0);
|
|
this.image_data[i] = canvas;
|
|
};
|
|
ImageBaseView.prototype._map_data = function () {
|
|
switch (this.model.properties.dw.units) {
|
|
case "data": {
|
|
this.sw = this.sdist(this.renderer.xscale, this._x, this._dw, 'edge', this.model.dilate);
|
|
break;
|
|
}
|
|
case "screen": {
|
|
this.sw = this._dw;
|
|
break;
|
|
}
|
|
}
|
|
switch (this.model.properties.dh.units) {
|
|
case "data": {
|
|
this.sh = this.sdist(this.renderer.yscale, this._y, this._dh, 'edge', this.model.dilate);
|
|
break;
|
|
}
|
|
case "screen": {
|
|
this.sh = this._dh;
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
ImageBaseView.prototype._image_index = function (index, x, y) {
|
|
var _a = this._lrtb(index), l = _a[0], r = _a[1], t = _a[2], b = _a[3];
|
|
var width = this._width[index];
|
|
var height = this._height[index];
|
|
var dx = (r - l) / width;
|
|
var dy = (t - b) / height;
|
|
var dim1 = Math.floor((x - l) / dx);
|
|
var dim2 = Math.floor((y - b) / dy);
|
|
return { index: index, dim1: dim1, dim2: dim2, flat_index: dim2 * width + dim1 };
|
|
};
|
|
ImageBaseView.prototype._hit_point = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x = this.renderer.xscale.invert(sx);
|
|
var y = this.renderer.yscale.invert(sy);
|
|
var bbox = hittest.validate_bbox_coords([x, x], [y, y]);
|
|
var candidates = this.index.indices(bbox);
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.image_indices = [];
|
|
for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
|
|
var index = candidates_1[_i];
|
|
if ((sx != Infinity) && (sy != Infinity)) {
|
|
result.image_indices.push(this._image_index(index, x, y));
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
return ImageBaseView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.ImageBaseView = ImageBaseView;
|
|
var ImageBase = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ImageBase, _super);
|
|
function ImageBase(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ImageBase.initClass = function () {
|
|
this.prototype.type = 'ImageBase';
|
|
this.prototype.default_view = ImageBaseView;
|
|
this.define({
|
|
image: [p.NumberSpec],
|
|
dw: [p.DistanceSpec],
|
|
dh: [p.DistanceSpec],
|
|
dilate: [p.Boolean, false],
|
|
global_alpha: [p.Number, 1.0],
|
|
});
|
|
};
|
|
return ImageBase;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.ImageBase = ImageBase;
|
|
ImageBase.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/image_rgba */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var image_base_1 = require(130) /* ./image_base */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var ImageRGBAView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ImageRGBAView, _super);
|
|
function ImageRGBAView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ImageRGBAView.prototype.initialize = function () {
|
|
var _this = this;
|
|
_super.prototype.initialize.call(this);
|
|
this.connect(this.model.properties.global_alpha.change, function () { return _this.renderer.request_render(); });
|
|
};
|
|
ImageRGBAView.prototype._set_data = function (indices) {
|
|
this._set_width_heigh_data();
|
|
for (var i = 0, end = this._image.length; i < end; i++) {
|
|
if (indices != null && indices.indexOf(i) < 0)
|
|
continue;
|
|
var buf = void 0;
|
|
if (this._image_shape != null && this._image_shape[i].length > 0) {
|
|
buf = this._image[i].buffer;
|
|
var shape = this._image_shape[i];
|
|
this._height[i] = shape[0];
|
|
this._width[i] = shape[1];
|
|
}
|
|
else {
|
|
var _image = this._image[i];
|
|
var flat = array_1.concat(_image);
|
|
buf = new ArrayBuffer(flat.length * 4);
|
|
var color = new Uint32Array(buf);
|
|
for (var j = 0, endj = flat.length; j < endj; j++) {
|
|
color[j] = flat[j];
|
|
}
|
|
this._height[i] = _image.length;
|
|
this._width[i] = _image[0].length;
|
|
}
|
|
var buf8 = new Uint8Array(buf);
|
|
this._set_image_data_from_buffer(i, buf8);
|
|
}
|
|
};
|
|
ImageRGBAView.prototype._render = function (ctx, indices, _a) {
|
|
var image_data = _a.image_data, sx = _a.sx, sy = _a.sy, sw = _a.sw, sh = _a.sh;
|
|
var old_smoothing = ctx.getImageSmoothingEnabled();
|
|
ctx.setImageSmoothingEnabled(false);
|
|
ctx.globalAlpha = this.model.global_alpha;
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + sw[i] + sh[i]))
|
|
continue;
|
|
var y_offset = sy[i];
|
|
ctx.translate(0, y_offset);
|
|
ctx.scale(1, -1);
|
|
ctx.translate(0, -y_offset);
|
|
ctx.drawImage(image_data[i], sx[i] | 0, sy[i] | 0, sw[i], sh[i]);
|
|
ctx.translate(0, y_offset);
|
|
ctx.scale(1, -1);
|
|
ctx.translate(0, -y_offset);
|
|
}
|
|
ctx.setImageSmoothingEnabled(old_smoothing);
|
|
};
|
|
return ImageRGBAView;
|
|
}(image_base_1.ImageBaseView));
|
|
exports.ImageRGBAView = ImageRGBAView;
|
|
var ImageRGBA = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ImageRGBA, _super);
|
|
function ImageRGBA(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ImageRGBA.initClass = function () {
|
|
this.prototype.type = 'ImageRGBA';
|
|
this.prototype.default_view = ImageRGBAView;
|
|
};
|
|
return ImageRGBA;
|
|
}(image_base_1.ImageBase));
|
|
exports.ImageRGBA = ImageRGBA;
|
|
ImageRGBA.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/image_url */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var arrayable_1 = require(25) /* ../../core/util/arrayable */;
|
|
var spatial_1 = require(39) /* ../../core/util/spatial */;
|
|
var ImageURLView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ImageURLView, _super);
|
|
function ImageURLView() {
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
_this._images_rendered = false;
|
|
return _this;
|
|
}
|
|
ImageURLView.prototype.initialize = function () {
|
|
var _this = this;
|
|
_super.prototype.initialize.call(this);
|
|
this.connect(this.model.properties.global_alpha.change, function () { return _this.renderer.request_render(); });
|
|
};
|
|
ImageURLView.prototype._index_data = function () {
|
|
return new spatial_1.SpatialIndex([]);
|
|
};
|
|
ImageURLView.prototype._set_data = function () {
|
|
var _this = this;
|
|
if (this.image == null || this.image.length != this._url.length)
|
|
this.image = arrayable_1.map(this._url, function () { return null; });
|
|
var _a = this.model, retry_attempts = _a.retry_attempts, retry_timeout = _a.retry_timeout;
|
|
this.retries = arrayable_1.map(this._url, function () { return retry_attempts; });
|
|
var _loop_1 = function (i, end) {
|
|
var url = this_1._url[i];
|
|
if (url == null || url == "")
|
|
return "continue";
|
|
var img = new Image();
|
|
img.onerror = function () {
|
|
if (_this.retries[i] > 0) {
|
|
logging_1.logger.trace("ImageURL failed to load " + url + " image, retrying in " + retry_timeout + " ms");
|
|
setTimeout(function () { return img.src = url; }, retry_timeout);
|
|
}
|
|
else
|
|
logging_1.logger.warn("ImageURL unable to load " + url + " image after " + retry_attempts + " retries");
|
|
_this.retries[i] -= 1;
|
|
};
|
|
img.onload = function () {
|
|
_this.image[i] = img;
|
|
_this.renderer.request_render();
|
|
};
|
|
img.src = url;
|
|
};
|
|
var this_1 = this;
|
|
for (var i = 0, end = this._url.length; i < end; i++) {
|
|
_loop_1(i, end);
|
|
}
|
|
var w_data = this.model.properties.w.units == "data";
|
|
var h_data = this.model.properties.h.units == "data";
|
|
var n = this._x.length;
|
|
var xs = new Array(w_data ? 2 * n : n);
|
|
var ys = new Array(h_data ? 2 * n : n);
|
|
for (var i = 0; i < n; i++) {
|
|
xs[i] = this._x[i];
|
|
ys[i] = this._y[i];
|
|
}
|
|
// if the width/height are in screen units, don't try to include them in bounds
|
|
if (w_data) {
|
|
for (var i = 0; i < n; i++)
|
|
xs[n + i] = this._x[i] + this._w[i];
|
|
}
|
|
if (h_data) {
|
|
for (var i = 0; i < n; i++)
|
|
ys[n + i] = this._y[i] + this._h[i];
|
|
}
|
|
var minX = arrayable_1.min(xs);
|
|
var maxX = arrayable_1.max(xs);
|
|
var minY = arrayable_1.min(ys);
|
|
var maxY = arrayable_1.max(ys);
|
|
this._bounds_rect = { minX: minX, maxX: maxX, minY: minY, maxY: maxY };
|
|
};
|
|
ImageURLView.prototype.has_finished = function () {
|
|
return _super.prototype.has_finished.call(this) && this._images_rendered == true;
|
|
};
|
|
ImageURLView.prototype._map_data = function () {
|
|
// Better to check this.model.w and this.model.h for null since the set_data
|
|
// machinery will have converted this._w and this._w to lists of null
|
|
var ws = this.model.w != null ? this._w : arrayable_1.map(this._x, function () { return NaN; });
|
|
var hs = this.model.h != null ? this._h : arrayable_1.map(this._x, function () { return NaN; });
|
|
switch (this.model.properties.w.units) {
|
|
case "data": {
|
|
this.sw = this.sdist(this.renderer.xscale, this._x, ws, "edge", this.model.dilate);
|
|
break;
|
|
}
|
|
case "screen": {
|
|
this.sw = ws;
|
|
break;
|
|
}
|
|
}
|
|
switch (this.model.properties.h.units) {
|
|
case "data": {
|
|
this.sh = this.sdist(this.renderer.yscale, this._y, hs, "edge", this.model.dilate);
|
|
break;
|
|
}
|
|
case "screen": {
|
|
this.sh = hs;
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
ImageURLView.prototype._render = function (ctx, indices, _a) {
|
|
var image = _a.image, sx = _a.sx, sy = _a.sy, sw = _a.sw, sh = _a.sh, _angle = _a._angle;
|
|
// TODO (bev): take actual border width into account when clipping
|
|
var frame = this.renderer.plot_view.frame;
|
|
ctx.rect(frame._left.value + 1, frame._top.value + 1, frame._width.value - 2, frame._height.value - 2);
|
|
ctx.clip();
|
|
var finished = true;
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + _angle[i]))
|
|
continue;
|
|
if (this.retries[i] == -1)
|
|
continue;
|
|
var img = image[i];
|
|
if (img == null) {
|
|
finished = false;
|
|
continue;
|
|
}
|
|
this._render_image(ctx, i, img, sx, sy, sw, sh, _angle);
|
|
}
|
|
if (finished && !this._images_rendered) {
|
|
this._images_rendered = true;
|
|
this.notify_finished();
|
|
}
|
|
};
|
|
ImageURLView.prototype._final_sx_sy = function (anchor, sx, sy, sw, sh) {
|
|
switch (anchor) {
|
|
case 'top_left': return [sx, sy];
|
|
case 'top_center': return [sx - (sw / 2), sy];
|
|
case 'top_right': return [sx - sw, sy];
|
|
case 'center_right': return [sx - sw, sy - (sh / 2)];
|
|
case 'bottom_right': return [sx - sw, sy - sh];
|
|
case 'bottom_center': return [sx - (sw / 2), sy - sh];
|
|
case 'bottom_left': return [sx, sy - sh];
|
|
case 'center_left': return [sx, sy - (sh / 2)];
|
|
case 'center': return [sx - (sw / 2), sy - (sh / 2)];
|
|
}
|
|
};
|
|
ImageURLView.prototype._render_image = function (ctx, i, image, sx, sy, sw, sh, angle) {
|
|
if (isNaN(sw[i]))
|
|
sw[i] = image.width;
|
|
if (isNaN(sh[i]))
|
|
sh[i] = image.height;
|
|
var anchor = this.model.anchor;
|
|
var _a = this._final_sx_sy(anchor, sx[i], sy[i], sw[i], sh[i]), sxi = _a[0], syi = _a[1];
|
|
ctx.save();
|
|
ctx.globalAlpha = this.model.global_alpha;
|
|
if (angle[i]) {
|
|
ctx.translate(sxi, syi);
|
|
ctx.rotate(angle[i]);
|
|
ctx.drawImage(image, 0, 0, sw[i], sh[i]);
|
|
ctx.rotate(-angle[i]);
|
|
ctx.translate(-sxi, -syi);
|
|
}
|
|
else
|
|
ctx.drawImage(image, sxi, syi, sw[i], sh[i]);
|
|
ctx.restore();
|
|
};
|
|
ImageURLView.prototype.bounds = function () {
|
|
return this._bounds_rect;
|
|
};
|
|
return ImageURLView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.ImageURLView = ImageURLView;
|
|
var ImageURL = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ImageURL, _super);
|
|
function ImageURL(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ImageURL.initClass = function () {
|
|
this.prototype.type = 'ImageURL';
|
|
this.prototype.default_view = ImageURLView;
|
|
this.define({
|
|
url: [p.StringSpec],
|
|
anchor: [p.Anchor, 'top_left'],
|
|
global_alpha: [p.Number, 1.0],
|
|
angle: [p.AngleSpec, 0],
|
|
w: [p.DistanceSpec],
|
|
h: [p.DistanceSpec],
|
|
dilate: [p.Boolean, false],
|
|
retry_attempts: [p.Number, 0],
|
|
retry_timeout: [p.Number, 0],
|
|
});
|
|
};
|
|
return ImageURL;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.ImageURL = ImageURL;
|
|
ImageURL.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/index */ function _(require, module, exports) {
|
|
var annular_wedge_1 = require(117) /* ./annular_wedge */;
|
|
exports.AnnularWedge = annular_wedge_1.AnnularWedge;
|
|
var annulus_1 = require(118) /* ./annulus */;
|
|
exports.Annulus = annulus_1.Annulus;
|
|
var arc_1 = require(119) /* ./arc */;
|
|
exports.Arc = arc_1.Arc;
|
|
var bezier_1 = require(120) /* ./bezier */;
|
|
exports.Bezier = bezier_1.Bezier;
|
|
var circle_1 = require(123) /* ./circle */;
|
|
exports.Circle = circle_1.Circle;
|
|
var center_rotatable_1 = require(122) /* ./center_rotatable */;
|
|
exports.CenterRotatable = center_rotatable_1.CenterRotatable;
|
|
var ellipse_1 = require(124) /* ./ellipse */;
|
|
exports.Ellipse = ellipse_1.Ellipse;
|
|
var ellipse_oval_1 = require(125) /* ./ellipse_oval */;
|
|
exports.EllipseOval = ellipse_oval_1.EllipseOval;
|
|
var glyph_1 = require(126) /* ./glyph */;
|
|
exports.Glyph = glyph_1.Glyph;
|
|
var hbar_1 = require(127) /* ./hbar */;
|
|
exports.HBar = hbar_1.HBar;
|
|
var hex_tile_1 = require(128) /* ./hex_tile */;
|
|
exports.HexTile = hex_tile_1.HexTile;
|
|
var image_1 = require(129) /* ./image */;
|
|
exports.Image = image_1.Image;
|
|
var image_rgba_1 = require(131) /* ./image_rgba */;
|
|
exports.ImageRGBA = image_rgba_1.ImageRGBA;
|
|
var image_url_1 = require(132) /* ./image_url */;
|
|
exports.ImageURL = image_url_1.ImageURL;
|
|
var line_1 = require(134) /* ./line */;
|
|
exports.Line = line_1.Line;
|
|
var multi_line_1 = require(135) /* ./multi_line */;
|
|
exports.MultiLine = multi_line_1.MultiLine;
|
|
var multi_polygons_1 = require(136) /* ./multi_polygons */;
|
|
exports.MultiPolygons = multi_polygons_1.MultiPolygons;
|
|
var oval_1 = require(137) /* ./oval */;
|
|
exports.Oval = oval_1.Oval;
|
|
var patch_1 = require(138) /* ./patch */;
|
|
exports.Patch = patch_1.Patch;
|
|
var patches_1 = require(139) /* ./patches */;
|
|
exports.Patches = patches_1.Patches;
|
|
var quad_1 = require(140) /* ./quad */;
|
|
exports.Quad = quad_1.Quad;
|
|
var quadratic_1 = require(141) /* ./quadratic */;
|
|
exports.Quadratic = quadratic_1.Quadratic;
|
|
var ray_1 = require(142) /* ./ray */;
|
|
exports.Ray = ray_1.Ray;
|
|
var rect_1 = require(143) /* ./rect */;
|
|
exports.Rect = rect_1.Rect;
|
|
var segment_1 = require(144) /* ./segment */;
|
|
exports.Segment = segment_1.Segment;
|
|
var step_1 = require(145) /* ./step */;
|
|
exports.Step = step_1.Step;
|
|
var text_1 = require(146) /* ./text */;
|
|
exports.Text = text_1.Text;
|
|
var vbar_1 = require(148) /* ./vbar */;
|
|
exports.VBar = vbar_1.VBar;
|
|
var wedge_1 = require(149) /* ./wedge */;
|
|
exports.Wedge = wedge_1.Wedge;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
exports.XYGlyph = xy_glyph_1.XYGlyph;
|
|
}
|
|
,
|
|
/* models/glyphs/line */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var LineView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LineView, _super);
|
|
function LineView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
LineView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy;
|
|
var drawing = false;
|
|
var last_index = null;
|
|
this.visuals.line.set_value(ctx);
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (drawing) {
|
|
if (!isFinite(sx[i] + sy[i])) {
|
|
ctx.stroke();
|
|
ctx.beginPath();
|
|
drawing = false;
|
|
last_index = i;
|
|
continue;
|
|
}
|
|
if (last_index != null && i - last_index > 1) {
|
|
ctx.stroke();
|
|
drawing = false;
|
|
}
|
|
}
|
|
if (drawing)
|
|
ctx.lineTo(sx[i], sy[i]);
|
|
else {
|
|
ctx.beginPath();
|
|
ctx.moveTo(sx[i], sy[i]);
|
|
drawing = true;
|
|
}
|
|
last_index = i;
|
|
}
|
|
if (drawing)
|
|
ctx.stroke();
|
|
};
|
|
LineView.prototype._hit_point = function (geometry) {
|
|
var _this = this;
|
|
/* Check if the point geometry hits this line glyph and return an object
|
|
that describes the hit result:
|
|
Args:
|
|
* geometry (object): object with the following keys
|
|
* sx (float): screen x coordinate of the point
|
|
* sy (float): screen y coordinate of the point
|
|
* type (str): type of geometry (in this case it's a point)
|
|
Output:
|
|
Object with the following keys:
|
|
* 0d (bool): whether the point hits the glyph or not
|
|
* 1d (array(int)): array with the indices hit by the point
|
|
*/
|
|
var result = hittest.create_empty_hit_test_result();
|
|
var point = { x: geometry.sx, y: geometry.sy };
|
|
var shortest = 9999;
|
|
var threshold = Math.max(2, this.visuals.line.line_width.value() / 2);
|
|
for (var i = 0, end = this.sx.length - 1; i < end; i++) {
|
|
var p0 = { x: this.sx[i], y: this.sy[i] };
|
|
var p1 = { x: this.sx[i + 1], y: this.sy[i + 1] };
|
|
var dist = hittest.dist_to_segment(point, p0, p1);
|
|
if (dist < threshold && dist < shortest) {
|
|
shortest = dist;
|
|
result.add_to_selected_glyphs(this.model);
|
|
result.get_view = function () { return _this; };
|
|
result.line_indices = [i];
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
LineView.prototype._hit_span = function (geometry) {
|
|
var _this = this;
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var result = hittest.create_empty_hit_test_result();
|
|
var val;
|
|
var values;
|
|
if (geometry.direction == 'v') {
|
|
val = this.renderer.yscale.invert(sy);
|
|
values = this._y;
|
|
}
|
|
else {
|
|
val = this.renderer.xscale.invert(sx);
|
|
values = this._x;
|
|
}
|
|
for (var i = 0, end = values.length - 1; i < end; i++) {
|
|
if ((values[i] <= val && val <= values[i + 1]) || (values[i + 1] <= val && val <= values[i])) {
|
|
result.add_to_selected_glyphs(this.model);
|
|
result.get_view = function () { return _this; };
|
|
result.line_indices.push(i);
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
LineView.prototype.get_interpolation_hit = function (i, geometry) {
|
|
var _a = [this._x[i], this._y[i], this._x[i + 1], this._y[i + 1]], x2 = _a[0], y2 = _a[1], x3 = _a[2], y3 = _a[3];
|
|
return utils_1.line_interpolation(this.renderer, geometry, x2, y2, x3, y3);
|
|
};
|
|
LineView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
return LineView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.LineView = LineView;
|
|
var Line = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Line, _super);
|
|
function Line(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Line.initClass = function () {
|
|
this.prototype.type = 'Line';
|
|
this.prototype.default_view = LineView;
|
|
this.mixins(['line']);
|
|
};
|
|
return Line;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.Line = Line;
|
|
Line.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/multi_line */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var spatial_1 = require(39) /* ../../core/util/spatial */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var glyph_1 = require(126) /* ./glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var MultiLineView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MultiLineView, _super);
|
|
function MultiLineView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
MultiLineView.prototype._index_data = function () {
|
|
var points = [];
|
|
for (var i = 0, end = this._xs.length; i < end; i++) {
|
|
if (this._xs[i] == null || this._xs[i].length === 0)
|
|
continue;
|
|
var _xsi = this._xs[i];
|
|
var xs = [];
|
|
for (var j = 0, n = _xsi.length; j < n; j++) {
|
|
var x = _xsi[j];
|
|
if (!types_1.isStrictNaN(x))
|
|
xs.push(x);
|
|
}
|
|
var _ysi = this._ys[i];
|
|
var ys = [];
|
|
for (var j = 0, n = _ysi.length; j < n; j++) {
|
|
var y = _ysi[j];
|
|
if (!types_1.isStrictNaN(y))
|
|
ys.push(y);
|
|
}
|
|
var _a = [array_1.min(xs), array_1.max(xs)], minX = _a[0], maxX = _a[1];
|
|
var _b = [array_1.min(ys), array_1.max(ys)], minY = _b[0], maxY = _b[1];
|
|
points.push({ minX: minX, minY: minY, maxX: maxX, maxY: maxY, i: i });
|
|
}
|
|
return new spatial_1.SpatialIndex(points);
|
|
};
|
|
MultiLineView.prototype._render = function (ctx, indices, _a) {
|
|
var sxs = _a.sxs, sys = _a.sys;
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
var _b = [sxs[i], sys[i]], sx = _b[0], sy = _b[1];
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
for (var j = 0, end = sx.length; j < end; j++) {
|
|
if (j == 0) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(sx[j], sy[j]);
|
|
continue;
|
|
}
|
|
else if (isNaN(sx[j]) || isNaN(sy[j])) {
|
|
ctx.stroke();
|
|
ctx.beginPath();
|
|
continue;
|
|
}
|
|
else
|
|
ctx.lineTo(sx[j], sy[j]);
|
|
}
|
|
ctx.stroke();
|
|
}
|
|
};
|
|
MultiLineView.prototype._hit_point = function (geometry) {
|
|
var result = hittest.create_empty_hit_test_result();
|
|
var point = { x: geometry.sx, y: geometry.sy };
|
|
var shortest = 9999;
|
|
var hits = {};
|
|
for (var i = 0, end = this.sxs.length; i < end; i++) {
|
|
var threshold = Math.max(2, this.visuals.line.cache_select('line_width', i) / 2);
|
|
var points = null;
|
|
for (var j = 0, endj = this.sxs[i].length - 1; j < endj; j++) {
|
|
var p0 = { x: this.sxs[i][j], y: this.sys[i][j] };
|
|
var p1 = { x: this.sxs[i][j + 1], y: this.sys[i][j + 1] };
|
|
var dist = hittest.dist_to_segment(point, p0, p1);
|
|
if (dist < threshold && dist < shortest) {
|
|
shortest = dist;
|
|
points = [j];
|
|
}
|
|
}
|
|
if (points)
|
|
hits[i] = points;
|
|
}
|
|
result.indices = object_1.keys(hits).map(function (x) { return parseInt(x, 10); });
|
|
result.multiline_indices = hits;
|
|
return result;
|
|
};
|
|
MultiLineView.prototype._hit_span = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var result = hittest.create_empty_hit_test_result();
|
|
var val;
|
|
var values;
|
|
if (geometry.direction === 'v') {
|
|
val = this.renderer.yscale.invert(sy);
|
|
values = this._ys;
|
|
}
|
|
else {
|
|
val = this.renderer.xscale.invert(sx);
|
|
values = this._xs;
|
|
}
|
|
var hits = {};
|
|
for (var i = 0, end = values.length; i < end; i++) {
|
|
var points = [];
|
|
for (var j = 0, endj = values[i].length - 1; j < endj; j++) {
|
|
if (values[i][j] <= val && val <= values[i][j + 1])
|
|
points.push(j);
|
|
}
|
|
if (points.length > 0)
|
|
hits[i] = points;
|
|
}
|
|
result.indices = object_1.keys(hits).map(function (x) { return parseInt(x, 10); });
|
|
result.multiline_indices = hits;
|
|
return result;
|
|
};
|
|
MultiLineView.prototype.get_interpolation_hit = function (i, point_i, geometry) {
|
|
var _a = [this._xs[i][point_i], this._ys[i][point_i], this._xs[i][point_i + 1], this._ys[i][point_i + 1]], x2 = _a[0], y2 = _a[1], x3 = _a[2], y3 = _a[3];
|
|
return utils_1.line_interpolation(this.renderer, geometry, x2, y2, x3, y3);
|
|
};
|
|
MultiLineView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
MultiLineView.prototype.scenterx = function () {
|
|
throw new Error("not implemented");
|
|
};
|
|
MultiLineView.prototype.scentery = function () {
|
|
throw new Error("not implemented");
|
|
};
|
|
return MultiLineView;
|
|
}(glyph_1.GlyphView));
|
|
exports.MultiLineView = MultiLineView;
|
|
var MultiLine = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MultiLine, _super);
|
|
function MultiLine(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
MultiLine.initClass = function () {
|
|
this.prototype.type = 'MultiLine';
|
|
this.prototype.default_view = MultiLineView;
|
|
this.coords([['xs', 'ys']]);
|
|
this.mixins(['line']);
|
|
};
|
|
return MultiLine;
|
|
}(glyph_1.Glyph));
|
|
exports.MultiLine = MultiLine;
|
|
MultiLine.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/multi_polygons */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var spatial_1 = require(39) /* ../../core/util/spatial */;
|
|
var glyph_1 = require(126) /* ./glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var arrayable_1 = require(25) /* ../../core/util/arrayable */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var MultiPolygonsView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MultiPolygonsView, _super);
|
|
function MultiPolygonsView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
MultiPolygonsView.prototype._index_data = function () {
|
|
var points = [];
|
|
for (var i = 0, end = this._xs.length; i < end; i++) {
|
|
for (var j = 0, endj = this._xs[i].length; j < endj; j++) {
|
|
var xs = this._xs[i][j][0]; // do not use holes
|
|
var ys = this._ys[i][j][0]; // do not use holes
|
|
if (xs.length == 0)
|
|
continue;
|
|
points.push({
|
|
minX: array_1.min(xs),
|
|
minY: array_1.min(ys),
|
|
maxX: array_1.max(xs),
|
|
maxY: array_1.max(ys),
|
|
i: i,
|
|
});
|
|
}
|
|
}
|
|
this.hole_index = this._index_hole_data(); // should this be set here?
|
|
return new spatial_1.SpatialIndex(points);
|
|
};
|
|
MultiPolygonsView.prototype._index_hole_data = function () {
|
|
// need advice on how to use this sure if this could be more useful
|
|
var points = [];
|
|
for (var i = 0, end = this._xs.length; i < end; i++) {
|
|
for (var j = 0, endj = this._xs[i].length; j < endj; j++) {
|
|
if (this._xs[i][j].length > 1) {
|
|
for (var k = 1, endk = this._xs[i][j].length; k < endk; k++) {
|
|
var xs = this._xs[i][j][k]; // only use holes
|
|
var ys = this._ys[i][j][k]; // only use holes
|
|
if (xs.length == 0)
|
|
continue;
|
|
points.push({
|
|
minX: array_1.min(xs),
|
|
minY: array_1.min(ys),
|
|
maxX: array_1.max(xs),
|
|
maxY: array_1.max(ys),
|
|
i: i,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return new spatial_1.SpatialIndex(points);
|
|
};
|
|
MultiPolygonsView.prototype._mask_data = function () {
|
|
var xr = this.renderer.plot_view.frame.x_ranges.default;
|
|
var _a = [xr.min, xr.max], x0 = _a[0], x1 = _a[1];
|
|
var yr = this.renderer.plot_view.frame.y_ranges.default;
|
|
var _b = [yr.min, yr.max], y0 = _b[0], y1 = _b[1];
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
var indices = this.index.indices(bbox);
|
|
// TODO this is probably needed in patches as well so that we don't draw glyphs multiple times
|
|
return indices.sort(function (a, b) { return a - b; }).filter(function (value, index, array) {
|
|
return (index === 0) || (value !== array[index - 1]);
|
|
});
|
|
};
|
|
MultiPolygonsView.prototype._render = function (ctx, indices, _a) {
|
|
var sxs = _a.sxs, sys = _a.sys;
|
|
if (this.visuals.fill.doit || this.visuals.line.doit) {
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
ctx.beginPath();
|
|
for (var j = 0, endj = sxs[i].length; j < endj; j++) {
|
|
for (var k = 0, endk = sxs[i][j].length; k < endk; k++) {
|
|
var _sx = sxs[i][j][k];
|
|
var _sy = sys[i][j][k];
|
|
for (var l = 0, endl = _sx.length; l < endl; l++) {
|
|
if (l == 0) {
|
|
ctx.moveTo(_sx[l], _sy[l]);
|
|
continue;
|
|
}
|
|
else
|
|
ctx.lineTo(_sx[l], _sy[l]);
|
|
}
|
|
ctx.closePath();
|
|
}
|
|
}
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_vectorize(ctx, i);
|
|
ctx.fill("evenodd");
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
MultiPolygonsView.prototype._hit_point = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x = this.renderer.xscale.invert(sx);
|
|
var y = this.renderer.yscale.invert(sy);
|
|
var candidates = this.index.indices({ minX: x, minY: y, maxX: x, maxY: y });
|
|
var hole_candidates = this.hole_index.indices({ minX: x, minY: y, maxX: x, maxY: y });
|
|
var hits = [];
|
|
for (var i = 0, end = candidates.length; i < end; i++) {
|
|
var idx = candidates[i];
|
|
var sxs = this.sxs[idx];
|
|
var sys = this.sys[idx];
|
|
for (var j = 0, endj = sxs.length; j < endj; j++) {
|
|
var nk = sxs[j].length;
|
|
if (hittest.point_in_poly(sx, sy, sxs[j][0], sys[j][0])) {
|
|
if (nk == 1) {
|
|
hits.push(idx);
|
|
}
|
|
else if (hole_candidates.indexOf(idx) == -1) {
|
|
hits.push(idx);
|
|
}
|
|
else if (nk > 1) {
|
|
var in_a_hole = false;
|
|
for (var k = 1; k < nk; k++) {
|
|
var sxs_k = sxs[j][k];
|
|
var sys_k = sys[j][k];
|
|
if (hittest.point_in_poly(sx, sy, sxs_k, sys_k)) {
|
|
in_a_hole = true;
|
|
break;
|
|
}
|
|
else {
|
|
continue;
|
|
}
|
|
}
|
|
if (!in_a_hole) {
|
|
hits.push(idx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
MultiPolygonsView.prototype._get_snap_coord = function (array) {
|
|
return arrayable_1.sum(array) / array.length;
|
|
};
|
|
MultiPolygonsView.prototype.scenterx = function (i, sx, sy) {
|
|
if (this.sxs[i].length == 1) {
|
|
// We don't have discontinuous objects so we're ok
|
|
return this._get_snap_coord(this.sxs[i][0][0]);
|
|
}
|
|
else {
|
|
// We have discontinuous objects, so we need to find which
|
|
// one we're in, we can use point_in_poly again
|
|
var sxs = this.sxs[i];
|
|
var sys = this.sys[i];
|
|
for (var j = 0, end = sxs.length; j < end; j++) {
|
|
if (hittest.point_in_poly(sx, sy, sxs[j][0], sys[j][0]))
|
|
return this._get_snap_coord(sxs[j][0]);
|
|
}
|
|
}
|
|
throw new Error("unreachable code");
|
|
};
|
|
MultiPolygonsView.prototype.scentery = function (i, sx, sy) {
|
|
if (this.sys[i].length == 1) {
|
|
// We don't have discontinuous objects so we're ok
|
|
return this._get_snap_coord(this.sys[i][0][0]);
|
|
}
|
|
else {
|
|
// We have discontinuous objects, so we need to find which
|
|
// one we're in, we can use point_in_poly again
|
|
var sxs = this.sxs[i];
|
|
var sys = this.sys[i];
|
|
for (var j = 0, end = sxs.length; j < end; j++) {
|
|
if (hittest.point_in_poly(sx, sy, sxs[j][0], sys[j][0]))
|
|
return this._get_snap_coord(sys[j][0]);
|
|
}
|
|
}
|
|
throw new Error("unreachable code");
|
|
};
|
|
MultiPolygonsView.prototype.map_data = function () {
|
|
var self = this;
|
|
for (var _i = 0, _a = this.model._coords; _i < _a.length; _i++) {
|
|
var _b = _a[_i], xname = _b[0], yname = _b[1];
|
|
var sxname = "s" + xname;
|
|
var syname = "s" + yname;
|
|
xname = "_" + xname;
|
|
yname = "_" + yname;
|
|
if (self[xname] != null && (types_1.isArray(self[xname][0]) || types_1.isTypedArray(self[xname][0]))) {
|
|
var ni = self[xname].length;
|
|
self[sxname] = new Array(ni);
|
|
self[syname] = new Array(ni);
|
|
for (var i = 0; i < ni; i++) {
|
|
var nj = self[xname][i].length;
|
|
self[sxname][i] = new Array(nj);
|
|
self[syname][i] = new Array(nj);
|
|
for (var j = 0; j < nj; j++) {
|
|
var nk = self[xname][i][j].length;
|
|
self[sxname][i][j] = new Array(nk);
|
|
self[syname][i][j] = new Array(nk);
|
|
for (var k = 0; k < nk; k++) {
|
|
var _c = this.map_to_screen(self[xname][i][j][k], self[yname][i][j][k]), sx = _c[0], sy = _c[1];
|
|
self[sxname][i][j][k] = sx;
|
|
self[syname][i][j][k] = sy;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
MultiPolygonsView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
return MultiPolygonsView;
|
|
}(glyph_1.GlyphView));
|
|
exports.MultiPolygonsView = MultiPolygonsView;
|
|
var MultiPolygons = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MultiPolygons, _super);
|
|
function MultiPolygons(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
MultiPolygons.initClass = function () {
|
|
this.prototype.type = 'MultiPolygons';
|
|
this.prototype.default_view = MultiPolygonsView;
|
|
this.coords([['xs', 'ys']]);
|
|
this.mixins(['line', 'fill']);
|
|
};
|
|
return MultiPolygons;
|
|
}(glyph_1.Glyph));
|
|
exports.MultiPolygons = MultiPolygons;
|
|
MultiPolygons.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/oval */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var ellipse_oval_1 = require(125) /* ./ellipse_oval */;
|
|
var OvalView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(OvalView, _super);
|
|
function OvalView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
OvalView.prototype._map_data = function () {
|
|
var sw;
|
|
var n = this._x.length;
|
|
this.sw = new Float64Array(n);
|
|
if (this.model.properties.width.units == "data")
|
|
sw = this.sdist(this.renderer.xscale, this._x, this._width, 'center');
|
|
else
|
|
sw = this._width;
|
|
// oval drawn from bezier curves = ellipse with width reduced by 3/4
|
|
for (var i = 0; i < n; i++)
|
|
this.sw[i] = sw[i] * 0.75;
|
|
if (this.model.properties.height.units == "data")
|
|
this.sh = this.sdist(this.renderer.yscale, this._y, this._height, 'center');
|
|
else
|
|
this.sh = this._height;
|
|
};
|
|
return OvalView;
|
|
}(ellipse_oval_1.EllipseOvalView));
|
|
exports.OvalView = OvalView;
|
|
var Oval = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Oval, _super);
|
|
function Oval(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Oval.initClass = function () {
|
|
this.prototype.type = 'Oval';
|
|
this.prototype.default_view = OvalView;
|
|
};
|
|
return Oval;
|
|
}(ellipse_oval_1.EllipseOval));
|
|
exports.Oval = Oval;
|
|
Oval.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/patch */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var PatchView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PatchView, _super);
|
|
function PatchView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
PatchView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy;
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_value(ctx);
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (i == 0) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(sx[i], sy[i]);
|
|
continue;
|
|
}
|
|
else if (isNaN(sx[i] + sy[i])) {
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
ctx.beginPath();
|
|
continue;
|
|
}
|
|
else
|
|
ctx.lineTo(sx[i], sy[i]);
|
|
}
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_value(ctx);
|
|
for (var _b = 0, indices_2 = indices; _b < indices_2.length; _b++) {
|
|
var i = indices_2[_b];
|
|
if (i == 0) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(sx[i], sy[i]);
|
|
continue;
|
|
}
|
|
else if (isNaN(sx[i] + sy[i])) {
|
|
ctx.closePath();
|
|
ctx.stroke();
|
|
ctx.beginPath();
|
|
continue;
|
|
}
|
|
else
|
|
ctx.lineTo(sx[i], sy[i]);
|
|
}
|
|
ctx.closePath();
|
|
return ctx.stroke();
|
|
}
|
|
};
|
|
PatchView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
return PatchView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.PatchView = PatchView;
|
|
var Patch = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Patch, _super);
|
|
function Patch(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Patch.initClass = function () {
|
|
this.prototype.type = 'Patch';
|
|
this.prototype.default_view = PatchView;
|
|
this.mixins(['line', 'fill']);
|
|
};
|
|
return Patch;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.Patch = Patch;
|
|
Patch.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/patches */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var spatial_1 = require(39) /* ../../core/util/spatial */;
|
|
var glyph_1 = require(126) /* ./glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var arrayable_1 = require(25) /* ../../core/util/arrayable */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var PatchesView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PatchesView, _super);
|
|
function PatchesView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
PatchesView.prototype._build_discontinuous_object = function (nanned_qs) {
|
|
// _s is this.xs, this.ys, this.sxs, this.sys
|
|
// an object of n 1-d arrays in either data or screen units
|
|
//
|
|
// Each 1-d array gets broken to an array of arrays split
|
|
// on any NaNs
|
|
//
|
|
// So:
|
|
// { 0: [x11, x12],
|
|
// 1: [x21, x22, x23],
|
|
// 2: [x31, NaN, x32]
|
|
// }
|
|
// becomes
|
|
// { 0: [[x11, x12]],
|
|
// 1: [[x21, x22, x23]],
|
|
// 2: [[x31],[x32]]
|
|
// }
|
|
var ds = [];
|
|
for (var i = 0, end = nanned_qs.length; i < end; i++) {
|
|
ds[i] = [];
|
|
var qs = array_1.copy(nanned_qs[i]);
|
|
while (qs.length > 0) {
|
|
var nan_index = array_1.find_last_index(qs, function (q) { return types_1.isStrictNaN(q); });
|
|
var qs_part = void 0;
|
|
if (nan_index >= 0)
|
|
qs_part = qs.splice(nan_index);
|
|
else {
|
|
qs_part = qs;
|
|
qs = [];
|
|
}
|
|
var denanned = qs_part.filter(function (q) { return !types_1.isStrictNaN(q); });
|
|
ds[i].push(denanned);
|
|
}
|
|
}
|
|
return ds;
|
|
};
|
|
PatchesView.prototype._index_data = function () {
|
|
var xss = this._build_discontinuous_object(this._xs); // XXX
|
|
var yss = this._build_discontinuous_object(this._ys); // XXX
|
|
var points = [];
|
|
for (var i = 0, end = this._xs.length; i < end; i++) {
|
|
for (var j = 0, endj = xss[i].length; j < endj; j++) {
|
|
var xs = xss[i][j];
|
|
var ys = yss[i][j];
|
|
if (xs.length == 0)
|
|
continue;
|
|
points.push({
|
|
minX: array_1.min(xs),
|
|
minY: array_1.min(ys),
|
|
maxX: array_1.max(xs),
|
|
maxY: array_1.max(ys),
|
|
i: i,
|
|
});
|
|
}
|
|
}
|
|
return new spatial_1.SpatialIndex(points);
|
|
};
|
|
PatchesView.prototype._mask_data = function () {
|
|
var xr = this.renderer.plot_view.frame.x_ranges.default;
|
|
var _a = [xr.min, xr.max], x0 = _a[0], x1 = _a[1];
|
|
var yr = this.renderer.plot_view.frame.y_ranges.default;
|
|
var _b = [yr.min, yr.max], y0 = _b[0], y1 = _b[1];
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
var indices = this.index.indices(bbox);
|
|
// TODO (bev) this should be under test
|
|
return indices.sort(function (a, b) { return a - b; });
|
|
};
|
|
PatchesView.prototype._render = function (ctx, indices, _a) {
|
|
var sxs = _a.sxs, sys = _a.sys;
|
|
// this.sxss and this.syss are used by _hit_point and sxc, syc
|
|
// This is the earliest we can build them, and only build them once
|
|
this.sxss = this._build_discontinuous_object(sxs); // XXX
|
|
this.syss = this._build_discontinuous_object(sys); // XXX
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
var _b = [sxs[i], sys[i]], sx = _b[0], sy = _b[1];
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_vectorize(ctx, i);
|
|
for (var j = 0, end = sx.length; j < end; j++) {
|
|
if (j == 0) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(sx[j], sy[j]);
|
|
continue;
|
|
}
|
|
else if (isNaN(sx[j] + sy[j])) {
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
ctx.beginPath();
|
|
continue;
|
|
}
|
|
else
|
|
ctx.lineTo(sx[j], sy[j]);
|
|
}
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
for (var j = 0, end = sx.length; j < end; j++) {
|
|
if (j == 0) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(sx[j], sy[j]);
|
|
continue;
|
|
}
|
|
else if (isNaN(sx[j] + sy[j])) {
|
|
ctx.closePath();
|
|
ctx.stroke();
|
|
ctx.beginPath();
|
|
continue;
|
|
}
|
|
else
|
|
ctx.lineTo(sx[j], sy[j]);
|
|
}
|
|
ctx.closePath();
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
};
|
|
PatchesView.prototype._hit_point = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x = this.renderer.xscale.invert(sx);
|
|
var y = this.renderer.yscale.invert(sy);
|
|
var candidates = this.index.indices({ minX: x, minY: y, maxX: x, maxY: y });
|
|
var hits = [];
|
|
for (var i = 0, end = candidates.length; i < end; i++) {
|
|
var idx = candidates[i];
|
|
var sxs = this.sxss[idx];
|
|
var sys = this.syss[idx];
|
|
for (var j = 0, endj = sxs.length; j < endj; j++) {
|
|
if (hittest.point_in_poly(sx, sy, sxs[j], sys[j])) {
|
|
hits.push(idx);
|
|
}
|
|
}
|
|
}
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
PatchesView.prototype._get_snap_coord = function (array) {
|
|
return arrayable_1.sum(array) / array.length;
|
|
};
|
|
PatchesView.prototype.scenterx = function (i, sx, sy) {
|
|
if (this.sxss[i].length == 1) {
|
|
// We don't have discontinuous objects so we're ok
|
|
return this._get_snap_coord(this.sxs[i]);
|
|
}
|
|
else {
|
|
// We have discontinuous objects, so we need to find which
|
|
// one we're in, we can use point_in_poly again
|
|
var sxs = this.sxss[i];
|
|
var sys = this.syss[i];
|
|
for (var j = 0, end = sxs.length; j < end; j++) {
|
|
if (hittest.point_in_poly(sx, sy, sxs[j], sys[j]))
|
|
return this._get_snap_coord(sxs[j]);
|
|
}
|
|
}
|
|
throw new Error("unreachable code");
|
|
};
|
|
PatchesView.prototype.scentery = function (i, sx, sy) {
|
|
if (this.syss[i].length == 1) {
|
|
// We don't have discontinuous objects so we're ok
|
|
return this._get_snap_coord(this.sys[i]);
|
|
}
|
|
else {
|
|
// We have discontinuous objects, so we need to find which
|
|
// one we're in, we can use point_in_poly again
|
|
var sxs = this.sxss[i];
|
|
var sys = this.syss[i];
|
|
for (var j = 0, end = sxs.length; j < end; j++) {
|
|
if (hittest.point_in_poly(sx, sy, sxs[j], sys[j]))
|
|
return this._get_snap_coord(sys[j]);
|
|
}
|
|
}
|
|
throw new Error("unreachable code");
|
|
};
|
|
PatchesView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
return PatchesView;
|
|
}(glyph_1.GlyphView));
|
|
exports.PatchesView = PatchesView;
|
|
var Patches = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Patches, _super);
|
|
function Patches(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Patches.initClass = function () {
|
|
this.prototype.type = 'Patches';
|
|
this.prototype.default_view = PatchesView;
|
|
this.coords([['xs', 'ys']]);
|
|
this.mixins(['line', 'fill']);
|
|
};
|
|
return Patches;
|
|
}(glyph_1.Glyph));
|
|
exports.Patches = Patches;
|
|
Patches.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/quad */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var box_1 = require(121) /* ./box */;
|
|
var QuadView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(QuadView, _super);
|
|
function QuadView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
QuadView.prototype.get_anchor_point = function (anchor, i, _spt) {
|
|
var left = Math.min(this.sleft[i], this.sright[i]);
|
|
var right = Math.max(this.sright[i], this.sleft[i]);
|
|
var top = Math.min(this.stop[i], this.sbottom[i]); // screen coordinates !!!
|
|
var bottom = Math.max(this.sbottom[i], this.stop[i]); //
|
|
switch (anchor) {
|
|
case "top_left": return { x: left, y: top };
|
|
case "top_center": return { x: (left + right) / 2, y: top };
|
|
case "top_right": return { x: right, y: top };
|
|
case "center_right": return { x: right, y: (top + bottom) / 2 };
|
|
case "bottom_right": return { x: right, y: bottom };
|
|
case "bottom_center": return { x: (left + right) / 2, y: bottom };
|
|
case "bottom_left": return { x: left, y: bottom };
|
|
case "center_left": return { x: left, y: (top + bottom) / 2 };
|
|
case "center": return { x: (left + right) / 2, y: (top + bottom) / 2 };
|
|
default: return null;
|
|
}
|
|
};
|
|
QuadView.prototype.scenterx = function (i) {
|
|
return (this.sleft[i] + this.sright[i]) / 2;
|
|
};
|
|
QuadView.prototype.scentery = function (i) {
|
|
return (this.stop[i] + this.sbottom[i]) / 2;
|
|
};
|
|
QuadView.prototype._index_data = function () {
|
|
return this._index_box(this._right.length);
|
|
};
|
|
QuadView.prototype._lrtb = function (i) {
|
|
var l = this._left[i];
|
|
var r = this._right[i];
|
|
var t = this._top[i];
|
|
var b = this._bottom[i];
|
|
return [l, r, t, b];
|
|
};
|
|
return QuadView;
|
|
}(box_1.BoxView));
|
|
exports.QuadView = QuadView;
|
|
var Quad = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Quad, _super);
|
|
function Quad(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Quad.initClass = function () {
|
|
this.prototype.type = 'Quad';
|
|
this.prototype.default_view = QuadView;
|
|
this.coords([['right', 'bottom'], ['left', 'top']]);
|
|
};
|
|
return Quad;
|
|
}(box_1.Box));
|
|
exports.Quad = Quad;
|
|
Quad.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/quadratic */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var spatial_1 = require(39) /* ../../core/util/spatial */;
|
|
var glyph_1 = require(126) /* ./glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
// Formula from: http://pomax.nihongoresources.com/pages/bezier/
|
|
//
|
|
// if segment is quadratic bezier do:
|
|
// for both directions do:
|
|
// if control between start and end, compute linear bounding box
|
|
// otherwise, compute
|
|
// bound = u(1-t)^2 + 2v(1-t)t + wt^2
|
|
// (with t = ((u-v) / (u-2v+w)), with {u = start, v = control, w = end})
|
|
// if control precedes start, min = bound, otherwise max = bound
|
|
function _qbb(u, v, w) {
|
|
if (v == (u + w) / 2)
|
|
return [u, w];
|
|
else {
|
|
var t = (u - v) / ((u - (2 * v)) + w);
|
|
var bd = (u * Math.pow((1 - t), 2)) + (2 * v * (1 - t) * t) + (w * Math.pow(t, 2));
|
|
return [Math.min(u, w, bd), Math.max(u, w, bd)];
|
|
}
|
|
}
|
|
var QuadraticView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(QuadraticView, _super);
|
|
function QuadraticView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
QuadraticView.prototype._index_data = function () {
|
|
var points = [];
|
|
for (var i = 0, end = this._x0.length; i < end; i++) {
|
|
if (isNaN(this._x0[i] + this._x1[i] + this._y0[i] + this._y1[i] + this._cx[i] + this._cy[i]))
|
|
continue;
|
|
var _a = _qbb(this._x0[i], this._cx[i], this._x1[i]), x0 = _a[0], x1 = _a[1];
|
|
var _b = _qbb(this._y0[i], this._cy[i], this._y1[i]), y0 = _b[0], y1 = _b[1];
|
|
points.push({ minX: x0, minY: y0, maxX: x1, maxY: y1, i: i });
|
|
}
|
|
return new spatial_1.SpatialIndex(points);
|
|
};
|
|
QuadraticView.prototype._render = function (ctx, indices, _a) {
|
|
var sx0 = _a.sx0, sy0 = _a.sy0, sx1 = _a.sx1, sy1 = _a.sy1, scx = _a.scx, scy = _a.scy;
|
|
if (this.visuals.line.doit) {
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx0[i] + sy0[i] + sx1[i] + sy1[i] + scx[i] + scy[i]))
|
|
continue;
|
|
ctx.beginPath();
|
|
ctx.moveTo(sx0[i], sy0[i]);
|
|
ctx.quadraticCurveTo(scx[i], scy[i], sx1[i], sy1[i]);
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
};
|
|
QuadraticView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
QuadraticView.prototype.scenterx = function () {
|
|
throw new Error("not implemented");
|
|
};
|
|
QuadraticView.prototype.scentery = function () {
|
|
throw new Error("not implemented");
|
|
};
|
|
return QuadraticView;
|
|
}(glyph_1.GlyphView));
|
|
exports.QuadraticView = QuadraticView;
|
|
var Quadratic = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Quadratic, _super);
|
|
function Quadratic(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Quadratic.initClass = function () {
|
|
this.prototype.type = 'Quadratic';
|
|
this.prototype.default_view = QuadraticView;
|
|
this.coords([['x0', 'y0'], ['x1', 'y1'], ['cx', 'cy']]);
|
|
this.mixins(['line']);
|
|
};
|
|
return Quadratic;
|
|
}(glyph_1.Glyph));
|
|
exports.Quadratic = Quadratic;
|
|
Quadratic.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/ray */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var RayView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(RayView, _super);
|
|
function RayView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
RayView.prototype._map_data = function () {
|
|
if (this.model.properties.length.units == "data")
|
|
this.slength = this.sdist(this.renderer.xscale, this._x, this._length);
|
|
else
|
|
this.slength = this._length;
|
|
};
|
|
RayView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy, slength = _a.slength, _angle = _a._angle;
|
|
if (this.visuals.line.doit) {
|
|
var width = this.renderer.plot_view.frame._width.value;
|
|
var height = this.renderer.plot_view.frame._height.value;
|
|
var inf_len = 2 * (width + height);
|
|
for (var i = 0, end = slength.length; i < end; i++) {
|
|
if (slength[i] == 0)
|
|
slength[i] = inf_len;
|
|
}
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + _angle[i] + slength[i]))
|
|
continue;
|
|
ctx.translate(sx[i], sy[i]);
|
|
ctx.rotate(_angle[i]);
|
|
ctx.beginPath();
|
|
ctx.moveTo(0, 0);
|
|
ctx.lineTo(slength[i], 0);
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
ctx.rotate(-_angle[i]);
|
|
ctx.translate(-sx[i], -sy[i]);
|
|
}
|
|
}
|
|
};
|
|
RayView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
return RayView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.RayView = RayView;
|
|
var Ray = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Ray, _super);
|
|
function Ray(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Ray.initClass = function () {
|
|
this.prototype.type = 'Ray';
|
|
this.prototype.default_view = RayView;
|
|
this.mixins(['line']);
|
|
this.define({
|
|
length: [p.DistanceSpec],
|
|
angle: [p.AngleSpec],
|
|
});
|
|
};
|
|
return Ray;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.Ray = Ray;
|
|
Ray.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/rect */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var center_rotatable_1 = require(122) /* ./center_rotatable */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var arrayable_1 = require(25) /* ../../core/util/arrayable */;
|
|
var RectView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(RectView, _super);
|
|
function RectView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
RectView.prototype._set_data = function () {
|
|
this.max_w2 = 0;
|
|
if (this.model.properties.width.units == "data")
|
|
this.max_w2 = this.max_width / 2;
|
|
this.max_h2 = 0;
|
|
if (this.model.properties.height.units == "data")
|
|
this.max_h2 = this.max_height / 2;
|
|
};
|
|
RectView.prototype._map_data = function () {
|
|
var _a, _b;
|
|
if (this.model.properties.width.units == "data")
|
|
_a = this._map_dist_corner_for_data_side_length(this._x, this._width, this.renderer.xscale), this.sw = _a[0], this.sx0 = _a[1];
|
|
else {
|
|
this.sw = this._width;
|
|
var n_1 = this.sx.length;
|
|
this.sx0 = new Float64Array(n_1);
|
|
for (var i = 0; i < n_1; i++)
|
|
this.sx0[i] = this.sx[i] - this.sw[i] / 2;
|
|
}
|
|
if (this.model.properties.height.units == "data")
|
|
_b = this._map_dist_corner_for_data_side_length(this._y, this._height, this.renderer.yscale), this.sh = _b[0], this.sy1 = _b[1];
|
|
else {
|
|
this.sh = this._height;
|
|
var n_2 = this.sy.length;
|
|
this.sy1 = new Float64Array(n_2);
|
|
for (var i = 0; i < n_2; i++)
|
|
this.sy1[i] = this.sy[i] - this.sh[i] / 2;
|
|
}
|
|
var n = this.sw.length;
|
|
this.ssemi_diag = new Float64Array(n);
|
|
for (var i = 0; i < n; i++)
|
|
this.ssemi_diag[i] = Math.sqrt((this.sw[i] / 2 * this.sw[i]) / 2 + (this.sh[i] / 2 * this.sh[i]) / 2);
|
|
};
|
|
RectView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy, sx0 = _a.sx0, sy1 = _a.sy1, sw = _a.sw, sh = _a.sh, _angle = _a._angle;
|
|
if (this.visuals.fill.doit) {
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + sx0[i] + sy1[i] + sw[i] + sh[i] + _angle[i]))
|
|
continue;
|
|
//no need to test the return value, we call fillRect for every glyph anyway
|
|
this.visuals.fill.set_vectorize(ctx, i);
|
|
if (_angle[i]) {
|
|
ctx.translate(sx[i], sy[i]);
|
|
ctx.rotate(_angle[i]);
|
|
ctx.fillRect(-sw[i] / 2, -sh[i] / 2, sw[i], sh[i]);
|
|
ctx.rotate(-_angle[i]);
|
|
ctx.translate(-sx[i], -sy[i]);
|
|
}
|
|
else
|
|
ctx.fillRect(sx0[i], sy1[i], sw[i], sh[i]);
|
|
}
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
ctx.beginPath();
|
|
for (var _b = 0, indices_2 = indices; _b < indices_2.length; _b++) {
|
|
var i = indices_2[_b];
|
|
if (isNaN(sx[i] + sy[i] + sx0[i] + sy1[i] + sw[i] + sh[i] + _angle[i]))
|
|
continue;
|
|
// fillRect does not fill zero-height or -width rects, but rect(...)
|
|
// does seem to stroke them (1px wide or tall). Explicitly ignore rects
|
|
// with zero width or height to be consistent
|
|
if (sw[i] == 0 || sh[i] == 0)
|
|
continue;
|
|
if (_angle[i]) {
|
|
ctx.translate(sx[i], sy[i]);
|
|
ctx.rotate(_angle[i]);
|
|
ctx.rect(-sw[i] / 2, -sh[i] / 2, sw[i], sh[i]);
|
|
ctx.rotate(-_angle[i]);
|
|
ctx.translate(-sx[i], -sy[i]);
|
|
}
|
|
else
|
|
ctx.rect(sx0[i], sy1[i], sw[i], sh[i]);
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
ctx.beginPath();
|
|
}
|
|
ctx.stroke();
|
|
}
|
|
};
|
|
RectView.prototype._hit_rect = function (geometry) {
|
|
return this._hit_rect_against_index(geometry);
|
|
};
|
|
RectView.prototype._hit_point = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x = this.renderer.xscale.invert(sx);
|
|
var y = this.renderer.yscale.invert(sy);
|
|
var scenter_x = [];
|
|
for (var i = 0, end = this.sx0.length; i < end; i++) {
|
|
scenter_x.push(this.sx0[i] + this.sw[i] / 2);
|
|
}
|
|
var scenter_y = [];
|
|
for (var i = 0, end = this.sy1.length; i < end; i++) {
|
|
scenter_y.push(this.sy1[i] + this.sh[i] / 2);
|
|
}
|
|
var max_x2_ddist = arrayable_1.max(this._ddist(0, scenter_x, this.ssemi_diag));
|
|
var max_y2_ddist = arrayable_1.max(this._ddist(1, scenter_y, this.ssemi_diag));
|
|
var x0 = x - max_x2_ddist;
|
|
var x1 = x + max_x2_ddist;
|
|
var y0 = y - max_y2_ddist;
|
|
var y1 = y + max_y2_ddist;
|
|
var hits = [];
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
for (var _i = 0, _a = this.index.indices(bbox); _i < _a.length; _i++) {
|
|
var i = _a[_i];
|
|
var height_in = void 0, width_in = void 0;
|
|
if (this._angle[i]) {
|
|
var s = Math.sin(-this._angle[i]);
|
|
var c = Math.cos(-this._angle[i]);
|
|
var px = c * (sx - this.sx[i]) - s * (sy - this.sy[i]) + this.sx[i];
|
|
var py = s * (sx - this.sx[i]) + c * (sy - this.sy[i]) + this.sy[i];
|
|
sx = px;
|
|
sy = py;
|
|
width_in = Math.abs(this.sx[i] - sx) <= this.sw[i] / 2;
|
|
height_in = Math.abs(this.sy[i] - sy) <= this.sh[i] / 2;
|
|
}
|
|
else {
|
|
width_in = (sx - this.sx0[i] <= this.sw[i]) && (sx - this.sx0[i] >= 0);
|
|
height_in = (sy - this.sy1[i] <= this.sh[i]) && (sy - this.sy1[i] >= 0);
|
|
}
|
|
if (height_in && width_in)
|
|
hits.push(i);
|
|
}
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
RectView.prototype._map_dist_corner_for_data_side_length = function (coord, side_length, scale) {
|
|
var n = coord.length;
|
|
var pt0 = new Float64Array(n);
|
|
var pt1 = new Float64Array(n);
|
|
for (var i = 0; i < n; i++) {
|
|
pt0[i] = Number(coord[i]) - side_length[i] / 2;
|
|
pt1[i] = Number(coord[i]) + side_length[i] / 2;
|
|
}
|
|
var spt0 = scale.v_compute(pt0);
|
|
var spt1 = scale.v_compute(pt1);
|
|
var sside_length = this.sdist(scale, pt0, side_length, 'edge', this.model.dilate);
|
|
var spt_corner = spt0;
|
|
for (var i = 0, end = spt0.length; i < end; i++) {
|
|
if (spt0[i] != spt1[i]) {
|
|
spt_corner = spt0[i] < spt1[i] ? spt0 : spt1;
|
|
break;
|
|
}
|
|
}
|
|
return [sside_length, spt_corner];
|
|
};
|
|
RectView.prototype._ddist = function (dim, spts, spans) {
|
|
var scale = dim == 0 ? this.renderer.xscale : this.renderer.yscale;
|
|
var spt0 = spts;
|
|
var m = spt0.length;
|
|
var spt1 = new Float64Array(m);
|
|
for (var i = 0; i < m; i++)
|
|
spt1[i] = spt0[i] + spans[i];
|
|
var pt0 = scale.v_invert(spt0);
|
|
var pt1 = scale.v_invert(spt1);
|
|
var n = pt0.length;
|
|
var ddist = new Float64Array(n);
|
|
for (var i = 0; i < n; i++)
|
|
ddist[i] = Math.abs(pt1[i] - pt0[i]);
|
|
return ddist;
|
|
};
|
|
RectView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
RectView.prototype._bounds = function (_a) {
|
|
var minX = _a.minX, maxX = _a.maxX, minY = _a.minY, maxY = _a.maxY;
|
|
return {
|
|
minX: minX - this.max_w2,
|
|
maxX: maxX + this.max_w2,
|
|
minY: minY - this.max_h2,
|
|
maxY: maxY + this.max_h2,
|
|
};
|
|
};
|
|
return RectView;
|
|
}(center_rotatable_1.CenterRotatableView));
|
|
exports.RectView = RectView;
|
|
var Rect = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Rect, _super);
|
|
function Rect(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Rect.initClass = function () {
|
|
this.prototype.type = 'Rect';
|
|
this.prototype.default_view = RectView;
|
|
this.define({
|
|
dilate: [p.Boolean, false],
|
|
});
|
|
};
|
|
return Rect;
|
|
}(center_rotatable_1.CenterRotatable));
|
|
exports.Rect = Rect;
|
|
Rect.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/segment */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var spatial_1 = require(39) /* ../../core/util/spatial */;
|
|
var glyph_1 = require(126) /* ./glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var SegmentView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(SegmentView, _super);
|
|
function SegmentView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
SegmentView.prototype._index_data = function () {
|
|
var points = [];
|
|
for (var i = 0, end = this._x0.length; i < end; i++) {
|
|
var x0 = this._x0[i];
|
|
var x1 = this._x1[i];
|
|
var y0 = this._y0[i];
|
|
var y1 = this._y1[i];
|
|
if (!isNaN(x0 + x1 + y0 + y1)) {
|
|
points.push({
|
|
minX: Math.min(x0, x1),
|
|
minY: Math.min(y0, y1),
|
|
maxX: Math.max(x0, x1),
|
|
maxY: Math.max(y0, y1),
|
|
i: i,
|
|
});
|
|
}
|
|
}
|
|
return new spatial_1.SpatialIndex(points);
|
|
};
|
|
SegmentView.prototype._render = function (ctx, indices, _a) {
|
|
var sx0 = _a.sx0, sy0 = _a.sy0, sx1 = _a.sx1, sy1 = _a.sy1;
|
|
if (this.visuals.line.doit) {
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx0[i] + sy0[i] + sx1[i] + sy1[i]))
|
|
continue;
|
|
ctx.beginPath();
|
|
ctx.moveTo(sx0[i], sy0[i]);
|
|
ctx.lineTo(sx1[i], sy1[i]);
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
};
|
|
SegmentView.prototype._hit_point = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var point = { x: sx, y: sy };
|
|
var hits = [];
|
|
var lw_voffset = 2; // FIXME: Use maximum of segments line_width/2 instead of magic constant 2
|
|
var _a = this.renderer.xscale.r_invert(sx - lw_voffset, sx + lw_voffset), minX = _a[0], maxX = _a[1];
|
|
var _b = this.renderer.yscale.r_invert(sy - lw_voffset, sy + lw_voffset), minY = _b[0], maxY = _b[1];
|
|
var candidates = this.index.indices({ minX: minX, minY: minY, maxX: maxX, maxY: maxY });
|
|
for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
|
|
var i = candidates_1[_i];
|
|
var threshold2 = Math.pow(Math.max(2, this.visuals.line.cache_select('line_width', i) / 2), 2);
|
|
var p0 = { x: this.sx0[i], y: this.sy0[i] };
|
|
var p1 = { x: this.sx1[i], y: this.sy1[i] };
|
|
var dist2 = hittest.dist_to_segment_squared(point, p0, p1);
|
|
if (dist2 < threshold2)
|
|
hits.push(i);
|
|
}
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
SegmentView.prototype._hit_span = function (geometry) {
|
|
var _a, _b;
|
|
var _c = this.renderer.plot_view.frame.bbox.ranges, hr = _c[0], vr = _c[1];
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var v0;
|
|
var v1;
|
|
var val;
|
|
if (geometry.direction == 'v') {
|
|
val = this.renderer.yscale.invert(sy);
|
|
_a = [this._y0, this._y1], v0 = _a[0], v1 = _a[1];
|
|
}
|
|
else {
|
|
val = this.renderer.xscale.invert(sx);
|
|
_b = [this._x0, this._x1], v0 = _b[0], v1 = _b[1];
|
|
}
|
|
var hits = [];
|
|
var _d = this.renderer.xscale.r_invert(hr.start, hr.end), minX = _d[0], maxX = _d[1];
|
|
var _e = this.renderer.yscale.r_invert(vr.start, vr.end), minY = _e[0], maxY = _e[1];
|
|
var candidates = this.index.indices({ minX: minX, minY: minY, maxX: maxX, maxY: maxY });
|
|
for (var _i = 0, candidates_2 = candidates; _i < candidates_2.length; _i++) {
|
|
var i = candidates_2[_i];
|
|
if ((v0[i] <= val && val <= v1[i]) || (v1[i] <= val && val <= v0[i]))
|
|
hits.push(i);
|
|
}
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
SegmentView.prototype.scenterx = function (i) {
|
|
return (this.sx0[i] + this.sx1[i]) / 2;
|
|
};
|
|
SegmentView.prototype.scentery = function (i) {
|
|
return (this.sy0[i] + this.sy1[i]) / 2;
|
|
};
|
|
SegmentView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
return SegmentView;
|
|
}(glyph_1.GlyphView));
|
|
exports.SegmentView = SegmentView;
|
|
var Segment = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Segment, _super);
|
|
function Segment(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Segment.initClass = function () {
|
|
this.prototype.type = 'Segment';
|
|
this.prototype.default_view = SegmentView;
|
|
this.coords([['x0', 'y0'], ['x1', 'y1']]);
|
|
this.mixins(['line']);
|
|
};
|
|
return Segment;
|
|
}(glyph_1.Glyph));
|
|
exports.Segment = Segment;
|
|
Segment.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/step */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var StepView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(StepView, _super);
|
|
function StepView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
StepView.prototype._render = function (ctx, indices, _a) {
|
|
var _b, _c, _d, _e, _f, _g;
|
|
var sx = _a.sx, sy = _a.sy;
|
|
var drawing = false;
|
|
var last_index = null;
|
|
this.visuals.line.set_value(ctx);
|
|
var L = indices.length;
|
|
if (L < 2)
|
|
return;
|
|
ctx.beginPath();
|
|
ctx.moveTo(sx[0], sy[0]);
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
var x1 = void 0, x2 = void 0;
|
|
var y1 = void 0, y2 = void 0;
|
|
switch (this.model.mode) {
|
|
case "before": {
|
|
_b = [sx[i - 1], sy[i]], x1 = _b[0], y1 = _b[1];
|
|
_c = [sx[i], sy[i]], x2 = _c[0], y2 = _c[1];
|
|
break;
|
|
}
|
|
case "after": {
|
|
_d = [sx[i], sy[i - 1]], x1 = _d[0], y1 = _d[1];
|
|
_e = [sx[i], sy[i]], x2 = _e[0], y2 = _e[1];
|
|
break;
|
|
}
|
|
case "center": {
|
|
var xm = (sx[i - 1] + sx[i]) / 2;
|
|
_f = [xm, sy[i - 1]], x1 = _f[0], y1 = _f[1];
|
|
_g = [xm, sy[i]], x2 = _g[0], y2 = _g[1];
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("unexpected");
|
|
}
|
|
if (drawing) {
|
|
if (!isFinite(sx[i] + sy[i])) {
|
|
ctx.stroke();
|
|
ctx.beginPath();
|
|
drawing = false;
|
|
last_index = i;
|
|
continue;
|
|
}
|
|
if (last_index != null && i - last_index > 1) {
|
|
ctx.stroke();
|
|
drawing = false;
|
|
}
|
|
}
|
|
if (drawing) {
|
|
ctx.lineTo(x1, y1);
|
|
ctx.lineTo(x2, y2);
|
|
}
|
|
else {
|
|
ctx.beginPath();
|
|
ctx.moveTo(sx[i], sy[i]);
|
|
drawing = true;
|
|
}
|
|
last_index = i;
|
|
}
|
|
ctx.lineTo(sx[L - 1], sy[L - 1]);
|
|
ctx.stroke();
|
|
};
|
|
StepView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
return StepView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.StepView = StepView;
|
|
var Step = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Step, _super);
|
|
function Step(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Step.initClass = function () {
|
|
this.prototype.type = 'Step';
|
|
this.prototype.default_view = StepView;
|
|
this.mixins(['line']);
|
|
this.define({
|
|
mode: [p.StepMode, "before"],
|
|
});
|
|
};
|
|
return Step;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.Step = Step;
|
|
Step.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/text */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var text_1 = require(43) /* ../../core/util/text */;
|
|
var TextView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TextView, _super);
|
|
function TextView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
TextView.prototype._rotate_point = function (x, y, xoff, yoff, angle) {
|
|
var sxr = (x - xoff) * Math.cos(angle) - (y - yoff) * Math.sin(angle) + xoff;
|
|
var syr = (x - xoff) * Math.sin(angle) + (y - yoff) * Math.cos(angle) + yoff;
|
|
return [sxr, syr];
|
|
};
|
|
TextView.prototype._text_bounds = function (x0, y0, width, height) {
|
|
var xvals = [x0, x0 + width, x0 + width, x0, x0];
|
|
var yvals = [y0, y0, y0 - height, y0 - height, y0];
|
|
return [xvals, yvals];
|
|
};
|
|
TextView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy, _x_offset = _a._x_offset, _y_offset = _a._y_offset, _angle = _a._angle, _text = _a._text;
|
|
this._sys = [];
|
|
this._sxs = [];
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + _x_offset[i] + _y_offset[i] + _angle[i]) || _text[i] == null)
|
|
continue;
|
|
this._sxs[i] = [];
|
|
this._sys[i] = [];
|
|
if (this.visuals.text.doit) {
|
|
var text = "" + _text[i];
|
|
ctx.save();
|
|
ctx.translate(sx[i] + _x_offset[i], sy[i] + _y_offset[i]);
|
|
ctx.rotate(_angle[i]);
|
|
this.visuals.text.set_vectorize(ctx, i);
|
|
var font = this.visuals.text.cache_select("font", i);
|
|
var height = text_1.measure_font(font).height;
|
|
var line_height = this.visuals.text.text_line_height.value() * height;
|
|
if (text.indexOf("\n") == -1) {
|
|
ctx.fillText(text, 0, 0);
|
|
var x0 = sx[i] + _x_offset[i];
|
|
var y0 = sy[i] + _y_offset[i];
|
|
var width = ctx.measureText(text).width;
|
|
var _b = this._text_bounds(x0, y0, width, line_height), xvalues = _b[0], yvalues = _b[1];
|
|
this._sxs[i].push(xvalues);
|
|
this._sys[i].push(yvalues);
|
|
}
|
|
else {
|
|
var lines = text.split("\n");
|
|
var block_height = line_height * lines.length;
|
|
var baseline = this.visuals.text.cache_select("text_baseline", i);
|
|
var y = void 0;
|
|
switch (baseline) {
|
|
case "top": {
|
|
y = 0;
|
|
break;
|
|
}
|
|
case "middle": {
|
|
y = (-block_height / 2) + (line_height / 2);
|
|
break;
|
|
}
|
|
case "bottom": {
|
|
y = -block_height + line_height;
|
|
break;
|
|
}
|
|
default: {
|
|
y = 0;
|
|
console.warn("'" + baseline + "' baseline not supported with multi line text");
|
|
}
|
|
}
|
|
for (var _c = 0, lines_1 = lines; _c < lines_1.length; _c++) {
|
|
var line = lines_1[_c];
|
|
ctx.fillText(line, 0, y);
|
|
var x0 = sx[i] + _x_offset[i];
|
|
var y0 = y + sy[i] + _y_offset[i];
|
|
var width = ctx.measureText(line).width;
|
|
var _d = this._text_bounds(x0, y0, width, line_height), xvalues = _d[0], yvalues = _d[1];
|
|
this._sxs[i].push(xvalues);
|
|
this._sys[i].push(yvalues);
|
|
y += line_height;
|
|
}
|
|
}
|
|
ctx.restore();
|
|
}
|
|
}
|
|
};
|
|
TextView.prototype._hit_point = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var hits = [];
|
|
for (var i = 0; i < this._sxs.length; i++) {
|
|
var sxs = this._sxs[i];
|
|
var sys = this._sys[i];
|
|
var n = sxs.length;
|
|
for (var j = 0, endj = n; j < endj; j++) {
|
|
var _a = this._rotate_point(sx, sy, sxs[n - 1][0], sys[n - 1][0], -this._angle[i]), sxr = _a[0], syr = _a[1];
|
|
if (hittest.point_in_poly(sxr, syr, sxs[j], sys[j])) {
|
|
hits.push(i);
|
|
}
|
|
}
|
|
}
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
TextView.prototype._scenterxy = function (i) {
|
|
var sx0 = this._sxs[i][0][0];
|
|
var sy0 = this._sys[i][0][0];
|
|
var sxc = (this._sxs[i][0][2] + sx0) / 2;
|
|
var syc = (this._sys[i][0][2] + sy0) / 2;
|
|
var _a = this._rotate_point(sxc, syc, sx0, sy0, this._angle[i]), sxcr = _a[0], sycr = _a[1];
|
|
return { x: sxcr, y: sycr };
|
|
};
|
|
TextView.prototype.scenterx = function (i) {
|
|
return this._scenterxy(i).x;
|
|
};
|
|
TextView.prototype.scentery = function (i) {
|
|
return this._scenterxy(i).y;
|
|
};
|
|
return TextView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.TextView = TextView;
|
|
var Text = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Text, _super);
|
|
function Text(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Text.initClass = function () {
|
|
this.prototype.type = 'Text';
|
|
this.prototype.default_view = TextView;
|
|
this.mixins(['text']);
|
|
this.define({
|
|
text: [p.NullStringSpec, { field: "text" }],
|
|
angle: [p.AngleSpec, 0],
|
|
x_offset: [p.NumberSpec, 0],
|
|
y_offset: [p.NumberSpec, 0],
|
|
});
|
|
};
|
|
return Text;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.Text = Text;
|
|
Text.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/utils */ function _(require, module, exports) {
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
function generic_line_legend(visuals, ctx, _a, index) {
|
|
var x0 = _a.x0, x1 = _a.x1, y0 = _a.y0, y1 = _a.y1;
|
|
ctx.save();
|
|
ctx.beginPath();
|
|
ctx.moveTo(x0, (y0 + y1) / 2);
|
|
ctx.lineTo(x1, (y0 + y1) / 2);
|
|
if (visuals.line.doit) {
|
|
visuals.line.set_vectorize(ctx, index);
|
|
ctx.stroke();
|
|
}
|
|
ctx.restore();
|
|
}
|
|
exports.generic_line_legend = generic_line_legend;
|
|
function generic_area_legend(visuals, ctx, _a, index) {
|
|
var x0 = _a.x0, x1 = _a.x1, y0 = _a.y0, y1 = _a.y1;
|
|
var w = Math.abs(x1 - x0);
|
|
var dw = w * 0.1;
|
|
var h = Math.abs(y1 - y0);
|
|
var dh = h * 0.1;
|
|
var sx0 = x0 + dw;
|
|
var sx1 = x1 - dw;
|
|
var sy0 = y0 + dh;
|
|
var sy1 = y1 - dh;
|
|
if (visuals.fill.doit) {
|
|
visuals.fill.set_vectorize(ctx, index);
|
|
ctx.fillRect(sx0, sy0, sx1 - sx0, sy1 - sy0);
|
|
}
|
|
if (visuals.line.doit) {
|
|
ctx.beginPath();
|
|
ctx.rect(sx0, sy0, sx1 - sx0, sy1 - sy0);
|
|
visuals.line.set_vectorize(ctx, index);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
exports.generic_area_legend = generic_area_legend;
|
|
function line_interpolation(renderer, geometry, x2, y2, x3, y3) {
|
|
var _a, _b, _c, _d, _e, _f;
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x0, x1;
|
|
var y0, y1;
|
|
if (geometry.type == 'point') {
|
|
// The +/- adjustments here are to dilate the hit point into a virtual "segment" to use below
|
|
_a = renderer.yscale.r_invert(sy - 1, sy + 1), y0 = _a[0], y1 = _a[1];
|
|
_b = renderer.xscale.r_invert(sx - 1, sx + 1), x0 = _b[0], x1 = _b[1];
|
|
}
|
|
else {
|
|
// The +/- adjustments here are to handle cases such as purely horizontal or vertical lines
|
|
if (geometry.direction == 'v') {
|
|
_c = renderer.yscale.r_invert(sy, sy), y0 = _c[0], y1 = _c[1];
|
|
_d = [Math.min(x2 - 1, x3 - 1), Math.max(x2 + 1, x3 + 1)], x0 = _d[0], x1 = _d[1];
|
|
}
|
|
else {
|
|
_e = renderer.xscale.r_invert(sx, sx), x0 = _e[0], x1 = _e[1];
|
|
_f = [Math.min(y2 - 1, y3 - 1), Math.max(y2 + 1, y3 + 1)], y0 = _f[0], y1 = _f[1];
|
|
}
|
|
}
|
|
var _g = hittest.check_2_segments_intersect(x0, y0, x1, y1, x2, y2, x3, y3), x = _g.x, y = _g.y;
|
|
return [x, y]; // XXX: null is not handled at use sites
|
|
}
|
|
exports.line_interpolation = line_interpolation;
|
|
}
|
|
,
|
|
/* models/glyphs/vbar */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var box_1 = require(121) /* ./box */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var VBarView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(VBarView, _super);
|
|
function VBarView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
VBarView.prototype.scenterx = function (i) {
|
|
return this.sx[i];
|
|
};
|
|
VBarView.prototype.scentery = function (i) {
|
|
return (this.stop[i] + this.sbottom[i]) / 2;
|
|
};
|
|
VBarView.prototype._index_data = function () {
|
|
return this._index_box(this._x.length);
|
|
};
|
|
VBarView.prototype._lrtb = function (i) {
|
|
var l = this._x[i] - (this._width[i] / 2);
|
|
var r = this._x[i] + (this._width[i] / 2);
|
|
var t = Math.max(this._top[i], this._bottom[i]);
|
|
var b = Math.min(this._top[i], this._bottom[i]);
|
|
return [l, r, t, b];
|
|
};
|
|
VBarView.prototype._map_data = function () {
|
|
this.sx = this.renderer.xscale.v_compute(this._x);
|
|
this.sw = this.sdist(this.renderer.xscale, this._x, this._width, "center");
|
|
this.stop = this.renderer.yscale.v_compute(this._top);
|
|
this.sbottom = this.renderer.yscale.v_compute(this._bottom);
|
|
var n = this.sx.length;
|
|
this.sleft = new Float64Array(n);
|
|
this.sright = new Float64Array(n);
|
|
for (var i = 0; i < n; i++) {
|
|
this.sleft[i] = this.sx[i] - this.sw[i] / 2;
|
|
this.sright[i] = this.sx[i] + this.sw[i] / 2;
|
|
}
|
|
this._clamp_viewport();
|
|
};
|
|
return VBarView;
|
|
}(box_1.BoxView));
|
|
exports.VBarView = VBarView;
|
|
var VBar = /** @class */ (function (_super) {
|
|
tslib_1.__extends(VBar, _super);
|
|
function VBar(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
VBar.initClass = function () {
|
|
this.prototype.type = 'VBar';
|
|
this.prototype.default_view = VBarView;
|
|
this.coords([['x', 'bottom']]);
|
|
this.define({
|
|
width: [p.DistanceSpec],
|
|
top: [p.CoordinateSpec],
|
|
});
|
|
this.override({
|
|
bottom: 0,
|
|
});
|
|
};
|
|
return VBar;
|
|
}(box_1.Box));
|
|
exports.VBar = VBar;
|
|
VBar.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/wedge */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ./xy_glyph */;
|
|
var utils_1 = require(147) /* ./utils */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var math_1 = require(34) /* ../../core/util/math */;
|
|
var WedgeView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(WedgeView, _super);
|
|
function WedgeView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
WedgeView.prototype._map_data = function () {
|
|
if (this.model.properties.radius.units == "data")
|
|
this.sradius = this.sdist(this.renderer.xscale, this._x, this._radius);
|
|
else
|
|
this.sradius = this._radius;
|
|
};
|
|
WedgeView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy, sradius = _a.sradius, _start_angle = _a._start_angle, _end_angle = _a._end_angle;
|
|
var direction = this.model.properties.direction.value();
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + sradius[i] + _start_angle[i] + _end_angle[i]))
|
|
continue;
|
|
ctx.beginPath();
|
|
ctx.arc(sx[i], sy[i], sradius[i], _start_angle[i], _end_angle[i], direction);
|
|
ctx.lineTo(sx[i], sy[i]);
|
|
ctx.closePath();
|
|
if (this.visuals.fill.doit) {
|
|
this.visuals.fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (this.visuals.line.doit) {
|
|
this.visuals.line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
};
|
|
WedgeView.prototype._hit_point = function (geometry) {
|
|
var _a, _b, _c, _d;
|
|
var dist, sx0, sx1, sy0, sy1, x0, x1, y0, y1;
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x = this.renderer.xscale.invert(sx);
|
|
var y = this.renderer.yscale.invert(sy);
|
|
// check diameter first
|
|
var max_diameter = 2 * this.max_radius;
|
|
if (this.model.properties.radius.units === "data") {
|
|
x0 = x - max_diameter;
|
|
x1 = x + max_diameter;
|
|
y0 = y - max_diameter;
|
|
y1 = y + max_diameter;
|
|
}
|
|
else {
|
|
sx0 = sx - max_diameter;
|
|
sx1 = sx + max_diameter;
|
|
_a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
sy0 = sy - max_diameter;
|
|
sy1 = sy + max_diameter;
|
|
_b = this.renderer.yscale.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
}
|
|
var candidates = [];
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
for (var _i = 0, _e = this.index.indices(bbox); _i < _e.length; _i++) {
|
|
var i = _e[_i];
|
|
var r2 = Math.pow(this.sradius[i], 2);
|
|
_c = this.renderer.xscale.r_compute(x, this._x[i]), sx0 = _c[0], sx1 = _c[1];
|
|
_d = this.renderer.yscale.r_compute(y, this._y[i]), sy0 = _d[0], sy1 = _d[1];
|
|
dist = Math.pow(sx0 - sx1, 2) + Math.pow(sy0 - sy1, 2);
|
|
if (dist <= r2) {
|
|
candidates.push([i, dist]);
|
|
}
|
|
}
|
|
var direction = this.model.properties.direction.value();
|
|
var hits = [];
|
|
for (var _f = 0, candidates_1 = candidates; _f < candidates_1.length; _f++) {
|
|
var _g = candidates_1[_f], i = _g[0], dist_1 = _g[1];
|
|
// NOTE: minus the angle because JS uses non-mathy convention for angles
|
|
var angle = Math.atan2(sy - this.sy[i], sx - this.sx[i]);
|
|
if (math_1.angle_between(-angle, -this._start_angle[i], -this._end_angle[i], direction)) {
|
|
hits.push([i, dist_1]);
|
|
}
|
|
}
|
|
return hittest.create_hit_test_result_from_hits(hits);
|
|
};
|
|
WedgeView.prototype.draw_legend_for_index = function (ctx, bbox, index) {
|
|
utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
|
|
};
|
|
WedgeView.prototype._scenterxy = function (i) {
|
|
var r = this.sradius[i] / 2;
|
|
var a = (this._start_angle[i] + this._end_angle[i]) / 2;
|
|
return { x: this.sx[i] + (r * Math.cos(a)), y: this.sy[i] + (r * Math.sin(a)) };
|
|
};
|
|
WedgeView.prototype.scenterx = function (i) {
|
|
return this._scenterxy(i).x;
|
|
};
|
|
WedgeView.prototype.scentery = function (i) {
|
|
return this._scenterxy(i).y;
|
|
};
|
|
return WedgeView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.WedgeView = WedgeView;
|
|
var Wedge = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Wedge, _super);
|
|
function Wedge(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Wedge.initClass = function () {
|
|
this.prototype.type = 'Wedge';
|
|
this.prototype.default_view = WedgeView;
|
|
this.mixins(['line', 'fill']);
|
|
this.define({
|
|
direction: [p.Direction, 'anticlock'],
|
|
radius: [p.DistanceSpec],
|
|
start_angle: [p.AngleSpec],
|
|
end_angle: [p.AngleSpec],
|
|
});
|
|
};
|
|
return Wedge;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.Wedge = Wedge;
|
|
Wedge.initClass();
|
|
}
|
|
,
|
|
/* models/glyphs/xy_glyph */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var spatial_1 = require(39) /* ../../core/util/spatial */;
|
|
var glyph_1 = require(126) /* ./glyph */;
|
|
var XYGlyphView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(XYGlyphView, _super);
|
|
function XYGlyphView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
XYGlyphView.prototype._index_data = function () {
|
|
var points = [];
|
|
for (var i = 0, end = this._x.length; i < end; i++) {
|
|
var x = this._x[i];
|
|
var y = this._y[i];
|
|
if (isNaN(x + y) || !isFinite(x + y))
|
|
continue;
|
|
points.push({ minX: x, minY: y, maxX: x, maxY: y, i: i });
|
|
}
|
|
return new spatial_1.SpatialIndex(points);
|
|
};
|
|
XYGlyphView.prototype.scenterx = function (i) {
|
|
return this.sx[i];
|
|
};
|
|
XYGlyphView.prototype.scentery = function (i) {
|
|
return this.sy[i];
|
|
};
|
|
return XYGlyphView;
|
|
}(glyph_1.GlyphView));
|
|
exports.XYGlyphView = XYGlyphView;
|
|
var XYGlyph = /** @class */ (function (_super) {
|
|
tslib_1.__extends(XYGlyph, _super);
|
|
function XYGlyph(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
XYGlyph.initClass = function () {
|
|
this.prototype.type = "XYGlyph";
|
|
this.coords([['x', 'y']]);
|
|
};
|
|
return XYGlyph;
|
|
}(glyph_1.Glyph));
|
|
exports.XYGlyph = XYGlyph;
|
|
XYGlyph.initClass();
|
|
}
|
|
,
|
|
/* models/graphs/graph_hit_test_policy */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var arrayable_1 = require(25) /* ../../core/util/arrayable */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var hittest_1 = require(9) /* ../../core/hittest */;
|
|
var GraphHitTestPolicy = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GraphHitTestPolicy, _super);
|
|
function GraphHitTestPolicy(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
GraphHitTestPolicy.initClass = function () {
|
|
this.prototype.type = "GraphHitTestPolicy";
|
|
};
|
|
GraphHitTestPolicy.prototype._hit_test_nodes = function (geometry, graph_view) {
|
|
if (!graph_view.model.visible)
|
|
return null;
|
|
var hit_test_result = graph_view.node_view.glyph.hit_test(geometry);
|
|
if (hit_test_result == null)
|
|
return null;
|
|
else
|
|
return graph_view.node_view.model.view.convert_selection_from_subset(hit_test_result);
|
|
};
|
|
GraphHitTestPolicy.prototype._hit_test_edges = function (geometry, graph_view) {
|
|
if (!graph_view.model.visible)
|
|
return null;
|
|
var hit_test_result = graph_view.edge_view.glyph.hit_test(geometry);
|
|
if (hit_test_result == null)
|
|
return null;
|
|
else
|
|
return graph_view.edge_view.model.view.convert_selection_from_subset(hit_test_result);
|
|
};
|
|
return GraphHitTestPolicy;
|
|
}(model_1.Model));
|
|
exports.GraphHitTestPolicy = GraphHitTestPolicy;
|
|
var NodesOnly = /** @class */ (function (_super) {
|
|
tslib_1.__extends(NodesOnly, _super);
|
|
function NodesOnly(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
NodesOnly.initClass = function () {
|
|
this.prototype.type = 'NodesOnly';
|
|
};
|
|
NodesOnly.prototype.hit_test = function (geometry, graph_view) {
|
|
return this._hit_test_nodes(geometry, graph_view);
|
|
};
|
|
NodesOnly.prototype.do_selection = function (hit_test_result, graph, final, append) {
|
|
if (hit_test_result == null)
|
|
return false;
|
|
var node_selection = graph.node_renderer.data_source.selected;
|
|
node_selection.update(hit_test_result, final, append);
|
|
graph.node_renderer.data_source._select.emit();
|
|
return !node_selection.is_empty();
|
|
};
|
|
NodesOnly.prototype.do_inspection = function (hit_test_result, geometry, graph_view, final, append) {
|
|
if (hit_test_result == null)
|
|
return false;
|
|
var node_inspection = graph_view.model.get_selection_manager().get_or_create_inspector(graph_view.node_view.model);
|
|
node_inspection.update(hit_test_result, final, append);
|
|
// silently set inspected attr to avoid triggering data_source.change event and rerender
|
|
graph_view.node_view.model.data_source.setv({ inspected: node_inspection }, { silent: true });
|
|
graph_view.node_view.model.data_source.inspect.emit([graph_view.node_view, { geometry: geometry }]);
|
|
return !node_inspection.is_empty();
|
|
};
|
|
return NodesOnly;
|
|
}(GraphHitTestPolicy));
|
|
exports.NodesOnly = NodesOnly;
|
|
NodesOnly.initClass();
|
|
var NodesAndLinkedEdges = /** @class */ (function (_super) {
|
|
tslib_1.__extends(NodesAndLinkedEdges, _super);
|
|
function NodesAndLinkedEdges(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
NodesAndLinkedEdges.initClass = function () {
|
|
this.prototype.type = 'NodesAndLinkedEdges';
|
|
};
|
|
NodesAndLinkedEdges.prototype.hit_test = function (geometry, graph_view) {
|
|
return this._hit_test_nodes(geometry, graph_view);
|
|
};
|
|
NodesAndLinkedEdges.prototype.get_linked_edges = function (node_source, edge_source, mode) {
|
|
var node_indices = [];
|
|
if (mode == 'selection') {
|
|
node_indices = node_source.selected.indices.map(function (i) { return node_source.data.index[i]; });
|
|
}
|
|
else if (mode == 'inspection') {
|
|
node_indices = node_source.inspected.indices.map(function (i) { return node_source.data.index[i]; });
|
|
}
|
|
var edge_indices = [];
|
|
for (var i = 0; i < edge_source.data.start.length; i++) {
|
|
if (array_1.contains(node_indices, edge_source.data.start[i]) || array_1.contains(node_indices, edge_source.data.end[i]))
|
|
edge_indices.push(i);
|
|
}
|
|
var linked_edges = hittest_1.create_empty_hit_test_result();
|
|
for (var _i = 0, edge_indices_1 = edge_indices; _i < edge_indices_1.length; _i++) {
|
|
var i = edge_indices_1[_i];
|
|
linked_edges.multiline_indices[i] = [0]; //currently only supports 2-element multilines, so this is all of it
|
|
}
|
|
linked_edges.indices = edge_indices;
|
|
return linked_edges;
|
|
};
|
|
NodesAndLinkedEdges.prototype.do_selection = function (hit_test_result, graph, final, append) {
|
|
if (hit_test_result == null)
|
|
return false;
|
|
var node_selection = graph.node_renderer.data_source.selected;
|
|
node_selection.update(hit_test_result, final, append);
|
|
var edge_selection = graph.edge_renderer.data_source.selected;
|
|
var linked_edges_selection = this.get_linked_edges(graph.node_renderer.data_source, graph.edge_renderer.data_source, 'selection');
|
|
edge_selection.update(linked_edges_selection, final, append);
|
|
graph.node_renderer.data_source._select.emit();
|
|
return !node_selection.is_empty();
|
|
};
|
|
NodesAndLinkedEdges.prototype.do_inspection = function (hit_test_result, geometry, graph_view, final, append) {
|
|
if (hit_test_result == null)
|
|
return false;
|
|
var node_inspection = graph_view.node_view.model.data_source.selection_manager.get_or_create_inspector(graph_view.node_view.model);
|
|
node_inspection.update(hit_test_result, final, append);
|
|
graph_view.node_view.model.data_source.setv({ inspected: node_inspection }, { silent: true });
|
|
var edge_inspection = graph_view.edge_view.model.data_source.selection_manager.get_or_create_inspector(graph_view.edge_view.model);
|
|
var linked_edges = this.get_linked_edges(graph_view.node_view.model.data_source, graph_view.edge_view.model.data_source, 'inspection');
|
|
edge_inspection.update(linked_edges, final, append);
|
|
//silently set inspected attr to avoid triggering data_source.change event and rerender
|
|
graph_view.edge_view.model.data_source.setv({ inspected: edge_inspection }, { silent: true });
|
|
graph_view.node_view.model.data_source.inspect.emit([graph_view.node_view, { geometry: geometry }]);
|
|
return !node_inspection.is_empty();
|
|
};
|
|
return NodesAndLinkedEdges;
|
|
}(GraphHitTestPolicy));
|
|
exports.NodesAndLinkedEdges = NodesAndLinkedEdges;
|
|
NodesAndLinkedEdges.initClass();
|
|
var EdgesAndLinkedNodes = /** @class */ (function (_super) {
|
|
tslib_1.__extends(EdgesAndLinkedNodes, _super);
|
|
function EdgesAndLinkedNodes(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
EdgesAndLinkedNodes.initClass = function () {
|
|
this.prototype.type = 'EdgesAndLinkedNodes';
|
|
};
|
|
EdgesAndLinkedNodes.prototype.hit_test = function (geometry, graph_view) {
|
|
return this._hit_test_edges(geometry, graph_view);
|
|
};
|
|
EdgesAndLinkedNodes.prototype.get_linked_nodes = function (node_source, edge_source, mode) {
|
|
var edge_indices = [];
|
|
if (mode == 'selection')
|
|
edge_indices = edge_source.selected.indices;
|
|
else if (mode == 'inspection')
|
|
edge_indices = edge_source.inspected.indices;
|
|
var nodes = [];
|
|
for (var _i = 0, edge_indices_2 = edge_indices; _i < edge_indices_2.length; _i++) {
|
|
var i = edge_indices_2[_i];
|
|
nodes.push(edge_source.data.start[i]);
|
|
nodes.push(edge_source.data.end[i]);
|
|
}
|
|
var node_indices = array_1.uniq(nodes).map(function (i) { return arrayable_1.indexOf(node_source.data.index, i); });
|
|
var linked_nodes = hittest_1.create_empty_hit_test_result();
|
|
linked_nodes.indices = node_indices;
|
|
return linked_nodes;
|
|
};
|
|
EdgesAndLinkedNodes.prototype.do_selection = function (hit_test_result, graph, final, append) {
|
|
if (hit_test_result == null)
|
|
return false;
|
|
var edge_selection = graph.edge_renderer.data_source.selected;
|
|
edge_selection.update(hit_test_result, final, append);
|
|
var node_selection = graph.node_renderer.data_source.selected;
|
|
var linked_nodes = this.get_linked_nodes(graph.node_renderer.data_source, graph.edge_renderer.data_source, 'selection');
|
|
node_selection.update(linked_nodes, final, append);
|
|
graph.edge_renderer.data_source._select.emit();
|
|
return !edge_selection.is_empty();
|
|
};
|
|
EdgesAndLinkedNodes.prototype.do_inspection = function (hit_test_result, geometry, graph_view, final, append) {
|
|
if (hit_test_result == null)
|
|
return false;
|
|
var edge_inspection = graph_view.edge_view.model.data_source.selection_manager.get_or_create_inspector(graph_view.edge_view.model);
|
|
edge_inspection.update(hit_test_result, final, append);
|
|
graph_view.edge_view.model.data_source.setv({ inspected: edge_inspection }, { silent: true });
|
|
var node_inspection = graph_view.node_view.model.data_source.selection_manager.get_or_create_inspector(graph_view.node_view.model);
|
|
var linked_nodes = this.get_linked_nodes(graph_view.node_view.model.data_source, graph_view.edge_view.model.data_source, 'inspection');
|
|
node_inspection.update(linked_nodes, final, append);
|
|
// silently set inspected attr to avoid triggering data_source.change event and rerender
|
|
graph_view.node_view.model.data_source.setv({ inspected: node_inspection }, { silent: true });
|
|
graph_view.edge_view.model.data_source.inspect.emit([graph_view.edge_view, { geometry: geometry }]);
|
|
return !edge_inspection.is_empty();
|
|
};
|
|
return EdgesAndLinkedNodes;
|
|
}(GraphHitTestPolicy));
|
|
exports.EdgesAndLinkedNodes = EdgesAndLinkedNodes;
|
|
EdgesAndLinkedNodes.initClass();
|
|
}
|
|
,
|
|
/* models/graphs/index */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
tslib_1.__exportStar(require(151) /* ./graph_hit_test_policy */, exports);
|
|
tslib_1.__exportStar(require(153) /* ./layout_provider */, exports);
|
|
tslib_1.__exportStar(require(154) /* ./static_layout_provider */, exports);
|
|
}
|
|
,
|
|
/* models/graphs/layout_provider */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var LayoutProvider = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LayoutProvider, _super);
|
|
function LayoutProvider(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
LayoutProvider.initClass = function () {
|
|
this.prototype.type = "LayoutProvider";
|
|
};
|
|
return LayoutProvider;
|
|
}(model_1.Model));
|
|
exports.LayoutProvider = LayoutProvider;
|
|
LayoutProvider.initClass();
|
|
}
|
|
,
|
|
/* models/graphs/static_layout_provider */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var layout_provider_1 = require(153) /* ./layout_provider */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var StaticLayoutProvider = /** @class */ (function (_super) {
|
|
tslib_1.__extends(StaticLayoutProvider, _super);
|
|
function StaticLayoutProvider(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
StaticLayoutProvider.initClass = function () {
|
|
this.prototype.type = "StaticLayoutProvider";
|
|
this.define({
|
|
graph_layout: [p.Any, {}],
|
|
});
|
|
};
|
|
StaticLayoutProvider.prototype.get_node_coordinates = function (node_source) {
|
|
var xs = [];
|
|
var ys = [];
|
|
var index = node_source.data.index;
|
|
for (var i = 0, end = index.length; i < end; i++) {
|
|
var point = this.graph_layout[index[i]];
|
|
var _a = point != null ? point : [NaN, NaN], x = _a[0], y = _a[1];
|
|
xs.push(x);
|
|
ys.push(y);
|
|
}
|
|
return [xs, ys];
|
|
};
|
|
StaticLayoutProvider.prototype.get_edge_coordinates = function (edge_source) {
|
|
var _a, _b;
|
|
var xs = [];
|
|
var ys = [];
|
|
var starts = edge_source.data.start;
|
|
var ends = edge_source.data.end;
|
|
var has_paths = (edge_source.data.xs != null) && (edge_source.data.ys != null);
|
|
for (var i = 0, endi = starts.length; i < endi; i++) {
|
|
var in_layout = (this.graph_layout[starts[i]] != null) && (this.graph_layout[ends[i]] != null);
|
|
if (has_paths && in_layout) {
|
|
xs.push(edge_source.data.xs[i]);
|
|
ys.push(edge_source.data.ys[i]);
|
|
}
|
|
else {
|
|
var end = void 0, start = void 0;
|
|
if (in_layout)
|
|
_a = [this.graph_layout[starts[i]], this.graph_layout[ends[i]]], start = _a[0], end = _a[1];
|
|
else
|
|
_b = [[NaN, NaN], [NaN, NaN]], start = _b[0], end = _b[1];
|
|
xs.push([start[0], end[0]]);
|
|
ys.push([start[1], end[1]]);
|
|
}
|
|
}
|
|
return [xs, ys];
|
|
};
|
|
return StaticLayoutProvider;
|
|
}(layout_provider_1.LayoutProvider));
|
|
exports.StaticLayoutProvider = StaticLayoutProvider;
|
|
StaticLayoutProvider.initClass();
|
|
}
|
|
,
|
|
/* models/grids/grid */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var guide_renderer_1 = require(195) /* ../renderers/guide_renderer */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var GridView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GridView, _super);
|
|
function GridView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Object.defineProperty(GridView.prototype, "_x_range_name", {
|
|
get: function () {
|
|
return this.model.x_range_name;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(GridView.prototype, "_y_range_name", {
|
|
get: function () {
|
|
return this.model.y_range_name;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
GridView.prototype.render = function () {
|
|
if (!this.model.visible)
|
|
return;
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
ctx.save();
|
|
this._draw_regions(ctx);
|
|
this._draw_minor_grids(ctx);
|
|
this._draw_grids(ctx);
|
|
ctx.restore();
|
|
};
|
|
GridView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.change, function () { return _this.request_render(); });
|
|
};
|
|
GridView.prototype._draw_regions = function (ctx) {
|
|
if (!this.visuals.band_fill.doit)
|
|
return;
|
|
var _a = this.grid_coords('major', false), xs = _a[0], ys = _a[1];
|
|
this.visuals.band_fill.set_value(ctx);
|
|
for (var i = 0; i < xs.length - 1; i++) {
|
|
if (i % 2 == 1) {
|
|
var _b = this.plot_view.map_to_screen(xs[i], ys[i], this._x_range_name, this._y_range_name), sx0 = _b[0], sy0 = _b[1];
|
|
var _c = this.plot_view.map_to_screen(xs[i + 1], ys[i + 1], this._x_range_name, this._y_range_name), sx1 = _c[0], sy1 = _c[1];
|
|
ctx.fillRect(sx0[0], sy0[0], sx1[1] - sx0[0], sy1[1] - sy0[0]);
|
|
}
|
|
}
|
|
};
|
|
GridView.prototype._draw_grids = function (ctx) {
|
|
if (!this.visuals.grid_line.doit)
|
|
return;
|
|
var _a = this.grid_coords('major'), xs = _a[0], ys = _a[1];
|
|
this._draw_grid_helper(ctx, this.visuals.grid_line, xs, ys);
|
|
};
|
|
GridView.prototype._draw_minor_grids = function (ctx) {
|
|
if (!this.visuals.minor_grid_line.doit)
|
|
return;
|
|
var _a = this.grid_coords('minor'), xs = _a[0], ys = _a[1];
|
|
this._draw_grid_helper(ctx, this.visuals.minor_grid_line, xs, ys);
|
|
};
|
|
GridView.prototype._draw_grid_helper = function (ctx, visuals, xs, ys) {
|
|
visuals.set_value(ctx);
|
|
for (var i = 0; i < xs.length; i++) {
|
|
var _a = this.plot_view.map_to_screen(xs[i], ys[i], this._x_range_name, this._y_range_name), sx = _a[0], sy = _a[1];
|
|
ctx.beginPath();
|
|
ctx.moveTo(Math.round(sx[0]), Math.round(sy[0]));
|
|
for (var i_1 = 1; i_1 < sx.length; i_1++)
|
|
ctx.lineTo(Math.round(sx[i_1]), Math.round(sy[i_1]));
|
|
ctx.stroke();
|
|
}
|
|
};
|
|
// {{{ TODO: state
|
|
GridView.prototype.ranges = function () {
|
|
var i = this.model.dimension;
|
|
var j = (i + 1) % 2;
|
|
var frame = this.plot_view.frame;
|
|
var ranges = [
|
|
frame.x_ranges[this.model.x_range_name],
|
|
frame.y_ranges[this.model.y_range_name],
|
|
];
|
|
return [ranges[i], ranges[j]];
|
|
};
|
|
GridView.prototype.computed_bounds = function () {
|
|
var _a;
|
|
var range = this.ranges()[0];
|
|
var user_bounds = this.model.bounds;
|
|
var range_bounds = [range.min, range.max];
|
|
var start;
|
|
var end;
|
|
if (types_1.isArray(user_bounds)) {
|
|
start = Math.min(user_bounds[0], user_bounds[1]);
|
|
end = Math.max(user_bounds[0], user_bounds[1]);
|
|
if (start < range_bounds[0])
|
|
start = range_bounds[0];
|
|
// XXX:
|
|
//else if (start > range_bounds[1])
|
|
// start = null
|
|
if (end > range_bounds[1])
|
|
end = range_bounds[1];
|
|
// XXX:
|
|
//else if (end < range_bounds[0])
|
|
// end = null
|
|
}
|
|
else {
|
|
start = range_bounds[0], end = range_bounds[1];
|
|
for (var _i = 0, _b = this.plot_view.axis_views; _i < _b.length; _i++) {
|
|
var axis_view = _b[_i];
|
|
if (axis_view.dimension == this.model.dimension
|
|
&& axis_view.model.x_range_name == this.model.x_range_name
|
|
&& axis_view.model.y_range_name == this.model.y_range_name) {
|
|
_a = axis_view.computed_bounds, start = _a[0], end = _a[1];
|
|
}
|
|
}
|
|
}
|
|
return [start, end];
|
|
};
|
|
GridView.prototype.grid_coords = function (location, exclude_ends) {
|
|
var _a;
|
|
if (exclude_ends === void 0) {
|
|
exclude_ends = true;
|
|
}
|
|
var i = this.model.dimension;
|
|
var j = (i + 1) % 2;
|
|
var _b = this.ranges(), range = _b[0], cross_range = _b[1];
|
|
var _c = this.computed_bounds(), start = _c[0], end = _c[1];
|
|
_a = [Math.min(start, end), Math.max(start, end)], start = _a[0], end = _a[1];
|
|
// TODO: (bev) using cross_range.min for cross_loc is a bit of a cheat. Since we
|
|
// currently only support "straight line" grids, this should be OK for now. If
|
|
// we ever want to support "curved" grids, e.g. for some projections, we may
|
|
// have to communicate more than just a single cross location.
|
|
var ticks = this.model.ticker.get_ticks(start, end, range, cross_range.min, {})[location];
|
|
var min = range.min;
|
|
var max = range.max;
|
|
var cmin = cross_range.min;
|
|
var cmax = cross_range.max;
|
|
var coords = [[], []];
|
|
if (!exclude_ends) {
|
|
if (ticks[0] != min)
|
|
ticks.splice(0, 0, min);
|
|
if (ticks[ticks.length - 1] != max)
|
|
ticks.push(max);
|
|
}
|
|
for (var ii = 0; ii < ticks.length; ii++) {
|
|
if ((ticks[ii] == min || ticks[ii] == max) && exclude_ends)
|
|
continue;
|
|
var dim_i = [];
|
|
var dim_j = [];
|
|
var N = 2;
|
|
for (var n = 0; n < N; n++) {
|
|
var loc = cmin + (cmax - cmin) / (N - 1) * n;
|
|
dim_i.push(ticks[ii]);
|
|
dim_j.push(loc);
|
|
}
|
|
coords[i].push(dim_i);
|
|
coords[j].push(dim_j);
|
|
}
|
|
return coords;
|
|
};
|
|
return GridView;
|
|
}(guide_renderer_1.GuideRendererView));
|
|
exports.GridView = GridView;
|
|
var Grid = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Grid, _super);
|
|
function Grid(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Grid.initClass = function () {
|
|
this.prototype.type = "Grid";
|
|
this.prototype.default_view = GridView;
|
|
this.mixins(['line:grid_', 'line:minor_grid_', 'fill:band_']);
|
|
this.define({
|
|
bounds: [p.Any, 'auto'],
|
|
dimension: [p.Any, 0],
|
|
ticker: [p.Instance],
|
|
x_range_name: [p.String, 'default'],
|
|
y_range_name: [p.String, 'default'],
|
|
});
|
|
this.override({
|
|
level: "underlay",
|
|
band_fill_color: null,
|
|
band_fill_alpha: 0,
|
|
grid_line_color: '#e5e5e5',
|
|
minor_grid_line_color: null,
|
|
});
|
|
};
|
|
return Grid;
|
|
}(guide_renderer_1.GuideRenderer));
|
|
exports.Grid = Grid;
|
|
Grid.initClass();
|
|
}
|
|
,
|
|
/* models/grids/index */ function _(require, module, exports) {
|
|
var grid_1 = require(155) /* ./grid */;
|
|
exports.Grid = grid_1.Grid;
|
|
}
|
|
,
|
|
/* models/index */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
tslib_1.__exportStar(require(69) /* ./annotations */, exports);
|
|
tslib_1.__exportStar(require(86) /* ./axes */, exports);
|
|
tslib_1.__exportStar(require(92) /* ./callbacks */, exports);
|
|
tslib_1.__exportStar(require(96) /* ./canvas */, exports);
|
|
tslib_1.__exportStar(require(99) /* ./expressions */, exports);
|
|
tslib_1.__exportStar(require(105) /* ./filters */, exports);
|
|
tslib_1.__exportStar(require(111) /* ./formatters */, exports);
|
|
tslib_1.__exportStar(require(133) /* ./glyphs */, exports);
|
|
tslib_1.__exportStar(require(152) /* ./graphs */, exports);
|
|
tslib_1.__exportStar(require(156) /* ./grids */, exports);
|
|
tslib_1.__exportStar(require(162) /* ./layouts */, exports);
|
|
tslib_1.__exportStar(require(173) /* ./mappers */, exports);
|
|
tslib_1.__exportStar(require(284) /* ./transforms */, exports);
|
|
tslib_1.__exportStar(require(178) /* ./markers */, exports);
|
|
tslib_1.__exportStar(require(183) /* ./plots */, exports);
|
|
tslib_1.__exportStar(require(189) /* ./ranges */, exports);
|
|
tslib_1.__exportStar(require(196) /* ./renderers */, exports);
|
|
tslib_1.__exportStar(require(199) /* ./scales */, exports);
|
|
tslib_1.__exportStar(require(203) /* ./selections */, exports);
|
|
tslib_1.__exportStar(require(212) /* ./sources */, exports);
|
|
tslib_1.__exportStar(require(224) /* ./tickers */, exports);
|
|
tslib_1.__exportStar(require(234) /* ./tiles */, exports);
|
|
tslib_1.__exportStar(require(270) /* ./tools */, exports);
|
|
}
|
|
,
|
|
/* models/layouts/box */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var layout_dom_1 = require(163) /* ./layout_dom */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var BoxView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BoxView, _super);
|
|
function BoxView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
BoxView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.properties.children.change, function () { return _this.rebuild(); });
|
|
};
|
|
Object.defineProperty(BoxView.prototype, "child_models", {
|
|
get: function () {
|
|
return this.model.children;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return BoxView;
|
|
}(layout_dom_1.LayoutDOMView));
|
|
exports.BoxView = BoxView;
|
|
var Box = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Box, _super);
|
|
function Box(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Box.initClass = function () {
|
|
this.prototype.type = "Box";
|
|
this.define({
|
|
children: [p.Array, []],
|
|
spacing: [p.Number, 0],
|
|
});
|
|
};
|
|
return Box;
|
|
}(layout_dom_1.LayoutDOM));
|
|
exports.Box = Box;
|
|
Box.initClass();
|
|
}
|
|
,
|
|
/* models/layouts/column */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var box_1 = require(158) /* ./box */;
|
|
var grid_1 = require(11) /* ../../core/layout/grid */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var ColumnView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ColumnView, _super);
|
|
function ColumnView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ColumnView.prototype._update_layout = function () {
|
|
var items = this.child_views.map(function (child) { return child.layout; });
|
|
this.layout = new grid_1.Column(items);
|
|
this.layout.rows = this.model.rows;
|
|
this.layout.spacing = [this.model.spacing, 0];
|
|
this.layout.set_sizing(this.box_sizing());
|
|
};
|
|
return ColumnView;
|
|
}(box_1.BoxView));
|
|
exports.ColumnView = ColumnView;
|
|
var Column = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Column, _super);
|
|
function Column(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Column.initClass = function () {
|
|
this.prototype.type = "Column";
|
|
this.prototype.default_view = ColumnView;
|
|
this.define({
|
|
rows: [p.Any, "auto"],
|
|
});
|
|
};
|
|
return Column;
|
|
}(box_1.Box));
|
|
exports.Column = Column;
|
|
Column.initClass();
|
|
}
|
|
,
|
|
/* models/layouts/grid_box */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var layout_dom_1 = require(163) /* ./layout_dom */;
|
|
var grid_1 = require(11) /* ../../core/layout/grid */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var GridBoxView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GridBoxView, _super);
|
|
function GridBoxView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
GridBoxView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.properties.children.change, function () { return _this.rebuild(); });
|
|
};
|
|
Object.defineProperty(GridBoxView.prototype, "child_models", {
|
|
get: function () {
|
|
return this.model.children.map(function (_a) {
|
|
var child = _a[0];
|
|
return child;
|
|
});
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
GridBoxView.prototype._update_layout = function () {
|
|
this.layout = new grid_1.Grid();
|
|
this.layout.rows = this.model.rows;
|
|
this.layout.cols = this.model.cols;
|
|
this.layout.spacing = this.model.spacing;
|
|
for (var _i = 0, _a = this.model.children; _i < _a.length; _i++) {
|
|
var _b = _a[_i], child = _b[0], row = _b[1], col = _b[2], row_span = _b[3], col_span = _b[4];
|
|
var child_view = this._child_views[child.id];
|
|
this.layout.items.push({ layout: child_view.layout, row: row, col: col, row_span: row_span, col_span: col_span });
|
|
}
|
|
this.layout.set_sizing(this.box_sizing());
|
|
};
|
|
return GridBoxView;
|
|
}(layout_dom_1.LayoutDOMView));
|
|
exports.GridBoxView = GridBoxView;
|
|
var GridBox = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GridBox, _super);
|
|
function GridBox(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
GridBox.initClass = function () {
|
|
this.prototype.type = "GridBox";
|
|
this.prototype.default_view = GridBoxView;
|
|
this.define({
|
|
children: [p.Array, []],
|
|
rows: [p.Any, "auto"],
|
|
cols: [p.Any, "auto"],
|
|
spacing: [p.Any, 0],
|
|
});
|
|
};
|
|
return GridBox;
|
|
}(layout_dom_1.LayoutDOM));
|
|
exports.GridBox = GridBox;
|
|
GridBox.initClass();
|
|
}
|
|
,
|
|
/* models/layouts/html_box */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var layout_dom_1 = require(163) /* ../layouts/layout_dom */;
|
|
var layout_1 = require(13) /* ../../core/layout */;
|
|
var HTMLBoxView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(HTMLBoxView, _super);
|
|
function HTMLBoxView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Object.defineProperty(HTMLBoxView.prototype, "child_models", {
|
|
get: function () {
|
|
return [];
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
HTMLBoxView.prototype._update_layout = function () {
|
|
this.layout = new layout_1.ContentBox(this.el);
|
|
this.layout.set_sizing(this.box_sizing());
|
|
};
|
|
return HTMLBoxView;
|
|
}(layout_dom_1.LayoutDOMView));
|
|
exports.HTMLBoxView = HTMLBoxView;
|
|
var HTMLBox = /** @class */ (function (_super) {
|
|
tslib_1.__extends(HTMLBox, _super);
|
|
function HTMLBox(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
HTMLBox.initClass = function () {
|
|
this.prototype.type = "HTMLBox";
|
|
};
|
|
return HTMLBox;
|
|
}(layout_dom_1.LayoutDOM));
|
|
exports.HTMLBox = HTMLBox;
|
|
HTMLBox.initClass();
|
|
}
|
|
,
|
|
/* models/layouts/index */ function _(require, module, exports) {
|
|
var box_1 = require(158) /* ./box */;
|
|
exports.Box = box_1.Box;
|
|
var column_1 = require(159) /* ./column */;
|
|
exports.Column = column_1.Column;
|
|
var grid_box_1 = require(160) /* ./grid_box */;
|
|
exports.GridBox = grid_box_1.GridBox;
|
|
var html_box_1 = require(161) /* ./html_box */;
|
|
exports.HTMLBox = html_box_1.HTMLBox;
|
|
var layout_dom_1 = require(163) /* ./layout_dom */;
|
|
exports.LayoutDOM = layout_dom_1.LayoutDOM;
|
|
var row_1 = require(164) /* ./row */;
|
|
exports.Row = row_1.Row;
|
|
var spacer_1 = require(165) /* ./spacer */;
|
|
exports.Spacer = spacer_1.Spacer;
|
|
var tabs_1 = require(166) /* ./tabs */;
|
|
exports.Panel = tabs_1.Panel;
|
|
exports.Tabs = tabs_1.Tabs;
|
|
var widget_box_1 = require(167) /* ./widget_box */;
|
|
exports.WidgetBox = widget_box_1.WidgetBox;
|
|
}
|
|
,
|
|
/* models/layouts/layout_dom */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var build_views_1 = require(4) /* ../../core/build_views */;
|
|
var dom_view_1 = require(6) /* ../../core/dom_view */;
|
|
var LayoutDOMView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LayoutDOMView, _super);
|
|
function LayoutDOMView() {
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
_this._idle_notified = false;
|
|
_this._offset_parent = null;
|
|
_this._viewport = {};
|
|
return _this;
|
|
}
|
|
LayoutDOMView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.el.style.position = this.is_root ? "relative" : "absolute";
|
|
this._child_views = {};
|
|
this.build_child_views();
|
|
};
|
|
LayoutDOMView.prototype.remove = function () {
|
|
for (var _i = 0, _a = this.child_views; _i < _a.length; _i++) {
|
|
var child_view = _a[_i];
|
|
child_view.remove();
|
|
}
|
|
this._child_views = {};
|
|
_super.prototype.remove.call(this);
|
|
};
|
|
LayoutDOMView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
if (this.is_root) {
|
|
this._on_resize = function () { return _this.resize_layout(); };
|
|
window.addEventListener("resize", this._on_resize);
|
|
this._parent_observer = setInterval(function () {
|
|
var offset_parent = _this.el.offsetParent;
|
|
if (_this._offset_parent != offset_parent) {
|
|
_this._offset_parent = offset_parent;
|
|
if (offset_parent != null) {
|
|
_this.compute_viewport();
|
|
_this.invalidate_layout();
|
|
}
|
|
}
|
|
}, 250);
|
|
}
|
|
var p = this.model.properties;
|
|
this.on_change([
|
|
p.width, p.height,
|
|
p.min_width, p.min_height,
|
|
p.max_width, p.max_height,
|
|
p.margin,
|
|
p.width_policy, p.height_policy, p.sizing_mode,
|
|
p.aspect_ratio,
|
|
p.visible,
|
|
p.background,
|
|
], function () { return _this.invalidate_layout(); });
|
|
this.on_change([
|
|
p.css_classes,
|
|
], function () { return _this.invalidate_render(); });
|
|
};
|
|
LayoutDOMView.prototype.disconnect_signals = function () {
|
|
if (this._parent_observer != null)
|
|
clearTimeout(this._parent_observer);
|
|
if (this._on_resize != null)
|
|
window.removeEventListener("resize", this._on_resize);
|
|
_super.prototype.disconnect_signals.call(this);
|
|
};
|
|
LayoutDOMView.prototype.css_classes = function () {
|
|
return _super.prototype.css_classes.call(this).concat(this.model.css_classes);
|
|
};
|
|
Object.defineProperty(LayoutDOMView.prototype, "child_views", {
|
|
get: function () {
|
|
var _this = this;
|
|
return this.child_models.map(function (child) { return _this._child_views[child.id]; });
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
LayoutDOMView.prototype.build_child_views = function () {
|
|
build_views_1.build_views(this._child_views, this.child_models, { parent: this });
|
|
};
|
|
LayoutDOMView.prototype.render = function () {
|
|
var _a;
|
|
_super.prototype.render.call(this);
|
|
dom_1.empty(this.el); // XXX: this should be in super
|
|
var background = this.model.background;
|
|
this.el.style.backgroundColor = background != null ? background : "";
|
|
(_a = dom_1.classes(this.el).clear()).add.apply(_a, this.css_classes());
|
|
for (var _i = 0, _b = this.child_views; _i < _b.length; _i++) {
|
|
var child_view = _b[_i];
|
|
this.el.appendChild(child_view.el);
|
|
child_view.render();
|
|
}
|
|
};
|
|
LayoutDOMView.prototype.update_layout = function () {
|
|
for (var _i = 0, _a = this.child_views; _i < _a.length; _i++) {
|
|
var child_view = _a[_i];
|
|
child_view.update_layout();
|
|
}
|
|
this._update_layout();
|
|
};
|
|
LayoutDOMView.prototype.update_position = function () {
|
|
this.el.style.display = this.model.visible ? "block" : "none";
|
|
var margin = this.is_root ? this.layout.sizing.margin : undefined;
|
|
dom_1.position(this.el, this.layout.bbox, margin);
|
|
for (var _i = 0, _a = this.child_views; _i < _a.length; _i++) {
|
|
var child_view = _a[_i];
|
|
child_view.update_position();
|
|
}
|
|
};
|
|
LayoutDOMView.prototype.after_layout = function () {
|
|
for (var _i = 0, _a = this.child_views; _i < _a.length; _i++) {
|
|
var child_view = _a[_i];
|
|
child_view.after_layout();
|
|
}
|
|
this._has_finished = true;
|
|
};
|
|
LayoutDOMView.prototype.compute_viewport = function () {
|
|
this._viewport = this._viewport_size();
|
|
};
|
|
LayoutDOMView.prototype.renderTo = function (element) {
|
|
element.appendChild(this.el);
|
|
this._offset_parent = this.el.offsetParent;
|
|
this.compute_viewport();
|
|
this.build();
|
|
};
|
|
LayoutDOMView.prototype.build = function () {
|
|
this.assert_root();
|
|
this.render();
|
|
this.update_layout();
|
|
this.compute_layout();
|
|
return this;
|
|
};
|
|
LayoutDOMView.prototype.rebuild = function () {
|
|
this.build_child_views();
|
|
this.invalidate_render();
|
|
};
|
|
LayoutDOMView.prototype.compute_layout = function () {
|
|
var start = Date.now();
|
|
this.layout.compute(this._viewport);
|
|
this.update_position();
|
|
this.after_layout();
|
|
logging_1.logger.debug("layout computed in " + (Date.now() - start) + " ms");
|
|
this.notify_finished();
|
|
};
|
|
LayoutDOMView.prototype.resize_layout = function () {
|
|
this.root.compute_viewport();
|
|
this.root.compute_layout();
|
|
};
|
|
LayoutDOMView.prototype.invalidate_layout = function () {
|
|
this.root.update_layout();
|
|
this.root.compute_layout();
|
|
};
|
|
LayoutDOMView.prototype.invalidate_render = function () {
|
|
this.render();
|
|
this.invalidate_layout();
|
|
};
|
|
LayoutDOMView.prototype.has_finished = function () {
|
|
if (!_super.prototype.has_finished.call(this))
|
|
return false;
|
|
for (var _i = 0, _a = this.child_views; _i < _a.length; _i++) {
|
|
var child_view = _a[_i];
|
|
if (!child_view.has_finished())
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
LayoutDOMView.prototype.notify_finished = function () {
|
|
if (!this.is_root)
|
|
this.root.notify_finished();
|
|
else {
|
|
if (!this._idle_notified && this.has_finished()) {
|
|
if (this.model.document != null) {
|
|
this._idle_notified = true;
|
|
this.model.document.notify_idle(this.model);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
LayoutDOMView.prototype._width_policy = function () {
|
|
return this.model.width != null ? "fixed" : "fit";
|
|
};
|
|
LayoutDOMView.prototype._height_policy = function () {
|
|
return this.model.height != null ? "fixed" : "fit";
|
|
};
|
|
LayoutDOMView.prototype.box_sizing = function () {
|
|
var _a = this.model, width_policy = _a.width_policy, height_policy = _a.height_policy, aspect_ratio = _a.aspect_ratio;
|
|
if (width_policy == "auto")
|
|
width_policy = this._width_policy();
|
|
if (height_policy == "auto")
|
|
height_policy = this._height_policy();
|
|
var sizing_mode = this.model.sizing_mode;
|
|
if (sizing_mode != null) {
|
|
if (sizing_mode == "fixed")
|
|
width_policy = height_policy = "fixed";
|
|
else if (sizing_mode == "stretch_both")
|
|
width_policy = height_policy = "max";
|
|
else if (sizing_mode == "stretch_width")
|
|
width_policy = "max";
|
|
else if (sizing_mode == "stretch_height")
|
|
height_policy = "max";
|
|
else {
|
|
if (aspect_ratio == null)
|
|
aspect_ratio = "auto";
|
|
switch (sizing_mode) {
|
|
case "scale_width":
|
|
width_policy = "max";
|
|
height_policy = "min";
|
|
break;
|
|
case "scale_height":
|
|
width_policy = "min";
|
|
height_policy = "max";
|
|
break;
|
|
case "scale_both":
|
|
width_policy = "max";
|
|
height_policy = "max";
|
|
break;
|
|
default:
|
|
throw new Error("unreachable");
|
|
}
|
|
}
|
|
}
|
|
var sizing = { width_policy: width_policy, height_policy: height_policy };
|
|
var _b = this.model, min_width = _b.min_width, min_height = _b.min_height;
|
|
if (min_width != null)
|
|
sizing.min_width = min_width;
|
|
if (min_height != null)
|
|
sizing.min_height = min_height;
|
|
var _c = this.model, width = _c.width, height = _c.height;
|
|
if (width != null)
|
|
sizing.width = width;
|
|
if (height != null)
|
|
sizing.height = height;
|
|
var _d = this.model, max_width = _d.max_width, max_height = _d.max_height;
|
|
if (max_width != null)
|
|
sizing.max_width = max_width;
|
|
if (max_height != null)
|
|
sizing.max_height = max_height;
|
|
if (aspect_ratio == "auto" && width != null && height != null)
|
|
sizing.aspect = width / height;
|
|
else if (types_1.isNumber(aspect_ratio))
|
|
sizing.aspect = aspect_ratio;
|
|
var margin = this.model.margin;
|
|
if (margin != null) {
|
|
if (types_1.isNumber(margin))
|
|
sizing.margin = { top: margin, right: margin, bottom: margin, left: margin };
|
|
else if (margin.length == 2) {
|
|
var vertical = margin[0], horizontal = margin[1];
|
|
sizing.margin = { top: vertical, right: horizontal, bottom: vertical, left: horizontal };
|
|
}
|
|
else {
|
|
var top_1 = margin[0], right = margin[1], bottom = margin[2], left = margin[3];
|
|
sizing.margin = { top: top_1, right: right, bottom: bottom, left: left };
|
|
}
|
|
}
|
|
sizing.visible = this.model.visible;
|
|
var align = this.model.align;
|
|
if (types_1.isArray(align))
|
|
sizing.halign = align[0], sizing.valign = align[1];
|
|
else
|
|
sizing.halign = sizing.valign = align;
|
|
return sizing;
|
|
};
|
|
LayoutDOMView.prototype._viewport_size = function () {
|
|
var _this = this;
|
|
return dom_1.undisplayed(this.el, function () {
|
|
var measuring = _this.el;
|
|
while (measuring = measuring.parentElement) {
|
|
// .bk-root element doesn't bring any value
|
|
if (measuring.classList.contains("bk-root"))
|
|
continue;
|
|
// we reached <body> element, so use viewport size
|
|
if (measuring == document.body) {
|
|
var _a = dom_1.extents(document.body).margin, left_1 = _a.left, right_1 = _a.right, top_2 = _a.top, bottom_1 = _a.bottom;
|
|
var width_1 = Math.ceil(document.documentElement.clientWidth - left_1 - right_1);
|
|
var height_1 = Math.ceil(document.documentElement.clientHeight - top_2 - bottom_1);
|
|
return { width: width_1, height: height_1 };
|
|
}
|
|
// stop on first element with sensible dimensions
|
|
var _b = dom_1.extents(measuring).padding, left = _b.left, right = _b.right, top_3 = _b.top, bottom = _b.bottom;
|
|
var _c = measuring.getBoundingClientRect(), width = _c.width, height = _c.height;
|
|
var inner_width = Math.ceil(width - left - right);
|
|
var inner_height = Math.ceil(height - top_3 - bottom);
|
|
if (inner_width > 0 || inner_height > 0)
|
|
return {
|
|
width: inner_width > 0 ? inner_width : undefined,
|
|
height: inner_height > 0 ? inner_height : undefined,
|
|
};
|
|
}
|
|
// this element is detached from DOM
|
|
return {};
|
|
});
|
|
};
|
|
LayoutDOMView.prototype.serializable_state = function () {
|
|
return tslib_1.__assign({}, _super.prototype.serializable_state.call(this), { bbox: this.layout.bbox.rect, children: this.child_views.map(function (child) { return child.serializable_state(); }) });
|
|
};
|
|
return LayoutDOMView;
|
|
}(dom_view_1.DOMView));
|
|
exports.LayoutDOMView = LayoutDOMView;
|
|
var LayoutDOM = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LayoutDOM, _super);
|
|
function LayoutDOM(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
LayoutDOM.initClass = function () {
|
|
this.prototype.type = "LayoutDOM";
|
|
this.define({
|
|
width: [p.Number, null],
|
|
height: [p.Number, null],
|
|
min_width: [p.Number, null],
|
|
min_height: [p.Number, null],
|
|
max_width: [p.Number, null],
|
|
max_height: [p.Number, null],
|
|
margin: [p.Any, [0, 0, 0, 0]],
|
|
width_policy: [p.Any, "auto"],
|
|
height_policy: [p.Any, "auto"],
|
|
aspect_ratio: [p.Any, null],
|
|
sizing_mode: [p.SizingMode, null],
|
|
visible: [p.Boolean, true],
|
|
disabled: [p.Boolean, false],
|
|
align: [p.Any, "start"],
|
|
background: [p.Color, null],
|
|
css_classes: [p.Array, []],
|
|
});
|
|
};
|
|
return LayoutDOM;
|
|
}(model_1.Model));
|
|
exports.LayoutDOM = LayoutDOM;
|
|
LayoutDOM.initClass();
|
|
}
|
|
,
|
|
/* models/layouts/row */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var box_1 = require(158) /* ./box */;
|
|
var grid_1 = require(11) /* ../../core/layout/grid */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var RowView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(RowView, _super);
|
|
function RowView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
RowView.prototype._update_layout = function () {
|
|
var items = this.child_views.map(function (child) { return child.layout; });
|
|
this.layout = new grid_1.Row(items);
|
|
this.layout.cols = this.model.cols;
|
|
this.layout.spacing = [0, this.model.spacing];
|
|
this.layout.set_sizing(this.box_sizing());
|
|
};
|
|
return RowView;
|
|
}(box_1.BoxView));
|
|
exports.RowView = RowView;
|
|
var Row = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Row, _super);
|
|
function Row(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Row.initClass = function () {
|
|
this.prototype.type = "Row";
|
|
this.prototype.default_view = RowView;
|
|
this.define({
|
|
cols: [p.Any, "auto"],
|
|
});
|
|
};
|
|
return Row;
|
|
}(box_1.Box));
|
|
exports.Row = Row;
|
|
Row.initClass();
|
|
}
|
|
,
|
|
/* models/layouts/spacer */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var layout_dom_1 = require(163) /* ./layout_dom */;
|
|
var layout_1 = require(13) /* ../../core/layout */;
|
|
var SpacerView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(SpacerView, _super);
|
|
function SpacerView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Object.defineProperty(SpacerView.prototype, "child_models", {
|
|
get: function () {
|
|
return [];
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
SpacerView.prototype._update_layout = function () {
|
|
this.layout = new layout_1.LayoutItem();
|
|
this.layout.set_sizing(this.box_sizing());
|
|
};
|
|
return SpacerView;
|
|
}(layout_dom_1.LayoutDOMView));
|
|
exports.SpacerView = SpacerView;
|
|
var Spacer = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Spacer, _super);
|
|
function Spacer(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Spacer.initClass = function () {
|
|
this.prototype.type = "Spacer";
|
|
this.prototype.default_view = SpacerView;
|
|
};
|
|
return Spacer;
|
|
}(layout_dom_1.LayoutDOM));
|
|
exports.Spacer = Spacer;
|
|
Spacer.initClass();
|
|
}
|
|
,
|
|
/* models/layouts/tabs */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var layout_1 = require(13) /* ../../core/layout */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var layout_dom_1 = require(163) /* ./layout_dom */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var TabsView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TabsView, _super);
|
|
function TabsView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
TabsView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.properties.tabs.change, function () { return _this.rebuild(); });
|
|
this.connect(this.model.properties.active.change, function () { return _this.on_active_change(); });
|
|
};
|
|
Object.defineProperty(TabsView.prototype, "child_models", {
|
|
get: function () {
|
|
return this.model.tabs.map(function (tab) { return tab.child; });
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
TabsView.prototype._update_layout = function () {
|
|
var loc = this.model.tabs_location;
|
|
var vertical = loc == "above" || loc == "below";
|
|
// XXX: this is a hack, this should be handled by "fit" policy in grid layout
|
|
var _a = this, scroll_el = _a.scroll_el, headers_el = _a.headers_el;
|
|
this.header = new /** @class */ (function (_super) {
|
|
tslib_1.__extends(class_1, _super);
|
|
function class_1() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
class_1.prototype._measure = function (viewport) {
|
|
var min_headers = 3;
|
|
var scroll = dom_1.size(scroll_el);
|
|
var headers = dom_1.children(headers_el).slice(0, min_headers).map(function (el) { return dom_1.size(el); });
|
|
var _a = _super.prototype._measure.call(this, viewport), width = _a.width, height = _a.height;
|
|
if (vertical) {
|
|
var min_width = scroll.width + array_1.sum(headers.map(function (size) { return size.width; }));
|
|
return { width: viewport.width != Infinity ? viewport.width : min_width, height: height };
|
|
}
|
|
else {
|
|
var min_height = scroll.height + array_1.sum(headers.map(function (size) { return size.height; }));
|
|
return { width: width, height: viewport.height != Infinity ? viewport.height : min_height };
|
|
}
|
|
};
|
|
return class_1;
|
|
}(layout_1.ContentBox))(this.header_el);
|
|
if (vertical)
|
|
this.header.set_sizing({ width_policy: "fit", height_policy: "fixed" });
|
|
else
|
|
this.header.set_sizing({ width_policy: "fixed", height_policy: "fit" });
|
|
var row = 1;
|
|
var col = 1;
|
|
switch (loc) {
|
|
case "above":
|
|
row -= 1;
|
|
break;
|
|
case "below":
|
|
row += 1;
|
|
break;
|
|
case "left":
|
|
col -= 1;
|
|
break;
|
|
case "right":
|
|
col += 1;
|
|
break;
|
|
}
|
|
var header = { layout: this.header, row: row, col: col };
|
|
var panels = this.child_views.map(function (child_view) {
|
|
return { layout: child_view.layout, row: 1, col: 1 };
|
|
});
|
|
this.layout = new layout_1.Grid([header].concat(panels));
|
|
this.layout.set_sizing(this.box_sizing());
|
|
};
|
|
TabsView.prototype.update_position = function () {
|
|
_super.prototype.update_position.call(this);
|
|
this.header_el.style.position = "absolute"; // XXX: do it in position()
|
|
dom_1.position(this.header_el, this.header.bbox);
|
|
var loc = this.model.tabs_location;
|
|
var vertical = loc == "above" || loc == "below";
|
|
var scroll_el_size = dom_1.size(this.scroll_el);
|
|
var headers_el_size = dom_1.scroll_size(this.headers_el);
|
|
if (vertical) {
|
|
var width = this.header.bbox.width;
|
|
if (headers_el_size.width > width) {
|
|
this.wrapper_el.style.maxWidth = width - scroll_el_size.width + "px";
|
|
dom_1.display(this.scroll_el);
|
|
}
|
|
else {
|
|
this.wrapper_el.style.maxWidth = "";
|
|
dom_1.undisplay(this.scroll_el);
|
|
}
|
|
}
|
|
else {
|
|
var height = this.header.bbox.height;
|
|
if (headers_el_size.height > height) {
|
|
this.wrapper_el.style.maxHeight = height - scroll_el_size.height + "px";
|
|
dom_1.display(this.scroll_el);
|
|
}
|
|
else {
|
|
this.wrapper_el.style.maxHeight = "";
|
|
dom_1.undisplay(this.scroll_el);
|
|
}
|
|
}
|
|
var child_views = this.child_views;
|
|
for (var _i = 0, child_views_1 = child_views; _i < child_views_1.length; _i++) {
|
|
var child_view = child_views_1[_i];
|
|
dom_1.hide(child_view.el);
|
|
}
|
|
var tab = child_views[this.model.active];
|
|
if (tab != null)
|
|
dom_1.show(tab.el);
|
|
};
|
|
TabsView.prototype.render = function () {
|
|
var _this = this;
|
|
_super.prototype.render.call(this);
|
|
var active = this.model.active;
|
|
var loc = this.model.tabs_location;
|
|
var vertical = loc == "above" || loc == "below";
|
|
var location = "bk-" + loc;
|
|
var headers = this.model.tabs.map(function (tab, i) {
|
|
var el = dom_1.div({ class: ["bk-tab", i == active ? "bk-active" : null] }, tab.title);
|
|
el.addEventListener("click", function (event) {
|
|
if (event.target == event.currentTarget)
|
|
_this.change_active(i);
|
|
});
|
|
if (tab.closable) {
|
|
var close_el = dom_1.div({ class: "bk-close" });
|
|
close_el.addEventListener("click", function (event) {
|
|
if (event.target == event.currentTarget) {
|
|
_this.model.tabs = array_1.remove_at(_this.model.tabs, i);
|
|
var ntabs = _this.model.tabs.length;
|
|
if (_this.model.active > ntabs - 1)
|
|
_this.model.active = ntabs - 1;
|
|
}
|
|
});
|
|
el.appendChild(close_el);
|
|
}
|
|
return el;
|
|
});
|
|
this.headers_el = dom_1.div({ class: ["bk-headers"] }, headers);
|
|
this.wrapper_el = dom_1.div({ class: "bk-headers-wrapper" }, this.headers_el);
|
|
var left_el = dom_1.div({ class: ["bk-btn", "bk-btn-default"], disabled: "" }, dom_1.div({ class: ["bk-caret", "bk-left"] }));
|
|
var right_el = dom_1.div({ class: ["bk-btn", "bk-btn-default"] }, dom_1.div({ class: ["bk-caret", "bk-right"] }));
|
|
var scroll_index = 0;
|
|
var do_scroll = function (dir) {
|
|
return function () {
|
|
var ntabs = _this.model.tabs.length;
|
|
if (dir == "left")
|
|
scroll_index = Math.max(scroll_index - 1, 0);
|
|
else
|
|
scroll_index = Math.min(scroll_index + 1, ntabs - 1);
|
|
if (scroll_index == 0)
|
|
left_el.setAttribute("disabled", "");
|
|
else
|
|
left_el.removeAttribute("disabled");
|
|
if (scroll_index == ntabs - 1)
|
|
right_el.setAttribute("disabled", "");
|
|
else
|
|
right_el.removeAttribute("disabled");
|
|
var sizes = dom_1.children(_this.headers_el)
|
|
.slice(0, scroll_index)
|
|
.map(function (el) { return el.getBoundingClientRect(); });
|
|
if (vertical) {
|
|
var left = -array_1.sum(sizes.map(function (size) { return size.width; }));
|
|
_this.headers_el.style.left = left + "px";
|
|
}
|
|
else {
|
|
var top_1 = -array_1.sum(sizes.map(function (size) { return size.height; }));
|
|
_this.headers_el.style.top = top_1 + "px";
|
|
}
|
|
};
|
|
};
|
|
left_el.addEventListener("click", do_scroll("left"));
|
|
right_el.addEventListener("click", do_scroll("right"));
|
|
this.scroll_el = dom_1.div({ class: "bk-btn-group" }, left_el, right_el);
|
|
this.header_el = dom_1.div({ class: ["bk-tabs-header", location] }, this.scroll_el, this.wrapper_el);
|
|
this.el.appendChild(this.header_el);
|
|
};
|
|
TabsView.prototype.change_active = function (i) {
|
|
if (i != this.model.active) {
|
|
this.model.active = i;
|
|
if (this.model.callback != null)
|
|
this.model.callback.execute(this.model);
|
|
}
|
|
};
|
|
TabsView.prototype.on_active_change = function () {
|
|
var i = this.model.active;
|
|
var headers = dom_1.children(this.headers_el);
|
|
for (var _i = 0, headers_1 = headers; _i < headers_1.length; _i++) {
|
|
var el = headers_1[_i];
|
|
el.classList.remove("bk-active");
|
|
}
|
|
headers[i].classList.add("bk-active");
|
|
var child_views = this.child_views;
|
|
for (var _a = 0, child_views_2 = child_views; _a < child_views_2.length; _a++) {
|
|
var child_view = child_views_2[_a];
|
|
dom_1.hide(child_view.el);
|
|
}
|
|
dom_1.show(child_views[i].el);
|
|
};
|
|
return TabsView;
|
|
}(layout_dom_1.LayoutDOMView));
|
|
exports.TabsView = TabsView;
|
|
var Tabs = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Tabs, _super);
|
|
function Tabs(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Tabs.initClass = function () {
|
|
this.prototype.type = "Tabs";
|
|
this.prototype.default_view = TabsView;
|
|
this.define({
|
|
tabs: [p.Array, []],
|
|
tabs_location: [p.Location, "above"],
|
|
active: [p.Number, 0],
|
|
callback: [p.Any],
|
|
});
|
|
};
|
|
return Tabs;
|
|
}(layout_dom_1.LayoutDOM));
|
|
exports.Tabs = Tabs;
|
|
Tabs.initClass();
|
|
var Panel = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Panel, _super);
|
|
function Panel(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Panel.initClass = function () {
|
|
this.prototype.type = "Panel";
|
|
this.define({
|
|
title: [p.String, ""],
|
|
child: [p.Instance],
|
|
closable: [p.Boolean, false],
|
|
});
|
|
};
|
|
return Panel;
|
|
}(model_1.Model));
|
|
exports.Panel = Panel;
|
|
Panel.initClass();
|
|
}
|
|
,
|
|
/* models/layouts/widget_box */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var column_1 = require(159) /* ./column */;
|
|
var WidgetBoxView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(WidgetBoxView, _super);
|
|
function WidgetBoxView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return WidgetBoxView;
|
|
}(column_1.ColumnView));
|
|
exports.WidgetBoxView = WidgetBoxView;
|
|
var WidgetBox = /** @class */ (function (_super) {
|
|
tslib_1.__extends(WidgetBox, _super);
|
|
function WidgetBox(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
WidgetBox.initClass = function () {
|
|
this.prototype.type = "WidgetBox";
|
|
this.prototype.default_view = WidgetBoxView;
|
|
};
|
|
return WidgetBox;
|
|
}(column_1.Column));
|
|
exports.WidgetBox = WidgetBox;
|
|
WidgetBox.initClass();
|
|
}
|
|
,
|
|
/* models/mappers/categorical_color_mapper */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var categorical_mapper_1 = require(169) /* ./categorical_mapper */;
|
|
var color_mapper_1 = require(171) /* ./color_mapper */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var CategoricalColorMapper = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CategoricalColorMapper, _super);
|
|
function CategoricalColorMapper(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CategoricalColorMapper.initClass = function () {
|
|
this.prototype.type = "CategoricalColorMapper";
|
|
this.define({
|
|
factors: [p.Array],
|
|
start: [p.Number, 0],
|
|
end: [p.Number],
|
|
});
|
|
};
|
|
CategoricalColorMapper.prototype._v_compute = function (data, values, palette, _a) {
|
|
var nan_color = _a.nan_color;
|
|
categorical_mapper_1.cat_v_compute(data, this.factors, palette, values, this.start, this.end, nan_color);
|
|
};
|
|
return CategoricalColorMapper;
|
|
}(color_mapper_1.ColorMapper));
|
|
exports.CategoricalColorMapper = CategoricalColorMapper;
|
|
CategoricalColorMapper.initClass();
|
|
}
|
|
,
|
|
/* models/mappers/categorical_mapper */ function _(require, module, exports) {
|
|
var arrayable_1 = require(25) /* ../../core/util/arrayable */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
function _cat_equals(a, b) {
|
|
if (a.length != b.length)
|
|
return false;
|
|
for (var i = 0, end = a.length; i < end; i++) {
|
|
if (a[i] !== b[i])
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
exports._cat_equals = _cat_equals;
|
|
function cat_v_compute(data, factors, targets, values, start, end, extra_value) {
|
|
var _loop_1 = function (i, N) {
|
|
var d = data[i];
|
|
var key = void 0;
|
|
if (types_1.isString(d))
|
|
key = arrayable_1.index_of(factors, d);
|
|
else {
|
|
if (start != null) {
|
|
if (end != null)
|
|
d = d.slice(start, end);
|
|
else
|
|
d = d.slice(start);
|
|
}
|
|
else if (end != null)
|
|
d = d.slice(0, end);
|
|
if (d.length == 1)
|
|
key = arrayable_1.index_of(factors, d[0]);
|
|
else
|
|
key = arrayable_1.find_index(factors, function (x) { return _cat_equals(x, d); });
|
|
}
|
|
var value = void 0;
|
|
if (key < 0 || key >= targets.length)
|
|
value = extra_value;
|
|
else
|
|
value = targets[key];
|
|
values[i] = value;
|
|
};
|
|
for (var i = 0, N = data.length; i < N; i++) {
|
|
_loop_1(i, N);
|
|
}
|
|
}
|
|
exports.cat_v_compute = cat_v_compute;
|
|
}
|
|
,
|
|
/* models/mappers/categorical_marker_mapper */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var categorical_mapper_1 = require(169) /* ./categorical_mapper */;
|
|
var mapper_1 = require(176) /* ./mapper */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var CategoricalMarkerMapper = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CategoricalMarkerMapper, _super);
|
|
function CategoricalMarkerMapper(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CategoricalMarkerMapper.initClass = function () {
|
|
this.prototype.type = "CategoricalMarkerMapper";
|
|
this.define({
|
|
factors: [p.Array],
|
|
markers: [p.Array],
|
|
start: [p.Number, 0],
|
|
end: [p.Number],
|
|
default_value: [p.MarkerType, "circle"],
|
|
});
|
|
};
|
|
CategoricalMarkerMapper.prototype.v_compute = function (xs) {
|
|
var values = new Array(xs.length);
|
|
categorical_mapper_1.cat_v_compute(xs, this.factors, this.markers, values, this.start, this.end, this.default_value);
|
|
return values;
|
|
};
|
|
return CategoricalMarkerMapper;
|
|
}(mapper_1.Mapper));
|
|
exports.CategoricalMarkerMapper = CategoricalMarkerMapper;
|
|
CategoricalMarkerMapper.initClass();
|
|
}
|
|
,
|
|
/* models/mappers/color_mapper */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var mapper_1 = require(176) /* ./mapper */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var color_1 = require(30) /* ../../core/util/color */;
|
|
var compat_1 = require(31) /* ../../core/util/compat */;
|
|
function _convert_color(color) {
|
|
if (types_1.isNumber(color))
|
|
return color;
|
|
if (color[0] != "#")
|
|
color = color_1.color2hex(color);
|
|
if (color.length != 9)
|
|
color = color + 'ff';
|
|
return parseInt(color.slice(1), 16);
|
|
}
|
|
exports._convert_color = _convert_color;
|
|
function _convert_palette(palette) {
|
|
var new_palette = new Uint32Array(palette.length);
|
|
for (var i = 0, end = palette.length; i < end; i++)
|
|
new_palette[i] = _convert_color(palette[i]);
|
|
return new_palette;
|
|
}
|
|
exports._convert_palette = _convert_palette;
|
|
function _uint32_to_rgba(values) {
|
|
if (compat_1.is_little_endian) {
|
|
var view = new DataView(values.buffer);
|
|
for (var i = 0, end = values.length; i < end; i++)
|
|
view.setUint32(i * 4, values[i]);
|
|
}
|
|
return new Uint8Array(values.buffer);
|
|
}
|
|
exports._uint32_to_rgba = _uint32_to_rgba;
|
|
var ColorMapper = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ColorMapper, _super);
|
|
function ColorMapper(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ColorMapper.initClass = function () {
|
|
this.prototype.type = "ColorMapper";
|
|
this.define({
|
|
palette: [p.Any],
|
|
nan_color: [p.Color, "gray"],
|
|
});
|
|
};
|
|
ColorMapper.prototype.v_compute = function (xs) {
|
|
var values = new Array(xs.length);
|
|
this._v_compute(xs, values, this.palette, this._colors(function (c) { return c; }));
|
|
return values;
|
|
};
|
|
Object.defineProperty(ColorMapper.prototype, "rgba_mapper", {
|
|
get: function () {
|
|
var self = this;
|
|
var palette = _convert_palette(this.palette);
|
|
var colors = this._colors(_convert_color);
|
|
return {
|
|
v_compute: function (xs) {
|
|
var values = new Uint32Array(xs.length);
|
|
self._v_compute(xs, values, palette, colors);
|
|
return _uint32_to_rgba(values);
|
|
},
|
|
};
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
ColorMapper.prototype._colors = function (conv) {
|
|
return { nan_color: conv(this.nan_color) };
|
|
};
|
|
return ColorMapper;
|
|
}(mapper_1.Mapper));
|
|
exports.ColorMapper = ColorMapper;
|
|
ColorMapper.initClass();
|
|
}
|
|
,
|
|
/* models/mappers/continuous_color_mapper */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var color_mapper_1 = require(171) /* ./color_mapper */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var ContinuousColorMapper = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ContinuousColorMapper, _super);
|
|
function ContinuousColorMapper(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ContinuousColorMapper.initClass = function () {
|
|
this.prototype.type = "ContinuousColorMapper";
|
|
this.define({
|
|
high: [p.Number],
|
|
low: [p.Number],
|
|
high_color: [p.Color],
|
|
low_color: [p.Color],
|
|
});
|
|
};
|
|
ContinuousColorMapper.prototype._colors = function (conv) {
|
|
return tslib_1.__assign({}, _super.prototype._colors.call(this, conv), { low_color: this.low_color != null ? conv(this.low_color) : undefined, high_color: this.high_color != null ? conv(this.high_color) : undefined });
|
|
};
|
|
return ContinuousColorMapper;
|
|
}(color_mapper_1.ColorMapper));
|
|
exports.ContinuousColorMapper = ContinuousColorMapper;
|
|
ContinuousColorMapper.initClass();
|
|
}
|
|
,
|
|
/* models/mappers/index */ function _(require, module, exports) {
|
|
var categorical_color_mapper_1 = require(168) /* ./categorical_color_mapper */;
|
|
exports.CategoricalColorMapper = categorical_color_mapper_1.CategoricalColorMapper;
|
|
var categorical_marker_mapper_1 = require(170) /* ./categorical_marker_mapper */;
|
|
exports.CategoricalMarkerMapper = categorical_marker_mapper_1.CategoricalMarkerMapper;
|
|
var continuous_color_mapper_1 = require(172) /* ./continuous_color_mapper */;
|
|
exports.ContinuousColorMapper = continuous_color_mapper_1.ContinuousColorMapper;
|
|
var color_mapper_1 = require(171) /* ./color_mapper */;
|
|
exports.ColorMapper = color_mapper_1.ColorMapper;
|
|
var linear_color_mapper_1 = require(174) /* ./linear_color_mapper */;
|
|
exports.LinearColorMapper = linear_color_mapper_1.LinearColorMapper;
|
|
var log_color_mapper_1 = require(175) /* ./log_color_mapper */;
|
|
exports.LogColorMapper = log_color_mapper_1.LogColorMapper;
|
|
}
|
|
,
|
|
/* models/mappers/linear_color_mapper */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var continuous_color_mapper_1 = require(172) /* ./continuous_color_mapper */;
|
|
var arrayable_1 = require(25) /* ../../core/util/arrayable */;
|
|
var LinearColorMapper = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LinearColorMapper, _super);
|
|
function LinearColorMapper(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
LinearColorMapper.initClass = function () {
|
|
this.prototype.type = "LinearColorMapper";
|
|
};
|
|
LinearColorMapper.prototype._v_compute = function (data, values, palette, colors) {
|
|
var nan_color = colors.nan_color, low_color = colors.low_color, high_color = colors.high_color;
|
|
var low = this.low != null ? this.low : arrayable_1.min(data);
|
|
var high = this.high != null ? this.high : arrayable_1.max(data);
|
|
var max_key = palette.length - 1;
|
|
var norm_factor = 1 / (high - low);
|
|
var normed_interval = 1 / palette.length;
|
|
for (var i = 0, end = data.length; i < end; i++) {
|
|
var d = data[i];
|
|
if (isNaN(d)) {
|
|
values[i] = nan_color;
|
|
continue;
|
|
}
|
|
// This handles the edge case where d == high, since the code below maps
|
|
// values exactly equal to high to palette.length, which is greater than
|
|
// max_key
|
|
if (d == high) {
|
|
values[i] = palette[max_key];
|
|
continue;
|
|
}
|
|
var normed_d = (d - low) * norm_factor;
|
|
var key = Math.floor(normed_d / normed_interval);
|
|
if (key < 0)
|
|
values[i] = low_color != null ? low_color : palette[0];
|
|
else if (key > max_key)
|
|
values[i] = high_color != null ? high_color : palette[max_key];
|
|
else
|
|
values[i] = palette[key];
|
|
}
|
|
};
|
|
return LinearColorMapper;
|
|
}(continuous_color_mapper_1.ContinuousColorMapper));
|
|
exports.LinearColorMapper = LinearColorMapper;
|
|
LinearColorMapper.initClass();
|
|
}
|
|
,
|
|
/* models/mappers/log_color_mapper */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var continuous_color_mapper_1 = require(172) /* ./continuous_color_mapper */;
|
|
var arrayable_1 = require(25) /* ../../core/util/arrayable */;
|
|
// Math.log1p() is not supported by any version of IE, so let's use a polyfill based on
|
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p.
|
|
var log1p = Math.log1p != null ? Math.log1p : function (x) { return Math.log(1 + x); };
|
|
var LogColorMapper = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LogColorMapper, _super);
|
|
function LogColorMapper(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
LogColorMapper.initClass = function () {
|
|
this.prototype.type = "LogColorMapper";
|
|
};
|
|
LogColorMapper.prototype._v_compute = function (data, values, palette, colors) {
|
|
var nan_color = colors.nan_color, low_color = colors.low_color, high_color = colors.high_color;
|
|
var n = palette.length;
|
|
var low = this.low != null ? this.low : arrayable_1.min(data);
|
|
var high = this.high != null ? this.high : arrayable_1.max(data);
|
|
var scale = n / (log1p(high) - log1p(low)); // subtract the low offset
|
|
var max_key = palette.length - 1;
|
|
for (var i = 0, end = data.length; i < end; i++) {
|
|
var d = data[i];
|
|
// Check NaN
|
|
if (isNaN(d)) {
|
|
values[i] = nan_color;
|
|
continue;
|
|
}
|
|
if (d > high) {
|
|
values[i] = high_color != null ? high_color : palette[max_key];
|
|
continue;
|
|
}
|
|
// This handles the edge case where d == high, since the code below maps
|
|
// values exactly equal to high to palette.length, which is greater than
|
|
// max_key
|
|
if (d == high) {
|
|
values[i] = palette[max_key];
|
|
continue;
|
|
}
|
|
if (d < low) {
|
|
values[i] = low_color != null ? low_color : palette[0];
|
|
continue;
|
|
}
|
|
// Get the key
|
|
var log = log1p(d) - log1p(low); // subtract the low offset
|
|
var key = Math.floor(log * scale);
|
|
// Deal with upper bound
|
|
if (key > max_key)
|
|
key = max_key;
|
|
values[i] = palette[key];
|
|
}
|
|
};
|
|
return LogColorMapper;
|
|
}(continuous_color_mapper_1.ContinuousColorMapper));
|
|
exports.LogColorMapper = LogColorMapper;
|
|
LogColorMapper.initClass();
|
|
}
|
|
,
|
|
/* models/mappers/mapper */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var transform_1 = require(289) /* ../transforms/transform */;
|
|
var Mapper = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Mapper, _super);
|
|
function Mapper(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Mapper.initClass = function () {
|
|
this.prototype.type = "Mapper";
|
|
};
|
|
Mapper.prototype.compute = function (_x) {
|
|
// If it's just a single value, then a mapper doesn't really make sense.
|
|
throw new Error("mapping single values is not supported");
|
|
};
|
|
return Mapper;
|
|
}(transform_1.Transform));
|
|
exports.Mapper = Mapper;
|
|
Mapper.initClass();
|
|
}
|
|
,
|
|
/* models/markers/defs */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var marker_1 = require(179) /* ./marker */;
|
|
var SQ3 = Math.sqrt(3);
|
|
function _one_line(ctx, r) {
|
|
ctx.moveTo(-r, 0);
|
|
ctx.lineTo(r, 0);
|
|
}
|
|
function _one_x(ctx, r) {
|
|
ctx.moveTo(-r, r);
|
|
ctx.lineTo(r, -r);
|
|
ctx.moveTo(-r, -r);
|
|
ctx.lineTo(r, r);
|
|
}
|
|
function _one_cross(ctx, r) {
|
|
ctx.moveTo(0, r);
|
|
ctx.lineTo(0, -r);
|
|
ctx.moveTo(-r, 0);
|
|
ctx.lineTo(r, 0);
|
|
}
|
|
function _one_diamond(ctx, r) {
|
|
ctx.moveTo(0, r);
|
|
ctx.lineTo(r / 1.5, 0);
|
|
ctx.lineTo(0, -r);
|
|
ctx.lineTo(-r / 1.5, 0);
|
|
ctx.closePath();
|
|
}
|
|
function _one_hex(ctx, r) {
|
|
var r2 = r / 2;
|
|
var h = SQ3 * r2;
|
|
ctx.moveTo(r, 0);
|
|
ctx.lineTo(r2, -h);
|
|
ctx.lineTo(-r2, -h);
|
|
ctx.lineTo(-r, 0);
|
|
ctx.lineTo(-r2, h);
|
|
ctx.lineTo(r2, h);
|
|
ctx.closePath();
|
|
}
|
|
function _one_tri(ctx, r) {
|
|
var h = r * SQ3;
|
|
var a = h / 3;
|
|
ctx.moveTo(-r, a);
|
|
ctx.lineTo(r, a);
|
|
ctx.lineTo(0, a - h);
|
|
ctx.closePath();
|
|
}
|
|
function asterisk(ctx, i, r, line, _fill) {
|
|
var r2 = r * 0.65;
|
|
_one_cross(ctx, r);
|
|
_one_x(ctx, r2);
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function circle(ctx, i, r, line, fill) {
|
|
ctx.arc(0, 0, r, 0, 2 * Math.PI, false);
|
|
if (fill.doit) {
|
|
fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function circle_cross(ctx, i, r, line, fill) {
|
|
ctx.arc(0, 0, r, 0, 2 * Math.PI, false);
|
|
if (fill.doit) {
|
|
fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
_one_cross(ctx, r);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function circle_x(ctx, i, r, line, fill) {
|
|
ctx.arc(0, 0, r, 0, 2 * Math.PI, false);
|
|
if (fill.doit) {
|
|
fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
_one_x(ctx, r);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function cross(ctx, i, r, line, _fill) {
|
|
_one_cross(ctx, r);
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function diamond(ctx, i, r, line, fill) {
|
|
_one_diamond(ctx, r);
|
|
if (fill.doit) {
|
|
fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function diamond_cross(ctx, i, r, line, fill) {
|
|
_one_diamond(ctx, r);
|
|
if (fill.doit) {
|
|
fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
_one_cross(ctx, r);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function hex(ctx, i, r, line, fill) {
|
|
_one_hex(ctx, r);
|
|
if (fill.doit) {
|
|
fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function inverted_triangle(ctx, i, r, line, fill) {
|
|
ctx.rotate(Math.PI);
|
|
_one_tri(ctx, r);
|
|
ctx.rotate(-Math.PI);
|
|
if (fill.doit) {
|
|
fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function square(ctx, i, r, line, fill) {
|
|
var size = 2 * r;
|
|
ctx.rect(-r, -r, size, size);
|
|
if (fill.doit) {
|
|
fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function square_cross(ctx, i, r, line, fill) {
|
|
var size = 2 * r;
|
|
ctx.rect(-r, -r, size, size);
|
|
if (fill.doit) {
|
|
fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
_one_cross(ctx, r);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function square_x(ctx, i, r, line, fill) {
|
|
var size = 2 * r;
|
|
ctx.rect(-r, -r, size, size);
|
|
if (fill.doit) {
|
|
fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
_one_x(ctx, r);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function triangle(ctx, i, r, line, fill) {
|
|
_one_tri(ctx, r);
|
|
if (fill.doit) {
|
|
fill.set_vectorize(ctx, i);
|
|
ctx.fill();
|
|
}
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function dash(ctx, i, r, line, _fill) {
|
|
_one_line(ctx, r);
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function x(ctx, i, r, line, _fill) {
|
|
_one_x(ctx, r);
|
|
if (line.doit) {
|
|
line.set_vectorize(ctx, i);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
function _mk_model(type, f) {
|
|
var view = /** @class */ (function (_super) {
|
|
tslib_1.__extends(class_1, _super);
|
|
function class_1() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
class_1.initClass = function () {
|
|
this.prototype._render_one = f;
|
|
};
|
|
return class_1;
|
|
}(marker_1.MarkerView));
|
|
view.initClass();
|
|
var model = /** @class */ (function (_super) {
|
|
tslib_1.__extends(class_2, _super);
|
|
function class_2() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
class_2.initClass = function () {
|
|
this.prototype.default_view = view;
|
|
this.prototype.type = type;
|
|
};
|
|
return class_2;
|
|
}(marker_1.Marker));
|
|
model.initClass();
|
|
return model;
|
|
}
|
|
// markers are final, so no need to export views
|
|
exports.Asterisk = _mk_model('Asterisk', asterisk);
|
|
exports.CircleCross = _mk_model('CircleCross', circle_cross);
|
|
exports.CircleX = _mk_model('CircleX', circle_x);
|
|
exports.Cross = _mk_model('Cross', cross);
|
|
exports.Dash = _mk_model('Dash', dash);
|
|
exports.Diamond = _mk_model('Diamond', diamond);
|
|
exports.DiamondCross = _mk_model('DiamondCross', diamond_cross);
|
|
exports.Hex = _mk_model('Hex', hex);
|
|
exports.InvertedTriangle = _mk_model('InvertedTriangle', inverted_triangle);
|
|
exports.Square = _mk_model('Square', square);
|
|
exports.SquareCross = _mk_model('SquareCross', square_cross);
|
|
exports.SquareX = _mk_model('SquareX', square_x);
|
|
exports.Triangle = _mk_model('Triangle', triangle);
|
|
exports.X = _mk_model('X', x);
|
|
exports.marker_funcs = {
|
|
asterisk: asterisk,
|
|
circle: circle,
|
|
circle_cross: circle_cross,
|
|
circle_x: circle_x,
|
|
cross: cross,
|
|
diamond: diamond,
|
|
diamond_cross: diamond_cross,
|
|
hex: hex,
|
|
inverted_triangle: inverted_triangle,
|
|
square: square,
|
|
square_cross: square_cross,
|
|
square_x: square_x,
|
|
triangle: triangle,
|
|
dash: dash,
|
|
x: x,
|
|
};
|
|
}
|
|
,
|
|
/* models/markers/index */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
tslib_1.__exportStar(require(177) /* ./defs */, exports);
|
|
var marker_1 = require(179) /* ./marker */;
|
|
exports.Marker = marker_1.Marker;
|
|
var scatter_1 = require(180) /* ./scatter */;
|
|
exports.Scatter = scatter_1.Scatter;
|
|
}
|
|
,
|
|
/* models/markers/marker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var xy_glyph_1 = require(150) /* ../glyphs/xy_glyph */;
|
|
var hittest = require(9) /* ../../core/hittest */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var MarkerView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MarkerView, _super);
|
|
function MarkerView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
MarkerView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy, _size = _a._size, _angle = _a._angle;
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + _size[i] + _angle[i]))
|
|
continue;
|
|
var r = _size[i] / 2;
|
|
ctx.beginPath();
|
|
ctx.translate(sx[i], sy[i]);
|
|
if (_angle[i])
|
|
ctx.rotate(_angle[i]);
|
|
this._render_one(ctx, i, r, this.visuals.line, this.visuals.fill);
|
|
if (_angle[i])
|
|
ctx.rotate(-_angle[i]);
|
|
ctx.translate(-sx[i], -sy[i]);
|
|
}
|
|
};
|
|
MarkerView.prototype._mask_data = function () {
|
|
// dilate the inner screen region by max_size and map back to data space for use in
|
|
// spatial query
|
|
var hr = this.renderer.plot_view.frame.bbox.h_range;
|
|
var sx0 = hr.start - this.max_size;
|
|
var sx1 = hr.end + this.max_size;
|
|
var _a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
var vr = this.renderer.plot_view.frame.bbox.v_range;
|
|
var sy0 = vr.start - this.max_size;
|
|
var sy1 = vr.end + this.max_size;
|
|
var _b = this.renderer.yscale.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
return this.index.indices(bbox);
|
|
};
|
|
MarkerView.prototype._hit_point = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var sx0 = sx - this.max_size;
|
|
var sx1 = sx + this.max_size;
|
|
var _a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
var sy0 = sy - this.max_size;
|
|
var sy1 = sy + this.max_size;
|
|
var _b = this.renderer.yscale.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
var candidates = this.index.indices(bbox);
|
|
var hits = [];
|
|
for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
|
|
var i = candidates_1[_i];
|
|
var s2 = this._size[i] / 2;
|
|
var dist = Math.abs(this.sx[i] - sx) + Math.abs(this.sy[i] - sy);
|
|
if (Math.abs(this.sx[i] - sx) <= s2 && Math.abs(this.sy[i] - sy) <= s2) {
|
|
hits.push([i, dist]);
|
|
}
|
|
}
|
|
return hittest.create_hit_test_result_from_hits(hits);
|
|
};
|
|
MarkerView.prototype._hit_span = function (geometry) {
|
|
var _a, _b;
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var _c = this.bounds(), minX = _c.minX, minY = _c.minY, maxX = _c.maxX, maxY = _c.maxY;
|
|
var result = hittest.create_empty_hit_test_result();
|
|
var x0, x1;
|
|
var y0, y1;
|
|
if (geometry.direction == 'h') {
|
|
y0 = minY;
|
|
y1 = maxY;
|
|
var ms = this.max_size / 2;
|
|
var sx0 = sx - ms;
|
|
var sx1 = sx + ms;
|
|
_a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
}
|
|
else {
|
|
x0 = minX;
|
|
x1 = maxX;
|
|
var ms = this.max_size / 2;
|
|
var sy0 = sy - ms;
|
|
var sy1 = sy + ms;
|
|
_b = this.renderer.yscale.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
}
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
var hits = this.index.indices(bbox);
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
MarkerView.prototype._hit_rect = function (geometry) {
|
|
var sx0 = geometry.sx0, sx1 = geometry.sx1, sy0 = geometry.sy0, sy1 = geometry.sy1;
|
|
var _a = this.renderer.xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
var _b = this.renderer.yscale.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
var bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = this.index.indices(bbox);
|
|
return result;
|
|
};
|
|
MarkerView.prototype._hit_poly = function (geometry) {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
// TODO (bev) use spatial index to pare candidate list
|
|
var candidates = array_1.range(0, this.sx.length);
|
|
var hits = [];
|
|
for (var i = 0, end = candidates.length; i < end; i++) {
|
|
var idx = candidates[i];
|
|
if (hittest.point_in_poly(this.sx[i], this.sy[i], sx, sy))
|
|
hits.push(idx);
|
|
}
|
|
var result = hittest.create_empty_hit_test_result();
|
|
result.indices = hits;
|
|
return result;
|
|
};
|
|
MarkerView.prototype.draw_legend_for_index = function (ctx, _a, index) {
|
|
var x0 = _a.x0, x1 = _a.x1, y0 = _a.y0, y1 = _a.y1;
|
|
// using objects like this seems a little wonky, since the keys are coerced to
|
|
// stings, but it works
|
|
var len = index + 1;
|
|
var sx = new Array(len);
|
|
sx[index] = (x0 + x1) / 2;
|
|
var sy = new Array(len);
|
|
sy[index] = (y0 + y1) / 2;
|
|
var size = new Array(len);
|
|
size[index] = Math.min(Math.abs(x1 - x0), Math.abs(y1 - y0)) * 0.4;
|
|
var angle = new Array(len);
|
|
angle[index] = 0; // don't attempt to match glyph angle
|
|
this._render(ctx, [index], { sx: sx, sy: sy, _size: size, _angle: angle }); // XXX
|
|
};
|
|
return MarkerView;
|
|
}(xy_glyph_1.XYGlyphView));
|
|
exports.MarkerView = MarkerView;
|
|
var Marker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Marker, _super);
|
|
function Marker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Marker.initClass = function () {
|
|
this.mixins(['line', 'fill']);
|
|
this.define({
|
|
size: [p.DistanceSpec, { units: "screen", value: 4 }],
|
|
angle: [p.AngleSpec, 0],
|
|
});
|
|
};
|
|
return Marker;
|
|
}(xy_glyph_1.XYGlyph));
|
|
exports.Marker = Marker;
|
|
Marker.initClass();
|
|
}
|
|
,
|
|
/* models/markers/scatter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var marker_1 = require(179) /* ./marker */;
|
|
var defs_1 = require(177) /* ./defs */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var ScatterView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ScatterView, _super);
|
|
function ScatterView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ScatterView.prototype._render = function (ctx, indices, _a) {
|
|
var sx = _a.sx, sy = _a.sy, _size = _a._size, _angle = _a._angle, _marker = _a._marker;
|
|
for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
|
|
var i = indices_1[_i];
|
|
if (isNaN(sx[i] + sy[i] + _size[i] + _angle[i]) || _marker[i] == null)
|
|
continue;
|
|
var r = _size[i] / 2;
|
|
ctx.beginPath();
|
|
ctx.translate(sx[i], sy[i]);
|
|
if (_angle[i])
|
|
ctx.rotate(_angle[i]);
|
|
defs_1.marker_funcs[_marker[i]](ctx, i, r, this.visuals.line, this.visuals.fill);
|
|
if (_angle[i])
|
|
ctx.rotate(-_angle[i]);
|
|
ctx.translate(-sx[i], -sy[i]);
|
|
}
|
|
};
|
|
ScatterView.prototype.draw_legend_for_index = function (ctx, _a, index) {
|
|
var x0 = _a.x0, x1 = _a.x1, y0 = _a.y0, y1 = _a.y1;
|
|
// using objects like this seems a little wonky, since the keys are coerced to
|
|
// stings, but it works
|
|
var len = index + 1;
|
|
var sx = new Array(len);
|
|
sx[index] = (x0 + x1) / 2;
|
|
var sy = new Array(len);
|
|
sy[index] = (y0 + y1) / 2;
|
|
var size = new Array(len);
|
|
size[index] = Math.min(Math.abs(x1 - x0), Math.abs(y1 - y0)) * 0.4;
|
|
var angle = new Array(len);
|
|
angle[index] = 0; // don't attempt to match glyph angle
|
|
var marker = new Array(len);
|
|
marker[index] = this._marker[index];
|
|
this._render(ctx, [index], { sx: sx, sy: sy, _size: size, _angle: angle, _marker: marker }); // XXX
|
|
};
|
|
return ScatterView;
|
|
}(marker_1.MarkerView));
|
|
exports.ScatterView = ScatterView;
|
|
var Scatter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Scatter, _super);
|
|
function Scatter(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Scatter.initClass = function () {
|
|
this.prototype.type = 'Scatter';
|
|
this.prototype.default_view = ScatterView;
|
|
this.define({
|
|
marker: [p.MarkerSpec, { value: "circle" }],
|
|
});
|
|
};
|
|
return Scatter;
|
|
}(marker_1.Marker));
|
|
exports.Scatter = Scatter;
|
|
Scatter.initClass();
|
|
}
|
|
,
|
|
/* models/plots/gmap_plot */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var plot_1 = require(184) /* ./plot */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var range1d_1 = require(191) /* ../ranges/range1d */;
|
|
var gmap_plot_canvas_1 = require(182) /* ./gmap_plot_canvas */;
|
|
exports.GMapPlotView = gmap_plot_canvas_1.GMapPlotView;
|
|
var MapOptions = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MapOptions, _super);
|
|
function MapOptions(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
MapOptions.initClass = function () {
|
|
this.prototype.type = "MapOptions";
|
|
this.define({
|
|
lat: [p.Number],
|
|
lng: [p.Number],
|
|
zoom: [p.Number, 12],
|
|
});
|
|
};
|
|
return MapOptions;
|
|
}(model_1.Model));
|
|
exports.MapOptions = MapOptions;
|
|
MapOptions.initClass();
|
|
var GMapOptions = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GMapOptions, _super);
|
|
function GMapOptions(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
GMapOptions.initClass = function () {
|
|
this.prototype.type = "GMapOptions";
|
|
this.define({
|
|
map_type: [p.String, "roadmap"],
|
|
scale_control: [p.Boolean, false],
|
|
styles: [p.String],
|
|
tilt: [p.Int, 45],
|
|
});
|
|
};
|
|
return GMapOptions;
|
|
}(MapOptions));
|
|
exports.GMapOptions = GMapOptions;
|
|
GMapOptions.initClass();
|
|
var GMapPlot = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GMapPlot, _super);
|
|
function GMapPlot(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
GMapPlot.initClass = function () {
|
|
this.prototype.type = "GMapPlot";
|
|
this.prototype.default_view = gmap_plot_canvas_1.GMapPlotView;
|
|
// This seems to be necessary so that everything can initialize.
|
|
// Feels very clumsy, but I'm not sure how the properties system wants
|
|
// to handle something like this situation.
|
|
this.define({
|
|
map_options: [p.Instance],
|
|
api_key: [p.String],
|
|
});
|
|
this.override({
|
|
x_range: function () { return new range1d_1.Range1d(); },
|
|
y_range: function () { return new range1d_1.Range1d(); },
|
|
});
|
|
};
|
|
GMapPlot.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.use_map = true;
|
|
if (!this.api_key)
|
|
logging_1.logger.error("api_key is required. See https://developers.google.com/maps/documentation/javascript/get-api-key for more information on how to obtain your own.");
|
|
};
|
|
return GMapPlot;
|
|
}(plot_1.Plot));
|
|
exports.GMapPlot = GMapPlot;
|
|
GMapPlot.initClass();
|
|
}
|
|
,
|
|
/* models/plots/gmap_plot_canvas */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var signaling_1 = require(22) /* ../../core/signaling */;
|
|
var projections_1 = require(36) /* ../../core/util/projections */;
|
|
var plot_canvas_1 = require(185) /* ./plot_canvas */;
|
|
var gmaps_ready = new signaling_1.Signal0({}, "gmaps_ready");
|
|
var load_google_api = function (api_key) {
|
|
window._bokeh_gmaps_callback = function () { return gmaps_ready.emit(); };
|
|
var script = document.createElement('script');
|
|
script.type = 'text/javascript';
|
|
script.src = "https://maps.googleapis.com/maps/api/js?key=" + api_key + "&callback=_bokeh_gmaps_callback";
|
|
document.body.appendChild(script);
|
|
};
|
|
var GMapPlotView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GMapPlotView, _super);
|
|
function GMapPlotView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
GMapPlotView.prototype.initialize = function () {
|
|
var _this = this;
|
|
this.pause();
|
|
_super.prototype.initialize.call(this);
|
|
this._tiles_loaded = false;
|
|
this.zoom_count = 0;
|
|
var _a = this.model.map_options, zoom = _a.zoom, lat = _a.lat, lng = _a.lng;
|
|
this.initial_zoom = zoom;
|
|
this.initial_lat = lat;
|
|
this.initial_lng = lng;
|
|
this.canvas_view.map_el.style.position = "absolute";
|
|
if (typeof google === "undefined" || google.maps == null) {
|
|
if (typeof window._bokeh_gmaps_callback === "undefined") {
|
|
load_google_api(this.model.api_key);
|
|
}
|
|
gmaps_ready.connect(function () { return _this.request_render(); });
|
|
}
|
|
this.unpause();
|
|
};
|
|
GMapPlotView.prototype.update_range = function (range_info) {
|
|
// RESET -------------------------
|
|
if (range_info == null) {
|
|
this.map.setCenter({ lat: this.initial_lat, lng: this.initial_lng });
|
|
this.map.setOptions({ zoom: this.initial_zoom });
|
|
_super.prototype.update_range.call(this, null);
|
|
// PAN ----------------------------
|
|
}
|
|
else if (range_info.sdx != null || range_info.sdy != null) {
|
|
this.map.panBy(range_info.sdx || 0, range_info.sdy || 0);
|
|
_super.prototype.update_range.call(this, range_info);
|
|
// ZOOM ---------------------------
|
|
}
|
|
else if (range_info.factor != null) {
|
|
// The zoom count decreases the sensitivity of the zoom. (We could make this user configurable)
|
|
var zoom_change = void 0;
|
|
if (this.zoom_count !== 10) {
|
|
this.zoom_count += 1;
|
|
return;
|
|
}
|
|
this.zoom_count = 0;
|
|
this.pause();
|
|
_super.prototype.update_range.call(this, range_info);
|
|
if (range_info.factor < 0)
|
|
zoom_change = -1;
|
|
else
|
|
zoom_change = 1;
|
|
var old_map_zoom = this.map.getZoom();
|
|
var new_map_zoom = old_map_zoom + zoom_change;
|
|
// Zooming out too far causes problems
|
|
if (new_map_zoom >= 2) {
|
|
this.map.setZoom(new_map_zoom);
|
|
// Check we haven't gone out of bounds, and if we have undo the zoom
|
|
var _a = this._get_projected_bounds(), proj_xstart = _a[0], proj_xend = _a[1];
|
|
if (proj_xend - proj_xstart < 0) {
|
|
this.map.setZoom(old_map_zoom);
|
|
}
|
|
}
|
|
this.unpause();
|
|
}
|
|
// Finally re-center
|
|
this._set_bokeh_ranges();
|
|
};
|
|
GMapPlotView.prototype._build_map = function () {
|
|
var _this = this;
|
|
var maps = google.maps;
|
|
this.map_types = {
|
|
satellite: maps.MapTypeId.SATELLITE,
|
|
terrain: maps.MapTypeId.TERRAIN,
|
|
roadmap: maps.MapTypeId.ROADMAP,
|
|
hybrid: maps.MapTypeId.HYBRID,
|
|
};
|
|
var mo = this.model.map_options;
|
|
var map_options = {
|
|
center: new maps.LatLng(mo.lat, mo.lng),
|
|
zoom: mo.zoom,
|
|
disableDefaultUI: true,
|
|
mapTypeId: this.map_types[mo.map_type],
|
|
scaleControl: mo.scale_control,
|
|
tilt: mo.tilt,
|
|
};
|
|
if (mo.styles != null)
|
|
map_options.styles = JSON.parse(mo.styles);
|
|
// create the map with above options in div
|
|
this.map = new maps.Map(this.canvas_view.map_el, map_options);
|
|
// update bokeh ranges whenever the map idles, which should be after most UI action
|
|
maps.event.addListener(this.map, 'idle', function () { return _this._set_bokeh_ranges(); });
|
|
// also need an event when bounds change so that map resizes trigger renders too
|
|
maps.event.addListener(this.map, 'bounds_changed', function () { return _this._set_bokeh_ranges(); });
|
|
maps.event.addListenerOnce(this.map, 'tilesloaded', function () { return _this._render_finished(); });
|
|
// wire up listeners so that changes to properties are reflected
|
|
this.connect(this.model.properties.map_options.change, function () { return _this._update_options(); });
|
|
this.connect(this.model.map_options.properties.styles.change, function () { return _this._update_styles(); });
|
|
this.connect(this.model.map_options.properties.lat.change, function () { return _this._update_center('lat'); });
|
|
this.connect(this.model.map_options.properties.lng.change, function () { return _this._update_center('lng'); });
|
|
this.connect(this.model.map_options.properties.zoom.change, function () { return _this._update_zoom(); });
|
|
this.connect(this.model.map_options.properties.map_type.change, function () { return _this._update_map_type(); });
|
|
this.connect(this.model.map_options.properties.scale_control.change, function () { return _this._update_scale_control(); });
|
|
this.connect(this.model.map_options.properties.tilt.change, function () { return _this._update_tilt(); });
|
|
};
|
|
GMapPlotView.prototype._render_finished = function () {
|
|
this._tiles_loaded = true;
|
|
this.notify_finished();
|
|
};
|
|
GMapPlotView.prototype.has_finished = function () {
|
|
return _super.prototype.has_finished.call(this) && this._tiles_loaded === true;
|
|
};
|
|
GMapPlotView.prototype._get_latlon_bounds = function () {
|
|
var bounds = this.map.getBounds();
|
|
var top_right = bounds.getNorthEast();
|
|
var bottom_left = bounds.getSouthWest();
|
|
var xstart = bottom_left.lng();
|
|
var xend = top_right.lng();
|
|
var ystart = bottom_left.lat();
|
|
var yend = top_right.lat();
|
|
return [xstart, xend, ystart, yend];
|
|
};
|
|
GMapPlotView.prototype._get_projected_bounds = function () {
|
|
var _a = this._get_latlon_bounds(), xstart = _a[0], xend = _a[1], ystart = _a[2], yend = _a[3];
|
|
var _b = projections_1.wgs84_mercator.forward([xstart, ystart]), proj_xstart = _b[0], proj_ystart = _b[1];
|
|
var _c = projections_1.wgs84_mercator.forward([xend, yend]), proj_xend = _c[0], proj_yend = _c[1];
|
|
return [proj_xstart, proj_xend, proj_ystart, proj_yend];
|
|
};
|
|
GMapPlotView.prototype._set_bokeh_ranges = function () {
|
|
var _a = this._get_projected_bounds(), proj_xstart = _a[0], proj_xend = _a[1], proj_ystart = _a[2], proj_yend = _a[3];
|
|
this.frame.x_range.setv({ start: proj_xstart, end: proj_xend });
|
|
this.frame.y_range.setv({ start: proj_ystart, end: proj_yend });
|
|
};
|
|
GMapPlotView.prototype._update_center = function (fld) {
|
|
var c = this.map.getCenter().toJSON();
|
|
c[fld] = this.model.map_options[fld];
|
|
this.map.setCenter(c);
|
|
this._set_bokeh_ranges();
|
|
};
|
|
GMapPlotView.prototype._update_map_type = function () {
|
|
this.map.setOptions({ mapTypeId: this.map_types[this.model.map_options.map_type] });
|
|
};
|
|
GMapPlotView.prototype._update_scale_control = function () {
|
|
this.map.setOptions({ scaleControl: this.model.map_options.scale_control });
|
|
};
|
|
GMapPlotView.prototype._update_tilt = function () {
|
|
this.map.setOptions({ tilt: this.model.map_options.tilt });
|
|
};
|
|
GMapPlotView.prototype._update_options = function () {
|
|
this._update_styles();
|
|
this._update_center('lat');
|
|
this._update_center('lng');
|
|
this._update_zoom();
|
|
this._update_map_type();
|
|
};
|
|
GMapPlotView.prototype._update_styles = function () {
|
|
this.map.setOptions({ styles: JSON.parse(this.model.map_options.styles) });
|
|
};
|
|
GMapPlotView.prototype._update_zoom = function () {
|
|
this.map.setOptions({ zoom: this.model.map_options.zoom });
|
|
this._set_bokeh_ranges();
|
|
};
|
|
// this method is expected and called by PlotView.render
|
|
GMapPlotView.prototype._map_hook = function (_ctx, frame_box) {
|
|
var left = frame_box[0], top = frame_box[1], width = frame_box[2], height = frame_box[3];
|
|
this.canvas_view.map_el.style.top = top + "px";
|
|
this.canvas_view.map_el.style.left = left + "px";
|
|
this.canvas_view.map_el.style.width = width + "px";
|
|
this.canvas_view.map_el.style.height = height + "px";
|
|
if (this.map == null && typeof google !== "undefined" && google.maps != null)
|
|
this._build_map();
|
|
};
|
|
// this overrides the standard _paint_empty to make the inner canvas transparent
|
|
GMapPlotView.prototype._paint_empty = function (ctx, frame_box) {
|
|
var ow = this.layout._width.value;
|
|
var oh = this.layout._height.value;
|
|
var left = frame_box[0], top = frame_box[1], iw = frame_box[2], ih = frame_box[3];
|
|
ctx.clearRect(0, 0, ow, oh);
|
|
ctx.beginPath();
|
|
ctx.moveTo(0, 0);
|
|
ctx.lineTo(0, oh);
|
|
ctx.lineTo(ow, oh);
|
|
ctx.lineTo(ow, 0);
|
|
ctx.lineTo(0, 0);
|
|
ctx.moveTo(left, top);
|
|
ctx.lineTo(left + iw, top);
|
|
ctx.lineTo(left + iw, top + ih);
|
|
ctx.lineTo(left, top + ih);
|
|
ctx.lineTo(left, top);
|
|
ctx.closePath();
|
|
if (this.model.border_fill_color != null) {
|
|
ctx.fillStyle = this.model.border_fill_color;
|
|
ctx.fill();
|
|
}
|
|
};
|
|
return GMapPlotView;
|
|
}(plot_canvas_1.PlotView));
|
|
exports.GMapPlotView = GMapPlotView;
|
|
}
|
|
,
|
|
/* models/plots/index */ function _(require, module, exports) {
|
|
var gmap_plot_1 = require(181) /* ./gmap_plot */;
|
|
exports.MapOptions = gmap_plot_1.MapOptions;
|
|
var gmap_plot_2 = require(181) /* ./gmap_plot */;
|
|
exports.GMapOptions = gmap_plot_2.GMapOptions;
|
|
var gmap_plot_3 = require(181) /* ./gmap_plot */;
|
|
exports.GMapPlot = gmap_plot_3.GMapPlot;
|
|
var plot_1 = require(184) /* ./plot */;
|
|
exports.Plot = plot_1.Plot;
|
|
}
|
|
,
|
|
/* models/plots/plot */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var signaling_1 = require(22) /* ../../core/signaling */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var layout_dom_1 = require(163) /* ../layouts/layout_dom */;
|
|
var title_1 = require(78) /* ../annotations/title */;
|
|
var linear_scale_1 = require(200) /* ../scales/linear_scale */;
|
|
var toolbar_1 = require(278) /* ../tools/toolbar */;
|
|
var column_data_source_1 = require(208) /* ../sources/column_data_source */;
|
|
var glyph_renderer_1 = require(193) /* ../renderers/glyph_renderer */;
|
|
var data_range1d_1 = require(187) /* ../ranges/data_range1d */;
|
|
var plot_canvas_1 = require(185) /* ./plot_canvas */;
|
|
exports.PlotView = plot_canvas_1.PlotView;
|
|
var Plot = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Plot, _super);
|
|
function Plot(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Plot.initClass = function () {
|
|
this.prototype.type = "Plot";
|
|
this.prototype.default_view = plot_canvas_1.PlotView;
|
|
this.mixins(["line:outline_", "fill:background_", "fill:border_"]);
|
|
this.define({
|
|
toolbar: [p.Instance, function () { return new toolbar_1.Toolbar(); }],
|
|
toolbar_location: [p.Location, 'right'],
|
|
toolbar_sticky: [p.Boolean, true],
|
|
plot_width: [p.Number, 600],
|
|
plot_height: [p.Number, 600],
|
|
frame_width: [p.Number, null],
|
|
frame_height: [p.Number, null],
|
|
title: [p.Any, function () { return new title_1.Title({ text: "" }); }],
|
|
title_location: [p.Location, 'above'],
|
|
above: [p.Array, []],
|
|
below: [p.Array, []],
|
|
left: [p.Array, []],
|
|
right: [p.Array, []],
|
|
center: [p.Array, []],
|
|
renderers: [p.Array, []],
|
|
x_range: [p.Instance, function () { return new data_range1d_1.DataRange1d(); }],
|
|
extra_x_ranges: [p.Any, {}],
|
|
y_range: [p.Instance, function () { return new data_range1d_1.DataRange1d(); }],
|
|
extra_y_ranges: [p.Any, {}],
|
|
x_scale: [p.Instance, function () { return new linear_scale_1.LinearScale(); }],
|
|
y_scale: [p.Instance, function () { return new linear_scale_1.LinearScale(); }],
|
|
lod_factor: [p.Number, 10],
|
|
lod_interval: [p.Number, 300],
|
|
lod_threshold: [p.Number, 2000],
|
|
lod_timeout: [p.Number, 500],
|
|
hidpi: [p.Boolean, true],
|
|
output_backend: [p.OutputBackend, "canvas"],
|
|
min_border: [p.Number, 5],
|
|
min_border_top: [p.Number, null],
|
|
min_border_left: [p.Number, null],
|
|
min_border_bottom: [p.Number, null],
|
|
min_border_right: [p.Number, null],
|
|
inner_width: [p.Number],
|
|
inner_height: [p.Number],
|
|
outer_width: [p.Number],
|
|
outer_height: [p.Number],
|
|
match_aspect: [p.Boolean, false],
|
|
aspect_scale: [p.Number, 1],
|
|
});
|
|
this.override({
|
|
outline_line_color: "#e5e5e5",
|
|
border_fill_color: "#ffffff",
|
|
background_fill_color: "#ffffff",
|
|
});
|
|
};
|
|
Object.defineProperty(Plot.prototype, "width", {
|
|
get: function () {
|
|
var width = this.getv("width");
|
|
return width != null ? width : this.plot_width;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(Plot.prototype, "height", {
|
|
get: function () {
|
|
var height = this.getv("height");
|
|
return height != null ? height : this.plot_height;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Plot.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.reset = new signaling_1.Signal0(this, "reset");
|
|
for (var _i = 0, _a = object_1.values(this.extra_x_ranges).concat(this.x_range); _i < _a.length; _i++) {
|
|
var xr = _a[_i];
|
|
var plots = xr.plots;
|
|
if (types_1.isArray(plots)) {
|
|
plots = plots.concat(this);
|
|
xr.setv({ plots: plots }, { silent: true });
|
|
}
|
|
}
|
|
for (var _b = 0, _c = object_1.values(this.extra_y_ranges).concat(this.y_range); _b < _c.length; _b++) {
|
|
var yr = _c[_b];
|
|
var plots = yr.plots;
|
|
if (types_1.isArray(plots)) {
|
|
plots = plots.concat(this);
|
|
yr.setv({ plots: plots }, { silent: true });
|
|
}
|
|
}
|
|
};
|
|
Plot.prototype.add_layout = function (renderer, side) {
|
|
if (side === void 0) {
|
|
side = "center";
|
|
}
|
|
var side_renderers = this.getv(side);
|
|
side_renderers.push(renderer /* XXX */);
|
|
};
|
|
Plot.prototype.remove_layout = function (renderer) {
|
|
var del = function (items) {
|
|
array_1.remove_by(items, function (item) { return item == renderer; });
|
|
};
|
|
del(this.left);
|
|
del(this.right);
|
|
del(this.above);
|
|
del(this.below);
|
|
del(this.center);
|
|
};
|
|
Plot.prototype.add_renderers = function () {
|
|
var renderers = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
renderers[_i] = arguments[_i];
|
|
}
|
|
this.renderers = this.renderers.concat(renderers);
|
|
};
|
|
Plot.prototype.add_glyph = function (glyph, source, extra_attrs) {
|
|
if (source === void 0) {
|
|
source = new column_data_source_1.ColumnDataSource();
|
|
}
|
|
if (extra_attrs === void 0) {
|
|
extra_attrs = {};
|
|
}
|
|
var attrs = tslib_1.__assign({}, extra_attrs, { data_source: source, glyph: glyph });
|
|
var renderer = new glyph_renderer_1.GlyphRenderer(attrs);
|
|
this.add_renderers(renderer);
|
|
return renderer;
|
|
};
|
|
Plot.prototype.add_tools = function () {
|
|
var tools = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
tools[_i] = arguments[_i];
|
|
}
|
|
this.toolbar.tools = this.toolbar.tools.concat(tools);
|
|
};
|
|
Object.defineProperty(Plot.prototype, "panels", {
|
|
get: function () {
|
|
return this.side_panels.concat(this.center);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(Plot.prototype, "side_panels", {
|
|
get: function () {
|
|
var _a = this, above = _a.above, below = _a.below, left = _a.left, right = _a.right;
|
|
return array_1.concat([above, below, left, right]);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return Plot;
|
|
}(layout_dom_1.LayoutDOM));
|
|
exports.Plot = Plot;
|
|
Plot.initClass();
|
|
}
|
|
,
|
|
/* models/plots/plot_canvas */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var cartesian_frame_1 = require(95) /* ../canvas/cartesian_frame */;
|
|
var canvas_1 = require(94) /* ../canvas/canvas */;
|
|
var data_range1d_1 = require(187) /* ../ranges/data_range1d */;
|
|
var glyph_renderer_1 = require(193) /* ../renderers/glyph_renderer */;
|
|
var layout_dom_1 = require(163) /* ../layouts/layout_dom */;
|
|
var title_1 = require(78) /* ../annotations/title */;
|
|
var axis_1 = require(82) /* ../axes/axis */;
|
|
var toolbar_panel_1 = require(79) /* ../annotations/toolbar_panel */;
|
|
var bokeh_events_1 = require(3) /* ../../core/bokeh_events */;
|
|
var signaling_1 = require(22) /* ../../core/signaling */;
|
|
var build_views_1 = require(4) /* ../../core/build_views */;
|
|
var visuals_1 = require(51) /* ../../core/visuals */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var throttle_1 = require(44) /* ../../core/util/throttle */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var layout_1 = require(13) /* ../../core/layout */;
|
|
var alignments_1 = require(10) /* ../../core/layout/alignments */;
|
|
var side_panel_1 = require(15) /* ../../core/layout/side_panel */;
|
|
var grid_1 = require(11) /* ../../core/layout/grid */;
|
|
var bbox_1 = require(27) /* ../../core/util/bbox */;
|
|
var global_gl = null;
|
|
var PlotLayout = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PlotLayout, _super);
|
|
function PlotLayout() {
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
_this.min_border = { left: 0, top: 0, right: 0, bottom: 0 };
|
|
return _this;
|
|
}
|
|
PlotLayout.prototype._measure = function (viewport) {
|
|
var _this = this;
|
|
viewport = new layout_1.Sizeable(viewport).bounded_to(this.sizing.size);
|
|
var left_hint = this.left_panel.measure({ width: 0, height: viewport.height });
|
|
var left = Math.max(left_hint.width, this.min_border.left);
|
|
var right_hint = this.right_panel.measure({ width: 0, height: viewport.height });
|
|
var right = Math.max(right_hint.width, this.min_border.right);
|
|
var top_hint = this.top_panel.measure({ width: viewport.width, height: 0 });
|
|
var top = Math.max(top_hint.height, this.min_border.top);
|
|
var bottom_hint = this.bottom_panel.measure({ width: viewport.width, height: 0 });
|
|
var bottom = Math.max(bottom_hint.height, this.min_border.bottom);
|
|
var center_viewport = new layout_1.Sizeable(viewport).shrink_by({ left: left, right: right, top: top, bottom: bottom });
|
|
var center = this.center_panel.measure(center_viewport);
|
|
var width = left + center.width + right;
|
|
var height = top + center.height + bottom;
|
|
var align = (function () {
|
|
var _a = _this.center_panel.sizing, width_policy = _a.width_policy, height_policy = _a.height_policy;
|
|
return width_policy != "fixed" && height_policy != "fixed";
|
|
})();
|
|
return { width: width, height: height, inner: { left: left, right: right, top: top, bottom: bottom }, align: align };
|
|
};
|
|
PlotLayout.prototype._set_geometry = function (outer, inner) {
|
|
_super.prototype._set_geometry.call(this, outer, inner);
|
|
this.center_panel.set_geometry(inner);
|
|
var left_hint = this.left_panel.measure({ width: 0, height: outer.height });
|
|
var right_hint = this.right_panel.measure({ width: 0, height: outer.height });
|
|
var top_hint = this.top_panel.measure({ width: outer.width, height: 0 });
|
|
var bottom_hint = this.bottom_panel.measure({ width: outer.width, height: 0 });
|
|
var left = inner.left, top = inner.top, right = inner.right, bottom = inner.bottom;
|
|
this.top_panel.set_geometry(new bbox_1.BBox({ left: left, right: right, bottom: top, height: top_hint.height }));
|
|
this.bottom_panel.set_geometry(new bbox_1.BBox({ left: left, right: right, top: bottom, height: bottom_hint.height }));
|
|
this.left_panel.set_geometry(new bbox_1.BBox({ top: top, bottom: bottom, right: left, width: left_hint.width }));
|
|
this.right_panel.set_geometry(new bbox_1.BBox({ top: top, bottom: bottom, left: right, width: right_hint.width }));
|
|
};
|
|
return PlotLayout;
|
|
}(layout_1.Layoutable));
|
|
exports.PlotLayout = PlotLayout;
|
|
var PlotView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PlotView, _super);
|
|
function PlotView() {
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
_this._outer_bbox = new bbox_1.BBox();
|
|
_this._inner_bbox = new bbox_1.BBox();
|
|
_this._needs_paint = true;
|
|
_this._needs_layout = false;
|
|
return _this;
|
|
}
|
|
Object.defineProperty(PlotView.prototype, "canvas_overlays", {
|
|
get: function () {
|
|
return this.canvas_view.overlays_el;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(PlotView.prototype, "canvas_events", {
|
|
get: function () {
|
|
return this.canvas_view.events_el;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(PlotView.prototype, "is_paused", {
|
|
get: function () {
|
|
return this._is_paused != null && this._is_paused !== 0;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(PlotView.prototype, "child_models", {
|
|
get: function () {
|
|
return [];
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
PlotView.prototype.pause = function () {
|
|
if (this._is_paused == null)
|
|
this._is_paused = 1;
|
|
else
|
|
this._is_paused += 1;
|
|
};
|
|
PlotView.prototype.unpause = function (no_render) {
|
|
if (no_render === void 0) {
|
|
no_render = false;
|
|
}
|
|
if (this._is_paused == null)
|
|
throw new Error("wasn't paused");
|
|
this._is_paused -= 1;
|
|
if (this._is_paused == 0 && !no_render)
|
|
this.request_paint();
|
|
};
|
|
// TODO: this needs to be removed
|
|
PlotView.prototype.request_render = function () {
|
|
this.request_paint();
|
|
};
|
|
PlotView.prototype.request_paint = function () {
|
|
if (!this.is_paused)
|
|
this.throttled_paint();
|
|
};
|
|
PlotView.prototype.request_layout = function () {
|
|
this._needs_layout = true;
|
|
this.request_paint();
|
|
};
|
|
PlotView.prototype.reset = function () {
|
|
this.clear_state();
|
|
this.reset_range();
|
|
this.reset_selection();
|
|
this.model.trigger_event(new bokeh_events_1.Reset());
|
|
};
|
|
PlotView.prototype.remove = function () {
|
|
this.ui_event_bus.destroy();
|
|
build_views_1.remove_views(this.renderer_views);
|
|
build_views_1.remove_views(this.tool_views);
|
|
this.canvas_view.remove();
|
|
_super.prototype.remove.call(this);
|
|
};
|
|
PlotView.prototype.render = function () {
|
|
_super.prototype.render.call(this);
|
|
this.el.appendChild(this.canvas_view.el);
|
|
this.canvas_view.render();
|
|
};
|
|
PlotView.prototype.initialize = function () {
|
|
var _this = this;
|
|
this.pause();
|
|
_super.prototype.initialize.call(this);
|
|
this.force_paint = new signaling_1.Signal0(this, "force_paint");
|
|
this.state_changed = new signaling_1.Signal0(this, "state_changed");
|
|
this.lod_started = false;
|
|
this.visuals = new visuals_1.Visuals(this.model); // XXX
|
|
this._initial_state_info = {
|
|
selection: {},
|
|
dimensions: { width: 0, height: 0 },
|
|
};
|
|
this.visibility_callbacks = [];
|
|
this.state = { history: [], index: -1 };
|
|
this.canvas = new canvas_1.Canvas({
|
|
map: this.model.use_map || false,
|
|
use_hidpi: this.model.hidpi,
|
|
output_backend: this.model.output_backend,
|
|
});
|
|
this.frame = new cartesian_frame_1.CartesianFrame(this.model.x_scale, this.model.y_scale, this.model.x_range, this.model.y_range, this.model.extra_x_ranges, this.model.extra_y_ranges);
|
|
this.canvas_view = new this.canvas.default_view({ model: this.canvas, parent: this });
|
|
// If requested, try enabling webgl
|
|
if (this.model.output_backend == "webgl")
|
|
this.init_webgl();
|
|
this.throttled_paint = throttle_1.throttle((function () { return _this.force_paint.emit(); }), 15); // TODO (bev) configurable
|
|
// XXX: lazy value import to avoid touching window
|
|
var UIEvents = require(23) /* ../../core/ui_events */.UIEvents;
|
|
this.ui_event_bus = new UIEvents(this, this.model.toolbar, this.canvas_view.events_el);
|
|
var _a = this.model, title_location = _a.title_location, title = _a.title;
|
|
if (title_location != null && title != null) {
|
|
this._title = title instanceof title_1.Title ? title : new title_1.Title({ text: title });
|
|
}
|
|
var _b = this.model, toolbar_location = _b.toolbar_location, toolbar = _b.toolbar;
|
|
if (toolbar_location != null && toolbar != null) {
|
|
this._toolbar = new toolbar_panel_1.ToolbarPanel({ toolbar: toolbar });
|
|
toolbar.toolbar_location = toolbar_location;
|
|
}
|
|
this.renderer_views = {};
|
|
this.tool_views = {};
|
|
this.build_renderer_views();
|
|
this.build_tool_views();
|
|
this.update_dataranges();
|
|
this.unpause(true);
|
|
logging_1.logger.debug("PlotView initialized");
|
|
};
|
|
PlotView.prototype._width_policy = function () {
|
|
return this.model.frame_width == null ? _super.prototype._width_policy.call(this) : "min";
|
|
};
|
|
PlotView.prototype._height_policy = function () {
|
|
return this.model.frame_height == null ? _super.prototype._height_policy.call(this) : "min";
|
|
};
|
|
PlotView.prototype._update_layout = function () {
|
|
var _this = this;
|
|
this.layout = new PlotLayout();
|
|
this.layout.set_sizing(this.box_sizing());
|
|
var _a = this.model, frame_width = _a.frame_width, frame_height = _a.frame_height;
|
|
this.layout.center_panel = this.frame;
|
|
this.layout.center_panel.set_sizing(tslib_1.__assign({}, (frame_width != null ? { width_policy: "fixed", width: frame_width } : { width_policy: "fit" }), (frame_height != null ? { height_policy: "fixed", height: frame_height } : { height_policy: "fit" })));
|
|
var above = array_1.copy(this.model.above);
|
|
var below = array_1.copy(this.model.below);
|
|
var left = array_1.copy(this.model.left);
|
|
var right = array_1.copy(this.model.right);
|
|
var get_side = function (side) {
|
|
switch (side) {
|
|
case "above": return above;
|
|
case "below": return below;
|
|
case "left": return left;
|
|
case "right": return right;
|
|
}
|
|
};
|
|
var _b = this.model, title_location = _b.title_location, title = _b.title;
|
|
if (title_location != null && title != null) {
|
|
get_side(title_location).push(this._title);
|
|
}
|
|
var _c = this.model, toolbar_location = _c.toolbar_location, toolbar = _c.toolbar;
|
|
if (toolbar_location != null && toolbar != null) {
|
|
var panels = get_side(toolbar_location);
|
|
var push_toolbar = true;
|
|
if (this.model.toolbar_sticky) {
|
|
for (var i = 0; i < panels.length; i++) {
|
|
var panel = panels[i];
|
|
if (panel instanceof title_1.Title) {
|
|
if (toolbar_location == "above" || toolbar_location == "below")
|
|
panels[i] = [panel, this._toolbar];
|
|
else
|
|
panels[i] = [this._toolbar, panel];
|
|
push_toolbar = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (push_toolbar)
|
|
panels.push(this._toolbar);
|
|
}
|
|
var set_layout = function (side, model) {
|
|
var view = _this.renderer_views[model.id];
|
|
return view.layout = new side_panel_1.SidePanel(side, view);
|
|
};
|
|
var set_layouts = function (side, panels) {
|
|
var horizontal = side == "above" || side == "below";
|
|
var layouts = [];
|
|
for (var _i = 0, panels_1 = panels; _i < panels_1.length; _i++) {
|
|
var panel = panels_1[_i];
|
|
if (types_1.isArray(panel)) {
|
|
var items = panel.map(function (subpanel) {
|
|
var _a;
|
|
var item = set_layout(side, subpanel);
|
|
if (subpanel instanceof toolbar_panel_1.ToolbarPanel) {
|
|
var dim = horizontal ? "width_policy" : "height_policy";
|
|
item.set_sizing(tslib_1.__assign({}, item.sizing, (_a = {}, _a[dim] = "min", _a)));
|
|
}
|
|
return item;
|
|
});
|
|
var layout = void 0;
|
|
if (horizontal) {
|
|
layout = new grid_1.Row(items);
|
|
layout.set_sizing({ width_policy: "max", height_policy: "min" });
|
|
}
|
|
else {
|
|
layout = new grid_1.Column(items);
|
|
layout.set_sizing({ width_policy: "min", height_policy: "max" });
|
|
}
|
|
layout.absolute = true;
|
|
layouts.push(layout);
|
|
}
|
|
else
|
|
layouts.push(set_layout(side, panel));
|
|
}
|
|
return layouts;
|
|
};
|
|
var min_border = this.model.min_border != null ? this.model.min_border : 0;
|
|
this.layout.min_border = {
|
|
left: this.model.min_border_left != null ? this.model.min_border_left : min_border,
|
|
top: this.model.min_border_top != null ? this.model.min_border_top : min_border,
|
|
right: this.model.min_border_right != null ? this.model.min_border_right : min_border,
|
|
bottom: this.model.min_border_bottom != null ? this.model.min_border_bottom : min_border,
|
|
};
|
|
var top_panel = new alignments_1.VStack();
|
|
var bottom_panel = new alignments_1.VStack();
|
|
var left_panel = new alignments_1.HStack();
|
|
var right_panel = new alignments_1.HStack();
|
|
top_panel.children = array_1.reversed(set_layouts("above", above));
|
|
bottom_panel.children = set_layouts("below", below);
|
|
left_panel.children = array_1.reversed(set_layouts("left", left));
|
|
right_panel.children = set_layouts("right", right);
|
|
top_panel.set_sizing({ width_policy: "fit", height_policy: "min" /*, min_height: this.layout.min_border.top*/ });
|
|
bottom_panel.set_sizing({ width_policy: "fit", height_policy: "min" /*, min_height: this.layout.min_width.bottom*/ });
|
|
left_panel.set_sizing({ width_policy: "min", height_policy: "fit" /*, min_width: this.layout.min_width.left*/ });
|
|
right_panel.set_sizing({ width_policy: "min", height_policy: "fit" /*, min_width: this.layout.min_width.right*/ });
|
|
this.layout.top_panel = top_panel;
|
|
this.layout.bottom_panel = bottom_panel;
|
|
this.layout.left_panel = left_panel;
|
|
this.layout.right_panel = right_panel;
|
|
};
|
|
Object.defineProperty(PlotView.prototype, "axis_views", {
|
|
get: function () {
|
|
var views = [];
|
|
for (var id in this.renderer_views) {
|
|
var child_view = this.renderer_views[id];
|
|
if (child_view instanceof axis_1.AxisView)
|
|
views.push(child_view);
|
|
}
|
|
return views;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
PlotView.prototype.set_cursor = function (cursor) {
|
|
if (cursor === void 0) {
|
|
cursor = "default";
|
|
}
|
|
this.canvas_view.el.style.cursor = cursor;
|
|
};
|
|
PlotView.prototype.set_toolbar_visibility = function (visible) {
|
|
for (var _i = 0, _a = this.visibility_callbacks; _i < _a.length; _i++) {
|
|
var callback = _a[_i];
|
|
callback(visible);
|
|
}
|
|
};
|
|
PlotView.prototype.init_webgl = function () {
|
|
// We use a global invisible canvas and gl context. By having a global context,
|
|
// we avoid the limitation of max 16 contexts that most browsers have.
|
|
if (global_gl == null) {
|
|
var canvas = document.createElement('canvas');
|
|
var opts = { premultipliedAlpha: true };
|
|
var ctx = canvas.getContext("webgl", opts) || canvas.getContext("experimental-webgl", opts);
|
|
// If WebGL is available, we store a reference to the gl canvas on
|
|
// the ctx object, because that's what gets passed everywhere.
|
|
if (ctx != null)
|
|
global_gl = { canvas: canvas, ctx: ctx };
|
|
}
|
|
if (global_gl != null)
|
|
this.gl = global_gl;
|
|
else
|
|
logging_1.logger.warn('WebGL is not supported, falling back to 2D canvas.');
|
|
};
|
|
PlotView.prototype.prepare_webgl = function (ratio, frame_box) {
|
|
// Prepare WebGL for a drawing pass
|
|
if (this.gl != null) {
|
|
var canvas = this.canvas_view.get_canvas_element();
|
|
// Sync canvas size
|
|
this.gl.canvas.width = canvas.width;
|
|
this.gl.canvas.height = canvas.height;
|
|
// Prepare GL for drawing
|
|
var gl = this.gl.ctx;
|
|
gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);
|
|
gl.clearColor(0, 0, 0, 0);
|
|
gl.clear(gl.COLOR_BUFFER_BIT || gl.DEPTH_BUFFER_BIT);
|
|
// Clipping
|
|
gl.enable(gl.SCISSOR_TEST);
|
|
var sx = frame_box[0], sy = frame_box[1], w = frame_box[2], h = frame_box[3];
|
|
var _a = this.canvas_view.bbox, xview = _a.xview, yview = _a.yview;
|
|
var vx = xview.compute(sx);
|
|
var vy = yview.compute(sy + h);
|
|
gl.scissor(ratio * vx, ratio * vy, ratio * w, ratio * h); // lower left corner, width, height
|
|
// Setup blending
|
|
gl.enable(gl.BLEND);
|
|
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE_MINUS_DST_ALPHA, gl.ONE); // premultipliedAlpha == true
|
|
}
|
|
};
|
|
//gl.blendFuncSeparate(gl.ONE_MINUS_DST_ALPHA, gl.DST_ALPHA, gl.ONE_MINUS_DST_ALPHA, gl.ONE) # Without premultipliedAlpha == false
|
|
PlotView.prototype.blit_webgl = function (ratio) {
|
|
// This should be called when the ctx has no state except the HIDPI transform
|
|
var ctx = this.canvas_view.ctx;
|
|
if (this.gl != null) {
|
|
// Blit gl canvas into the 2D canvas. To do 1-on-1 blitting, we need
|
|
// to remove the hidpi transform, then blit, then restore.
|
|
// ctx.globalCompositeOperation = "source-over" -> OK; is the default
|
|
logging_1.logger.debug('drawing with WebGL');
|
|
ctx.restore();
|
|
ctx.drawImage(this.gl.canvas, 0, 0);
|
|
// Set back hidpi transform
|
|
ctx.save();
|
|
ctx.scale(ratio, ratio);
|
|
ctx.translate(0.5, 0.5);
|
|
}
|
|
};
|
|
PlotView.prototype.update_dataranges = function () {
|
|
// Update any DataRange1ds here
|
|
var bounds = {};
|
|
var log_bounds = {};
|
|
var calculate_log_bounds = false;
|
|
for (var _i = 0, _a = object_1.values(this.frame.x_ranges).concat(object_1.values(this.frame.y_ranges)); _i < _a.length; _i++) {
|
|
var r_1 = _a[_i];
|
|
if (r_1 instanceof data_range1d_1.DataRange1d) {
|
|
if (r_1.scale_hint == "log")
|
|
calculate_log_bounds = true;
|
|
}
|
|
}
|
|
for (var id in this.renderer_views) {
|
|
var view = this.renderer_views[id];
|
|
if (view instanceof glyph_renderer_1.GlyphRendererView) {
|
|
var bds = view.glyph.bounds();
|
|
if (bds != null)
|
|
bounds[id] = bds;
|
|
if (calculate_log_bounds) {
|
|
var log_bds = view.glyph.log_bounds();
|
|
if (log_bds != null)
|
|
log_bounds[id] = log_bds;
|
|
}
|
|
}
|
|
}
|
|
var follow_enabled = false;
|
|
var has_bounds = false;
|
|
var _b = this.frame.bbox, width = _b.width, height = _b.height;
|
|
var r;
|
|
if (this.model.match_aspect !== false && width != 0 && height != 0)
|
|
r = (1 / this.model.aspect_scale) * (width / height);
|
|
for (var _c = 0, _d = object_1.values(this.frame.x_ranges); _c < _d.length; _c++) {
|
|
var xr = _d[_c];
|
|
if (xr instanceof data_range1d_1.DataRange1d) {
|
|
var bounds_to_use = xr.scale_hint == "log" ? log_bounds : bounds;
|
|
xr.update(bounds_to_use, 0, this.model.id, r);
|
|
if (xr.follow) {
|
|
follow_enabled = true;
|
|
}
|
|
}
|
|
if (xr.bounds != null)
|
|
has_bounds = true;
|
|
}
|
|
for (var _e = 0, _f = object_1.values(this.frame.y_ranges); _e < _f.length; _e++) {
|
|
var yr = _f[_e];
|
|
if (yr instanceof data_range1d_1.DataRange1d) {
|
|
var bounds_to_use = yr.scale_hint == "log" ? log_bounds : bounds;
|
|
yr.update(bounds_to_use, 1, this.model.id, r);
|
|
if (yr.follow) {
|
|
follow_enabled = true;
|
|
}
|
|
}
|
|
if (yr.bounds != null)
|
|
has_bounds = true;
|
|
}
|
|
if (follow_enabled && has_bounds) {
|
|
logging_1.logger.warn('Follow enabled so bounds are unset.');
|
|
for (var _g = 0, _h = object_1.values(this.frame.x_ranges); _g < _h.length; _g++) {
|
|
var xr = _h[_g];
|
|
xr.bounds = null;
|
|
}
|
|
for (var _j = 0, _k = object_1.values(this.frame.y_ranges); _j < _k.length; _j++) {
|
|
var yr = _k[_j];
|
|
yr.bounds = null;
|
|
}
|
|
}
|
|
this.range_update_timestamp = Date.now();
|
|
};
|
|
PlotView.prototype.map_to_screen = function (x, y, x_name, y_name) {
|
|
if (x_name === void 0) {
|
|
x_name = "default";
|
|
}
|
|
if (y_name === void 0) {
|
|
y_name = "default";
|
|
}
|
|
return this.frame.map_to_screen(x, y, x_name, y_name);
|
|
};
|
|
PlotView.prototype.push_state = function (type, new_info) {
|
|
var _a = this.state, history = _a.history, index = _a.index;
|
|
var prev_info = history[index] != null ? history[index].info : {};
|
|
var info = tslib_1.__assign({}, this._initial_state_info, prev_info, new_info);
|
|
this.state.history = this.state.history.slice(0, this.state.index + 1);
|
|
this.state.history.push({ type: type, info: info });
|
|
this.state.index = this.state.history.length - 1;
|
|
this.state_changed.emit();
|
|
};
|
|
PlotView.prototype.clear_state = function () {
|
|
this.state = { history: [], index: -1 };
|
|
this.state_changed.emit();
|
|
};
|
|
PlotView.prototype.can_undo = function () {
|
|
return this.state.index >= 0;
|
|
};
|
|
PlotView.prototype.can_redo = function () {
|
|
return this.state.index < this.state.history.length - 1;
|
|
};
|
|
PlotView.prototype.undo = function () {
|
|
if (this.can_undo()) {
|
|
this.state.index -= 1;
|
|
this._do_state_change(this.state.index);
|
|
this.state_changed.emit();
|
|
}
|
|
};
|
|
PlotView.prototype.redo = function () {
|
|
if (this.can_redo()) {
|
|
this.state.index += 1;
|
|
this._do_state_change(this.state.index);
|
|
this.state_changed.emit();
|
|
}
|
|
};
|
|
PlotView.prototype._do_state_change = function (index) {
|
|
var info = this.state.history[index] != null ? this.state.history[index].info : this._initial_state_info;
|
|
if (info.range != null)
|
|
this.update_range(info.range);
|
|
if (info.selection != null)
|
|
this.update_selection(info.selection);
|
|
};
|
|
PlotView.prototype.get_selection = function () {
|
|
var selection = {};
|
|
for (var _i = 0, _a = this.model.renderers; _i < _a.length; _i++) {
|
|
var renderer = _a[_i];
|
|
if (renderer instanceof glyph_renderer_1.GlyphRenderer) {
|
|
var selected = renderer.data_source.selected;
|
|
selection[renderer.id] = selected;
|
|
}
|
|
}
|
|
return selection;
|
|
};
|
|
PlotView.prototype.update_selection = function (selection) {
|
|
for (var _i = 0, _a = this.model.renderers; _i < _a.length; _i++) {
|
|
var renderer = _a[_i];
|
|
if (!(renderer instanceof glyph_renderer_1.GlyphRenderer))
|
|
continue;
|
|
var ds = renderer.data_source;
|
|
if (selection != null) {
|
|
if (selection[renderer.id] != null)
|
|
ds.selected.update(selection[renderer.id], true, false);
|
|
}
|
|
else
|
|
ds.selection_manager.clear();
|
|
}
|
|
};
|
|
PlotView.prototype.reset_selection = function () {
|
|
this.update_selection(null);
|
|
};
|
|
PlotView.prototype._update_ranges_together = function (range_info_iter) {
|
|
// Get weight needed to scale the diff of the range to honor interval limits
|
|
var weight = 1.0;
|
|
for (var _i = 0, range_info_iter_1 = range_info_iter; _i < range_info_iter_1.length; _i++) {
|
|
var _a = range_info_iter_1[_i], rng = _a[0], range_info = _a[1];
|
|
weight = Math.min(weight, this._get_weight_to_constrain_interval(rng, range_info));
|
|
}
|
|
// Apply shared weight to all ranges
|
|
if (weight < 1) {
|
|
for (var _b = 0, range_info_iter_2 = range_info_iter; _b < range_info_iter_2.length; _b++) {
|
|
var _c = range_info_iter_2[_b], rng = _c[0], range_info = _c[1];
|
|
range_info.start = weight * range_info.start + (1 - weight) * rng.start;
|
|
range_info.end = weight * range_info.end + (1 - weight) * rng.end;
|
|
}
|
|
}
|
|
};
|
|
PlotView.prototype._update_ranges_individually = function (range_info_iter, is_panning, is_scrolling, maintain_focus) {
|
|
var hit_bound = false;
|
|
for (var _i = 0, range_info_iter_3 = range_info_iter; _i < range_info_iter_3.length; _i++) {
|
|
var _a = range_info_iter_3[_i], rng = _a[0], range_info = _a[1];
|
|
// Limit range interval first. Note that for scroll events,
|
|
// the interval has already been limited for all ranges simultaneously
|
|
if (!is_scrolling) {
|
|
var weight = this._get_weight_to_constrain_interval(rng, range_info);
|
|
if (weight < 1) {
|
|
range_info.start = weight * range_info.start + (1 - weight) * rng.start;
|
|
range_info.end = weight * range_info.end + (1 - weight) * rng.end;
|
|
}
|
|
}
|
|
// Prevent range from going outside limits
|
|
// Also ensure that range keeps the same delta when panning/scrolling
|
|
if (rng.bounds != null && rng.bounds != "auto") { // check `auto` for type-checking purpose
|
|
var _b = rng.bounds, min = _b[0], max = _b[1];
|
|
var new_interval = Math.abs(range_info.end - range_info.start);
|
|
if (rng.is_reversed) {
|
|
if (min != null) {
|
|
if (min >= range_info.end) {
|
|
hit_bound = true;
|
|
range_info.end = min;
|
|
if (is_panning || is_scrolling) {
|
|
range_info.start = min + new_interval;
|
|
}
|
|
}
|
|
}
|
|
if (max != null) {
|
|
if (max <= range_info.start) {
|
|
hit_bound = true;
|
|
range_info.start = max;
|
|
if (is_panning || is_scrolling) {
|
|
range_info.end = max - new_interval;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (min != null) {
|
|
if (min >= range_info.start) {
|
|
hit_bound = true;
|
|
range_info.start = min;
|
|
if (is_panning || is_scrolling) {
|
|
range_info.end = min + new_interval;
|
|
}
|
|
}
|
|
}
|
|
if (max != null) {
|
|
if (max <= range_info.end) {
|
|
hit_bound = true;
|
|
range_info.end = max;
|
|
if (is_panning || is_scrolling) {
|
|
range_info.start = max - new_interval;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Cancel the event when hitting a bound while scrolling. This ensures that
|
|
// the scroll-zoom tool maintains its focus position. Setting `maintain_focus`
|
|
// to false results in a more "gliding" behavior, allowing one to
|
|
// zoom out more smoothly, at the cost of losing the focus position.
|
|
if (is_scrolling && hit_bound && maintain_focus)
|
|
return;
|
|
for (var _c = 0, range_info_iter_4 = range_info_iter; _c < range_info_iter_4.length; _c++) {
|
|
var _d = range_info_iter_4[_c], rng = _d[0], range_info = _d[1];
|
|
rng.have_updated_interactively = true;
|
|
if (rng.start != range_info.start || rng.end != range_info.end)
|
|
rng.setv(range_info);
|
|
}
|
|
};
|
|
PlotView.prototype._get_weight_to_constrain_interval = function (rng, range_info) {
|
|
// Get the weight by which a range-update can be applied
|
|
// to still honor the interval limits (including the implicit
|
|
// max interval imposed by the bounds)
|
|
var min_interval = rng.min_interval;
|
|
var max_interval = rng.max_interval;
|
|
// Express bounds as a max_interval. By doing this, the application of
|
|
// bounds and interval limits can be applied independent from each-other.
|
|
if (rng.bounds != null && rng.bounds != "auto") { // check `auto` for type-checking purpose
|
|
var _a = rng.bounds, min = _a[0], max = _a[1];
|
|
if (min != null && max != null) {
|
|
var max_interval2 = Math.abs(max - min);
|
|
max_interval = max_interval != null ? Math.min(max_interval, max_interval2) : max_interval2;
|
|
}
|
|
}
|
|
var weight = 1.0;
|
|
if (min_interval != null || max_interval != null) {
|
|
var old_interval = Math.abs(rng.end - rng.start);
|
|
var new_interval = Math.abs(range_info.end - range_info.start);
|
|
if (min_interval > 0 && new_interval < min_interval) {
|
|
weight = (old_interval - min_interval) / (old_interval - new_interval);
|
|
}
|
|
if (max_interval > 0 && new_interval > max_interval) {
|
|
weight = (max_interval - old_interval) / (new_interval - old_interval);
|
|
}
|
|
weight = Math.max(0.0, Math.min(1.0, weight));
|
|
}
|
|
return weight;
|
|
};
|
|
PlotView.prototype.update_range = function (range_info, is_panning, is_scrolling, maintain_focus) {
|
|
if (is_panning === void 0) {
|
|
is_panning = false;
|
|
}
|
|
if (is_scrolling === void 0) {
|
|
is_scrolling = false;
|
|
}
|
|
if (maintain_focus === void 0) {
|
|
maintain_focus = true;
|
|
}
|
|
this.pause();
|
|
var _a = this.frame, x_ranges = _a.x_ranges, y_ranges = _a.y_ranges;
|
|
if (range_info == null) {
|
|
for (var name_1 in x_ranges) {
|
|
var rng = x_ranges[name_1];
|
|
rng.reset();
|
|
}
|
|
for (var name_2 in y_ranges) {
|
|
var rng = y_ranges[name_2];
|
|
rng.reset();
|
|
}
|
|
this.update_dataranges();
|
|
}
|
|
else {
|
|
var range_info_iter = [];
|
|
for (var name_3 in x_ranges) {
|
|
var rng = x_ranges[name_3];
|
|
range_info_iter.push([rng, range_info.xrs[name_3]]);
|
|
}
|
|
for (var name_4 in y_ranges) {
|
|
var rng = y_ranges[name_4];
|
|
range_info_iter.push([rng, range_info.yrs[name_4]]);
|
|
}
|
|
if (is_scrolling) {
|
|
this._update_ranges_together(range_info_iter); // apply interval bounds while keeping aspect
|
|
}
|
|
this._update_ranges_individually(range_info_iter, is_panning, is_scrolling, maintain_focus);
|
|
}
|
|
this.unpause();
|
|
};
|
|
PlotView.prototype.reset_range = function () {
|
|
this.update_range(null);
|
|
};
|
|
PlotView.prototype._invalidate_layout = function () {
|
|
var _this = this;
|
|
var needs_layout = function () {
|
|
for (var _i = 0, _a = _this.model.side_panels; _i < _a.length; _i++) {
|
|
var panel = _a[_i];
|
|
var view = _this.renderer_views[panel.id];
|
|
if (view.layout.has_size_changed())
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
if (needs_layout())
|
|
this.root.compute_layout();
|
|
};
|
|
PlotView.prototype.build_renderer_views = function () {
|
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
this.computed_renderers = [];
|
|
(_a = this.computed_renderers).push.apply(_a, this.model.above);
|
|
(_b = this.computed_renderers).push.apply(_b, this.model.below);
|
|
(_c = this.computed_renderers).push.apply(_c, this.model.left);
|
|
(_d = this.computed_renderers).push.apply(_d, this.model.right);
|
|
(_e = this.computed_renderers).push.apply(_e, this.model.center);
|
|
(_f = this.computed_renderers).push.apply(_f, this.model.renderers);
|
|
if (this._title != null)
|
|
this.computed_renderers.push(this._title);
|
|
if (this._toolbar != null)
|
|
this.computed_renderers.push(this._toolbar);
|
|
for (var _i = 0, _h = this.model.toolbar.tools; _i < _h.length; _i++) {
|
|
var tool = _h[_i];
|
|
if (tool.overlay != null)
|
|
this.computed_renderers.push(tool.overlay);
|
|
(_g = this.computed_renderers).push.apply(_g, tool.synthetic_renderers);
|
|
}
|
|
build_views_1.build_views(this.renderer_views, this.computed_renderers, { parent: this });
|
|
};
|
|
PlotView.prototype.get_renderer_views = function () {
|
|
var _this = this;
|
|
return this.computed_renderers.map(function (r) { return _this.renderer_views[r.id]; });
|
|
};
|
|
PlotView.prototype.build_tool_views = function () {
|
|
var _this = this;
|
|
var tool_models = this.model.toolbar.tools;
|
|
var new_tool_views = build_views_1.build_views(this.tool_views, tool_models, { parent: this });
|
|
new_tool_views.map(function (tool_view) { return _this.ui_event_bus.register_tool(tool_view); });
|
|
};
|
|
PlotView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.force_paint, function () { return _this.repaint(); });
|
|
var _a = this.frame, x_ranges = _a.x_ranges, y_ranges = _a.y_ranges;
|
|
for (var name_5 in x_ranges) {
|
|
var rng = x_ranges[name_5];
|
|
this.connect(rng.change, function () { _this._needs_layout = true; _this.request_paint(); });
|
|
}
|
|
for (var name_6 in y_ranges) {
|
|
var rng = y_ranges[name_6];
|
|
this.connect(rng.change, function () { _this._needs_layout = true; _this.request_paint(); });
|
|
}
|
|
this.connect(this.model.properties.renderers.change, function () { return _this.build_renderer_views(); });
|
|
this.connect(this.model.toolbar.properties.tools.change, function () { _this.build_renderer_views(); _this.build_tool_views(); });
|
|
this.connect(this.model.change, function () { return _this.request_paint(); });
|
|
this.connect(this.model.reset, function () { return _this.reset(); });
|
|
};
|
|
PlotView.prototype.set_initial_range = function () {
|
|
// check for good values for ranges before setting initial range
|
|
var good_vals = true;
|
|
var _a = this.frame, x_ranges = _a.x_ranges, y_ranges = _a.y_ranges;
|
|
var xrs = {};
|
|
var yrs = {};
|
|
for (var name_7 in x_ranges) {
|
|
var _b = x_ranges[name_7], start = _b.start, end = _b.end;
|
|
if (start == null || end == null || types_1.isStrictNaN(start + end)) {
|
|
good_vals = false;
|
|
break;
|
|
}
|
|
xrs[name_7] = { start: start, end: end };
|
|
}
|
|
if (good_vals) {
|
|
for (var name_8 in y_ranges) {
|
|
var _c = y_ranges[name_8], start = _c.start, end = _c.end;
|
|
if (start == null || end == null || types_1.isStrictNaN(start + end)) {
|
|
good_vals = false;
|
|
break;
|
|
}
|
|
yrs[name_8] = { start: start, end: end };
|
|
}
|
|
}
|
|
if (good_vals) {
|
|
this._initial_state_info.range = { xrs: xrs, yrs: yrs };
|
|
logging_1.logger.debug("initial ranges set");
|
|
}
|
|
else
|
|
logging_1.logger.warn('could not set initial ranges');
|
|
};
|
|
PlotView.prototype.has_finished = function () {
|
|
if (!_super.prototype.has_finished.call(this))
|
|
return false;
|
|
for (var id in this.renderer_views) {
|
|
var view = this.renderer_views[id];
|
|
if (!view.has_finished())
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
PlotView.prototype.after_layout = function () {
|
|
_super.prototype.after_layout.call(this);
|
|
this._needs_layout = false;
|
|
this.model.setv({
|
|
inner_width: Math.round(this.frame._width.value),
|
|
inner_height: Math.round(this.frame._height.value),
|
|
outer_width: Math.round(this.layout._width.value),
|
|
outer_height: Math.round(this.layout._height.value),
|
|
}, { no_change: true });
|
|
if (this.model.match_aspect !== false) {
|
|
this.pause();
|
|
this.update_dataranges();
|
|
this.unpause(true);
|
|
}
|
|
if (!this._outer_bbox.equals(this.layout.bbox)) {
|
|
var _a = this.layout.bbox, width = _a.width, height = _a.height;
|
|
this.canvas_view.prepare_canvas(width, height);
|
|
this._outer_bbox = this.layout.bbox;
|
|
this._needs_paint = true;
|
|
}
|
|
if (!this._inner_bbox.equals(this.frame.inner_bbox)) {
|
|
this._inner_bbox = this.layout.inner_bbox;
|
|
this._needs_paint = true;
|
|
}
|
|
if (this._needs_paint) {
|
|
// XXX: can't be this.request_paint(), because it would trigger back-and-forth
|
|
// layout recomputing feedback loop between plots. Plots are also much more
|
|
// responsive this way, especially in interactive mode.
|
|
this._needs_paint = false;
|
|
this.paint();
|
|
}
|
|
};
|
|
PlotView.prototype.repaint = function () {
|
|
if (this._needs_layout)
|
|
this._invalidate_layout();
|
|
this.paint();
|
|
};
|
|
PlotView.prototype.paint = function () {
|
|
var _this = this;
|
|
if (this.is_paused)
|
|
return;
|
|
logging_1.logger.trace("PlotView.paint() for " + this.model.id);
|
|
var document = this.model.document;
|
|
if (document != null) {
|
|
var interactive_duration = document.interactive_duration();
|
|
if (interactive_duration >= 0 && interactive_duration < this.model.lod_interval) {
|
|
setTimeout(function () {
|
|
if (document.interactive_duration() > _this.model.lod_timeout) {
|
|
document.interactive_stop(_this.model);
|
|
}
|
|
_this.request_paint();
|
|
}, this.model.lod_timeout);
|
|
}
|
|
else
|
|
document.interactive_stop(this.model);
|
|
}
|
|
for (var id in this.renderer_views) {
|
|
var v = this.renderer_views[id];
|
|
if (this.range_update_timestamp == null ||
|
|
(v instanceof glyph_renderer_1.GlyphRendererView && v.set_data_timestamp > this.range_update_timestamp)) {
|
|
this.update_dataranges();
|
|
break;
|
|
}
|
|
}
|
|
var ctx = this.canvas_view.ctx;
|
|
var ratio = this.canvas.pixel_ratio;
|
|
// Set hidpi-transform
|
|
ctx.save(); // Save default state, do *after* getting ratio, cause setting canvas.width resets transforms
|
|
ctx.scale(ratio, ratio);
|
|
ctx.translate(0.5, 0.5);
|
|
var frame_box = [
|
|
this.frame._left.value,
|
|
this.frame._top.value,
|
|
this.frame._width.value,
|
|
this.frame._height.value,
|
|
];
|
|
this._map_hook(ctx, frame_box);
|
|
this._paint_empty(ctx, frame_box);
|
|
this.prepare_webgl(ratio, frame_box);
|
|
ctx.save();
|
|
if (this.visuals.outline_line.doit) {
|
|
this.visuals.outline_line.set_value(ctx);
|
|
var x0 = frame_box[0], y0 = frame_box[1], w = frame_box[2], h = frame_box[3];
|
|
// XXX: shrink outline region by 1px to make right and bottom lines visible
|
|
// if they are on the edge of the canvas.
|
|
if (x0 + w == this.layout._width.value) {
|
|
w -= 1;
|
|
}
|
|
if (y0 + h == this.layout._height.value) {
|
|
h -= 1;
|
|
}
|
|
ctx.strokeRect(x0, y0, w, h);
|
|
}
|
|
ctx.restore();
|
|
this._paint_levels(ctx, ['image', 'underlay', 'glyph'], frame_box, true);
|
|
this.blit_webgl(ratio);
|
|
this._paint_levels(ctx, ['annotation'], frame_box, false);
|
|
this._paint_levels(ctx, ['overlay'], frame_box, false);
|
|
if (this._initial_state_info.range == null)
|
|
this.set_initial_range();
|
|
ctx.restore(); // Restore to default state
|
|
};
|
|
PlotView.prototype._paint_levels = function (ctx, levels, clip_region, global_clip) {
|
|
ctx.save();
|
|
if (global_clip) {
|
|
ctx.beginPath();
|
|
ctx.rect.apply(ctx, clip_region);
|
|
ctx.clip();
|
|
}
|
|
for (var _i = 0, levels_1 = levels; _i < levels_1.length; _i++) {
|
|
var level = levels_1[_i];
|
|
for (var _a = 0, _b = this.computed_renderers; _a < _b.length; _a++) {
|
|
var renderer = _b[_a];
|
|
if (renderer.level != level)
|
|
continue;
|
|
var renderer_view = this.renderer_views[renderer.id];
|
|
if (!global_clip && renderer_view.needs_clip) {
|
|
ctx.save();
|
|
ctx.beginPath();
|
|
ctx.rect.apply(ctx, clip_region);
|
|
ctx.clip();
|
|
}
|
|
renderer_view.render();
|
|
if (!global_clip && renderer_view.needs_clip) {
|
|
ctx.restore();
|
|
}
|
|
}
|
|
}
|
|
ctx.restore();
|
|
};
|
|
PlotView.prototype._map_hook = function (_ctx, _frame_box) { };
|
|
PlotView.prototype._paint_empty = function (ctx, frame_box) {
|
|
var _a = [0, 0, this.layout._width.value, this.layout._height.value], cx = _a[0], cy = _a[1], cw = _a[2], ch = _a[3];
|
|
var fx = frame_box[0], fy = frame_box[1], fw = frame_box[2], fh = frame_box[3];
|
|
ctx.clearRect(cx, cy, cw, ch);
|
|
if (this.visuals.border_fill.doit) {
|
|
this.visuals.border_fill.set_value(ctx);
|
|
ctx.fillRect(cx, cy, cw, ch);
|
|
ctx.clearRect(fx, fy, fw, fh);
|
|
}
|
|
if (this.visuals.background_fill.doit) {
|
|
this.visuals.background_fill.set_value(ctx);
|
|
ctx.fillRect(fx, fy, fw, fh);
|
|
}
|
|
};
|
|
PlotView.prototype.save = function (name) {
|
|
switch (this.model.output_backend) {
|
|
case "canvas":
|
|
case "webgl": {
|
|
var canvas = this.canvas_view.get_canvas_element();
|
|
if (canvas.msToBlob != null) {
|
|
var blob = canvas.msToBlob();
|
|
window.navigator.msSaveBlob(blob, name);
|
|
}
|
|
else {
|
|
var link = document.createElement('a');
|
|
link.href = canvas.toDataURL('image/png');
|
|
link.download = name + ".png";
|
|
link.target = "_blank";
|
|
link.dispatchEvent(new MouseEvent('click'));
|
|
}
|
|
break;
|
|
}
|
|
case "svg": {
|
|
var ctx = this.canvas_view._ctx;
|
|
var svg = ctx.getSerializedSvg(true);
|
|
var svgblob = new Blob([svg], { type: 'text/plain' });
|
|
var downloadLink = document.createElement("a");
|
|
downloadLink.download = name + ".svg";
|
|
downloadLink.innerHTML = "Download svg";
|
|
downloadLink.href = window.URL.createObjectURL(svgblob);
|
|
downloadLink.onclick = function (event) { return document.body.removeChild(event.target); };
|
|
downloadLink.style.display = "none";
|
|
document.body.appendChild(downloadLink);
|
|
downloadLink.click();
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
PlotView.prototype.serializable_state = function () {
|
|
var _a = _super.prototype.serializable_state.call(this), children = _a.children, state = tslib_1.__rest(_a, ["children"]);
|
|
var renderers = this.get_renderer_views()
|
|
.map(function (view) { return view.serializable_state(); })
|
|
.filter(function (item) { return "bbox" in item; });
|
|
return tslib_1.__assign({}, state, { children: children.concat(renderers) }); // XXX
|
|
};
|
|
return PlotView;
|
|
}(layout_dom_1.LayoutDOMView));
|
|
exports.PlotView = PlotView;
|
|
}
|
|
,
|
|
/* models/ranges/data_range */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var range_1 = require(190) /* ./range */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var DataRange = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DataRange, _super);
|
|
function DataRange(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
DataRange.initClass = function () {
|
|
this.prototype.type = "DataRange";
|
|
this.define({
|
|
names: [p.Array, []],
|
|
renderers: [p.Array, []],
|
|
});
|
|
};
|
|
return DataRange;
|
|
}(range_1.Range));
|
|
exports.DataRange = DataRange;
|
|
DataRange.initClass();
|
|
}
|
|
,
|
|
/* models/ranges/data_range1d */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var data_range_1 = require(186) /* ./data_range */;
|
|
var glyph_renderer_1 = require(193) /* ../renderers/glyph_renderer */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var bbox = require(27) /* ../../core/util/bbox */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var DataRange1d = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DataRange1d, _super);
|
|
function DataRange1d(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this._plot_bounds = {};
|
|
_this.have_updated_interactively = false;
|
|
return _this;
|
|
}
|
|
DataRange1d.initClass = function () {
|
|
this.prototype.type = "DataRange1d";
|
|
this.define({
|
|
start: [p.Number],
|
|
end: [p.Number],
|
|
range_padding: [p.Number, 0.1],
|
|
range_padding_units: [p.PaddingUnits, "percent"],
|
|
flipped: [p.Boolean, false],
|
|
follow: [p.StartEnd,],
|
|
follow_interval: [p.Number],
|
|
default_span: [p.Number, 2],
|
|
});
|
|
this.internal({
|
|
scale_hint: [p.String, 'auto'],
|
|
});
|
|
};
|
|
DataRange1d.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this._initial_start = this.start;
|
|
this._initial_end = this.end;
|
|
this._initial_range_padding = this.range_padding;
|
|
this._initial_range_padding_units = this.range_padding_units;
|
|
this._initial_follow = this.follow;
|
|
this._initial_follow_interval = this.follow_interval;
|
|
this._initial_default_span = this.default_span;
|
|
};
|
|
Object.defineProperty(DataRange1d.prototype, "min", {
|
|
get: function () {
|
|
return Math.min(this.start, this.end);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(DataRange1d.prototype, "max", {
|
|
get: function () {
|
|
return Math.max(this.start, this.end);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
DataRange1d.prototype.computed_renderers = function () {
|
|
// TODO (bev) check that renderers actually configured with this range
|
|
var names = this.names;
|
|
var renderers = this.renderers;
|
|
if (renderers.length == 0) {
|
|
for (var _i = 0, _a = this.plots; _i < _a.length; _i++) {
|
|
var plot = _a[_i];
|
|
var rs = plot.renderers.filter(function (r) { return r instanceof glyph_renderer_1.GlyphRenderer; });
|
|
renderers = renderers.concat(rs);
|
|
}
|
|
}
|
|
if (names.length > 0)
|
|
renderers = renderers.filter(function (r) { return array_1.includes(names, r.name); });
|
|
logging_1.logger.debug("computed " + renderers.length + " renderers for DataRange1d " + this.id);
|
|
for (var _b = 0, renderers_1 = renderers; _b < renderers_1.length; _b++) {
|
|
var r = renderers_1[_b];
|
|
logging_1.logger.trace(" - " + r.type + " " + r.id);
|
|
}
|
|
return renderers;
|
|
};
|
|
/*protected*/ DataRange1d.prototype._compute_plot_bounds = function (renderers, bounds) {
|
|
var result = bbox.empty();
|
|
for (var _i = 0, renderers_2 = renderers; _i < renderers_2.length; _i++) {
|
|
var r = renderers_2[_i];
|
|
if (bounds[r.id] != null)
|
|
result = bbox.union(result, bounds[r.id]);
|
|
}
|
|
return result;
|
|
};
|
|
DataRange1d.prototype.adjust_bounds_for_aspect = function (bounds, ratio) {
|
|
var result = bbox.empty();
|
|
var width = bounds.maxX - bounds.minX;
|
|
if (width <= 0) {
|
|
width = 1.0;
|
|
}
|
|
var height = bounds.maxY - bounds.minY;
|
|
if (height <= 0) {
|
|
height = 1.0;
|
|
}
|
|
var xcenter = 0.5 * (bounds.maxX + bounds.minX);
|
|
var ycenter = 0.5 * (bounds.maxY + bounds.minY);
|
|
if (width < ratio * height) {
|
|
width = ratio * height;
|
|
}
|
|
else {
|
|
height = width / ratio;
|
|
}
|
|
result.maxX = xcenter + 0.5 * width;
|
|
result.minX = xcenter - 0.5 * width;
|
|
result.maxY = ycenter + 0.5 * height;
|
|
result.minY = ycenter - 0.5 * height;
|
|
return result;
|
|
};
|
|
/*protected*/ DataRange1d.prototype._compute_min_max = function (plot_bounds, dimension) {
|
|
var _a, _b;
|
|
var overall = bbox.empty();
|
|
for (var k in plot_bounds) {
|
|
var v = plot_bounds[k];
|
|
overall = bbox.union(overall, v);
|
|
}
|
|
var min, max;
|
|
if (dimension == 0)
|
|
_a = [overall.minX, overall.maxX], min = _a[0], max = _a[1];
|
|
else
|
|
_b = [overall.minY, overall.maxY], min = _b[0], max = _b[1];
|
|
return [min, max];
|
|
};
|
|
/*protected*/ DataRange1d.prototype._compute_range = function (min, max) {
|
|
var _a;
|
|
var range_padding = this.range_padding; // XXX: ? 0
|
|
var start, end;
|
|
if (this.scale_hint == "log") {
|
|
if (isNaN(min) || !isFinite(min) || min <= 0) {
|
|
if (isNaN(max) || !isFinite(max) || max <= 0)
|
|
min = 0.1;
|
|
else
|
|
min = max / 100;
|
|
logging_1.logger.warn("could not determine minimum data value for log axis, DataRange1d using value " + min);
|
|
}
|
|
if (isNaN(max) || !isFinite(max) || max <= 0) {
|
|
if (isNaN(min) || !isFinite(min) || min <= 0)
|
|
max = 10;
|
|
else
|
|
max = min * 100;
|
|
logging_1.logger.warn("could not determine maximum data value for log axis, DataRange1d using value " + max);
|
|
}
|
|
var center = void 0, span = void 0;
|
|
if (max == min) {
|
|
span = this.default_span + 0.001;
|
|
center = Math.log(min) / Math.log(10);
|
|
}
|
|
else {
|
|
var log_min = void 0, log_max = void 0;
|
|
if (this.range_padding_units == "percent") {
|
|
log_min = Math.log(min) / Math.log(10);
|
|
log_max = Math.log(max) / Math.log(10);
|
|
span = (log_max - log_min) * (1 + range_padding);
|
|
}
|
|
else {
|
|
log_min = Math.log(min - range_padding) / Math.log(10);
|
|
log_max = Math.log(max + range_padding) / Math.log(10);
|
|
span = log_max - log_min;
|
|
}
|
|
center = (log_min + log_max) / 2.0;
|
|
}
|
|
start = Math.pow(10, center - span / 2.0);
|
|
end = Math.pow(10, center + span / 2.0);
|
|
}
|
|
else {
|
|
var span = void 0;
|
|
if (max == min)
|
|
span = this.default_span;
|
|
else {
|
|
if (this.range_padding_units == "percent")
|
|
span = (max - min) * (1 + range_padding);
|
|
else
|
|
span = (max - min) + 2 * range_padding;
|
|
}
|
|
var center = (max + min) / 2.0;
|
|
start = center - span / 2.0;
|
|
end = center + span / 2.0;
|
|
}
|
|
var follow_sign = +1;
|
|
if (this.flipped) {
|
|
_a = [end, start], start = _a[0], end = _a[1];
|
|
follow_sign = -1;
|
|
}
|
|
var follow_interval = this.follow_interval;
|
|
if (follow_interval != null && Math.abs(start - end) > follow_interval) {
|
|
if (this.follow == 'start')
|
|
end = start + follow_sign * follow_interval;
|
|
else if (this.follow == 'end')
|
|
start = end - follow_sign * follow_interval;
|
|
}
|
|
return [start, end];
|
|
};
|
|
DataRange1d.prototype.update = function (bounds, dimension, bounds_id, ratio) {
|
|
if (this.have_updated_interactively)
|
|
return;
|
|
var renderers = this.computed_renderers();
|
|
// update the raw data bounds for all renderers we care about
|
|
var total_bounds = this._compute_plot_bounds(renderers, bounds);
|
|
if (ratio != null)
|
|
total_bounds = this.adjust_bounds_for_aspect(total_bounds, ratio);
|
|
this._plot_bounds[bounds_id] = total_bounds;
|
|
// compute the min/mix for our specified dimension
|
|
var _a = this._compute_min_max(this._plot_bounds, dimension), min = _a[0], max = _a[1];
|
|
// derive start, end from bounds and data range config
|
|
var _b = this._compute_range(min, max), start = _b[0], end = _b[1];
|
|
if (this._initial_start != null) {
|
|
if (this.scale_hint == "log") {
|
|
if (this._initial_start > 0)
|
|
start = this._initial_start;
|
|
}
|
|
else
|
|
start = this._initial_start;
|
|
}
|
|
if (this._initial_end != null) {
|
|
if (this.scale_hint == "log") {
|
|
if (this._initial_end > 0)
|
|
end = this._initial_end;
|
|
}
|
|
else
|
|
end = this._initial_end;
|
|
}
|
|
// only trigger updates when there are changes
|
|
var _c = [this.start, this.end], _start = _c[0], _end = _c[1];
|
|
if (start != _start || end != _end) {
|
|
var new_range = {};
|
|
if (start != _start)
|
|
new_range.start = start;
|
|
if (end != _end)
|
|
new_range.end = end;
|
|
this.setv(new_range);
|
|
}
|
|
if (this.bounds == 'auto')
|
|
this.setv({ bounds: [start, end] }, { silent: true });
|
|
this.change.emit();
|
|
};
|
|
DataRange1d.prototype.reset = function () {
|
|
this.have_updated_interactively = false;
|
|
// change events silenced as PlotView.update_dataranges triggers property callbacks
|
|
this.setv({
|
|
range_padding: this._initial_range_padding,
|
|
range_padding_units: this._initial_range_padding_units,
|
|
follow: this._initial_follow,
|
|
follow_interval: this._initial_follow_interval,
|
|
default_span: this._initial_default_span,
|
|
}, { silent: true });
|
|
this.change.emit();
|
|
};
|
|
return DataRange1d;
|
|
}(data_range_1.DataRange));
|
|
exports.DataRange1d = DataRange1d;
|
|
DataRange1d.initClass();
|
|
}
|
|
,
|
|
/* models/ranges/factor_range */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var range_1 = require(190) /* ./range */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var arrayable_1 = require(25) /* ../../core/util/arrayable */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
function map_one_level(factors, padding, offset) {
|
|
if (offset === void 0) {
|
|
offset = 0;
|
|
}
|
|
var mapping = {};
|
|
for (var i = 0; i < factors.length; i++) {
|
|
var factor = factors[i];
|
|
if (factor in mapping)
|
|
throw new Error("duplicate factor or subfactor: " + factor);
|
|
else
|
|
mapping[factor] = { value: 0.5 + i * (1 + padding) + offset };
|
|
}
|
|
return [mapping, (factors.length - 1) * padding];
|
|
}
|
|
exports.map_one_level = map_one_level;
|
|
function map_two_levels(factors, outer_pad, factor_pad, offset) {
|
|
if (offset === void 0) {
|
|
offset = 0;
|
|
}
|
|
var mapping = {};
|
|
var tops = {};
|
|
var tops_order = [];
|
|
for (var _i = 0, factors_1 = factors; _i < factors_1.length; _i++) {
|
|
var _a = factors_1[_i], f0 = _a[0], f1 = _a[1];
|
|
if (!(f0 in tops)) {
|
|
tops[f0] = [];
|
|
tops_order.push(f0);
|
|
}
|
|
tops[f0].push(f1);
|
|
}
|
|
var suboffset = offset;
|
|
var total_subpad = 0;
|
|
var _loop_1 = function (f0) {
|
|
var n = tops[f0].length;
|
|
var _a = map_one_level(tops[f0], factor_pad, suboffset), submap = _a[0], subpad = _a[1];
|
|
total_subpad += subpad;
|
|
var subtot = array_1.sum(tops[f0].map(function (f1) { return submap[f1].value; }));
|
|
mapping[f0] = { value: subtot / n, mapping: submap };
|
|
suboffset += n + outer_pad + subpad;
|
|
};
|
|
for (var _b = 0, tops_order_1 = tops_order; _b < tops_order_1.length; _b++) {
|
|
var f0 = tops_order_1[_b];
|
|
_loop_1(f0);
|
|
}
|
|
return [mapping, tops_order, (tops_order.length - 1) * outer_pad + total_subpad];
|
|
}
|
|
exports.map_two_levels = map_two_levels;
|
|
function map_three_levels(factors, outer_pad, inner_pad, factor_pad, offset) {
|
|
if (offset === void 0) {
|
|
offset = 0;
|
|
}
|
|
var mapping = {};
|
|
var tops = {};
|
|
var tops_order = [];
|
|
for (var _i = 0, factors_2 = factors; _i < factors_2.length; _i++) {
|
|
var _a = factors_2[_i], f0 = _a[0], f1 = _a[1], f2 = _a[2];
|
|
if (!(f0 in tops)) {
|
|
tops[f0] = [];
|
|
tops_order.push(f0);
|
|
}
|
|
tops[f0].push([f1, f2]);
|
|
}
|
|
var mids_order = [];
|
|
var suboffset = offset;
|
|
var total_subpad = 0;
|
|
var _loop_2 = function (f0) {
|
|
var n = tops[f0].length;
|
|
var _a = map_two_levels(tops[f0], inner_pad, factor_pad, suboffset), submap = _a[0], submids_order = _a[1], subpad = _a[2];
|
|
for (var _i = 0, submids_order_1 = submids_order; _i < submids_order_1.length; _i++) {
|
|
var f1 = submids_order_1[_i];
|
|
mids_order.push([f0, f1]);
|
|
}
|
|
total_subpad += subpad;
|
|
var subtot = array_1.sum(tops[f0].map(function (_a) {
|
|
var f1 = _a[0];
|
|
return submap[f1].value;
|
|
}));
|
|
mapping[f0] = { value: subtot / n, mapping: submap };
|
|
suboffset += n + outer_pad + subpad;
|
|
};
|
|
for (var _b = 0, tops_order_2 = tops_order; _b < tops_order_2.length; _b++) {
|
|
var f0 = tops_order_2[_b];
|
|
_loop_2(f0);
|
|
}
|
|
return [mapping, tops_order, mids_order, (tops_order.length - 1) * outer_pad + total_subpad];
|
|
}
|
|
exports.map_three_levels = map_three_levels;
|
|
var FactorRange = /** @class */ (function (_super) {
|
|
tslib_1.__extends(FactorRange, _super);
|
|
function FactorRange(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
FactorRange.initClass = function () {
|
|
this.prototype.type = "FactorRange";
|
|
this.define({
|
|
factors: [p.Array, []],
|
|
factor_padding: [p.Number, 0],
|
|
subgroup_padding: [p.Number, 0.8],
|
|
group_padding: [p.Number, 1.4],
|
|
range_padding: [p.Number, 0],
|
|
range_padding_units: [p.PaddingUnits, "percent"],
|
|
start: [p.Number],
|
|
end: [p.Number],
|
|
});
|
|
this.internal({
|
|
levels: [p.Number],
|
|
mids: [p.Array],
|
|
tops: [p.Array],
|
|
tops_groups: [p.Array],
|
|
});
|
|
};
|
|
Object.defineProperty(FactorRange.prototype, "min", {
|
|
get: function () {
|
|
return this.start;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(FactorRange.prototype, "max", {
|
|
get: function () {
|
|
return this.end;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
FactorRange.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this._init(true);
|
|
};
|
|
FactorRange.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.properties.factors.change, function () { return _this.reset(); });
|
|
this.connect(this.properties.factor_padding.change, function () { return _this.reset(); });
|
|
this.connect(this.properties.group_padding.change, function () { return _this.reset(); });
|
|
this.connect(this.properties.subgroup_padding.change, function () { return _this.reset(); });
|
|
this.connect(this.properties.range_padding.change, function () { return _this.reset(); });
|
|
this.connect(this.properties.range_padding_units.change, function () { return _this.reset(); });
|
|
};
|
|
FactorRange.prototype.reset = function () {
|
|
this._init(false);
|
|
this.change.emit();
|
|
};
|
|
FactorRange.prototype._lookup = function (x) {
|
|
if (x.length == 1) {
|
|
var m = this._mapping;
|
|
if (!m.hasOwnProperty(x[0])) {
|
|
return NaN;
|
|
}
|
|
return m[x[0]].value;
|
|
}
|
|
else if (x.length == 2) {
|
|
var m = this._mapping;
|
|
if (!m.hasOwnProperty(x[0]) || !m[x[0]].mapping.hasOwnProperty(x[1])) {
|
|
return NaN;
|
|
}
|
|
return m[x[0]].mapping[x[1]].value;
|
|
}
|
|
else if (x.length == 3) {
|
|
var m = this._mapping;
|
|
if (!m.hasOwnProperty(x[0]) || !m[x[0]].mapping.hasOwnProperty(x[1]) || !m[x[0]].mapping[x[1]].mapping.hasOwnProperty(x[2])) {
|
|
return NaN;
|
|
}
|
|
return m[x[0]].mapping[x[1]].mapping[x[2]].value;
|
|
}
|
|
else
|
|
throw new Error("unreachable code");
|
|
};
|
|
// convert a string factor into a synthetic coordinate
|
|
FactorRange.prototype.synthetic = function (x) {
|
|
if (types_1.isNumber(x))
|
|
return x;
|
|
if (types_1.isString(x))
|
|
return this._lookup([x]);
|
|
var offset = 0;
|
|
var off = x[x.length - 1];
|
|
if (types_1.isNumber(off)) {
|
|
offset = off;
|
|
x = x.slice(0, -1);
|
|
}
|
|
return this._lookup(x) + offset;
|
|
};
|
|
// convert an array of string factors into synthetic coordinates
|
|
FactorRange.prototype.v_synthetic = function (xs) {
|
|
var _this = this;
|
|
return arrayable_1.map(xs, function (x) { return _this.synthetic(x); });
|
|
};
|
|
FactorRange.prototype._init = function (silent) {
|
|
var _a, _b, _c;
|
|
var levels;
|
|
var inside_padding;
|
|
if (array_1.every(this.factors, types_1.isString)) {
|
|
levels = 1;
|
|
_a = map_one_level(this.factors, this.factor_padding), this._mapping = _a[0], inside_padding = _a[1];
|
|
}
|
|
else if (array_1.every(this.factors, function (x) { return types_1.isArray(x) && x.length == 2 && types_1.isString(x[0]) && types_1.isString(x[1]); })) {
|
|
levels = 2;
|
|
_b = map_two_levels(this.factors, this.group_padding, this.factor_padding), this._mapping = _b[0], this.tops = _b[1], inside_padding = _b[2];
|
|
}
|
|
else if (array_1.every(this.factors, function (x) { return types_1.isArray(x) && x.length == 3 && types_1.isString(x[0]) && types_1.isString(x[1]) && types_1.isString(x[2]); })) {
|
|
levels = 3;
|
|
_c = map_three_levels(this.factors, this.group_padding, this.subgroup_padding, this.factor_padding), this._mapping = _c[0], this.tops = _c[1], this.mids = _c[2], inside_padding = _c[3];
|
|
}
|
|
else
|
|
throw new Error("???");
|
|
var start = 0;
|
|
var end = this.factors.length + inside_padding;
|
|
if (this.range_padding_units == "percent") {
|
|
var half_span = (end - start) * this.range_padding / 2;
|
|
start -= half_span;
|
|
end += half_span;
|
|
}
|
|
else {
|
|
start -= this.range_padding;
|
|
end += this.range_padding;
|
|
}
|
|
this.setv({ start: start, end: end, levels: levels }, { silent: silent });
|
|
if (this.bounds == "auto")
|
|
this.setv({ bounds: [start, end] }, { silent: true });
|
|
};
|
|
return FactorRange;
|
|
}(range_1.Range));
|
|
exports.FactorRange = FactorRange;
|
|
FactorRange.initClass();
|
|
}
|
|
,
|
|
/* models/ranges/index */ function _(require, module, exports) {
|
|
var data_range_1 = require(186) /* ./data_range */;
|
|
exports.DataRange = data_range_1.DataRange;
|
|
var data_range1d_1 = require(187) /* ./data_range1d */;
|
|
exports.DataRange1d = data_range1d_1.DataRange1d;
|
|
var factor_range_1 = require(188) /* ./factor_range */;
|
|
exports.FactorRange = factor_range_1.FactorRange;
|
|
var range_1 = require(190) /* ./range */;
|
|
exports.Range = range_1.Range;
|
|
var range1d_1 = require(191) /* ./range1d */;
|
|
exports.Range1d = range1d_1.Range1d;
|
|
}
|
|
,
|
|
/* models/ranges/range */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var Range = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Range, _super);
|
|
function Range(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.have_updated_interactively = false;
|
|
return _this;
|
|
}
|
|
Range.initClass = function () {
|
|
this.prototype.type = "Range";
|
|
this.define({
|
|
callback: [p.Any],
|
|
bounds: [p.Any],
|
|
min_interval: [p.Any],
|
|
max_interval: [p.Any],
|
|
});
|
|
this.internal({
|
|
plots: [p.Array, []],
|
|
});
|
|
};
|
|
Range.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.change, function () { return _this._emit_callback(); });
|
|
};
|
|
Range.prototype._emit_callback = function () {
|
|
if (this.callback != null) {
|
|
if (types_1.isFunction(this.callback))
|
|
this.callback(this);
|
|
else
|
|
this.callback.execute(this, {});
|
|
}
|
|
};
|
|
Object.defineProperty(Range.prototype, "is_reversed", {
|
|
get: function () {
|
|
return this.start > this.end;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return Range;
|
|
}(model_1.Model));
|
|
exports.Range = Range;
|
|
Range.initClass();
|
|
}
|
|
,
|
|
/* models/ranges/range1d */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var range_1 = require(190) /* ./range */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var Range1d = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Range1d, _super);
|
|
function Range1d(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Range1d.initClass = function () {
|
|
this.prototype.type = "Range1d";
|
|
this.define({
|
|
start: [p.Number, 0],
|
|
end: [p.Number, 1],
|
|
reset_start: [p.Number],
|
|
reset_end: [p.Number],
|
|
});
|
|
};
|
|
Range1d.prototype._set_auto_bounds = function () {
|
|
if (this.bounds == 'auto') {
|
|
var min = Math.min(this.reset_start, this.reset_end);
|
|
var max = Math.max(this.reset_start, this.reset_end);
|
|
this.setv({ bounds: [min, max] }, { silent: true });
|
|
}
|
|
};
|
|
Range1d.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
if (this.reset_start == null) {
|
|
this.reset_start = this.start;
|
|
}
|
|
if (this.reset_end == null) {
|
|
this.reset_end = this.end;
|
|
}
|
|
this._set_auto_bounds();
|
|
};
|
|
Object.defineProperty(Range1d.prototype, "min", {
|
|
get: function () {
|
|
return Math.min(this.start, this.end);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(Range1d.prototype, "max", {
|
|
get: function () {
|
|
return Math.max(this.start, this.end);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Range1d.prototype.reset = function () {
|
|
this._set_auto_bounds();
|
|
if (this.start != this.reset_start || this.end != this.reset_end)
|
|
this.setv({ start: this.reset_start, end: this.reset_end });
|
|
else
|
|
this.change.emit();
|
|
};
|
|
return Range1d;
|
|
}(range_1.Range));
|
|
exports.Range1d = Range1d;
|
|
Range1d.initClass();
|
|
}
|
|
,
|
|
/* models/renderers/data_renderer */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var renderer_1 = require(197) /* ./renderer */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var DataRendererView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DataRendererView, _super);
|
|
function DataRendererView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return DataRendererView;
|
|
}(renderer_1.RendererView));
|
|
exports.DataRendererView = DataRendererView;
|
|
var DataRenderer = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DataRenderer, _super);
|
|
function DataRenderer(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
DataRenderer.initClass = function () {
|
|
this.prototype.type = "DataRenderer";
|
|
this.define({
|
|
x_range_name: [p.String, 'default'],
|
|
y_range_name: [p.String, 'default'],
|
|
});
|
|
this.override({
|
|
level: 'glyph',
|
|
});
|
|
};
|
|
return DataRenderer;
|
|
}(renderer_1.Renderer));
|
|
exports.DataRenderer = DataRenderer;
|
|
DataRenderer.initClass();
|
|
}
|
|
,
|
|
/* models/renderers/glyph_renderer */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var data_renderer_1 = require(192) /* ./data_renderer */;
|
|
var line_1 = require(134) /* ../glyphs/line */;
|
|
var cds_view_1 = require(207) /* ../sources/cds_view */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var arrayable_1 = require(25) /* ../../core/util/arrayable */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var factor_range_1 = require(188) /* ../ranges/factor_range */;
|
|
var selection_defaults = {
|
|
fill: {},
|
|
line: {},
|
|
};
|
|
var decimated_defaults = {
|
|
fill: { fill_alpha: 0.3, fill_color: "grey" },
|
|
line: { line_alpha: 0.3, line_color: "grey" },
|
|
};
|
|
var nonselection_defaults = {
|
|
fill: { fill_alpha: 0.2 },
|
|
line: {},
|
|
};
|
|
var GlyphRendererView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GlyphRendererView, _super);
|
|
function GlyphRendererView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
GlyphRendererView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
var base_glyph = this.model.glyph;
|
|
var has_fill = array_1.includes(base_glyph.mixins, "fill");
|
|
var has_line = array_1.includes(base_glyph.mixins, "line");
|
|
var glyph_attrs = object_1.clone(base_glyph.attributes);
|
|
delete glyph_attrs.id;
|
|
function mk_glyph(defaults) {
|
|
var attrs = object_1.clone(glyph_attrs);
|
|
if (has_fill)
|
|
object_1.extend(attrs, defaults.fill);
|
|
if (has_line)
|
|
object_1.extend(attrs, defaults.line);
|
|
return new base_glyph.constructor(attrs);
|
|
}
|
|
this.glyph = this.build_glyph_view(base_glyph);
|
|
var selection_glyph = this.model.selection_glyph;
|
|
if (selection_glyph == null)
|
|
selection_glyph = mk_glyph({ fill: {}, line: {} });
|
|
else if (selection_glyph === "auto")
|
|
selection_glyph = mk_glyph(selection_defaults);
|
|
this.selection_glyph = this.build_glyph_view(selection_glyph);
|
|
var nonselection_glyph = this.model.nonselection_glyph;
|
|
if ((nonselection_glyph == null))
|
|
nonselection_glyph = mk_glyph({ fill: {}, line: {} });
|
|
else if (nonselection_glyph === "auto")
|
|
nonselection_glyph = mk_glyph(nonselection_defaults);
|
|
this.nonselection_glyph = this.build_glyph_view(nonselection_glyph);
|
|
var hover_glyph = this.model.hover_glyph;
|
|
if (hover_glyph != null)
|
|
this.hover_glyph = this.build_glyph_view(hover_glyph);
|
|
var muted_glyph = this.model.muted_glyph;
|
|
if (muted_glyph != null)
|
|
this.muted_glyph = this.build_glyph_view(muted_glyph);
|
|
var decimated_glyph = mk_glyph(decimated_defaults);
|
|
this.decimated_glyph = this.build_glyph_view(decimated_glyph);
|
|
this.xscale = this.plot_view.frame.xscales[this.model.x_range_name];
|
|
this.yscale = this.plot_view.frame.yscales[this.model.y_range_name];
|
|
this.set_data(false);
|
|
};
|
|
GlyphRendererView.prototype.build_glyph_view = function (model) {
|
|
return new model.default_view({ model: model, parent: this }); // XXX
|
|
};
|
|
GlyphRendererView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.change, function () { return _this.request_render(); });
|
|
this.connect(this.model.glyph.change, function () { return _this.set_data(); });
|
|
this.connect(this.model.data_source.change, function () { return _this.set_data(); });
|
|
this.connect(this.model.data_source.streaming, function () { return _this.set_data(); });
|
|
this.connect(this.model.data_source.patching, function (indices /* XXX: WHY? */) { return _this.set_data(true, indices); });
|
|
this.connect(this.model.data_source.selected.change, function () { return _this.request_render(); });
|
|
this.connect(this.model.data_source._select, function () { return _this.request_render(); });
|
|
if (this.hover_glyph != null)
|
|
this.connect(this.model.data_source.inspect, function () { return _this.request_render(); });
|
|
this.connect(this.model.properties.view.change, function () { return _this.set_data(); });
|
|
this.connect(this.model.view.change, function () { return _this.set_data(); });
|
|
var _a = this.plot_view.frame, x_ranges = _a.x_ranges, y_ranges = _a.y_ranges;
|
|
for (var name_1 in x_ranges) {
|
|
var rng = x_ranges[name_1];
|
|
if (rng instanceof factor_range_1.FactorRange)
|
|
this.connect(rng.change, function () { return _this.set_data(); });
|
|
}
|
|
for (var name_2 in y_ranges) {
|
|
var rng = y_ranges[name_2];
|
|
if (rng instanceof factor_range_1.FactorRange)
|
|
this.connect(rng.change, function () { return _this.set_data(); });
|
|
}
|
|
this.connect(this.model.glyph.transformchange, function () { return _this.set_data(); });
|
|
};
|
|
GlyphRendererView.prototype.have_selection_glyphs = function () {
|
|
return this.selection_glyph != null && this.nonselection_glyph != null;
|
|
};
|
|
// in case of partial updates like patching, the list of indices that actually
|
|
// changed may be passed as the "indices" parameter to afford any optional optimizations
|
|
GlyphRendererView.prototype.set_data = function (request_render, indices) {
|
|
if (request_render === void 0) {
|
|
request_render = true;
|
|
}
|
|
if (indices === void 0) {
|
|
indices = null;
|
|
}
|
|
var t0 = Date.now();
|
|
var source = this.model.data_source;
|
|
this.all_indices = this.model.view.indices;
|
|
// TODO (bev) this is a bit clunky, need to make sure glyphs use the correct ranges when they call
|
|
// mapping functions on the base Renderer class
|
|
this.glyph.model.setv({ x_range_name: this.model.x_range_name,
|
|
y_range_name: this.model.y_range_name }, { silent: true });
|
|
this.glyph.set_data(source, this.all_indices, indices);
|
|
this.glyph.set_visuals(source);
|
|
this.decimated_glyph.set_visuals(source);
|
|
if (this.have_selection_glyphs()) {
|
|
this.selection_glyph.set_visuals(source);
|
|
this.nonselection_glyph.set_visuals(source);
|
|
}
|
|
if (this.hover_glyph != null)
|
|
this.hover_glyph.set_visuals(source);
|
|
if (this.muted_glyph != null)
|
|
this.muted_glyph.set_visuals(source);
|
|
var lod_factor = this.plot_model.lod_factor;
|
|
this.decimated = [];
|
|
for (var i = 0, end = Math.floor(this.all_indices.length / lod_factor); i < end; i++) {
|
|
this.decimated.push(i * lod_factor);
|
|
}
|
|
var dt = Date.now() - t0;
|
|
logging_1.logger.debug(this.glyph.model.type + " GlyphRenderer (" + this.model.id + "): set_data finished in " + dt + "ms");
|
|
this.set_data_timestamp = Date.now();
|
|
if (request_render)
|
|
this.request_render();
|
|
};
|
|
GlyphRendererView.prototype.render = function () {
|
|
var _this = this;
|
|
if (!this.model.visible)
|
|
return;
|
|
var t0 = Date.now();
|
|
var glsupport = this.glyph.glglyph;
|
|
this.glyph.map_data();
|
|
var dtmap = Date.now() - t0;
|
|
var tmask = Date.now();
|
|
// all_indices is in full data space, indices is converted to subset space
|
|
// either by mask_data (that uses the spatial index) or manually
|
|
var indices = this.glyph.mask_data(this.all_indices);
|
|
if (indices.length === this.all_indices.length) {
|
|
indices = array_1.range(0, this.all_indices.length);
|
|
}
|
|
var dtmask = Date.now() - tmask;
|
|
var ctx = this.plot_view.canvas_view.ctx;
|
|
ctx.save();
|
|
// selected is in full set space
|
|
var selected = this.model.data_source.selected;
|
|
var selected_full_indices;
|
|
if (!selected || selected.is_empty()) {
|
|
selected_full_indices = [];
|
|
}
|
|
else {
|
|
if (this.glyph instanceof line_1.LineView && selected.selected_glyph === this.glyph.model) {
|
|
selected_full_indices = this.model.view.convert_indices_from_subset(indices);
|
|
}
|
|
else {
|
|
selected_full_indices = selected.indices;
|
|
}
|
|
}
|
|
// inspected is in full set space
|
|
var inspected = this.model.data_source.inspected;
|
|
var inspected_full_indices;
|
|
if (!inspected || (inspected.length === 0)) {
|
|
inspected_full_indices = [];
|
|
}
|
|
else {
|
|
if (inspected['0d'].glyph) {
|
|
inspected_full_indices = this.model.view.convert_indices_from_subset(indices);
|
|
}
|
|
else if (inspected['1d'].indices.length > 0) {
|
|
inspected_full_indices = inspected['1d'].indices;
|
|
}
|
|
else {
|
|
inspected_full_indices = ((function () {
|
|
var result = [];
|
|
for (var _i = 0, _a = Object.keys(inspected["2d"].indices); _i < _a.length; _i++) {
|
|
var i = _a[_i];
|
|
result.push(parseInt(i));
|
|
}
|
|
return result;
|
|
})());
|
|
}
|
|
}
|
|
// inspected is transformed to subset space
|
|
var inspected_subset_indices = ((function () {
|
|
var result = [];
|
|
for (var _i = 0, indices_2 = indices; _i < indices_2.length; _i++) {
|
|
var i = indices_2[_i];
|
|
if (array_1.includes(inspected_full_indices, _this.all_indices[i]))
|
|
result.push(i);
|
|
}
|
|
return result;
|
|
})());
|
|
var lod_threshold = this.plot_model.lod_threshold;
|
|
var glyph;
|
|
var nonselection_glyph;
|
|
var selection_glyph;
|
|
if ((this.model.document != null ? this.model.document.interactive_duration() > 0 : false)
|
|
&& !glsupport && lod_threshold != null && this.all_indices.length > lod_threshold) {
|
|
// Render decimated during interaction if too many elements and not using GL
|
|
indices = this.decimated;
|
|
glyph = this.decimated_glyph;
|
|
nonselection_glyph = this.decimated_glyph;
|
|
selection_glyph = this.selection_glyph;
|
|
}
|
|
else {
|
|
glyph = this.model.muted && this.muted_glyph != null ? this.muted_glyph : this.glyph;
|
|
nonselection_glyph = this.nonselection_glyph;
|
|
selection_glyph = this.selection_glyph;
|
|
}
|
|
if (this.hover_glyph != null && inspected_subset_indices.length)
|
|
indices = array_1.difference(indices, inspected_subset_indices);
|
|
// Render with no selection
|
|
var dtselect = null;
|
|
var trender;
|
|
if (!(selected_full_indices.length && this.have_selection_glyphs())) {
|
|
trender = Date.now();
|
|
if (this.glyph instanceof line_1.LineView) {
|
|
if (this.hover_glyph && inspected_subset_indices.length)
|
|
this.hover_glyph.render(ctx, this.model.view.convert_indices_from_subset(inspected_subset_indices), this.glyph);
|
|
else
|
|
glyph.render(ctx, this.all_indices, this.glyph);
|
|
}
|
|
else {
|
|
glyph.render(ctx, indices, this.glyph);
|
|
if (this.hover_glyph && inspected_subset_indices.length)
|
|
this.hover_glyph.render(ctx, inspected_subset_indices, this.glyph);
|
|
}
|
|
// Render with selection
|
|
}
|
|
else {
|
|
// reset the selection mask
|
|
var tselect = Date.now();
|
|
var selected_mask = {};
|
|
for (var _i = 0, selected_full_indices_1 = selected_full_indices; _i < selected_full_indices_1.length; _i++) {
|
|
var i = selected_full_indices_1[_i];
|
|
selected_mask[i] = true;
|
|
}
|
|
// intersect/different selection with render mask
|
|
var selected_subset_indices = new Array();
|
|
var nonselected_subset_indices = new Array();
|
|
// now, selected is changed to subset space, except for Line glyph
|
|
if (this.glyph instanceof line_1.LineView) {
|
|
for (var _a = 0, _b = this.all_indices; _a < _b.length; _a++) {
|
|
var i = _b[_a];
|
|
if (selected_mask[i] != null)
|
|
selected_subset_indices.push(i);
|
|
else
|
|
nonselected_subset_indices.push(i);
|
|
}
|
|
}
|
|
else {
|
|
for (var _c = 0, indices_1 = indices; _c < indices_1.length; _c++) {
|
|
var i = indices_1[_c];
|
|
if (selected_mask[this.all_indices[i]] != null)
|
|
selected_subset_indices.push(i);
|
|
else
|
|
nonselected_subset_indices.push(i);
|
|
}
|
|
}
|
|
dtselect = Date.now() - tselect;
|
|
trender = Date.now();
|
|
nonselection_glyph.render(ctx, nonselected_subset_indices, this.glyph);
|
|
selection_glyph.render(ctx, selected_subset_indices, this.glyph);
|
|
if (this.hover_glyph != null) {
|
|
if (this.glyph instanceof line_1.LineView)
|
|
this.hover_glyph.render(ctx, this.model.view.convert_indices_from_subset(inspected_subset_indices), this.glyph);
|
|
else
|
|
this.hover_glyph.render(ctx, inspected_subset_indices, this.glyph);
|
|
}
|
|
}
|
|
var dtrender = Date.now() - trender;
|
|
this.last_dtrender = dtrender;
|
|
var dttot = Date.now() - t0;
|
|
logging_1.logger.debug(this.glyph.model.type + " GlyphRenderer (" + this.model.id + "): render finished in " + dttot + "ms");
|
|
logging_1.logger.trace(" - map_data finished in : " + dtmap + "ms");
|
|
logging_1.logger.trace(" - mask_data finished in : " + dtmask + "ms");
|
|
if (dtselect != null) {
|
|
logging_1.logger.trace(" - selection mask finished in : " + dtselect + "ms");
|
|
}
|
|
logging_1.logger.trace(" - glyph renders finished in : " + dtrender + "ms");
|
|
return ctx.restore();
|
|
};
|
|
GlyphRendererView.prototype.draw_legend = function (ctx, x0, x1, y0, y1, field, label, index) {
|
|
if (index == null)
|
|
index = this.model.get_reference_point(field, label);
|
|
this.glyph.draw_legend_for_index(ctx, { x0: x0, x1: x1, y0: y0, y1: y1 }, index);
|
|
};
|
|
GlyphRendererView.prototype.hit_test = function (geometry) {
|
|
if (!this.model.visible)
|
|
return null;
|
|
var hit_test_result = this.glyph.hit_test(geometry);
|
|
// glyphs that don't have hit-testing implemented will return null
|
|
if (hit_test_result == null)
|
|
return null;
|
|
return this.model.view.convert_selection_from_subset(hit_test_result);
|
|
};
|
|
return GlyphRendererView;
|
|
}(data_renderer_1.DataRendererView));
|
|
exports.GlyphRendererView = GlyphRendererView;
|
|
var GlyphRenderer = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GlyphRenderer, _super);
|
|
function GlyphRenderer(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
GlyphRenderer.initClass = function () {
|
|
this.prototype.type = 'GlyphRenderer';
|
|
this.prototype.default_view = GlyphRendererView;
|
|
this.define({
|
|
data_source: [p.Instance],
|
|
view: [p.Instance, function () { return new cds_view_1.CDSView(); }],
|
|
glyph: [p.Instance],
|
|
hover_glyph: [p.Instance],
|
|
nonselection_glyph: [p.Any, 'auto'],
|
|
selection_glyph: [p.Any, 'auto'],
|
|
muted_glyph: [p.Instance],
|
|
muted: [p.Boolean, false],
|
|
});
|
|
};
|
|
GlyphRenderer.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
if (this.view.source == null) {
|
|
this.view.source = this.data_source;
|
|
this.view.compute_indices();
|
|
}
|
|
};
|
|
GlyphRenderer.prototype.get_reference_point = function (field, value) {
|
|
var index = 0;
|
|
if (field != null) {
|
|
var data = this.data_source.get_column(field);
|
|
if (data != null) {
|
|
var i = arrayable_1.indexOf(data, value);
|
|
if (i != -1)
|
|
index = i;
|
|
}
|
|
}
|
|
return index;
|
|
};
|
|
GlyphRenderer.prototype.get_selection_manager = function () {
|
|
return this.data_source.selection_manager;
|
|
};
|
|
return GlyphRenderer;
|
|
}(data_renderer_1.DataRenderer));
|
|
exports.GlyphRenderer = GlyphRenderer;
|
|
GlyphRenderer.initClass();
|
|
}
|
|
,
|
|
/* models/renderers/graph_renderer */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var data_renderer_1 = require(192) /* ./data_renderer */;
|
|
var graph_hit_test_policy_1 = require(151) /* ../graphs/graph_hit_test_policy */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var build_views_1 = require(4) /* ../../core/build_views */;
|
|
var GraphRendererView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GraphRendererView, _super);
|
|
function GraphRendererView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
GraphRendererView.prototype.initialize = function () {
|
|
var _a;
|
|
_super.prototype.initialize.call(this);
|
|
this.xscale = this.plot_view.frame.xscales.default;
|
|
this.yscale = this.plot_view.frame.yscales.default;
|
|
this._renderer_views = {};
|
|
_a = build_views_1.build_views(this._renderer_views, [this.model.node_renderer, this.model.edge_renderer], { parent: this.parent }), this.node_view = _a[0], this.edge_view = _a[1];
|
|
this.set_data();
|
|
};
|
|
GraphRendererView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.layout_provider.change, function () { return _this.set_data(); });
|
|
this.connect(this.model.node_renderer.data_source._select, function () { return _this.set_data(); });
|
|
this.connect(this.model.node_renderer.data_source.inspect, function () { return _this.set_data(); });
|
|
this.connect(this.model.node_renderer.data_source.change, function () { return _this.set_data(); });
|
|
this.connect(this.model.edge_renderer.data_source._select, function () { return _this.set_data(); });
|
|
this.connect(this.model.edge_renderer.data_source.inspect, function () { return _this.set_data(); });
|
|
this.connect(this.model.edge_renderer.data_source.change, function () { return _this.set_data(); });
|
|
var _a = this.plot_view.frame, x_ranges = _a.x_ranges, y_ranges = _a.y_ranges;
|
|
for (var name_1 in x_ranges) {
|
|
var rng = x_ranges[name_1];
|
|
this.connect(rng.change, function () { return _this.set_data(); });
|
|
}
|
|
for (var name_2 in y_ranges) {
|
|
var rng = y_ranges[name_2];
|
|
this.connect(rng.change, function () { return _this.set_data(); });
|
|
}
|
|
};
|
|
GraphRendererView.prototype.set_data = function (request_render) {
|
|
var _a, _b;
|
|
if (request_render === void 0) {
|
|
request_render = true;
|
|
}
|
|
// TODO (bev) this is a bit clunky, need to make sure glyphs use the correct ranges when they call
|
|
// mapping functions on the base Renderer class
|
|
this.node_view.glyph.model.setv({ x_range_name: this.model.x_range_name, y_range_name: this.model.y_range_name }, { silent: true });
|
|
this.edge_view.glyph.model.setv({ x_range_name: this.model.x_range_name, y_range_name: this.model.y_range_name }, { silent: true });
|
|
// XXX
|
|
var node_glyph = this.node_view.glyph;
|
|
_a = this.model.layout_provider.get_node_coordinates(this.model.node_renderer.data_source), node_glyph._x = _a[0], node_glyph._y = _a[1];
|
|
var edge_glyph = this.edge_view.glyph;
|
|
_b = this.model.layout_provider.get_edge_coordinates(this.model.edge_renderer.data_source), edge_glyph._xs = _b[0], edge_glyph._ys = _b[1];
|
|
node_glyph.index_data();
|
|
edge_glyph.index_data();
|
|
if (request_render)
|
|
this.request_render();
|
|
};
|
|
GraphRendererView.prototype.render = function () {
|
|
this.edge_view.render();
|
|
this.node_view.render();
|
|
};
|
|
return GraphRendererView;
|
|
}(data_renderer_1.DataRendererView));
|
|
exports.GraphRendererView = GraphRendererView;
|
|
var GraphRenderer = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GraphRenderer, _super);
|
|
function GraphRenderer(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
GraphRenderer.initClass = function () {
|
|
this.prototype.type = 'GraphRenderer';
|
|
this.prototype.default_view = GraphRendererView;
|
|
this.define({
|
|
layout_provider: [p.Instance],
|
|
node_renderer: [p.Instance],
|
|
edge_renderer: [p.Instance],
|
|
selection_policy: [p.Instance, function () { return new graph_hit_test_policy_1.NodesOnly(); }],
|
|
inspection_policy: [p.Instance, function () { return new graph_hit_test_policy_1.NodesOnly(); }],
|
|
});
|
|
};
|
|
GraphRenderer.prototype.get_selection_manager = function () {
|
|
return this.node_renderer.data_source.selection_manager;
|
|
};
|
|
return GraphRenderer;
|
|
}(data_renderer_1.DataRenderer));
|
|
exports.GraphRenderer = GraphRenderer;
|
|
GraphRenderer.initClass();
|
|
}
|
|
,
|
|
/* models/renderers/guide_renderer */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var renderer_1 = require(197) /* ./renderer */;
|
|
var GuideRendererView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GuideRendererView, _super);
|
|
function GuideRendererView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return GuideRendererView;
|
|
}(renderer_1.RendererView));
|
|
exports.GuideRendererView = GuideRendererView;
|
|
var GuideRenderer = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GuideRenderer, _super);
|
|
function GuideRenderer(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
GuideRenderer.initClass = function () {
|
|
this.prototype.type = "GuideRenderer";
|
|
this.override({
|
|
level: "overlay",
|
|
});
|
|
};
|
|
return GuideRenderer;
|
|
}(renderer_1.Renderer));
|
|
exports.GuideRenderer = GuideRenderer;
|
|
GuideRenderer.initClass();
|
|
}
|
|
,
|
|
/* models/renderers/index */ function _(require, module, exports) {
|
|
var glyph_renderer_1 = require(193) /* ./glyph_renderer */;
|
|
exports.GlyphRenderer = glyph_renderer_1.GlyphRenderer;
|
|
var graph_renderer_1 = require(194) /* ./graph_renderer */;
|
|
exports.GraphRenderer = graph_renderer_1.GraphRenderer;
|
|
var guide_renderer_1 = require(195) /* ./guide_renderer */;
|
|
exports.GuideRenderer = guide_renderer_1.GuideRenderer;
|
|
var renderer_1 = require(197) /* ./renderer */;
|
|
exports.Renderer = renderer_1.Renderer;
|
|
}
|
|
,
|
|
/* models/renderers/renderer */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var dom_view_1 = require(6) /* ../../core/dom_view */;
|
|
var visuals = require(51) /* ../../core/visuals */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
// This shouldn't be a DOMView, but annotations create a mess.
|
|
var RendererView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(RendererView, _super);
|
|
function RendererView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
RendererView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.visuals = new visuals.Visuals(this.model);
|
|
this._has_finished = true; // XXX: should be in render() but subclasses don't respect super()
|
|
};
|
|
Object.defineProperty(RendererView.prototype, "plot_view", {
|
|
get: function () {
|
|
return this.parent;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(RendererView.prototype, "plot_model", {
|
|
get: function () {
|
|
return this.parent.model;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
RendererView.prototype.request_render = function () {
|
|
this.plot_view.request_render();
|
|
};
|
|
RendererView.prototype.map_to_screen = function (x, y) {
|
|
return this.plot_view.map_to_screen(x, y, this.model.x_range_name, this.model.y_range_name);
|
|
};
|
|
Object.defineProperty(RendererView.prototype, "needs_clip", {
|
|
get: function () {
|
|
return false;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
RendererView.prototype.notify_finished = function () {
|
|
this.plot_view.notify_finished();
|
|
};
|
|
return RendererView;
|
|
}(dom_view_1.DOMView));
|
|
exports.RendererView = RendererView;
|
|
var Renderer = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Renderer, _super);
|
|
function Renderer(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Renderer.initClass = function () {
|
|
this.prototype.type = "Renderer";
|
|
this.define({
|
|
level: [p.RenderLevel],
|
|
visible: [p.Boolean, true],
|
|
});
|
|
};
|
|
return Renderer;
|
|
}(model_1.Model));
|
|
exports.Renderer = Renderer;
|
|
Renderer.initClass();
|
|
}
|
|
,
|
|
/* models/scales/categorical_scale */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var linear_scale_1 = require(200) /* ./linear_scale */;
|
|
var CategoricalScale = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CategoricalScale, _super);
|
|
function CategoricalScale(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CategoricalScale.initClass = function () {
|
|
this.prototype.type = "CategoricalScale";
|
|
};
|
|
CategoricalScale.prototype.compute = function (x) {
|
|
return _super.prototype.compute.call(this, this.source_range.synthetic(x));
|
|
};
|
|
CategoricalScale.prototype.v_compute = function (xs) {
|
|
return _super.prototype.v_compute.call(this, this.source_range.v_synthetic(xs));
|
|
};
|
|
return CategoricalScale;
|
|
}(linear_scale_1.LinearScale));
|
|
exports.CategoricalScale = CategoricalScale;
|
|
CategoricalScale.initClass();
|
|
}
|
|
,
|
|
/* models/scales/index */ function _(require, module, exports) {
|
|
var categorical_scale_1 = require(198) /* ./categorical_scale */;
|
|
exports.CategoricalScale = categorical_scale_1.CategoricalScale;
|
|
var linear_scale_1 = require(200) /* ./linear_scale */;
|
|
exports.LinearScale = linear_scale_1.LinearScale;
|
|
var log_scale_1 = require(201) /* ./log_scale */;
|
|
exports.LogScale = log_scale_1.LogScale;
|
|
var scale_1 = require(202) /* ./scale */;
|
|
exports.Scale = scale_1.Scale;
|
|
}
|
|
,
|
|
/* models/scales/linear_scale */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var scale_1 = require(202) /* ./scale */;
|
|
var LinearScale = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LinearScale, _super);
|
|
function LinearScale(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
LinearScale.initClass = function () {
|
|
this.prototype.type = "LinearScale";
|
|
};
|
|
LinearScale.prototype.compute = function (x) {
|
|
var _a = this._compute_state(), factor = _a[0], offset = _a[1];
|
|
return factor * x + offset;
|
|
};
|
|
LinearScale.prototype.v_compute = function (xs) {
|
|
var _a = this._compute_state(), factor = _a[0], offset = _a[1];
|
|
var result = new Float64Array(xs.length);
|
|
for (var i = 0; i < xs.length; i++)
|
|
result[i] = factor * xs[i] + offset;
|
|
return result;
|
|
};
|
|
LinearScale.prototype.invert = function (xprime) {
|
|
var _a = this._compute_state(), factor = _a[0], offset = _a[1];
|
|
return (xprime - offset) / factor;
|
|
};
|
|
LinearScale.prototype.v_invert = function (xprimes) {
|
|
var _a = this._compute_state(), factor = _a[0], offset = _a[1];
|
|
var result = new Float64Array(xprimes.length);
|
|
for (var i = 0; i < xprimes.length; i++)
|
|
result[i] = (xprimes[i] - offset) / factor;
|
|
return result;
|
|
};
|
|
/*protected*/ LinearScale.prototype._compute_state = function () {
|
|
//
|
|
// (t1 - t0) (t1 - t0)
|
|
// --------- * x - --------- * s0 + t0
|
|
// (s1 - s0) (s1 - s0)
|
|
//
|
|
// [ factor ] [ offset ]
|
|
//
|
|
var source_start = this.source_range.start;
|
|
var source_end = this.source_range.end;
|
|
var target_start = this.target_range.start;
|
|
var target_end = this.target_range.end;
|
|
var factor = (target_end - target_start) / (source_end - source_start);
|
|
var offset = -(factor * source_start) + target_start;
|
|
return [factor, offset];
|
|
};
|
|
return LinearScale;
|
|
}(scale_1.Scale));
|
|
exports.LinearScale = LinearScale;
|
|
LinearScale.initClass();
|
|
}
|
|
,
|
|
/* models/scales/log_scale */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var scale_1 = require(202) /* ./scale */;
|
|
var LogScale = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LogScale, _super);
|
|
function LogScale(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
LogScale.initClass = function () {
|
|
this.prototype.type = "LogScale";
|
|
};
|
|
LogScale.prototype.compute = function (x) {
|
|
var _a = this._compute_state(), factor = _a[0], offset = _a[1], inter_factor = _a[2], inter_offset = _a[3];
|
|
var value;
|
|
if (inter_factor == 0)
|
|
value = 0;
|
|
else {
|
|
var _x = (Math.log(x) - inter_offset) / inter_factor;
|
|
if (isFinite(_x))
|
|
value = _x * factor + offset;
|
|
else
|
|
value = NaN;
|
|
}
|
|
return value;
|
|
};
|
|
LogScale.prototype.v_compute = function (xs) {
|
|
var _a = this._compute_state(), factor = _a[0], offset = _a[1], inter_factor = _a[2], inter_offset = _a[3];
|
|
var result = new Float64Array(xs.length);
|
|
if (inter_factor == 0) {
|
|
for (var i = 0; i < xs.length; i++)
|
|
result[i] = 0;
|
|
}
|
|
else {
|
|
for (var i = 0; i < xs.length; i++) {
|
|
var _x = (Math.log(xs[i]) - inter_offset) / inter_factor;
|
|
var value = void 0;
|
|
if (isFinite(_x))
|
|
value = _x * factor + offset;
|
|
else
|
|
value = NaN;
|
|
result[i] = value;
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
LogScale.prototype.invert = function (xprime) {
|
|
var _a = this._compute_state(), factor = _a[0], offset = _a[1], inter_factor = _a[2], inter_offset = _a[3];
|
|
var value = (xprime - offset) / factor;
|
|
return Math.exp(inter_factor * value + inter_offset);
|
|
};
|
|
LogScale.prototype.v_invert = function (xprimes) {
|
|
var _a = this._compute_state(), factor = _a[0], offset = _a[1], inter_factor = _a[2], inter_offset = _a[3];
|
|
var result = new Float64Array(xprimes.length);
|
|
for (var i = 0; i < xprimes.length; i++) {
|
|
var value = (xprimes[i] - offset) / factor;
|
|
result[i] = Math.exp(inter_factor * value + inter_offset);
|
|
}
|
|
return result;
|
|
};
|
|
LogScale.prototype._get_safe_factor = function (orig_start, orig_end) {
|
|
var _a;
|
|
var start = orig_start < 0 ? 0 : orig_start;
|
|
var end = orig_end < 0 ? 0 : orig_end;
|
|
if (start == end) {
|
|
if (start == 0)
|
|
_a = [1, 10], start = _a[0], end = _a[1];
|
|
else {
|
|
var log_val = Math.log(start) / Math.log(10);
|
|
start = Math.pow(10, Math.floor(log_val));
|
|
if (Math.ceil(log_val) != Math.floor(log_val))
|
|
end = Math.pow(10, Math.ceil(log_val));
|
|
else
|
|
end = Math.pow(10, Math.ceil(log_val) + 1);
|
|
}
|
|
}
|
|
return [start, end];
|
|
};
|
|
/*protected*/ LogScale.prototype._compute_state = function () {
|
|
var source_start = this.source_range.start;
|
|
var source_end = this.source_range.end;
|
|
var target_start = this.target_range.start;
|
|
var target_end = this.target_range.end;
|
|
var screen_range = target_end - target_start;
|
|
var _a = this._get_safe_factor(source_start, source_end), start = _a[0], end = _a[1];
|
|
var inter_factor;
|
|
var inter_offset;
|
|
if (start == 0) {
|
|
inter_factor = Math.log(end);
|
|
inter_offset = 0;
|
|
}
|
|
else {
|
|
inter_factor = Math.log(end) - Math.log(start);
|
|
inter_offset = Math.log(start);
|
|
}
|
|
var factor = screen_range;
|
|
var offset = target_start;
|
|
return [factor, offset, inter_factor, inter_offset];
|
|
};
|
|
return LogScale;
|
|
}(scale_1.Scale));
|
|
exports.LogScale = LogScale;
|
|
LogScale.initClass();
|
|
}
|
|
,
|
|
/* models/scales/scale */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var transforms_1 = require(284) /* ../transforms */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var Scale = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Scale, _super);
|
|
function Scale(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Scale.initClass = function () {
|
|
this.prototype.type = "Scale";
|
|
this.internal({
|
|
source_range: [p.Any],
|
|
target_range: [p.Any],
|
|
});
|
|
};
|
|
Scale.prototype.r_compute = function (x0, x1) {
|
|
if (this.target_range.is_reversed)
|
|
return [this.compute(x1), this.compute(x0)];
|
|
else
|
|
return [this.compute(x0), this.compute(x1)];
|
|
};
|
|
Scale.prototype.r_invert = function (sx0, sx1) {
|
|
if (this.target_range.is_reversed)
|
|
return [this.invert(sx1), this.invert(sx0)];
|
|
else
|
|
return [this.invert(sx0), this.invert(sx1)];
|
|
};
|
|
return Scale;
|
|
}(transforms_1.Transform));
|
|
exports.Scale = Scale;
|
|
Scale.initClass();
|
|
}
|
|
,
|
|
/* models/selections/index */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
tslib_1.__exportStar(require(204) /* ./interaction_policy */, exports);
|
|
var selection_1 = require(205) /* ./selection */;
|
|
exports.Selection = selection_1.Selection;
|
|
}
|
|
,
|
|
/* models/selections/interaction_policy */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var SelectionPolicy = /** @class */ (function (_super) {
|
|
tslib_1.__extends(SelectionPolicy, _super);
|
|
function SelectionPolicy() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
SelectionPolicy.prototype.do_selection = function (hit_test_result, source, final, append) {
|
|
if (hit_test_result === null) {
|
|
return false;
|
|
}
|
|
else {
|
|
source.selected.update(hit_test_result, final, append);
|
|
source._select.emit();
|
|
return !source.selected.is_empty();
|
|
}
|
|
};
|
|
return SelectionPolicy;
|
|
}(model_1.Model));
|
|
exports.SelectionPolicy = SelectionPolicy;
|
|
SelectionPolicy.prototype.type = "SelectionPolicy";
|
|
var IntersectRenderers = /** @class */ (function (_super) {
|
|
tslib_1.__extends(IntersectRenderers, _super);
|
|
function IntersectRenderers() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
IntersectRenderers.prototype.hit_test = function (geometry, renderer_views) {
|
|
var hit_test_result_renderers = [];
|
|
for (var _i = 0, renderer_views_1 = renderer_views; _i < renderer_views_1.length; _i++) {
|
|
var r = renderer_views_1[_i];
|
|
var result = r.hit_test(geometry);
|
|
if (result !== null)
|
|
hit_test_result_renderers.push(result);
|
|
}
|
|
if (hit_test_result_renderers.length > 0) {
|
|
var hit_test_result = hit_test_result_renderers[0];
|
|
for (var _a = 0, hit_test_result_renderers_1 = hit_test_result_renderers; _a < hit_test_result_renderers_1.length; _a++) {
|
|
var hit_test_result_other = hit_test_result_renderers_1[_a];
|
|
hit_test_result.update_through_intersection(hit_test_result_other);
|
|
}
|
|
return hit_test_result;
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
};
|
|
return IntersectRenderers;
|
|
}(SelectionPolicy));
|
|
exports.IntersectRenderers = IntersectRenderers;
|
|
IntersectRenderers.prototype.type = "IntersectRenderers";
|
|
var UnionRenderers = /** @class */ (function (_super) {
|
|
tslib_1.__extends(UnionRenderers, _super);
|
|
function UnionRenderers() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
UnionRenderers.prototype.hit_test = function (geometry, renderer_views) {
|
|
var hit_test_result_renderers = [];
|
|
for (var _i = 0, renderer_views_2 = renderer_views; _i < renderer_views_2.length; _i++) {
|
|
var r = renderer_views_2[_i];
|
|
var result = r.hit_test(geometry);
|
|
if (result !== null)
|
|
hit_test_result_renderers.push(result);
|
|
}
|
|
if (hit_test_result_renderers.length > 0) {
|
|
var hit_test_result = hit_test_result_renderers[0];
|
|
for (var _a = 0, hit_test_result_renderers_2 = hit_test_result_renderers; _a < hit_test_result_renderers_2.length; _a++) {
|
|
var hit_test_result_other = hit_test_result_renderers_2[_a];
|
|
hit_test_result.update_through_union(hit_test_result_other);
|
|
}
|
|
return hit_test_result;
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
};
|
|
return UnionRenderers;
|
|
}(SelectionPolicy));
|
|
exports.UnionRenderers = UnionRenderers;
|
|
UnionRenderers.prototype.type = "UnionRenderers";
|
|
}
|
|
,
|
|
/* models/selections/selection */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var Selection = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Selection, _super);
|
|
function Selection(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Selection.initClass = function () {
|
|
this.prototype.type = "Selection";
|
|
this.define({
|
|
indices: [p.Array, []],
|
|
line_indices: [p.Array, []],
|
|
multiline_indices: [p.Any, {}],
|
|
});
|
|
this.internal({
|
|
final: [p.Boolean],
|
|
selected_glyphs: [p.Array, []],
|
|
get_view: [p.Any],
|
|
image_indices: [p.Array, []],
|
|
});
|
|
};
|
|
Selection.prototype.initialize = function () {
|
|
var _this = this;
|
|
_super.prototype.initialize.call(this);
|
|
this['0d'] = { glyph: null, indices: [], flag: false, get_view: function () { return null; } };
|
|
this['2d'] = { indices: {} };
|
|
this['1d'] = { indices: this.indices };
|
|
this.get_view = function () { return null; };
|
|
this.connect(this.properties.indices.change, function () {
|
|
return _this['1d'].indices = _this.indices;
|
|
});
|
|
this.connect(this.properties.line_indices.change, function () {
|
|
_this['0d'].indices = _this.line_indices;
|
|
if (_this.line_indices.length == 0)
|
|
_this['0d'].flag = false;
|
|
else
|
|
_this['0d'].flag = true;
|
|
});
|
|
this.connect(this.properties.selected_glyphs.change, function () {
|
|
return _this['0d'].glyph = _this.selected_glyph;
|
|
});
|
|
this.connect(this.properties.get_view.change, function () {
|
|
return _this['0d'].get_view = _this.get_view;
|
|
});
|
|
this.connect(this.properties.multiline_indices.change, function () {
|
|
return _this['2d'].indices = _this.multiline_indices;
|
|
});
|
|
};
|
|
Object.defineProperty(Selection.prototype, "selected_glyph", {
|
|
get: function () {
|
|
if (this.selected_glyphs.length > 0)
|
|
return this.selected_glyphs[0];
|
|
else
|
|
return null;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Selection.prototype.add_to_selected_glyphs = function (glyph) {
|
|
this.selected_glyphs.push(glyph);
|
|
};
|
|
Selection.prototype.update = function (selection, final, append) {
|
|
this.final = final;
|
|
if (append)
|
|
this.update_through_union(selection);
|
|
else {
|
|
this.indices = selection.indices;
|
|
this.line_indices = selection.line_indices;
|
|
this.selected_glyphs = selection.selected_glyphs;
|
|
this.get_view = selection.get_view;
|
|
this.multiline_indices = selection.multiline_indices;
|
|
this.image_indices = selection.image_indices;
|
|
}
|
|
};
|
|
Selection.prototype.clear = function () {
|
|
this.final = true;
|
|
this.indices = [];
|
|
this.line_indices = [];
|
|
this.multiline_indices = {};
|
|
this.get_view = function () { return null; };
|
|
this.selected_glyphs = [];
|
|
};
|
|
Selection.prototype.is_empty = function () {
|
|
return this.indices.length == 0 && this.line_indices.length == 0 && this.image_indices.length == 0;
|
|
};
|
|
Selection.prototype.update_through_union = function (other) {
|
|
this.indices = array_1.union(other.indices, this.indices);
|
|
this.selected_glyphs = array_1.union(other.selected_glyphs, this.selected_glyphs);
|
|
this.line_indices = array_1.union(other.line_indices, this.line_indices);
|
|
if (!this.get_view())
|
|
this.get_view = other.get_view;
|
|
this.multiline_indices = object_1.merge(other.multiline_indices, this.multiline_indices);
|
|
};
|
|
Selection.prototype.update_through_intersection = function (other) {
|
|
this.indices = array_1.intersection(other.indices, this.indices);
|
|
// TODO: think through and fix any logic below
|
|
this.selected_glyphs = array_1.union(other.selected_glyphs, this.selected_glyphs);
|
|
this.line_indices = array_1.union(other.line_indices, this.line_indices);
|
|
if (!this.get_view())
|
|
this.get_view = other.get_view;
|
|
this.multiline_indices = object_1.merge(other.multiline_indices, this.multiline_indices);
|
|
};
|
|
return Selection;
|
|
}(model_1.Model));
|
|
exports.Selection = Selection;
|
|
Selection.initClass();
|
|
}
|
|
,
|
|
/* models/sources/ajax_data_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var remote_data_source_1 = require(213) /* ./remote_data_source */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var AjaxDataSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(AjaxDataSource, _super);
|
|
function AjaxDataSource(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.initialized = false;
|
|
return _this;
|
|
}
|
|
AjaxDataSource.initClass = function () {
|
|
this.prototype.type = 'AjaxDataSource';
|
|
this.define({
|
|
content_type: [p.String, 'application/json'],
|
|
http_headers: [p.Any, {}],
|
|
method: [p.HTTPMethod, 'POST'],
|
|
if_modified: [p.Boolean, false],
|
|
});
|
|
};
|
|
AjaxDataSource.prototype.destroy = function () {
|
|
if (this.interval != null)
|
|
clearInterval(this.interval);
|
|
_super.prototype.destroy.call(this);
|
|
};
|
|
AjaxDataSource.prototype.setup = function () {
|
|
var _this = this;
|
|
if (!this.initialized) {
|
|
this.initialized = true;
|
|
this.get_data(this.mode);
|
|
if (this.polling_interval) {
|
|
var callback = function () { return _this.get_data(_this.mode, _this.max_size, _this.if_modified); };
|
|
this.interval = setInterval(callback, this.polling_interval);
|
|
}
|
|
}
|
|
};
|
|
AjaxDataSource.prototype.get_data = function (mode, max_size, _if_modified) {
|
|
var _this = this;
|
|
if (max_size === void 0) {
|
|
max_size = 0;
|
|
}
|
|
if (_if_modified === void 0) {
|
|
_if_modified = false;
|
|
}
|
|
var xhr = this.prepare_request();
|
|
// TODO: if_modified
|
|
xhr.addEventListener("load", function () { return _this.do_load(xhr, mode, max_size); });
|
|
xhr.addEventListener("error", function () { return _this.do_error(xhr); });
|
|
xhr.send();
|
|
};
|
|
AjaxDataSource.prototype.prepare_request = function () {
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open(this.method, this.data_url, true);
|
|
xhr.withCredentials = false;
|
|
xhr.setRequestHeader("Content-Type", this.content_type);
|
|
var http_headers = this.http_headers;
|
|
for (var name_1 in http_headers) {
|
|
var value = http_headers[name_1];
|
|
xhr.setRequestHeader(name_1, value);
|
|
}
|
|
return xhr;
|
|
};
|
|
AjaxDataSource.prototype.do_load = function (xhr, mode, max_size) {
|
|
if (xhr.status === 200) {
|
|
var raw_data = JSON.parse(xhr.responseText);
|
|
this.load_data(raw_data, mode, max_size);
|
|
}
|
|
};
|
|
AjaxDataSource.prototype.do_error = function (xhr) {
|
|
logging_1.logger.error("Failed to fetch JSON from " + this.data_url + " with code " + xhr.status);
|
|
};
|
|
return AjaxDataSource;
|
|
}(remote_data_source_1.RemoteDataSource));
|
|
exports.AjaxDataSource = AjaxDataSource;
|
|
AjaxDataSource.initClass();
|
|
}
|
|
,
|
|
/* models/sources/cds_view */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var selection_1 = require(205) /* ../selections/selection */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var columnar_data_source_1 = require(209) /* ./columnar_data_source */;
|
|
var CDSView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CDSView, _super);
|
|
function CDSView(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CDSView.initClass = function () {
|
|
this.prototype.type = 'CDSView';
|
|
this.define({
|
|
filters: [p.Array, []],
|
|
source: [p.Instance],
|
|
});
|
|
this.internal({
|
|
indices: [p.Array, []],
|
|
indices_map: [p.Any, {}],
|
|
});
|
|
};
|
|
CDSView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.compute_indices();
|
|
};
|
|
CDSView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.properties.filters.change, function () {
|
|
_this.compute_indices();
|
|
_this.change.emit();
|
|
});
|
|
var connect_listeners = function () {
|
|
var fn = function () { return _this.compute_indices(); };
|
|
if (_this.source != null) {
|
|
_this.connect(_this.source.change, fn);
|
|
if (_this.source instanceof columnar_data_source_1.ColumnarDataSource) {
|
|
_this.connect(_this.source.streaming, fn);
|
|
_this.connect(_this.source.patching, fn);
|
|
}
|
|
}
|
|
};
|
|
var initialized = this.source != null;
|
|
if (initialized)
|
|
connect_listeners();
|
|
else {
|
|
this.connect(this.properties.source.change, function () {
|
|
if (!initialized) {
|
|
connect_listeners();
|
|
initialized = true;
|
|
}
|
|
});
|
|
}
|
|
};
|
|
CDSView.prototype.compute_indices = function () {
|
|
var _this = this;
|
|
var indices = this.filters.map(function (filter) { return filter.compute_indices(_this.source); })
|
|
.filter(function (indices) { return indices != null; });
|
|
if (indices.length > 0)
|
|
this.indices = array_1.intersection.apply(this, indices);
|
|
else if (this.source instanceof columnar_data_source_1.ColumnarDataSource)
|
|
this.indices = this.source.get_indices();
|
|
this.indices_map_to_subset();
|
|
};
|
|
CDSView.prototype.indices_map_to_subset = function () {
|
|
this.indices_map = {};
|
|
for (var i = 0; i < this.indices.length; i++) {
|
|
this.indices_map[this.indices[i]] = i;
|
|
}
|
|
};
|
|
CDSView.prototype.convert_selection_from_subset = function (selection_subset) {
|
|
var _this = this;
|
|
var selection_full = new selection_1.Selection();
|
|
selection_full.update_through_union(selection_subset);
|
|
var indices_1d = selection_subset.indices.map(function (i) { return _this.indices[i]; });
|
|
selection_full.indices = indices_1d;
|
|
selection_full.image_indices = selection_subset.image_indices;
|
|
return selection_full;
|
|
};
|
|
CDSView.prototype.convert_selection_to_subset = function (selection_full) {
|
|
var _this = this;
|
|
var selection_subset = new selection_1.Selection();
|
|
selection_subset.update_through_union(selection_full);
|
|
var indices_1d = selection_full.indices.map(function (i) { return _this.indices_map[i]; });
|
|
selection_subset.indices = indices_1d;
|
|
selection_subset.image_indices = selection_full.image_indices;
|
|
return selection_subset;
|
|
};
|
|
CDSView.prototype.convert_indices_from_subset = function (indices) {
|
|
var _this = this;
|
|
return indices.map(function (i) { return _this.indices[i]; });
|
|
};
|
|
return CDSView;
|
|
}(model_1.Model));
|
|
exports.CDSView = CDSView;
|
|
CDSView.initClass();
|
|
}
|
|
,
|
|
/* models/sources/column_data_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var columnar_data_source_1 = require(209) /* ./columnar_data_source */;
|
|
var has_props_1 = require(8) /* ../../core/has_props */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var data_structures_1 = require(32) /* ../../core/util/data_structures */;
|
|
var serialization_1 = require(38) /* ../../core/util/serialization */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var typed_array = require(45) /* ../../core/util/typed_array */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var events_1 = require(53) /* ../../document/events */;
|
|
//exported for testing
|
|
function stream_to_column(col, new_col, rollover) {
|
|
if (types_1.isArray(col)) {
|
|
var result = col.concat(new_col);
|
|
if (rollover != null && result.length > rollover)
|
|
return result.slice(-rollover);
|
|
else
|
|
return result;
|
|
}
|
|
else if (types_1.isTypedArray(col)) {
|
|
var total_len = col.length + new_col.length;
|
|
// handle rollover case for typed arrays
|
|
if (rollover != null && total_len > rollover) {
|
|
var start = total_len - rollover;
|
|
var end = col.length;
|
|
// resize col if it is shorter than the rollover length
|
|
var result = void 0;
|
|
if (col.length < rollover) {
|
|
result = new (col.constructor)(rollover);
|
|
result.set(col, 0);
|
|
}
|
|
else
|
|
result = col;
|
|
// shift values in original col to accommodate new_col
|
|
for (var i = start, endi = end; i < endi; i++) {
|
|
result[i - start] = result[i];
|
|
}
|
|
// update end values in col with new_col
|
|
for (var i = 0, endi = new_col.length; i < endi; i++) {
|
|
result[i + (end - start)] = new_col[i];
|
|
}
|
|
return result;
|
|
}
|
|
else {
|
|
var tmp = new (col.constructor)(new_col);
|
|
return typed_array.concat(col, tmp);
|
|
}
|
|
}
|
|
else
|
|
throw new Error("unsupported array types");
|
|
}
|
|
exports.stream_to_column = stream_to_column;
|
|
// exported for testing
|
|
function slice(ind, length) {
|
|
var start, step, stop;
|
|
if (types_1.isNumber(ind)) {
|
|
start = ind;
|
|
stop = ind + 1;
|
|
step = 1;
|
|
}
|
|
else {
|
|
start = ind.start != null ? ind.start : 0;
|
|
stop = ind.stop != null ? ind.stop : length;
|
|
step = ind.step != null ? ind.step : 1;
|
|
}
|
|
return [start, stop, step];
|
|
}
|
|
exports.slice = slice;
|
|
// exported for testing
|
|
function patch_to_column(col, patch, shapes) {
|
|
var patched = new data_structures_1.Set();
|
|
var patched_range = false;
|
|
for (var _i = 0, patch_1 = patch; _i < patch_1.length; _i++) {
|
|
var _a = patch_1[_i], ind = _a[0], val = _a[1];
|
|
// make the single index case look like the length-3 multi-index case
|
|
var item = void 0, shape = void 0;
|
|
var index = void 0;
|
|
var value = void 0;
|
|
if (types_1.isArray(ind)) {
|
|
var i = ind[0];
|
|
patched.add(i);
|
|
shape = shapes[i];
|
|
item = col[i];
|
|
value = val;
|
|
// this is basically like NumPy's "newaxis", inserting an empty dimension
|
|
// makes length 2 and 3 multi-index cases uniform, so that the same code
|
|
// can handle both
|
|
if (ind.length === 2) {
|
|
shape = [1, shape[0]];
|
|
index = [ind[0], 0, ind[1]];
|
|
}
|
|
else
|
|
index = ind;
|
|
}
|
|
else {
|
|
if (types_1.isNumber(ind)) {
|
|
value = [val];
|
|
patched.add(ind);
|
|
}
|
|
else {
|
|
value = val;
|
|
patched_range = true;
|
|
}
|
|
index = [0, 0, ind];
|
|
shape = [1, col.length];
|
|
item = col;
|
|
}
|
|
// now this one nested loop handles all cases
|
|
var flat_index = 0;
|
|
var _b = slice(index[1], shape[0]), istart = _b[0], istop = _b[1], istep = _b[2];
|
|
var _c = slice(index[2], shape[1]), jstart = _c[0], jstop = _c[1], jstep = _c[2];
|
|
for (var i = istart; i < istop; i += istep) {
|
|
for (var j = jstart; j < jstop; j += jstep) {
|
|
if (patched_range) {
|
|
patched.add(j);
|
|
}
|
|
item[(i * shape[1]) + j] = value[flat_index];
|
|
flat_index++;
|
|
}
|
|
}
|
|
}
|
|
return patched;
|
|
}
|
|
exports.patch_to_column = patch_to_column;
|
|
var ColumnDataSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ColumnDataSource, _super);
|
|
function ColumnDataSource(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ColumnDataSource.initClass = function () {
|
|
this.prototype.type = 'ColumnDataSource';
|
|
this.define({
|
|
data: [p.Any, {}],
|
|
});
|
|
};
|
|
ColumnDataSource.prototype.initialize = function () {
|
|
var _a;
|
|
_super.prototype.initialize.call(this);
|
|
_a = serialization_1.decode_column_data(this.data), this.data = _a[0], this._shapes = _a[1];
|
|
};
|
|
ColumnDataSource.prototype.attributes_as_json = function (include_defaults, value_to_json) {
|
|
if (include_defaults === void 0) {
|
|
include_defaults = true;
|
|
}
|
|
if (value_to_json === void 0) {
|
|
value_to_json = ColumnDataSource._value_to_json;
|
|
}
|
|
var attrs = {};
|
|
var obj = this.serializable_attributes();
|
|
for (var _i = 0, _a = object_1.keys(obj); _i < _a.length; _i++) {
|
|
var key = _a[_i];
|
|
var value = obj[key];
|
|
if (key === 'data')
|
|
value = serialization_1.encode_column_data(value, this._shapes);
|
|
if (include_defaults)
|
|
attrs[key] = value;
|
|
else if (key in this._set_after_defaults)
|
|
attrs[key] = value;
|
|
}
|
|
return value_to_json("attributes", attrs, this);
|
|
};
|
|
ColumnDataSource._value_to_json = function (key, value, optional_parent_object) {
|
|
if (types_1.isPlainObject(value) && key === 'data')
|
|
return serialization_1.encode_column_data(value, optional_parent_object._shapes); // XXX: unknown vs. any
|
|
else
|
|
return has_props_1.HasProps._value_to_json(key, value, optional_parent_object);
|
|
};
|
|
ColumnDataSource.prototype.stream = function (new_data, rollover, setter_id) {
|
|
var data = this.data;
|
|
for (var k in new_data) {
|
|
data[k] = stream_to_column(data[k], new_data[k], rollover);
|
|
}
|
|
this.setv({ data: data }, { silent: true });
|
|
this.streaming.emit();
|
|
if (this.document != null) {
|
|
var hint = new events_1.ColumnsStreamedEvent(this.document, this.ref(), new_data, rollover);
|
|
this.document._notify_change(this, 'data', null, null, { setter_id: setter_id, hint: hint });
|
|
}
|
|
};
|
|
ColumnDataSource.prototype.patch = function (patches, setter_id) {
|
|
var data = this.data;
|
|
var patched = new data_structures_1.Set();
|
|
for (var k in patches) {
|
|
var patch = patches[k];
|
|
patched = patched.union(patch_to_column(data[k], patch, this._shapes[k]));
|
|
}
|
|
this.setv({ data: data }, { silent: true });
|
|
this.patching.emit(patched.values);
|
|
if (this.document != null) {
|
|
var hint = new events_1.ColumnsPatchedEvent(this.document, this.ref(), patches);
|
|
this.document._notify_change(this, 'data', null, null, { setter_id: setter_id, hint: hint });
|
|
}
|
|
};
|
|
return ColumnDataSource;
|
|
}(columnar_data_source_1.ColumnarDataSource));
|
|
exports.ColumnDataSource = ColumnDataSource;
|
|
ColumnDataSource.initClass();
|
|
}
|
|
,
|
|
/* models/sources/columnar_data_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var data_source_1 = require(210) /* ./data_source */;
|
|
var signaling_1 = require(22) /* ../../core/signaling */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var selection_manager_1 = require(20) /* ../../core/selection_manager */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var selection_1 = require(205) /* ../selections/selection */;
|
|
var interaction_policy_1 = require(204) /* ../selections/interaction_policy */;
|
|
var ColumnarDataSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ColumnarDataSource, _super);
|
|
function ColumnarDataSource(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ColumnarDataSource.prototype.get_array = function (key) {
|
|
var column = this.data[key];
|
|
if (column == null)
|
|
this.data[key] = column = [];
|
|
else if (!types_1.isArray(column))
|
|
this.data[key] = column = Array.from(column);
|
|
return column;
|
|
};
|
|
ColumnarDataSource.initClass = function () {
|
|
this.prototype.type = 'ColumnarDataSource';
|
|
this.define({
|
|
selection_policy: [p.Instance, function () { return new interaction_policy_1.UnionRenderers(); }],
|
|
});
|
|
this.internal({
|
|
selection_manager: [p.Instance, function (self) { return new selection_manager_1.SelectionManager({ source: self }); }],
|
|
inspected: [p.Instance, function () { return new selection_1.Selection(); }],
|
|
_shapes: [p.Any, {}],
|
|
});
|
|
};
|
|
ColumnarDataSource.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this._select = new signaling_1.Signal0(this, "select");
|
|
this.inspect = new signaling_1.Signal(this, "inspect"); // XXX: <[indices, tool, renderer-view, source, data], this>
|
|
this.streaming = new signaling_1.Signal0(this, "streaming");
|
|
this.patching = new signaling_1.Signal(this, "patching");
|
|
};
|
|
ColumnarDataSource.prototype.get_column = function (colname) {
|
|
var column = this.data[colname];
|
|
return column != null ? column : null;
|
|
};
|
|
ColumnarDataSource.prototype.columns = function () {
|
|
// return the column names in this data source
|
|
return object_1.keys(this.data);
|
|
};
|
|
ColumnarDataSource.prototype.get_length = function (soft) {
|
|
if (soft === void 0) {
|
|
soft = true;
|
|
}
|
|
var lengths = array_1.uniq(object_1.values(this.data).map(function (v) { return v.length; }));
|
|
switch (lengths.length) {
|
|
case 0: {
|
|
return null; // XXX: don't guess, treat on case-by-case basis
|
|
}
|
|
case 1: {
|
|
return lengths[0];
|
|
}
|
|
default: {
|
|
var msg = "data source has columns of inconsistent lengths";
|
|
if (soft) {
|
|
logging_1.logger.warn(msg);
|
|
return lengths.sort()[0];
|
|
}
|
|
else
|
|
throw new Error(msg);
|
|
}
|
|
}
|
|
};
|
|
ColumnarDataSource.prototype.get_indices = function () {
|
|
var length = this.get_length();
|
|
return array_1.range(0, length != null ? length : 1);
|
|
//TODO: returns [0] when no data, should it?
|
|
};
|
|
ColumnarDataSource.prototype.clear = function () {
|
|
var empty = {};
|
|
for (var _i = 0, _a = this.columns(); _i < _a.length; _i++) {
|
|
var col = _a[_i];
|
|
empty[col] = new this.data[col].constructor;
|
|
}
|
|
this.data = empty;
|
|
};
|
|
return ColumnarDataSource;
|
|
}(data_source_1.DataSource));
|
|
exports.ColumnarDataSource = ColumnarDataSource;
|
|
ColumnarDataSource.initClass();
|
|
}
|
|
,
|
|
/* models/sources/data_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var selection_1 = require(205) /* ../selections/selection */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var DataSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DataSource, _super);
|
|
function DataSource(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
DataSource.initClass = function () {
|
|
this.prototype.type = "DataSource";
|
|
this.define({
|
|
selected: [p.Instance, function () { return new selection_1.Selection(); }],
|
|
callback: [p.Any],
|
|
});
|
|
};
|
|
DataSource.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.selected.change, function () {
|
|
if (_this.callback != null)
|
|
_this.callback.execute(_this);
|
|
});
|
|
};
|
|
return DataSource;
|
|
}(model_1.Model));
|
|
exports.DataSource = DataSource;
|
|
DataSource.initClass();
|
|
}
|
|
,
|
|
/* models/sources/geojson_data_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var columnar_data_source_1 = require(209) /* ./columnar_data_source */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var GeoJSONDataSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GeoJSONDataSource, _super);
|
|
function GeoJSONDataSource(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
GeoJSONDataSource.initClass = function () {
|
|
this.prototype.type = 'GeoJSONDataSource';
|
|
this.define({
|
|
geojson: [p.Any],
|
|
});
|
|
this.internal({
|
|
data: [p.Any, {}],
|
|
});
|
|
};
|
|
GeoJSONDataSource.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this._update_data();
|
|
};
|
|
GeoJSONDataSource.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.properties.geojson.change, function () { return _this._update_data(); });
|
|
};
|
|
GeoJSONDataSource.prototype._update_data = function () {
|
|
this.data = this.geojson_to_column_data();
|
|
};
|
|
GeoJSONDataSource.prototype._get_new_list_array = function (length) {
|
|
return array_1.range(0, length).map(function (_i) { return []; });
|
|
};
|
|
GeoJSONDataSource.prototype._get_new_nan_array = function (length) {
|
|
return array_1.range(0, length).map(function (_i) { return NaN; });
|
|
};
|
|
GeoJSONDataSource.prototype._add_properties = function (item, data, i, item_count) {
|
|
var properties = item.properties || {};
|
|
for (var property in properties) {
|
|
if (!data.hasOwnProperty(property))
|
|
data[property] = this._get_new_nan_array(item_count);
|
|
data[property][i] = properties[property];
|
|
}
|
|
};
|
|
GeoJSONDataSource.prototype._add_geometry = function (geometry, data, i) {
|
|
function orNaN(v) {
|
|
return v != null ? v : NaN;
|
|
}
|
|
function flatten(acc, item) {
|
|
return acc.concat([[NaN, NaN, NaN]]).concat(item);
|
|
}
|
|
switch (geometry.type) {
|
|
case "Point": {
|
|
var _a = geometry.coordinates, x = _a[0], y = _a[1], z = _a[2];
|
|
data.x[i] = x;
|
|
data.y[i] = y;
|
|
data.z[i] = orNaN(z);
|
|
break;
|
|
}
|
|
case "LineString": {
|
|
var coordinates = geometry.coordinates;
|
|
for (var j = 0; j < coordinates.length; j++) {
|
|
var _b = coordinates[j], x = _b[0], y = _b[1], z = _b[2];
|
|
data.xs[i][j] = x;
|
|
data.ys[i][j] = y;
|
|
data.zs[i][j] = orNaN(z);
|
|
}
|
|
break;
|
|
}
|
|
case "Polygon": {
|
|
if (geometry.coordinates.length > 1)
|
|
logging_1.logger.warn('Bokeh does not support Polygons with holes in, only exterior ring used.');
|
|
var exterior_ring = geometry.coordinates[0];
|
|
for (var j = 0; j < exterior_ring.length; j++) {
|
|
var _c = exterior_ring[j], x = _c[0], y = _c[1], z = _c[2];
|
|
data.xs[i][j] = x;
|
|
data.ys[i][j] = y;
|
|
data.zs[i][j] = orNaN(z);
|
|
}
|
|
break;
|
|
}
|
|
case "MultiPoint": {
|
|
logging_1.logger.warn('MultiPoint not supported in Bokeh');
|
|
break;
|
|
}
|
|
case "MultiLineString": {
|
|
var coordinates = geometry.coordinates.reduce(flatten);
|
|
for (var j = 0; j < coordinates.length; j++) {
|
|
var _d = coordinates[j], x = _d[0], y = _d[1], z = _d[2];
|
|
data.xs[i][j] = x;
|
|
data.ys[i][j] = y;
|
|
data.zs[i][j] = orNaN(z);
|
|
}
|
|
break;
|
|
}
|
|
case "MultiPolygon": {
|
|
var exterior_rings = [];
|
|
for (var _e = 0, _f = geometry.coordinates; _e < _f.length; _e++) {
|
|
var polygon = _f[_e];
|
|
if (polygon.length > 1)
|
|
logging_1.logger.warn('Bokeh does not support Polygons with holes in, only exterior ring used.');
|
|
exterior_rings.push(polygon[0]);
|
|
}
|
|
var coordinates = exterior_rings.reduce(flatten);
|
|
for (var j = 0; j < coordinates.length; j++) {
|
|
var _g = coordinates[j], x = _g[0], y = _g[1], z = _g[2];
|
|
data.xs[i][j] = x;
|
|
data.ys[i][j] = y;
|
|
data.zs[i][j] = orNaN(z);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("Invalid GeoJSON geometry type: " + geometry.type);
|
|
}
|
|
};
|
|
GeoJSONDataSource.prototype.geojson_to_column_data = function () {
|
|
var geojson = JSON.parse(this.geojson);
|
|
var items;
|
|
switch (geojson.type) {
|
|
case "GeometryCollection": {
|
|
if (geojson.geometries == null)
|
|
throw new Error('No geometries found in GeometryCollection');
|
|
if (geojson.geometries.length === 0)
|
|
throw new Error('geojson.geometries must have one or more items');
|
|
items = geojson.geometries;
|
|
break;
|
|
}
|
|
case "FeatureCollection": {
|
|
if (geojson.features == null)
|
|
throw new Error('No features found in FeaturesCollection');
|
|
if (geojson.features.length == 0)
|
|
throw new Error('geojson.features must have one or more items');
|
|
items = geojson.features;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error('Bokeh only supports type GeometryCollection and FeatureCollection at top level');
|
|
}
|
|
var item_count = 0;
|
|
for (var _a = 0, items_1 = items; _a < items_1.length; _a++) {
|
|
var item = items_1[_a];
|
|
var geometry = item.type === 'Feature' ? item.geometry : item;
|
|
if (geometry.type == 'GeometryCollection')
|
|
item_count += geometry.geometries.length;
|
|
else
|
|
item_count += 1;
|
|
}
|
|
var data = {
|
|
x: this._get_new_nan_array(item_count),
|
|
y: this._get_new_nan_array(item_count),
|
|
z: this._get_new_nan_array(item_count),
|
|
xs: this._get_new_list_array(item_count),
|
|
ys: this._get_new_list_array(item_count),
|
|
zs: this._get_new_list_array(item_count),
|
|
};
|
|
var arr_index = 0;
|
|
for (var _b = 0, items_2 = items; _b < items_2.length; _b++) {
|
|
var item = items_2[_b];
|
|
var geometry = item.type == 'Feature' ? item.geometry : item;
|
|
if (geometry.type == "GeometryCollection") {
|
|
for (var _c = 0, _d = geometry.geometries; _c < _d.length; _c++) {
|
|
var g = _d[_c];
|
|
this._add_geometry(g, data, arr_index);
|
|
if (item.type === 'Feature')
|
|
this._add_properties(item, data, arr_index, item_count);
|
|
arr_index += 1;
|
|
}
|
|
}
|
|
else {
|
|
this._add_geometry(geometry, data, arr_index);
|
|
if (item.type === 'Feature')
|
|
this._add_properties(item, data, arr_index, item_count);
|
|
arr_index += 1;
|
|
}
|
|
}
|
|
return data;
|
|
};
|
|
return GeoJSONDataSource;
|
|
}(columnar_data_source_1.ColumnarDataSource));
|
|
exports.GeoJSONDataSource = GeoJSONDataSource;
|
|
GeoJSONDataSource.initClass();
|
|
}
|
|
,
|
|
/* models/sources/index */ function _(require, module, exports) {
|
|
var server_sent_data_source_1 = require(214) /* ./server_sent_data_source */;
|
|
exports.ServerSentDataSource = server_sent_data_source_1.ServerSentDataSource;
|
|
var ajax_data_source_1 = require(206) /* ./ajax_data_source */;
|
|
exports.AjaxDataSource = ajax_data_source_1.AjaxDataSource;
|
|
var column_data_source_1 = require(208) /* ./column_data_source */;
|
|
exports.ColumnDataSource = column_data_source_1.ColumnDataSource;
|
|
var columnar_data_source_1 = require(209) /* ./columnar_data_source */;
|
|
exports.ColumnarDataSource = columnar_data_source_1.ColumnarDataSource;
|
|
var cds_view_1 = require(207) /* ./cds_view */;
|
|
exports.CDSView = cds_view_1.CDSView;
|
|
var data_source_1 = require(210) /* ./data_source */;
|
|
exports.DataSource = data_source_1.DataSource;
|
|
var geojson_data_source_1 = require(211) /* ./geojson_data_source */;
|
|
exports.GeoJSONDataSource = geojson_data_source_1.GeoJSONDataSource;
|
|
var remote_data_source_1 = require(213) /* ./remote_data_source */;
|
|
exports.RemoteDataSource = remote_data_source_1.RemoteDataSource;
|
|
}
|
|
,
|
|
/* models/sources/remote_data_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var web_data_source_1 = require(215) /* ./web_data_source */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var RemoteDataSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(RemoteDataSource, _super);
|
|
function RemoteDataSource(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
RemoteDataSource.prototype.get_column = function (colname) {
|
|
var column = this.data[colname];
|
|
return column != null ? column : [];
|
|
};
|
|
RemoteDataSource.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.setup();
|
|
};
|
|
RemoteDataSource.initClass = function () {
|
|
this.prototype.type = 'RemoteDataSource';
|
|
this.define({
|
|
polling_interval: [p.Number],
|
|
});
|
|
};
|
|
return RemoteDataSource;
|
|
}(web_data_source_1.WebDataSource));
|
|
exports.RemoteDataSource = RemoteDataSource;
|
|
RemoteDataSource.initClass();
|
|
}
|
|
,
|
|
/* models/sources/server_sent_data_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var web_data_source_1 = require(215) /* ./web_data_source */;
|
|
var ServerSentDataSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ServerSentDataSource, _super);
|
|
function ServerSentDataSource(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.initialized = false;
|
|
return _this;
|
|
}
|
|
ServerSentDataSource.initClass = function () {
|
|
this.prototype.type = 'ServerSentDataSource';
|
|
};
|
|
ServerSentDataSource.prototype.destroy = function () {
|
|
_super.prototype.destroy.call(this);
|
|
};
|
|
ServerSentDataSource.prototype.setup = function () {
|
|
var _this = this;
|
|
if (!this.initialized) {
|
|
this.initialized = true;
|
|
var source = new EventSource(this.data_url);
|
|
source.onmessage = function (event) {
|
|
_this.load_data(JSON.parse(event.data), _this.mode, _this.max_size);
|
|
};
|
|
}
|
|
};
|
|
return ServerSentDataSource;
|
|
}(web_data_source_1.WebDataSource));
|
|
exports.ServerSentDataSource = ServerSentDataSource;
|
|
ServerSentDataSource.initClass();
|
|
}
|
|
,
|
|
/* models/sources/web_data_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var column_data_source_1 = require(208) /* ./column_data_source */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var WebDataSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(WebDataSource, _super);
|
|
function WebDataSource(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
WebDataSource.prototype.get_column = function (colname) {
|
|
var column = this.data[colname];
|
|
return column != null ? column : [];
|
|
};
|
|
WebDataSource.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.setup();
|
|
};
|
|
WebDataSource.prototype.load_data = function (raw_data, mode, max_size) {
|
|
var adapter = this.adapter;
|
|
var data;
|
|
if (adapter != null)
|
|
data = adapter.execute(this, { response: raw_data });
|
|
else
|
|
data = raw_data;
|
|
switch (mode) {
|
|
case "replace": {
|
|
this.data = data;
|
|
break;
|
|
}
|
|
case "append": {
|
|
var original_data = this.data;
|
|
for (var _i = 0, _a = this.columns(); _i < _a.length; _i++) {
|
|
var column = _a[_i];
|
|
// XXX: support typed arrays
|
|
var old_col = Array.from(original_data[column]);
|
|
var new_col = Array.from(data[column]);
|
|
data[column] = old_col.concat(new_col).slice(-max_size);
|
|
}
|
|
this.data = data;
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
WebDataSource.initClass = function () {
|
|
this.prototype.type = 'WebDataSource';
|
|
this.define({
|
|
mode: [p.UpdateMode, 'replace'],
|
|
max_size: [p.Number],
|
|
adapter: [p.Any, null],
|
|
data_url: [p.String],
|
|
});
|
|
};
|
|
return WebDataSource;
|
|
}(column_data_source_1.ColumnDataSource));
|
|
exports.WebDataSource = WebDataSource;
|
|
WebDataSource.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/adaptive_ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var continuous_ticker_1 = require(220) /* ./continuous_ticker */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
// Forces a number x into a specified range [min_val, max_val].
|
|
function clamp(x, min_val, max_val) {
|
|
return Math.max(min_val, Math.min(max_val, x));
|
|
}
|
|
// A log function with an optional base.
|
|
function log(x, base) {
|
|
if (base === void 0) {
|
|
base = Math.E;
|
|
}
|
|
return Math.log(x) / Math.log(base);
|
|
}
|
|
var AdaptiveTicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(AdaptiveTicker, _super);
|
|
function AdaptiveTicker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
AdaptiveTicker.initClass = function () {
|
|
this.prototype.type = "AdaptiveTicker";
|
|
this.define({
|
|
base: [p.Number, 10.0],
|
|
mantissas: [p.Array, [1, 2, 5]],
|
|
min_interval: [p.Number, 0.0],
|
|
max_interval: [p.Number],
|
|
});
|
|
};
|
|
// These arguments control the range of possible intervals. The interval I
|
|
// returned by get_interval() will be the one that most closely matches the
|
|
// desired number of ticks, subject to the following constraints:
|
|
// I = (M * B^N), where
|
|
// M is a member of mantissas,
|
|
// B is base,
|
|
// and N is an integer;
|
|
// and min_interval <= I <= max_interval.
|
|
AdaptiveTicker.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
var prefix_mantissa = array_1.nth(this.mantissas, -1) / this.base;
|
|
var suffix_mantissa = array_1.nth(this.mantissas, 0) * this.base;
|
|
this.extended_mantissas = [prefix_mantissa].concat(this.mantissas, [suffix_mantissa]);
|
|
this.base_factor = this.get_min_interval() === 0.0 ? 1.0 : this.get_min_interval();
|
|
};
|
|
AdaptiveTicker.prototype.get_interval = function (data_low, data_high, desired_n_ticks) {
|
|
var data_range = data_high - data_low;
|
|
var ideal_interval = this.get_ideal_interval(data_low, data_high, desired_n_ticks);
|
|
var interval_exponent = Math.floor(log(ideal_interval / this.base_factor, this.base));
|
|
var ideal_magnitude = Math.pow(this.base, interval_exponent) * this.base_factor;
|
|
// An untested optimization.
|
|
// const ideal_mantissa = ideal_interval / ideal_magnitude
|
|
// index = sorted_index(this.extended_mantissas, ideal_mantissa)
|
|
// candidate_mantissas = this.extended_mantissas[index..index + 1]
|
|
var candidate_mantissas = this.extended_mantissas;
|
|
var errors = candidate_mantissas.map(function (mantissa) {
|
|
return Math.abs(desired_n_ticks - (data_range / (mantissa * ideal_magnitude)));
|
|
});
|
|
var best_mantissa = candidate_mantissas[array_1.argmin(errors)];
|
|
var interval = best_mantissa * ideal_magnitude;
|
|
return clamp(interval, this.get_min_interval(), this.get_max_interval());
|
|
};
|
|
return AdaptiveTicker;
|
|
}(continuous_ticker_1.ContinuousTicker));
|
|
exports.AdaptiveTicker = AdaptiveTicker;
|
|
AdaptiveTicker.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/basic_ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var adaptive_ticker_1 = require(216) /* ./adaptive_ticker */;
|
|
var BasicTicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BasicTicker, _super);
|
|
function BasicTicker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
BasicTicker.initClass = function () {
|
|
this.prototype.type = "BasicTicker";
|
|
};
|
|
return BasicTicker;
|
|
}(adaptive_ticker_1.AdaptiveTicker));
|
|
exports.BasicTicker = BasicTicker;
|
|
BasicTicker.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/categorical_ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var ticker_1 = require(229) /* ./ticker */;
|
|
var CategoricalTicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CategoricalTicker, _super);
|
|
function CategoricalTicker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CategoricalTicker.initClass = function () {
|
|
this.prototype.type = "CategoricalTicker";
|
|
};
|
|
CategoricalTicker.prototype.get_ticks = function (start, end, range, _cross_loc, _) {
|
|
var majors = this._collect(range.factors, range, start, end);
|
|
var tops = this._collect(range.tops || [], range, start, end);
|
|
var mids = this._collect(range.mids || [], range, start, end);
|
|
return {
|
|
major: majors,
|
|
minor: [],
|
|
tops: tops,
|
|
mids: mids,
|
|
};
|
|
};
|
|
CategoricalTicker.prototype._collect = function (factors, range, start, end) {
|
|
var result = [];
|
|
for (var _i = 0, factors_1 = factors; _i < factors_1.length; _i++) {
|
|
var factor = factors_1[_i];
|
|
var coord = range.synthetic(factor);
|
|
if (coord > start && coord < end)
|
|
result.push(factor);
|
|
}
|
|
return result;
|
|
};
|
|
return CategoricalTicker;
|
|
}(ticker_1.Ticker));
|
|
exports.CategoricalTicker = CategoricalTicker;
|
|
CategoricalTicker.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/composite_ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var continuous_ticker_1 = require(220) /* ./continuous_ticker */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var CompositeTicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CompositeTicker, _super);
|
|
function CompositeTicker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CompositeTicker.initClass = function () {
|
|
this.prototype.type = "CompositeTicker";
|
|
this.define({
|
|
tickers: [p.Array, []],
|
|
});
|
|
};
|
|
Object.defineProperty(CompositeTicker.prototype, "min_intervals", {
|
|
// The tickers should be in order of increasing interval size; specifically,
|
|
// if S comes before T, then it should be the case that
|
|
// S.get_max_interval() < T.get_min_interval().
|
|
// FIXME Enforce this automatically.
|
|
get: function () {
|
|
return this.tickers.map(function (ticker) { return ticker.get_min_interval(); });
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(CompositeTicker.prototype, "max_intervals", {
|
|
get: function () {
|
|
return this.tickers.map(function (ticker) { return ticker.get_max_interval(); });
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(CompositeTicker.prototype, "min_interval", {
|
|
get: function () {
|
|
return this.min_intervals[0];
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(CompositeTicker.prototype, "max_interval", {
|
|
get: function () {
|
|
return this.max_intervals[0];
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
CompositeTicker.prototype.get_best_ticker = function (data_low, data_high, desired_n_ticks) {
|
|
var data_range = data_high - data_low;
|
|
var ideal_interval = this.get_ideal_interval(data_low, data_high, desired_n_ticks);
|
|
var ticker_ndxs = [
|
|
array_1.sorted_index(this.min_intervals, ideal_interval) - 1,
|
|
array_1.sorted_index(this.max_intervals, ideal_interval),
|
|
];
|
|
var intervals = [
|
|
this.min_intervals[ticker_ndxs[0]],
|
|
this.max_intervals[ticker_ndxs[1]],
|
|
];
|
|
var errors = intervals.map(function (interval) {
|
|
return Math.abs(desired_n_ticks - (data_range / interval));
|
|
});
|
|
var best_ticker;
|
|
if (object_1.isEmpty(errors.filter(function (e) { return !isNaN(e); }))) {
|
|
// this can happen if the data isn't loaded yet, we just default to the first scale
|
|
best_ticker = this.tickers[0];
|
|
}
|
|
else {
|
|
var best_index = array_1.argmin(errors);
|
|
var best_ticker_ndx = ticker_ndxs[best_index];
|
|
best_ticker = this.tickers[best_ticker_ndx];
|
|
}
|
|
return best_ticker;
|
|
};
|
|
CompositeTicker.prototype.get_interval = function (data_low, data_high, desired_n_ticks) {
|
|
var best_ticker = this.get_best_ticker(data_low, data_high, desired_n_ticks);
|
|
return best_ticker.get_interval(data_low, data_high, desired_n_ticks);
|
|
};
|
|
CompositeTicker.prototype.get_ticks_no_defaults = function (data_low, data_high, cross_loc, desired_n_ticks) {
|
|
var best_ticker = this.get_best_ticker(data_low, data_high, desired_n_ticks);
|
|
return best_ticker.get_ticks_no_defaults(data_low, data_high, cross_loc, desired_n_ticks);
|
|
};
|
|
return CompositeTicker;
|
|
}(continuous_ticker_1.ContinuousTicker));
|
|
exports.CompositeTicker = CompositeTicker;
|
|
CompositeTicker.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/continuous_ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var ticker_1 = require(229) /* ./ticker */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var ContinuousTicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ContinuousTicker, _super);
|
|
function ContinuousTicker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ContinuousTicker.initClass = function () {
|
|
this.prototype.type = "ContinuousTicker";
|
|
this.define({
|
|
num_minor_ticks: [p.Number, 5],
|
|
desired_num_ticks: [p.Number, 6],
|
|
});
|
|
};
|
|
ContinuousTicker.prototype.get_ticks = function (data_low, data_high, _range, cross_loc, _) {
|
|
return this.get_ticks_no_defaults(data_low, data_high, cross_loc, this.desired_num_ticks);
|
|
};
|
|
// The version of get_ticks() that does the work (and the version that
|
|
// should be overridden in subclasses).
|
|
ContinuousTicker.prototype.get_ticks_no_defaults = function (data_low, data_high, _cross_loc, desired_n_ticks) {
|
|
var interval = this.get_interval(data_low, data_high, desired_n_ticks);
|
|
var start_factor = Math.floor(data_low / interval);
|
|
var end_factor = Math.ceil(data_high / interval);
|
|
var factors;
|
|
if (types_1.isStrictNaN(start_factor) || types_1.isStrictNaN(end_factor))
|
|
factors = [];
|
|
else
|
|
factors = array_1.range(start_factor, end_factor + 1);
|
|
var ticks = factors.map(function (factor) { return factor * interval; })
|
|
.filter(function (tick) { return data_low <= tick && tick <= data_high; });
|
|
var num_minor_ticks = this.num_minor_ticks;
|
|
var minor_ticks = [];
|
|
if (num_minor_ticks > 0 && ticks.length > 0) {
|
|
var minor_interval_1 = interval / num_minor_ticks;
|
|
var minor_offsets = array_1.range(0, num_minor_ticks).map(function (i) { return i * minor_interval_1; });
|
|
for (var _i = 0, _a = minor_offsets.slice(1); _i < _a.length; _i++) {
|
|
var x = _a[_i];
|
|
var mt = ticks[0] - x;
|
|
if (data_low <= mt && mt <= data_high) {
|
|
minor_ticks.push(mt);
|
|
}
|
|
}
|
|
for (var _b = 0, ticks_1 = ticks; _b < ticks_1.length; _b++) {
|
|
var tick = ticks_1[_b];
|
|
for (var _c = 0, minor_offsets_1 = minor_offsets; _c < minor_offsets_1.length; _c++) {
|
|
var x = minor_offsets_1[_c];
|
|
var mt = tick + x;
|
|
if (data_low <= mt && mt <= data_high) {
|
|
minor_ticks.push(mt);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
major: ticks,
|
|
minor: minor_ticks,
|
|
};
|
|
};
|
|
// Returns the smallest interval that can be returned by get_interval().
|
|
ContinuousTicker.prototype.get_min_interval = function () {
|
|
return this.min_interval;
|
|
};
|
|
// Returns the largest interval that can be returned by get_interval().
|
|
ContinuousTicker.prototype.get_max_interval = function () {
|
|
return this.max_interval != null ? this.max_interval : Infinity;
|
|
};
|
|
// Returns the interval size that would produce exactly the number of
|
|
// desired ticks. (In general we won't use exactly this interval, because
|
|
// we want the ticks to be round numbers.)
|
|
ContinuousTicker.prototype.get_ideal_interval = function (data_low, data_high, desired_n_ticks) {
|
|
var data_range = data_high - data_low;
|
|
return data_range / desired_n_ticks;
|
|
};
|
|
return ContinuousTicker;
|
|
}(ticker_1.Ticker));
|
|
exports.ContinuousTicker = ContinuousTicker;
|
|
ContinuousTicker.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/datetime_ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var adaptive_ticker_1 = require(216) /* ./adaptive_ticker */;
|
|
var composite_ticker_1 = require(219) /* ./composite_ticker */;
|
|
var days_ticker_1 = require(222) /* ./days_ticker */;
|
|
var months_ticker_1 = require(227) /* ./months_ticker */;
|
|
var years_ticker_1 = require(231) /* ./years_ticker */;
|
|
var util_1 = require(230) /* ./util */;
|
|
var DatetimeTicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DatetimeTicker, _super);
|
|
function DatetimeTicker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
DatetimeTicker.initClass = function () {
|
|
this.prototype.type = "DatetimeTicker";
|
|
this.override({
|
|
num_minor_ticks: 0,
|
|
tickers: function () {
|
|
return [
|
|
// Sub-second.
|
|
new adaptive_ticker_1.AdaptiveTicker({
|
|
mantissas: [1, 2, 5],
|
|
base: 10,
|
|
min_interval: 0,
|
|
max_interval: 500 * util_1.ONE_MILLI,
|
|
num_minor_ticks: 0,
|
|
}),
|
|
// Seconds, minutes.
|
|
new adaptive_ticker_1.AdaptiveTicker({
|
|
mantissas: [1, 2, 5, 10, 15, 20, 30],
|
|
base: 60,
|
|
min_interval: util_1.ONE_SECOND,
|
|
max_interval: 30 * util_1.ONE_MINUTE,
|
|
num_minor_ticks: 0,
|
|
}),
|
|
// Hours.
|
|
new adaptive_ticker_1.AdaptiveTicker({
|
|
mantissas: [1, 2, 4, 6, 8, 12],
|
|
base: 24.0,
|
|
min_interval: util_1.ONE_HOUR,
|
|
max_interval: 12 * util_1.ONE_HOUR,
|
|
num_minor_ticks: 0,
|
|
}),
|
|
// Days.
|
|
new days_ticker_1.DaysTicker({ days: array_1.range(1, 32) }),
|
|
new days_ticker_1.DaysTicker({ days: array_1.range(1, 31, 3) }),
|
|
new days_ticker_1.DaysTicker({ days: [1, 8, 15, 22] }),
|
|
new days_ticker_1.DaysTicker({ days: [1, 15] }),
|
|
// Months.
|
|
new months_ticker_1.MonthsTicker({ months: array_1.range(0, 12, 1) }),
|
|
new months_ticker_1.MonthsTicker({ months: array_1.range(0, 12, 2) }),
|
|
new months_ticker_1.MonthsTicker({ months: array_1.range(0, 12, 4) }),
|
|
new months_ticker_1.MonthsTicker({ months: array_1.range(0, 12, 6) }),
|
|
// Years
|
|
new years_ticker_1.YearsTicker({}),
|
|
];
|
|
},
|
|
});
|
|
};
|
|
return DatetimeTicker;
|
|
}(composite_ticker_1.CompositeTicker));
|
|
exports.DatetimeTicker = DatetimeTicker;
|
|
DatetimeTicker.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/days_ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var single_interval_ticker_1 = require(228) /* ./single_interval_ticker */;
|
|
var util_1 = require(230) /* ./util */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
// Given a start and end time in millis, returns the shortest array of
|
|
// consecutive months (as Dates) that surrounds both times.
|
|
function date_range_by_month(start_time, end_time) {
|
|
var start_date = util_1.last_month_no_later_than(new Date(start_time));
|
|
var end_date = util_1.last_month_no_later_than(new Date(end_time));
|
|
// XXX This is not a reliable technique in general, but it should be
|
|
// safe when the day of the month is 1. (The problem case is this:
|
|
// Mar 31 -> Apr 31, which becomes May 1.)
|
|
end_date.setUTCMonth(end_date.getUTCMonth() + 1);
|
|
var dates = [];
|
|
var date = start_date;
|
|
while (true) {
|
|
dates.push(util_1.copy_date(date));
|
|
date.setUTCMonth(date.getUTCMonth() + 1);
|
|
if (date > end_date)
|
|
break;
|
|
}
|
|
return dates;
|
|
}
|
|
var DaysTicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(DaysTicker, _super);
|
|
function DaysTicker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
DaysTicker.initClass = function () {
|
|
this.prototype.type = "DaysTicker";
|
|
this.define({
|
|
days: [p.Array, []],
|
|
});
|
|
this.override({
|
|
num_minor_ticks: 0,
|
|
});
|
|
};
|
|
DaysTicker.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
var days = this.days;
|
|
if (days.length > 1)
|
|
this.interval = (days[1] - days[0]) * util_1.ONE_DAY;
|
|
else
|
|
this.interval = 31 * util_1.ONE_DAY;
|
|
};
|
|
DaysTicker.prototype.get_ticks_no_defaults = function (data_low, data_high, _cross_loc, _desired_n_ticks) {
|
|
var month_dates = date_range_by_month(data_low, data_high);
|
|
var days = this.days;
|
|
var days_of_month = function (month_date, interval) {
|
|
var current_month = month_date.getUTCMonth();
|
|
var dates = [];
|
|
for (var _i = 0, days_1 = days; _i < days_1.length; _i++) {
|
|
var day = days_1[_i];
|
|
var day_date = util_1.copy_date(month_date);
|
|
day_date.setUTCDate(day);
|
|
// We can't use all of the values in this.days, because they may not
|
|
// fall within the current month. In fact, if, e.g., our month is 28 days
|
|
// and we're marking every third day, we don't want day 28 to show up
|
|
// because it'll be right next to the 1st of the next month. So we
|
|
// make sure we have a bit of room before we include a day.
|
|
// TODO (bev) The above description does not exactly work because JS Date
|
|
// is broken and will happily consider "Feb 28 + 3*ONE_DAY" to have month "2"
|
|
var future_date = new Date(day_date.getTime() + (interval / 2));
|
|
if (future_date.getUTCMonth() == current_month)
|
|
dates.push(day_date);
|
|
}
|
|
return dates;
|
|
};
|
|
var interval = this.interval;
|
|
var day_dates = array_1.concat(month_dates.map(function (date) { return days_of_month(date, interval); }));
|
|
var all_ticks = day_dates.map(function (day_date) { return day_date.getTime(); });
|
|
var ticks_in_range = all_ticks.filter(function (tick) { return data_low <= tick && tick <= data_high; });
|
|
return {
|
|
major: ticks_in_range,
|
|
minor: [],
|
|
};
|
|
};
|
|
return DaysTicker;
|
|
}(single_interval_ticker_1.SingleIntervalTicker));
|
|
exports.DaysTicker = DaysTicker;
|
|
DaysTicker.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/fixed_ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var continuous_ticker_1 = require(220) /* ./continuous_ticker */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var FixedTicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(FixedTicker, _super);
|
|
function FixedTicker(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.min_interval = 0;
|
|
_this.max_interval = 0;
|
|
return _this;
|
|
}
|
|
FixedTicker.initClass = function () {
|
|
this.prototype.type = "FixedTicker";
|
|
this.define({
|
|
ticks: [p.Array, []],
|
|
minor_ticks: [p.Array, []],
|
|
});
|
|
};
|
|
FixedTicker.prototype.get_ticks_no_defaults = function (_data_low, _data_high, _cross_loc, _desired_n_ticks) {
|
|
return {
|
|
major: this.ticks,
|
|
minor: this.minor_ticks,
|
|
};
|
|
};
|
|
// XXX: whatever, because FixedTicker needs to fullfill the interface somehow
|
|
FixedTicker.prototype.get_interval = function (_data_low, _data_high, _desired_n_ticks) {
|
|
return 0;
|
|
};
|
|
return FixedTicker;
|
|
}(continuous_ticker_1.ContinuousTicker));
|
|
exports.FixedTicker = FixedTicker;
|
|
FixedTicker.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/index */ function _(require, module, exports) {
|
|
var adaptive_ticker_1 = require(216) /* ./adaptive_ticker */;
|
|
exports.AdaptiveTicker = adaptive_ticker_1.AdaptiveTicker;
|
|
var basic_ticker_1 = require(217) /* ./basic_ticker */;
|
|
exports.BasicTicker = basic_ticker_1.BasicTicker;
|
|
var categorical_ticker_1 = require(218) /* ./categorical_ticker */;
|
|
exports.CategoricalTicker = categorical_ticker_1.CategoricalTicker;
|
|
var composite_ticker_1 = require(219) /* ./composite_ticker */;
|
|
exports.CompositeTicker = composite_ticker_1.CompositeTicker;
|
|
var continuous_ticker_1 = require(220) /* ./continuous_ticker */;
|
|
exports.ContinuousTicker = continuous_ticker_1.ContinuousTicker;
|
|
var datetime_ticker_1 = require(221) /* ./datetime_ticker */;
|
|
exports.DatetimeTicker = datetime_ticker_1.DatetimeTicker;
|
|
var days_ticker_1 = require(222) /* ./days_ticker */;
|
|
exports.DaysTicker = days_ticker_1.DaysTicker;
|
|
var fixed_ticker_1 = require(223) /* ./fixed_ticker */;
|
|
exports.FixedTicker = fixed_ticker_1.FixedTicker;
|
|
var log_ticker_1 = require(225) /* ./log_ticker */;
|
|
exports.LogTicker = log_ticker_1.LogTicker;
|
|
var mercator_ticker_1 = require(226) /* ./mercator_ticker */;
|
|
exports.MercatorTicker = mercator_ticker_1.MercatorTicker;
|
|
var months_ticker_1 = require(227) /* ./months_ticker */;
|
|
exports.MonthsTicker = months_ticker_1.MonthsTicker;
|
|
var single_interval_ticker_1 = require(228) /* ./single_interval_ticker */;
|
|
exports.SingleIntervalTicker = single_interval_ticker_1.SingleIntervalTicker;
|
|
var ticker_1 = require(229) /* ./ticker */;
|
|
exports.Ticker = ticker_1.Ticker;
|
|
var years_ticker_1 = require(231) /* ./years_ticker */;
|
|
exports.YearsTicker = years_ticker_1.YearsTicker;
|
|
}
|
|
,
|
|
/* models/tickers/log_ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var adaptive_ticker_1 = require(216) /* ./adaptive_ticker */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var LogTicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LogTicker, _super);
|
|
function LogTicker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
LogTicker.initClass = function () {
|
|
this.prototype.type = "LogTicker";
|
|
this.override({
|
|
mantissas: [1, 5],
|
|
});
|
|
};
|
|
LogTicker.prototype.get_ticks_no_defaults = function (data_low, data_high, _cross_loc, desired_n_ticks) {
|
|
var num_minor_ticks = this.num_minor_ticks;
|
|
var minor_ticks = [];
|
|
var base = this.base;
|
|
var log_low = Math.log(data_low) / Math.log(base);
|
|
var log_high = Math.log(data_high) / Math.log(base);
|
|
var log_interval = log_high - log_low;
|
|
var ticks;
|
|
if (!isFinite(log_interval)) {
|
|
ticks = [];
|
|
}
|
|
else if (log_interval < 2) { // treat as linear ticker
|
|
var interval_1 = this.get_interval(data_low, data_high, desired_n_ticks);
|
|
var start_factor = Math.floor(data_low / interval_1);
|
|
var end_factor = Math.ceil(data_high / interval_1);
|
|
ticks = array_1.range(start_factor, end_factor + 1)
|
|
.filter(function (factor) { return factor != 0; })
|
|
.map(function (factor) { return factor * interval_1; })
|
|
.filter(function (tick) { return data_low <= tick && tick <= data_high; });
|
|
if (num_minor_ticks > 0 && ticks.length > 0) {
|
|
var minor_interval_1 = interval_1 / num_minor_ticks;
|
|
var minor_offsets = array_1.range(0, num_minor_ticks).map(function (i) { return i * minor_interval_1; });
|
|
for (var _i = 0, _a = minor_offsets.slice(1); _i < _a.length; _i++) {
|
|
var x = _a[_i];
|
|
minor_ticks.push(ticks[0] - x);
|
|
}
|
|
for (var _b = 0, ticks_1 = ticks; _b < ticks_1.length; _b++) {
|
|
var tick = ticks_1[_b];
|
|
for (var _c = 0, minor_offsets_1 = minor_offsets; _c < minor_offsets_1.length; _c++) {
|
|
var x = minor_offsets_1[_c];
|
|
minor_ticks.push(tick + x);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
var startlog = Math.ceil(log_low * 0.999999);
|
|
var endlog = Math.floor(log_high * 1.000001);
|
|
var interval = Math.ceil((endlog - startlog) / 9.0);
|
|
ticks = array_1.range(startlog - 1, endlog + 1, interval)
|
|
.map(function (i) { return Math.pow(base, i); });
|
|
if (num_minor_ticks > 0 && ticks.length > 0) {
|
|
var minor_interval_2 = Math.pow(base, interval) / num_minor_ticks;
|
|
var minor_offsets = array_1.range(1, num_minor_ticks + 1).map(function (i) { return i * minor_interval_2; });
|
|
for (var _d = 0, minor_offsets_2 = minor_offsets; _d < minor_offsets_2.length; _d++) {
|
|
var x = minor_offsets_2[_d];
|
|
minor_ticks.push(ticks[0] / x);
|
|
}
|
|
minor_ticks.push(ticks[0]);
|
|
for (var _e = 0, ticks_2 = ticks; _e < ticks_2.length; _e++) {
|
|
var tick = ticks_2[_e];
|
|
for (var _f = 0, minor_offsets_3 = minor_offsets; _f < minor_offsets_3.length; _f++) {
|
|
var x = minor_offsets_3[_f];
|
|
minor_ticks.push(tick * x);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
major: ticks.filter(function (tick) { return data_low <= tick && tick <= data_high; }),
|
|
minor: minor_ticks.filter(function (tick) { return data_low <= tick && tick <= data_high; }),
|
|
};
|
|
};
|
|
return LogTicker;
|
|
}(adaptive_ticker_1.AdaptiveTicker));
|
|
exports.LogTicker = LogTicker;
|
|
LogTicker.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/mercator_ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var basic_ticker_1 = require(217) /* ./basic_ticker */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var projections_1 = require(36) /* ../../core/util/projections */;
|
|
var MercatorTicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MercatorTicker, _super);
|
|
function MercatorTicker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
MercatorTicker.initClass = function () {
|
|
this.prototype.type = "MercatorTicker";
|
|
this.define({
|
|
dimension: [p.LatLon],
|
|
});
|
|
};
|
|
MercatorTicker.prototype.get_ticks_no_defaults = function (data_low, data_high, cross_loc, desired_n_ticks) {
|
|
var _a, _b, _c, _d, _e;
|
|
if (this.dimension == null) {
|
|
throw new Error("MercatorTicker.dimension not configured");
|
|
}
|
|
_a = projections_1.clip_mercator(data_low, data_high, this.dimension), data_low = _a[0], data_high = _a[1];
|
|
var proj_low, proj_high, proj_cross_loc;
|
|
if (this.dimension === "lon") {
|
|
_b = projections_1.wgs84_mercator.inverse([data_low, cross_loc]), proj_low = _b[0], proj_cross_loc = _b[1];
|
|
_c = projections_1.wgs84_mercator.inverse([data_high, cross_loc]), proj_high = _c[0], proj_cross_loc = _c[1];
|
|
}
|
|
else {
|
|
_d = projections_1.wgs84_mercator.inverse([cross_loc, data_low]), proj_cross_loc = _d[0], proj_low = _d[1];
|
|
_e = projections_1.wgs84_mercator.inverse([cross_loc, data_high]), proj_cross_loc = _e[0], proj_high = _e[1];
|
|
}
|
|
var proj_ticks = _super.prototype.get_ticks_no_defaults.call(this, proj_low, proj_high, cross_loc, desired_n_ticks);
|
|
var major = [];
|
|
var minor = [];
|
|
if (this.dimension === "lon") {
|
|
for (var _i = 0, _f = proj_ticks.major; _i < _f.length; _i++) {
|
|
var tick = _f[_i];
|
|
if (projections_1.in_bounds(tick, 'lon')) {
|
|
var lon = projections_1.wgs84_mercator.forward([tick, proj_cross_loc])[0];
|
|
major.push(lon);
|
|
}
|
|
}
|
|
for (var _g = 0, _h = proj_ticks.minor; _g < _h.length; _g++) {
|
|
var tick = _h[_g];
|
|
if (projections_1.in_bounds(tick, 'lon')) {
|
|
var lon = projections_1.wgs84_mercator.forward([tick, proj_cross_loc])[0];
|
|
minor.push(lon);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
for (var _j = 0, _k = proj_ticks.major; _j < _k.length; _j++) {
|
|
var tick = _k[_j];
|
|
if (projections_1.in_bounds(tick, 'lat')) {
|
|
var _l = projections_1.wgs84_mercator.forward([proj_cross_loc, tick]), lat = _l[1];
|
|
major.push(lat);
|
|
}
|
|
}
|
|
for (var _m = 0, _o = proj_ticks.minor; _m < _o.length; _m++) {
|
|
var tick = _o[_m];
|
|
if (projections_1.in_bounds(tick, 'lat')) {
|
|
var _p = projections_1.wgs84_mercator.forward([proj_cross_loc, tick]), lat = _p[1];
|
|
minor.push(lat);
|
|
}
|
|
}
|
|
}
|
|
return { major: major, minor: minor };
|
|
};
|
|
return MercatorTicker;
|
|
}(basic_ticker_1.BasicTicker));
|
|
exports.MercatorTicker = MercatorTicker;
|
|
MercatorTicker.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/months_ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var single_interval_ticker_1 = require(228) /* ./single_interval_ticker */;
|
|
var util_1 = require(230) /* ./util */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
// Given a start and end time in millis, returns the shortest array of
|
|
// consecutive years (as Dates) that surrounds both times.
|
|
function date_range_by_year(start_time, end_time) {
|
|
var start_date = util_1.last_year_no_later_than(new Date(start_time));
|
|
var end_date = util_1.last_year_no_later_than(new Date(end_time));
|
|
end_date.setUTCFullYear(end_date.getUTCFullYear() + 1);
|
|
var dates = [];
|
|
var date = start_date;
|
|
while (true) {
|
|
dates.push(util_1.copy_date(date));
|
|
date.setUTCFullYear(date.getUTCFullYear() + 1);
|
|
if (date > end_date)
|
|
break;
|
|
}
|
|
return dates;
|
|
}
|
|
var MonthsTicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MonthsTicker, _super);
|
|
function MonthsTicker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
MonthsTicker.initClass = function () {
|
|
this.prototype.type = "MonthsTicker";
|
|
this.define({
|
|
months: [p.Array, []],
|
|
});
|
|
};
|
|
MonthsTicker.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
var months = this.months;
|
|
if (months.length > 1)
|
|
this.interval = (months[1] - months[0]) * util_1.ONE_MONTH;
|
|
else
|
|
this.interval = 12 * util_1.ONE_MONTH;
|
|
};
|
|
MonthsTicker.prototype.get_ticks_no_defaults = function (data_low, data_high, _cross_loc, _desired_n_ticks) {
|
|
var year_dates = date_range_by_year(data_low, data_high);
|
|
var months = this.months;
|
|
var months_of_year = function (year_date) {
|
|
return months.map(function (month) {
|
|
var month_date = util_1.copy_date(year_date);
|
|
month_date.setUTCMonth(month);
|
|
return month_date;
|
|
});
|
|
};
|
|
var month_dates = array_1.concat(year_dates.map(months_of_year));
|
|
var all_ticks = month_dates.map(function (month_date) { return month_date.getTime(); });
|
|
var ticks_in_range = all_ticks.filter(function (tick) { return data_low <= tick && tick <= data_high; });
|
|
return {
|
|
major: ticks_in_range,
|
|
minor: [],
|
|
};
|
|
};
|
|
return MonthsTicker;
|
|
}(single_interval_ticker_1.SingleIntervalTicker));
|
|
exports.MonthsTicker = MonthsTicker;
|
|
MonthsTicker.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/single_interval_ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var continuous_ticker_1 = require(220) /* ./continuous_ticker */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var SingleIntervalTicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(SingleIntervalTicker, _super);
|
|
function SingleIntervalTicker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
SingleIntervalTicker.initClass = function () {
|
|
this.prototype.type = "SingleIntervalTicker";
|
|
this.define({
|
|
interval: [p.Number],
|
|
});
|
|
};
|
|
SingleIntervalTicker.prototype.get_interval = function (_data_low, _data_high, _n_desired_ticks) {
|
|
return this.interval;
|
|
};
|
|
Object.defineProperty(SingleIntervalTicker.prototype, "min_interval", {
|
|
get: function () {
|
|
return this.interval;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(SingleIntervalTicker.prototype, "max_interval", {
|
|
get: function () {
|
|
return this.interval;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return SingleIntervalTicker;
|
|
}(continuous_ticker_1.ContinuousTicker));
|
|
exports.SingleIntervalTicker = SingleIntervalTicker;
|
|
SingleIntervalTicker.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var Ticker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Ticker, _super);
|
|
function Ticker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Ticker.initClass = function () {
|
|
this.prototype.type = "Ticker";
|
|
};
|
|
return Ticker;
|
|
}(model_1.Model));
|
|
exports.Ticker = Ticker;
|
|
Ticker.initClass();
|
|
}
|
|
,
|
|
/* models/tickers/util */ function _(require, module, exports) {
|
|
// Some time constants, in milliseconds.
|
|
exports.ONE_MILLI = 1.0;
|
|
exports.ONE_SECOND = 1000.0;
|
|
exports.ONE_MINUTE = 60.0 * exports.ONE_SECOND;
|
|
exports.ONE_HOUR = 60 * exports.ONE_MINUTE;
|
|
exports.ONE_DAY = 24 * exports.ONE_HOUR;
|
|
exports.ONE_MONTH = 30 * exports.ONE_DAY; // An approximation, obviously.
|
|
exports.ONE_YEAR = 365 * exports.ONE_DAY;
|
|
// ---------------------------------------------------------------------------
|
|
// Date/time utility functions
|
|
// ---------------------------------------------------------------------------
|
|
// Makes a copy of a date object.
|
|
function copy_date(date) {
|
|
return new Date(date.getTime());
|
|
}
|
|
exports.copy_date = copy_date;
|
|
// Rounds a date down to the month.
|
|
function last_month_no_later_than(date) {
|
|
var new_date = copy_date(date);
|
|
new_date.setUTCDate(1);
|
|
new_date.setUTCHours(0);
|
|
new_date.setUTCMinutes(0);
|
|
new_date.setUTCSeconds(0);
|
|
new_date.setUTCMilliseconds(0);
|
|
return new_date;
|
|
}
|
|
exports.last_month_no_later_than = last_month_no_later_than;
|
|
// Rounds a date down to the year.
|
|
function last_year_no_later_than(date) {
|
|
var new_date = last_month_no_later_than(date);
|
|
new_date.setUTCMonth(0);
|
|
return new_date;
|
|
}
|
|
exports.last_year_no_later_than = last_year_no_later_than;
|
|
}
|
|
,
|
|
/* models/tickers/years_ticker */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var basic_ticker_1 = require(217) /* ./basic_ticker */;
|
|
var single_interval_ticker_1 = require(228) /* ./single_interval_ticker */;
|
|
var util_1 = require(230) /* ./util */;
|
|
var YearsTicker = /** @class */ (function (_super) {
|
|
tslib_1.__extends(YearsTicker, _super);
|
|
function YearsTicker(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
YearsTicker.initClass = function () {
|
|
this.prototype.type = "YearsTicker";
|
|
};
|
|
YearsTicker.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.interval = util_1.ONE_YEAR;
|
|
this.basic_ticker = new basic_ticker_1.BasicTicker({ num_minor_ticks: 0 });
|
|
};
|
|
YearsTicker.prototype.get_ticks_no_defaults = function (data_low, data_high, cross_loc, desired_n_ticks) {
|
|
var start_year = util_1.last_year_no_later_than(new Date(data_low)).getUTCFullYear();
|
|
var end_year = util_1.last_year_no_later_than(new Date(data_high)).getUTCFullYear();
|
|
var years = this.basic_ticker.get_ticks_no_defaults(start_year, end_year, cross_loc, desired_n_ticks).major;
|
|
var all_ticks = years.map(function (year) { return Date.UTC(year, 0, 1); });
|
|
var ticks_in_range = all_ticks.filter(function (tick) { return data_low <= tick && tick <= data_high; });
|
|
return {
|
|
major: ticks_in_range,
|
|
minor: [],
|
|
};
|
|
};
|
|
return YearsTicker;
|
|
}(single_interval_ticker_1.SingleIntervalTicker));
|
|
exports.YearsTicker = YearsTicker;
|
|
YearsTicker.initClass();
|
|
}
|
|
,
|
|
/* models/tiles/bbox_tile_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var mercator_tile_source_1 = require(235) /* ./mercator_tile_source */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var BBoxTileSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BBoxTileSource, _super);
|
|
function BBoxTileSource(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
BBoxTileSource.initClass = function () {
|
|
this.prototype.type = 'BBoxTileSource';
|
|
this.define({
|
|
use_latlon: [p.Boolean, false],
|
|
});
|
|
};
|
|
BBoxTileSource.prototype.get_image_url = function (x, y, z) {
|
|
var _a, _b;
|
|
var image_url = this.string_lookup_replace(this.url, this.extra_url_vars);
|
|
var xmax, xmin, ymax, ymin;
|
|
if (this.use_latlon)
|
|
_a = this.get_tile_geographic_bounds(x, y, z), xmin = _a[0], ymin = _a[1], xmax = _a[2], ymax = _a[3];
|
|
else
|
|
_b = this.get_tile_meter_bounds(x, y, z), xmin = _b[0], ymin = _b[1], xmax = _b[2], ymax = _b[3];
|
|
return image_url.replace("{XMIN}", xmin.toString())
|
|
.replace("{YMIN}", ymin.toString())
|
|
.replace("{XMAX}", xmax.toString())
|
|
.replace("{YMAX}", ymax.toString());
|
|
};
|
|
return BBoxTileSource;
|
|
}(mercator_tile_source_1.MercatorTileSource));
|
|
exports.BBoxTileSource = BBoxTileSource;
|
|
BBoxTileSource.initClass();
|
|
}
|
|
,
|
|
/* models/tiles/image_pool */ function _(require, module, exports) {
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var ImagePool = /** @class */ (function () {
|
|
function ImagePool() {
|
|
this.images = [];
|
|
}
|
|
ImagePool.prototype.pop = function () {
|
|
var img = this.images.pop();
|
|
return img != null ? img : new Image();
|
|
};
|
|
ImagePool.prototype.push = function (img) {
|
|
var _a;
|
|
if (this.images.length > 50)
|
|
return;
|
|
if (types_1.isArray(img))
|
|
(_a = this.images).push.apply(_a, img);
|
|
else
|
|
this.images.push(img);
|
|
};
|
|
return ImagePool;
|
|
}());
|
|
exports.ImagePool = ImagePool;
|
|
}
|
|
,
|
|
/* models/tiles/index */ function _(require, module, exports) {
|
|
var bbox_tile_source_1 = require(232) /* ./bbox_tile_source */;
|
|
exports.BBoxTileSource = bbox_tile_source_1.BBoxTileSource;
|
|
var mercator_tile_source_1 = require(235) /* ./mercator_tile_source */;
|
|
exports.MercatorTileSource = mercator_tile_source_1.MercatorTileSource;
|
|
var quadkey_tile_source_1 = require(236) /* ./quadkey_tile_source */;
|
|
exports.QUADKEYTileSource = quadkey_tile_source_1.QUADKEYTileSource;
|
|
var tile_renderer_1 = require(237) /* ./tile_renderer */;
|
|
exports.TileRenderer = tile_renderer_1.TileRenderer;
|
|
var tile_source_1 = require(238) /* ./tile_source */;
|
|
exports.TileSource = tile_source_1.TileSource;
|
|
var tms_tile_source_1 = require(240) /* ./tms_tile_source */;
|
|
exports.TMSTileSource = tms_tile_source_1.TMSTileSource;
|
|
var wmts_tile_source_1 = require(241) /* ./wmts_tile_source */;
|
|
exports.WMTSTileSource = wmts_tile_source_1.WMTSTileSource;
|
|
}
|
|
,
|
|
/* models/tiles/mercator_tile_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var tile_source_1 = require(238) /* ./tile_source */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var tile_utils_1 = require(239) /* ./tile_utils */;
|
|
var MercatorTileSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(MercatorTileSource, _super);
|
|
function MercatorTileSource(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
MercatorTileSource.initClass = function () {
|
|
this.prototype.type = 'MercatorTileSource';
|
|
this.define({
|
|
snap_to_zoom: [p.Boolean, false],
|
|
wrap_around: [p.Boolean, true],
|
|
});
|
|
this.override({
|
|
x_origin_offset: 20037508.34,
|
|
y_origin_offset: 20037508.34,
|
|
initial_resolution: 156543.03392804097,
|
|
});
|
|
};
|
|
MercatorTileSource.prototype.initialize = function () {
|
|
var _this = this;
|
|
_super.prototype.initialize.call(this);
|
|
this._resolutions = array_1.range(this.min_zoom, this.max_zoom + 1).map(function (z) { return _this.get_resolution(z); });
|
|
};
|
|
MercatorTileSource.prototype._computed_initial_resolution = function () {
|
|
if (this.initial_resolution != null)
|
|
return this.initial_resolution;
|
|
else {
|
|
// TODO testing 2015-11-17, if this codepath is used it seems
|
|
// to use 100% cpu and wedge Chrome
|
|
return (2 * Math.PI * 6378137) / this.tile_size;
|
|
}
|
|
};
|
|
MercatorTileSource.prototype.is_valid_tile = function (x, y, z) {
|
|
if (!this.wrap_around) {
|
|
if (x < 0 || x >= Math.pow(2, z))
|
|
return false;
|
|
}
|
|
if (y < 0 || y >= Math.pow(2, z))
|
|
return false;
|
|
return true;
|
|
};
|
|
MercatorTileSource.prototype.parent_by_tile_xyz = function (x, y, z) {
|
|
var quadkey = this.tile_xyz_to_quadkey(x, y, z);
|
|
var parent_quadkey = quadkey.substring(0, quadkey.length - 1);
|
|
return this.quadkey_to_tile_xyz(parent_quadkey);
|
|
};
|
|
MercatorTileSource.prototype.get_resolution = function (level) {
|
|
return this._computed_initial_resolution() / Math.pow(2, level);
|
|
};
|
|
MercatorTileSource.prototype.get_resolution_by_extent = function (extent, height, width) {
|
|
var x_rs = (extent[2] - extent[0]) / width;
|
|
var y_rs = (extent[3] - extent[1]) / height;
|
|
return [x_rs, y_rs];
|
|
};
|
|
MercatorTileSource.prototype.get_level_by_extent = function (extent, height, width) {
|
|
var x_rs = (extent[2] - extent[0]) / width;
|
|
var y_rs = (extent[3] - extent[1]) / height;
|
|
var resolution = Math.max(x_rs, y_rs);
|
|
var i = 0;
|
|
for (var _i = 0, _a = this._resolutions; _i < _a.length; _i++) {
|
|
var r = _a[_i];
|
|
if (resolution > r) {
|
|
if (i == 0)
|
|
return 0;
|
|
if (i > 0)
|
|
return i - 1;
|
|
}
|
|
i += 1;
|
|
}
|
|
// otherwise return the highest available resolution
|
|
return (i - 1);
|
|
};
|
|
MercatorTileSource.prototype.get_closest_level_by_extent = function (extent, height, width) {
|
|
var x_rs = (extent[2] - extent[0]) / width;
|
|
var y_rs = (extent[3] - extent[1]) / height;
|
|
var resolution = Math.max(x_rs, y_rs);
|
|
var closest = this._resolutions.reduce(function (previous, current) {
|
|
if (Math.abs(current - resolution) < Math.abs(previous - resolution))
|
|
return current;
|
|
else
|
|
return previous;
|
|
});
|
|
return this._resolutions.indexOf(closest);
|
|
};
|
|
MercatorTileSource.prototype.snap_to_zoom_level = function (extent, height, width, level) {
|
|
var xmin = extent[0], ymin = extent[1], xmax = extent[2], ymax = extent[3];
|
|
var desired_res = this._resolutions[level];
|
|
var desired_x_delta = width * desired_res;
|
|
var desired_y_delta = height * desired_res;
|
|
if (!this.snap_to_zoom) {
|
|
var xscale = (xmax - xmin) / desired_x_delta;
|
|
var yscale = (ymax - ymin) / desired_y_delta;
|
|
if (xscale > yscale) {
|
|
desired_x_delta = (xmax - xmin);
|
|
desired_y_delta = desired_y_delta * xscale;
|
|
}
|
|
else {
|
|
desired_x_delta = desired_x_delta * yscale;
|
|
desired_y_delta = (ymax - ymin);
|
|
}
|
|
}
|
|
var x_adjust = (desired_x_delta - (xmax - xmin)) / 2;
|
|
var y_adjust = (desired_y_delta - (ymax - ymin)) / 2;
|
|
return [xmin - x_adjust, ymin - y_adjust, xmax + x_adjust, ymax + y_adjust];
|
|
};
|
|
MercatorTileSource.prototype.tms_to_wmts = function (x, y, z) {
|
|
'Note this works both ways';
|
|
return [x, Math.pow(2, z) - 1 - y, z];
|
|
};
|
|
MercatorTileSource.prototype.wmts_to_tms = function (x, y, z) {
|
|
'Note this works both ways';
|
|
return [x, Math.pow(2, z) - 1 - y, z];
|
|
};
|
|
MercatorTileSource.prototype.pixels_to_meters = function (px, py, level) {
|
|
var res = this.get_resolution(level);
|
|
var mx = (px * res) - this.x_origin_offset;
|
|
var my = (py * res) - this.y_origin_offset;
|
|
return [mx, my];
|
|
};
|
|
MercatorTileSource.prototype.meters_to_pixels = function (mx, my, level) {
|
|
var res = this.get_resolution(level);
|
|
var px = (mx + this.x_origin_offset) / res;
|
|
var py = (my + this.y_origin_offset) / res;
|
|
return [px, py];
|
|
};
|
|
MercatorTileSource.prototype.pixels_to_tile = function (px, py) {
|
|
var tx = Math.ceil(px / this.tile_size);
|
|
tx = tx === 0 ? tx : tx - 1;
|
|
var ty = Math.max(Math.ceil(py / this.tile_size) - 1, 0);
|
|
return [tx, ty];
|
|
};
|
|
MercatorTileSource.prototype.pixels_to_raster = function (px, py, level) {
|
|
var mapSize = this.tile_size << level;
|
|
return [px, mapSize - py];
|
|
};
|
|
MercatorTileSource.prototype.meters_to_tile = function (mx, my, level) {
|
|
var _a = this.meters_to_pixels(mx, my, level), px = _a[0], py = _a[1];
|
|
return this.pixels_to_tile(px, py);
|
|
};
|
|
MercatorTileSource.prototype.get_tile_meter_bounds = function (tx, ty, level) {
|
|
// expects tms styles coordinates (bottom-left origin)
|
|
var _a = this.pixels_to_meters(tx * this.tile_size, ty * this.tile_size, level), xmin = _a[0], ymin = _a[1];
|
|
var _b = this.pixels_to_meters((tx + 1) * this.tile_size, (ty + 1) * this.tile_size, level), xmax = _b[0], ymax = _b[1];
|
|
return [xmin, ymin, xmax, ymax];
|
|
};
|
|
MercatorTileSource.prototype.get_tile_geographic_bounds = function (tx, ty, level) {
|
|
var bounds = this.get_tile_meter_bounds(tx, ty, level);
|
|
var _a = tile_utils_1.meters_extent_to_geographic(bounds), minLon = _a[0], minLat = _a[1], maxLon = _a[2], maxLat = _a[3];
|
|
return [minLon, minLat, maxLon, maxLat];
|
|
};
|
|
MercatorTileSource.prototype.get_tiles_by_extent = function (extent, level, tile_border) {
|
|
if (tile_border === void 0) {
|
|
tile_border = 1;
|
|
}
|
|
// unpack extent and convert to tile coordinates
|
|
var xmin = extent[0], ymin = extent[1], xmax = extent[2], ymax = extent[3];
|
|
var _a = this.meters_to_tile(xmin, ymin, level), txmin = _a[0], tymin = _a[1];
|
|
var _b = this.meters_to_tile(xmax, ymax, level), txmax = _b[0], tymax = _b[1];
|
|
// add tiles which border
|
|
txmin -= tile_border;
|
|
tymin -= tile_border;
|
|
txmax += tile_border;
|
|
tymax += tile_border;
|
|
var tiles = [];
|
|
for (var ty = tymax; ty >= tymin; ty--) {
|
|
for (var tx = txmin; tx <= txmax; tx++) {
|
|
if (this.is_valid_tile(tx, ty, level))
|
|
tiles.push([tx, ty, level, this.get_tile_meter_bounds(tx, ty, level)]);
|
|
}
|
|
}
|
|
this.sort_tiles_from_center(tiles, [txmin, tymin, txmax, tymax]);
|
|
return tiles;
|
|
};
|
|
MercatorTileSource.prototype.quadkey_to_tile_xyz = function (quadKey) {
|
|
/**
|
|
* Computes tile x, y and z values based on quadKey.
|
|
*/
|
|
var tileX = 0;
|
|
var tileY = 0;
|
|
var tileZ = quadKey.length;
|
|
for (var i = tileZ; i > 0; i--) {
|
|
var value = quadKey.charAt(tileZ - i);
|
|
var mask = 1 << (i - 1);
|
|
switch (value) {
|
|
case '0':
|
|
continue;
|
|
case '1':
|
|
tileX |= mask;
|
|
break;
|
|
case '2':
|
|
tileY |= mask;
|
|
break;
|
|
case '3':
|
|
tileX |= mask;
|
|
tileY |= mask;
|
|
break;
|
|
default:
|
|
throw new TypeError("Invalid Quadkey: " + quadKey);
|
|
}
|
|
}
|
|
return [tileX, tileY, tileZ];
|
|
};
|
|
MercatorTileSource.prototype.tile_xyz_to_quadkey = function (x, y, z) {
|
|
/*
|
|
* Computes quadkey value based on tile x, y and z values.
|
|
*/
|
|
var quadkey = "";
|
|
for (var i = z; i > 0; i--) {
|
|
var mask = 1 << (i - 1);
|
|
var digit = 0;
|
|
if ((x & mask) !== 0) {
|
|
digit += 1;
|
|
}
|
|
if ((y & mask) !== 0) {
|
|
digit += 2;
|
|
}
|
|
quadkey += digit.toString();
|
|
}
|
|
return quadkey;
|
|
};
|
|
MercatorTileSource.prototype.children_by_tile_xyz = function (x, y, z) {
|
|
var quadkey = this.tile_xyz_to_quadkey(x, y, z);
|
|
var child_tile_xyz = [];
|
|
for (var i = 0; i <= 3; i++) {
|
|
var _a = this.quadkey_to_tile_xyz(quadkey + i.toString()), x_1 = _a[0], y_1 = _a[1], z_1 = _a[2];
|
|
var b = this.get_tile_meter_bounds(x_1, y_1, z_1);
|
|
child_tile_xyz.push([x_1, y_1, z_1, b]);
|
|
}
|
|
return child_tile_xyz;
|
|
};
|
|
MercatorTileSource.prototype.get_closest_parent_by_tile_xyz = function (x, y, z) {
|
|
var _a, _b, _c;
|
|
var world_x = this.calculate_world_x_by_tile_xyz(x, y, z);
|
|
_a = this.normalize_xyz(x, y, z), x = _a[0], y = _a[1], z = _a[2];
|
|
var quadkey = this.tile_xyz_to_quadkey(x, y, z);
|
|
while (quadkey.length > 0) {
|
|
quadkey = quadkey.substring(0, quadkey.length - 1);
|
|
_b = this.quadkey_to_tile_xyz(quadkey), x = _b[0], y = _b[1], z = _b[2];
|
|
_c = this.denormalize_xyz(x, y, z, world_x), x = _c[0], y = _c[1], z = _c[2];
|
|
if (this.tile_xyz_to_key(x, y, z) in this.tiles)
|
|
return [x, y, z];
|
|
}
|
|
return [0, 0, 0];
|
|
};
|
|
MercatorTileSource.prototype.normalize_xyz = function (x, y, z) {
|
|
if (this.wrap_around) {
|
|
var tile_count = Math.pow(2, z);
|
|
return [((x % tile_count) + tile_count) % tile_count, y, z];
|
|
}
|
|
else {
|
|
return [x, y, z];
|
|
}
|
|
};
|
|
MercatorTileSource.prototype.denormalize_xyz = function (x, y, z, world_x) {
|
|
return [x + (world_x * Math.pow(2, z)), y, z];
|
|
};
|
|
MercatorTileSource.prototype.denormalize_meters = function (meters_x, meters_y, _level, world_x) {
|
|
return [meters_x + (world_x * 2 * Math.PI * 6378137), meters_y];
|
|
};
|
|
MercatorTileSource.prototype.calculate_world_x_by_tile_xyz = function (x, _y, z) {
|
|
return Math.floor(x / Math.pow(2, z));
|
|
};
|
|
return MercatorTileSource;
|
|
}(tile_source_1.TileSource));
|
|
exports.MercatorTileSource = MercatorTileSource;
|
|
MercatorTileSource.initClass();
|
|
}
|
|
,
|
|
/* models/tiles/quadkey_tile_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var mercator_tile_source_1 = require(235) /* ./mercator_tile_source */;
|
|
var QUADKEYTileSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(QUADKEYTileSource, _super);
|
|
function QUADKEYTileSource(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
QUADKEYTileSource.initClass = function () {
|
|
this.prototype.type = 'QUADKEYTileSource';
|
|
};
|
|
QUADKEYTileSource.prototype.get_image_url = function (x, y, z) {
|
|
var image_url = this.string_lookup_replace(this.url, this.extra_url_vars);
|
|
var _a = this.tms_to_wmts(x, y, z), wx = _a[0], wy = _a[1], wz = _a[2];
|
|
var quadKey = this.tile_xyz_to_quadkey(wx, wy, wz);
|
|
return image_url.replace("{Q}", quadKey);
|
|
};
|
|
return QUADKEYTileSource;
|
|
}(mercator_tile_source_1.MercatorTileSource));
|
|
exports.QUADKEYTileSource = QUADKEYTileSource;
|
|
QUADKEYTileSource.initClass();
|
|
}
|
|
,
|
|
/* models/tiles/tile_renderer */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var image_pool_1 = require(233) /* ./image_pool */;
|
|
var wmts_tile_source_1 = require(241) /* ./wmts_tile_source */;
|
|
var data_renderer_1 = require(192) /* ../renderers/data_renderer */;
|
|
var range1d_1 = require(191) /* ../ranges/range1d */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var selection_manager_1 = require(20) /* ../../core/selection_manager */;
|
|
var column_data_source_1 = require(208) /* ../sources/column_data_source */;
|
|
var TileRendererView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TileRendererView, _super);
|
|
function TileRendererView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
TileRendererView.prototype.initialize = function () {
|
|
this._tiles = [];
|
|
_super.prototype.initialize.call(this);
|
|
};
|
|
TileRendererView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.change, function () { return _this.request_render(); });
|
|
this.connect(this.model.tile_source.change, function () { return _this.request_render(); });
|
|
};
|
|
TileRendererView.prototype.get_extent = function () {
|
|
return [this.x_range.start, this.y_range.start, this.x_range.end, this.y_range.end];
|
|
};
|
|
Object.defineProperty(TileRendererView.prototype, "map_plot", {
|
|
get: function () {
|
|
return this.plot_model;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(TileRendererView.prototype, "map_canvas", {
|
|
get: function () {
|
|
return this.plot_view.canvas_view.ctx;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(TileRendererView.prototype, "map_frame", {
|
|
get: function () {
|
|
return this.plot_view.frame;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(TileRendererView.prototype, "x_range", {
|
|
get: function () {
|
|
return this.map_plot.x_range;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(TileRendererView.prototype, "y_range", {
|
|
get: function () {
|
|
return this.map_plot.y_range;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
TileRendererView.prototype._set_data = function () {
|
|
this.pool = new image_pool_1.ImagePool();
|
|
this.extent = this.get_extent();
|
|
this._last_height = undefined;
|
|
this._last_width = undefined;
|
|
};
|
|
TileRendererView.prototype._update_attribution = function () {
|
|
if (this.attribution_el != null)
|
|
dom_1.removeElement(this.attribution_el);
|
|
var attribution = this.model.tile_source.attribution;
|
|
if (types_1.isString(attribution) && attribution.length > 0) {
|
|
var _a = this.plot_view, layout = _a.layout, frame = _a.frame;
|
|
var offset_right = layout._width.value - frame._right.value;
|
|
var offset_bottom = layout._height.value - frame._bottom.value;
|
|
var max_width = frame._width.value;
|
|
this.attribution_el = dom_1.div({
|
|
class: 'bk-tile-attribution',
|
|
style: {
|
|
position: "absolute",
|
|
right: offset_right + "px",
|
|
bottom: offset_bottom + "px",
|
|
'max-width': max_width - 4 /*padding*/ + "px",
|
|
padding: "2px",
|
|
'background-color': 'rgba(255,255,255,0.5)',
|
|
'font-size': '7pt',
|
|
'line-height': '1.05',
|
|
'white-space': 'nowrap',
|
|
overflow: 'hidden',
|
|
'text-overflow': 'ellipsis',
|
|
},
|
|
});
|
|
var overlays = this.plot_view.canvas_view.events_el;
|
|
overlays.appendChild(this.attribution_el);
|
|
this.attribution_el.innerHTML = attribution;
|
|
this.attribution_el.title = this.attribution_el.textContent.replace(/\s*\n\s*/g, " ");
|
|
}
|
|
};
|
|
TileRendererView.prototype._map_data = function () {
|
|
this.initial_extent = this.get_extent();
|
|
var zoom_level = this.model.tile_source.get_level_by_extent(this.initial_extent, this.map_frame._height.value, this.map_frame._width.value);
|
|
var new_extent = this.model.tile_source.snap_to_zoom_level(this.initial_extent, this.map_frame._height.value, this.map_frame._width.value, zoom_level);
|
|
this.x_range.start = new_extent[0];
|
|
this.y_range.start = new_extent[1];
|
|
this.x_range.end = new_extent[2];
|
|
this.y_range.end = new_extent[3];
|
|
if (this.x_range instanceof range1d_1.Range1d) {
|
|
this.x_range.reset_start = new_extent[0];
|
|
this.x_range.reset_end = new_extent[2];
|
|
}
|
|
if (this.y_range instanceof range1d_1.Range1d) {
|
|
this.y_range.reset_start = new_extent[1];
|
|
this.y_range.reset_end = new_extent[3];
|
|
}
|
|
this._update_attribution();
|
|
};
|
|
TileRendererView.prototype._on_tile_load = function (tile_data, e) {
|
|
tile_data.img = e.target;
|
|
tile_data.loaded = true;
|
|
this.request_render();
|
|
};
|
|
TileRendererView.prototype._on_tile_cache_load = function (tile_data, e) {
|
|
tile_data.img = e.target;
|
|
tile_data.loaded = true;
|
|
tile_data.finished = true;
|
|
this.notify_finished();
|
|
};
|
|
TileRendererView.prototype._on_tile_error = function (tile_data) {
|
|
tile_data.finished = true;
|
|
};
|
|
TileRendererView.prototype._create_tile = function (x, y, z, bounds, cache_only) {
|
|
if (cache_only === void 0) {
|
|
cache_only = false;
|
|
}
|
|
var _a = this.model.tile_source.normalize_xyz(x, y, z), nx = _a[0], ny = _a[1], nz = _a[2];
|
|
var img = this.pool.pop();
|
|
var tile = {
|
|
img: img,
|
|
tile_coords: [x, y, z],
|
|
normalized_coords: [nx, ny, nz],
|
|
quadkey: this.model.tile_source.tile_xyz_to_quadkey(x, y, z),
|
|
cache_key: this.model.tile_source.tile_xyz_to_key(x, y, z),
|
|
bounds: bounds,
|
|
loaded: false,
|
|
finished: false,
|
|
x_coord: bounds[0],
|
|
y_coord: bounds[3],
|
|
};
|
|
img.onload = cache_only ? this._on_tile_cache_load.bind(this, tile) : this._on_tile_load.bind(this, tile);
|
|
img.onerror = this._on_tile_error.bind(this, tile);
|
|
img.alt = '';
|
|
img.src = this.model.tile_source.get_image_url(nx, ny, nz);
|
|
this.model.tile_source.tiles[tile.cache_key] = tile;
|
|
this._tiles.push(tile);
|
|
};
|
|
TileRendererView.prototype._enforce_aspect_ratio = function () {
|
|
// brute force way of handling resize or sizing_mode event -------------------------------------------------------------
|
|
if ((this._last_height !== this.map_frame._height.value) || (this._last_width !== this.map_frame._width.value)) {
|
|
var extent = this.get_extent();
|
|
var zoom_level = this.model.tile_source.get_level_by_extent(extent, this.map_frame._height.value, this.map_frame._width.value);
|
|
var new_extent = this.model.tile_source.snap_to_zoom_level(extent, this.map_frame._height.value, this.map_frame._width.value, zoom_level);
|
|
this.x_range.setv({ start: new_extent[0], end: new_extent[2] });
|
|
this.y_range.setv({ start: new_extent[1], end: new_extent[3] });
|
|
this.extent = new_extent;
|
|
this._last_height = this.map_frame._height.value;
|
|
this._last_width = this.map_frame._width.value;
|
|
}
|
|
};
|
|
TileRendererView.prototype.has_finished = function () {
|
|
if (!_super.prototype.has_finished.call(this)) {
|
|
return false;
|
|
}
|
|
if (this._tiles.length === 0) {
|
|
return false;
|
|
}
|
|
for (var _i = 0, _a = this._tiles; _i < _a.length; _i++) {
|
|
var tile = _a[_i];
|
|
if (!tile.finished) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
TileRendererView.prototype.render = function () {
|
|
if (this.map_initialized == null) {
|
|
this._set_data();
|
|
this._map_data();
|
|
this.map_initialized = true;
|
|
}
|
|
this._enforce_aspect_ratio();
|
|
this._update();
|
|
if (this.prefetch_timer != null) {
|
|
clearTimeout(this.prefetch_timer);
|
|
}
|
|
this.prefetch_timer = setTimeout(this._prefetch_tiles.bind(this), 500);
|
|
if (this.has_finished()) {
|
|
this.notify_finished();
|
|
}
|
|
};
|
|
TileRendererView.prototype._draw_tile = function (tile_key) {
|
|
var tile_obj = this.model.tile_source.tiles[tile_key];
|
|
if (tile_obj != null) {
|
|
var _a = this.plot_view.map_to_screen([tile_obj.bounds[0]], [tile_obj.bounds[3]]), sxmin = _a[0][0], symin = _a[1][0]; // XXX: TS #20623
|
|
var _b = this.plot_view.map_to_screen([tile_obj.bounds[2]], [tile_obj.bounds[1]]), sxmax = _b[0][0], symax = _b[1][0]; //
|
|
var sw = sxmax - sxmin;
|
|
var sh = symax - symin;
|
|
var sx = sxmin;
|
|
var sy = symin;
|
|
var old_smoothing = this.map_canvas.getImageSmoothingEnabled();
|
|
this.map_canvas.setImageSmoothingEnabled(this.model.smoothing);
|
|
this.map_canvas.drawImage(tile_obj.img, sx, sy, sw, sh);
|
|
this.map_canvas.setImageSmoothingEnabled(old_smoothing);
|
|
tile_obj.finished = true;
|
|
}
|
|
};
|
|
TileRendererView.prototype._set_rect = function () {
|
|
var outline_width = this.plot_model.properties.outline_line_width.value();
|
|
var l = this.map_frame._left.value + (outline_width / 2);
|
|
var t = this.map_frame._top.value + (outline_width / 2);
|
|
var w = this.map_frame._width.value - outline_width;
|
|
var h = this.map_frame._height.value - outline_width;
|
|
this.map_canvas.rect(l, t, w, h);
|
|
this.map_canvas.clip();
|
|
};
|
|
TileRendererView.prototype._render_tiles = function (tile_keys) {
|
|
this.map_canvas.save();
|
|
this._set_rect();
|
|
this.map_canvas.globalAlpha = this.model.alpha;
|
|
for (var _i = 0, tile_keys_1 = tile_keys; _i < tile_keys_1.length; _i++) {
|
|
var tile_key = tile_keys_1[_i];
|
|
this._draw_tile(tile_key);
|
|
}
|
|
this.map_canvas.restore();
|
|
};
|
|
TileRendererView.prototype._prefetch_tiles = function () {
|
|
var tile_source = this.model.tile_source;
|
|
var extent = this.get_extent();
|
|
var h = this.map_frame._height.value;
|
|
var w = this.map_frame._width.value;
|
|
var zoom_level = this.model.tile_source.get_level_by_extent(extent, h, w);
|
|
var tiles = this.model.tile_source.get_tiles_by_extent(extent, zoom_level);
|
|
for (var t = 0, end = Math.min(10, tiles.length); t < end; t++) {
|
|
var _a = tiles[t], x = _a[0], y = _a[1], z = _a[2];
|
|
var children = this.model.tile_source.children_by_tile_xyz(x, y, z);
|
|
for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
|
|
var c = children_1[_i];
|
|
var cx = c[0], cy = c[1], cz = c[2], cbounds = c[3];
|
|
if (tile_source.tile_xyz_to_key(cx, cy, cz) in tile_source.tiles) {
|
|
continue;
|
|
}
|
|
else {
|
|
this._create_tile(cx, cy, cz, cbounds, true);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
TileRendererView.prototype._fetch_tiles = function (tiles) {
|
|
for (var _i = 0, tiles_1 = tiles; _i < tiles_1.length; _i++) {
|
|
var tile = tiles_1[_i];
|
|
var x = tile[0], y = tile[1], z = tile[2], bounds = tile[3];
|
|
this._create_tile(x, y, z, bounds);
|
|
}
|
|
};
|
|
TileRendererView.prototype._update = function () {
|
|
var _this = this;
|
|
var tile_source = this.model.tile_source;
|
|
var min_zoom = tile_source.min_zoom;
|
|
var max_zoom = tile_source.max_zoom;
|
|
var extent = this.get_extent();
|
|
var zooming_out = (this.extent[2] - this.extent[0]) < (extent[2] - extent[0]);
|
|
var h = this.map_frame._height.value;
|
|
var w = this.map_frame._width.value;
|
|
var zoom_level = tile_source.get_level_by_extent(extent, h, w);
|
|
var snap_back = false;
|
|
if (zoom_level < min_zoom) {
|
|
extent = this.extent;
|
|
zoom_level = min_zoom;
|
|
snap_back = true;
|
|
}
|
|
else if (zoom_level > max_zoom) {
|
|
extent = this.extent;
|
|
zoom_level = max_zoom;
|
|
snap_back = true;
|
|
}
|
|
if (snap_back) {
|
|
this.x_range.setv({ x_range: { start: extent[0], end: extent[2] } });
|
|
this.y_range.setv({ start: extent[1], end: extent[3] });
|
|
this.extent = extent;
|
|
}
|
|
this.extent = extent;
|
|
var tiles = tile_source.get_tiles_by_extent(extent, zoom_level);
|
|
var need_load = [];
|
|
var cached = [];
|
|
var parents = [];
|
|
var children = [];
|
|
for (var _i = 0, tiles_2 = tiles; _i < tiles_2.length; _i++) {
|
|
var t = tiles_2[_i];
|
|
var x = t[0], y = t[1], z = t[2];
|
|
var key = tile_source.tile_xyz_to_key(x, y, z);
|
|
var tile = tile_source.tiles[key];
|
|
if (tile != null && tile.loaded) {
|
|
cached.push(key);
|
|
}
|
|
else {
|
|
if (this.model.render_parents) {
|
|
var _a = tile_source.get_closest_parent_by_tile_xyz(x, y, z), px = _a[0], py = _a[1], pz = _a[2];
|
|
var parent_key = tile_source.tile_xyz_to_key(px, py, pz);
|
|
var parent_tile = tile_source.tiles[parent_key];
|
|
if ((parent_tile != null) && parent_tile.loaded && !array_1.includes(parents, parent_key)) {
|
|
parents.push(parent_key);
|
|
}
|
|
if (zooming_out) {
|
|
var child_tiles = tile_source.children_by_tile_xyz(x, y, z);
|
|
for (var _b = 0, child_tiles_1 = child_tiles; _b < child_tiles_1.length; _b++) {
|
|
var _c = child_tiles_1[_b], cx = _c[0], cy = _c[1], cz = _c[2];
|
|
var child_key = tile_source.tile_xyz_to_key(cx, cy, cz);
|
|
if (child_key in tile_source.tiles)
|
|
children.push(child_key);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (tile == null)
|
|
need_load.push(t);
|
|
}
|
|
// draw stand-in parents ----------
|
|
this._render_tiles(parents);
|
|
this._render_tiles(children);
|
|
// draw cached ----------
|
|
this._render_tiles(cached);
|
|
// fetch missing -------
|
|
if (this.render_timer != null) {
|
|
clearTimeout(this.render_timer);
|
|
}
|
|
this.render_timer = setTimeout((function () { return _this._fetch_tiles(need_load); }), 65);
|
|
};
|
|
return TileRendererView;
|
|
}(data_renderer_1.DataRendererView));
|
|
exports.TileRendererView = TileRendererView;
|
|
var TileRenderer = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TileRenderer, _super);
|
|
function TileRenderer(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
// XXX: tile renderer doesn't allow selection, but needs to fulfil the APIs
|
|
_this._selection_manager = new selection_manager_1.SelectionManager({
|
|
source: new column_data_source_1.ColumnDataSource(),
|
|
});
|
|
return _this;
|
|
}
|
|
TileRenderer.initClass = function () {
|
|
this.prototype.type = 'TileRenderer';
|
|
this.prototype.default_view = TileRendererView;
|
|
this.define({
|
|
alpha: [p.Number, 1.0],
|
|
smoothing: [p.Boolean, true],
|
|
tile_source: [p.Instance, function () { return new wmts_tile_source_1.WMTSTileSource(); }],
|
|
render_parents: [p.Boolean, true],
|
|
});
|
|
};
|
|
TileRenderer.prototype.get_selection_manager = function () {
|
|
return this._selection_manager;
|
|
};
|
|
return TileRenderer;
|
|
}(data_renderer_1.DataRenderer));
|
|
exports.TileRenderer = TileRenderer;
|
|
TileRenderer.initClass();
|
|
}
|
|
,
|
|
/* models/tiles/tile_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var image_pool_1 = require(233) /* ./image_pool */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var TileSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TileSource, _super);
|
|
function TileSource(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
TileSource.initClass = function () {
|
|
this.prototype.type = 'TileSource';
|
|
this.define({
|
|
url: [p.String, ''],
|
|
tile_size: [p.Number, 256],
|
|
max_zoom: [p.Number, 30],
|
|
min_zoom: [p.Number, 0],
|
|
extra_url_vars: [p.Any, {}],
|
|
attribution: [p.String, ''],
|
|
x_origin_offset: [p.Number],
|
|
y_origin_offset: [p.Number],
|
|
initial_resolution: [p.Number],
|
|
});
|
|
};
|
|
TileSource.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.tiles = {};
|
|
this.pool = new image_pool_1.ImagePool();
|
|
this._normalize_case();
|
|
};
|
|
TileSource.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.change, function () { return _this._clear_cache(); });
|
|
};
|
|
TileSource.prototype.string_lookup_replace = function (str, lookup) {
|
|
var result_str = str;
|
|
for (var key in lookup) {
|
|
var value = lookup[key];
|
|
result_str = result_str.replace("{" + key + "}", value);
|
|
}
|
|
return result_str;
|
|
};
|
|
TileSource.prototype._normalize_case = function () {
|
|
/*
|
|
* Note: should probably be refactored into subclasses.
|
|
*/
|
|
var url = this.url
|
|
.replace('{x}', '{X}')
|
|
.replace('{y}', '{Y}')
|
|
.replace('{z}', '{Z}')
|
|
.replace('{q}', '{Q}')
|
|
.replace('{xmin}', '{XMIN}')
|
|
.replace('{ymin}', '{YMIN}')
|
|
.replace('{xmax}', '{XMAX}')
|
|
.replace('{ymax}', '{YMAX}');
|
|
this.url = url;
|
|
};
|
|
TileSource.prototype._clear_cache = function () {
|
|
this.tiles = {};
|
|
};
|
|
TileSource.prototype.tile_xyz_to_key = function (x, y, z) {
|
|
return x + ":" + y + ":" + z;
|
|
};
|
|
TileSource.prototype.key_to_tile_xyz = function (key) {
|
|
var _a = key.split(':').map(function (c) { return parseInt(c); }), x = _a[0], y = _a[1], z = _a[2];
|
|
return [x, y, z];
|
|
};
|
|
TileSource.prototype.sort_tiles_from_center = function (tiles, tile_extent) {
|
|
var txmin = tile_extent[0], tymin = tile_extent[1], txmax = tile_extent[2], tymax = tile_extent[3];
|
|
var center_x = ((txmax - txmin) / 2) + txmin;
|
|
var center_y = ((tymax - tymin) / 2) + tymin;
|
|
tiles.sort(function (a, b) {
|
|
var a_distance = Math.sqrt(Math.pow(center_x - a[0], 2) + Math.pow(center_y - a[1], 2));
|
|
var b_distance = Math.sqrt(Math.pow(center_x - b[0], 2) + Math.pow(center_y - b[1], 2));
|
|
return a_distance - b_distance;
|
|
});
|
|
};
|
|
TileSource.prototype.get_image_url = function (x, y, z) {
|
|
var image_url = this.string_lookup_replace(this.url, this.extra_url_vars);
|
|
return image_url.replace("{X}", x.toString())
|
|
.replace('{Y}', y.toString())
|
|
.replace("{Z}", z.toString());
|
|
};
|
|
return TileSource;
|
|
}(model_1.Model));
|
|
exports.TileSource = TileSource;
|
|
TileSource.initClass();
|
|
}
|
|
,
|
|
/* models/tiles/tile_utils */ function _(require, module, exports) {
|
|
var projections_1 = require(36) /* ../../core/util/projections */;
|
|
function geographic_to_meters(xLon, yLat) {
|
|
return projections_1.wgs84_mercator.forward([xLon, yLat]);
|
|
}
|
|
exports.geographic_to_meters = geographic_to_meters;
|
|
function meters_to_geographic(mx, my) {
|
|
return projections_1.wgs84_mercator.inverse([mx, my]);
|
|
}
|
|
exports.meters_to_geographic = meters_to_geographic;
|
|
function geographic_extent_to_meters(extent) {
|
|
var g_xmin = extent[0], g_ymin = extent[1], g_xmax = extent[2], g_ymax = extent[3];
|
|
var _a = geographic_to_meters(g_xmin, g_ymin), m_xmin = _a[0], m_ymin = _a[1];
|
|
var _b = geographic_to_meters(g_xmax, g_ymax), m_xmax = _b[0], m_ymax = _b[1];
|
|
return [m_xmin, m_ymin, m_xmax, m_ymax];
|
|
}
|
|
exports.geographic_extent_to_meters = geographic_extent_to_meters;
|
|
function meters_extent_to_geographic(extent) {
|
|
var m_xmin = extent[0], m_ymin = extent[1], m_xmax = extent[2], m_ymax = extent[3];
|
|
var _a = meters_to_geographic(m_xmin, m_ymin), g_xmin = _a[0], g_ymin = _a[1];
|
|
var _b = meters_to_geographic(m_xmax, m_ymax), g_xmax = _b[0], g_ymax = _b[1];
|
|
return [g_xmin, g_ymin, g_xmax, g_ymax];
|
|
}
|
|
exports.meters_extent_to_geographic = meters_extent_to_geographic;
|
|
}
|
|
,
|
|
/* models/tiles/tms_tile_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var mercator_tile_source_1 = require(235) /* ./mercator_tile_source */;
|
|
var TMSTileSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TMSTileSource, _super);
|
|
function TMSTileSource(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
TMSTileSource.initClass = function () {
|
|
this.prototype.type = 'TMSTileSource';
|
|
};
|
|
TMSTileSource.prototype.get_image_url = function (x, y, z) {
|
|
var image_url = this.string_lookup_replace(this.url, this.extra_url_vars);
|
|
return image_url.replace("{X}", x.toString())
|
|
.replace('{Y}', y.toString())
|
|
.replace("{Z}", z.toString());
|
|
};
|
|
return TMSTileSource;
|
|
}(mercator_tile_source_1.MercatorTileSource));
|
|
exports.TMSTileSource = TMSTileSource;
|
|
TMSTileSource.initClass();
|
|
}
|
|
,
|
|
/* models/tiles/wmts_tile_source */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var mercator_tile_source_1 = require(235) /* ./mercator_tile_source */;
|
|
var WMTSTileSource = /** @class */ (function (_super) {
|
|
tslib_1.__extends(WMTSTileSource, _super);
|
|
function WMTSTileSource(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
WMTSTileSource.initClass = function () {
|
|
this.prototype.type = 'WMTSTileSource';
|
|
};
|
|
WMTSTileSource.prototype.get_image_url = function (x, y, z) {
|
|
var image_url = this.string_lookup_replace(this.url, this.extra_url_vars);
|
|
var _a = this.tms_to_wmts(x, y, z), wx = _a[0], wy = _a[1], wz = _a[2];
|
|
return image_url.replace("{X}", wx.toString())
|
|
.replace('{Y}', wy.toString())
|
|
.replace("{Z}", wz.toString());
|
|
};
|
|
return WMTSTileSource;
|
|
}(mercator_tile_source_1.MercatorTileSource));
|
|
exports.WMTSTileSource = WMTSTileSource;
|
|
WMTSTileSource.initClass();
|
|
}
|
|
,
|
|
/* models/tools/actions/action_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var button_tool_1 = require(251) /* ../button_tool */;
|
|
var signaling_1 = require(22) /* ../../../core/signaling */;
|
|
var ActionToolButtonView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ActionToolButtonView, _super);
|
|
function ActionToolButtonView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ActionToolButtonView.prototype._clicked = function () {
|
|
this.model.do.emit();
|
|
};
|
|
return ActionToolButtonView;
|
|
}(button_tool_1.ButtonToolButtonView));
|
|
exports.ActionToolButtonView = ActionToolButtonView;
|
|
var ActionToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ActionToolView, _super);
|
|
function ActionToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ActionToolView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.do, function () { return _this.doit(); });
|
|
};
|
|
return ActionToolView;
|
|
}(button_tool_1.ButtonToolView));
|
|
exports.ActionToolView = ActionToolView;
|
|
var ActionTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ActionTool, _super);
|
|
function ActionTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.button_view = ActionToolButtonView;
|
|
_this.do = new signaling_1.Signal0(_this, "do");
|
|
return _this;
|
|
}
|
|
ActionTool.initClass = function () {
|
|
this.prototype.type = "ActionTool";
|
|
};
|
|
return ActionTool;
|
|
}(button_tool_1.ButtonTool));
|
|
exports.ActionTool = ActionTool;
|
|
ActionTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/actions/custom_action */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var action_tool_1 = require(242) /* ./action_tool */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var CustomActionButtonView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CustomActionButtonView, _super);
|
|
function CustomActionButtonView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
CustomActionButtonView.prototype.css_classes = function () {
|
|
return _super.prototype.css_classes.call(this).concat("bk-toolbar-button-custom-action");
|
|
};
|
|
return CustomActionButtonView;
|
|
}(action_tool_1.ActionToolButtonView));
|
|
exports.CustomActionButtonView = CustomActionButtonView;
|
|
var CustomActionView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CustomActionView, _super);
|
|
function CustomActionView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
CustomActionView.prototype.doit = function () {
|
|
if (this.model.callback != null)
|
|
this.model.callback.execute(this.model);
|
|
};
|
|
return CustomActionView;
|
|
}(action_tool_1.ActionToolView));
|
|
exports.CustomActionView = CustomActionView;
|
|
var CustomAction = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CustomAction, _super);
|
|
function CustomAction(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Custom Action";
|
|
_this.button_view = CustomActionButtonView;
|
|
return _this;
|
|
}
|
|
CustomAction.initClass = function () {
|
|
this.prototype.type = "CustomAction";
|
|
this.prototype.default_view = CustomActionView;
|
|
this.define({
|
|
action_tooltip: [p.String, 'Perform a Custom Action'],
|
|
callback: [p.Any],
|
|
icon: [p.String,],
|
|
});
|
|
};
|
|
Object.defineProperty(CustomAction.prototype, "tooltip", {
|
|
get: function () {
|
|
return this.action_tooltip;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return CustomAction;
|
|
}(action_tool_1.ActionTool));
|
|
exports.CustomAction = CustomAction;
|
|
CustomAction.initClass();
|
|
}
|
|
,
|
|
/* models/tools/actions/help_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var action_tool_1 = require(242) /* ./action_tool */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var HelpToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(HelpToolView, _super);
|
|
function HelpToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
HelpToolView.prototype.doit = function () {
|
|
window.open(this.model.redirect);
|
|
};
|
|
return HelpToolView;
|
|
}(action_tool_1.ActionToolView));
|
|
exports.HelpToolView = HelpToolView;
|
|
var HelpTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(HelpTool, _super);
|
|
function HelpTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Help";
|
|
_this.icon = "bk-tool-icon-help";
|
|
return _this;
|
|
}
|
|
HelpTool.initClass = function () {
|
|
this.prototype.type = "HelpTool";
|
|
this.prototype.default_view = HelpToolView;
|
|
this.define({
|
|
help_tooltip: [p.String, 'Click the question mark to learn more about Bokeh plot tools.'],
|
|
redirect: [p.String, 'https://bokeh.pydata.org/en/latest/docs/user_guide/tools.html#built-in-tools'],
|
|
});
|
|
};
|
|
Object.defineProperty(HelpTool.prototype, "tooltip", {
|
|
get: function () {
|
|
return this.help_tooltip;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return HelpTool;
|
|
}(action_tool_1.ActionTool));
|
|
exports.HelpTool = HelpTool;
|
|
HelpTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/actions/redo_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var action_tool_1 = require(242) /* ./action_tool */;
|
|
var RedoToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(RedoToolView, _super);
|
|
function RedoToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
RedoToolView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.plot_view.state_changed, function () { return _this.model.disabled = !_this.plot_view.can_redo(); });
|
|
};
|
|
RedoToolView.prototype.doit = function () {
|
|
this.plot_view.redo();
|
|
};
|
|
return RedoToolView;
|
|
}(action_tool_1.ActionToolView));
|
|
exports.RedoToolView = RedoToolView;
|
|
var RedoTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(RedoTool, _super);
|
|
function RedoTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Redo";
|
|
_this.icon = "bk-tool-icon-redo";
|
|
return _this;
|
|
}
|
|
RedoTool.initClass = function () {
|
|
this.prototype.type = "RedoTool";
|
|
this.prototype.default_view = RedoToolView;
|
|
this.override({
|
|
disabled: true,
|
|
});
|
|
};
|
|
return RedoTool;
|
|
}(action_tool_1.ActionTool));
|
|
exports.RedoTool = RedoTool;
|
|
RedoTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/actions/reset_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var action_tool_1 = require(242) /* ./action_tool */;
|
|
var ResetToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ResetToolView, _super);
|
|
function ResetToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ResetToolView.prototype.doit = function () {
|
|
this.plot_view.reset();
|
|
};
|
|
return ResetToolView;
|
|
}(action_tool_1.ActionToolView));
|
|
exports.ResetToolView = ResetToolView;
|
|
var ResetTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ResetTool, _super);
|
|
function ResetTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Reset";
|
|
_this.icon = "bk-tool-icon-reset";
|
|
return _this;
|
|
}
|
|
ResetTool.initClass = function () {
|
|
this.prototype.type = "ResetTool";
|
|
this.prototype.default_view = ResetToolView;
|
|
};
|
|
return ResetTool;
|
|
}(action_tool_1.ActionTool));
|
|
exports.ResetTool = ResetTool;
|
|
ResetTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/actions/save_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var action_tool_1 = require(242) /* ./action_tool */;
|
|
var SaveToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(SaveToolView, _super);
|
|
function SaveToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
SaveToolView.prototype.doit = function () {
|
|
this.plot_view.save("bokeh_plot");
|
|
};
|
|
return SaveToolView;
|
|
}(action_tool_1.ActionToolView));
|
|
exports.SaveToolView = SaveToolView;
|
|
var SaveTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(SaveTool, _super);
|
|
function SaveTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Save";
|
|
_this.icon = "bk-tool-icon-save";
|
|
return _this;
|
|
}
|
|
SaveTool.initClass = function () {
|
|
this.prototype.type = "SaveTool";
|
|
this.prototype.default_view = SaveToolView;
|
|
};
|
|
return SaveTool;
|
|
}(action_tool_1.ActionTool));
|
|
exports.SaveTool = SaveTool;
|
|
SaveTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/actions/undo_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var action_tool_1 = require(242) /* ./action_tool */;
|
|
var UndoToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(UndoToolView, _super);
|
|
function UndoToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
UndoToolView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.plot_view.state_changed, function () { return _this.model.disabled = !_this.plot_view.can_undo(); });
|
|
};
|
|
UndoToolView.prototype.doit = function () {
|
|
this.plot_view.undo();
|
|
};
|
|
return UndoToolView;
|
|
}(action_tool_1.ActionToolView));
|
|
exports.UndoToolView = UndoToolView;
|
|
var UndoTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(UndoTool, _super);
|
|
function UndoTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Undo";
|
|
_this.icon = "bk-tool-icon-undo";
|
|
return _this;
|
|
}
|
|
UndoTool.initClass = function () {
|
|
this.prototype.type = "UndoTool";
|
|
this.prototype.default_view = UndoToolView;
|
|
this.override({
|
|
disabled: true,
|
|
});
|
|
};
|
|
return UndoTool;
|
|
}(action_tool_1.ActionTool));
|
|
exports.UndoTool = UndoTool;
|
|
UndoTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/actions/zoom_in_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var action_tool_1 = require(242) /* ./action_tool */;
|
|
var zoom_1 = require(48) /* ../../../core/util/zoom */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var ZoomInToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ZoomInToolView, _super);
|
|
function ZoomInToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ZoomInToolView.prototype.doit = function () {
|
|
var frame = this.plot_view.frame;
|
|
var dims = this.model.dimensions;
|
|
// restrict to axis configured in tool's dimensions property
|
|
var h_axis = dims == 'width' || dims == 'both';
|
|
var v_axis = dims == 'height' || dims == 'both';
|
|
var zoom_info = zoom_1.scale_range(frame, this.model.factor, h_axis, v_axis);
|
|
this.plot_view.push_state('zoom_out', { range: zoom_info });
|
|
this.plot_view.update_range(zoom_info, false, true);
|
|
if (this.model.document)
|
|
this.model.document.interactive_start(this.plot_model);
|
|
};
|
|
return ZoomInToolView;
|
|
}(action_tool_1.ActionToolView));
|
|
exports.ZoomInToolView = ZoomInToolView;
|
|
var ZoomInTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ZoomInTool, _super);
|
|
function ZoomInTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Zoom In";
|
|
_this.icon = "bk-tool-icon-zoom-in";
|
|
return _this;
|
|
}
|
|
ZoomInTool.initClass = function () {
|
|
this.prototype.type = "ZoomInTool";
|
|
this.prototype.default_view = ZoomInToolView;
|
|
this.define({
|
|
factor: [p.Percent, 0.1],
|
|
dimensions: [p.Dimensions, "both"],
|
|
});
|
|
};
|
|
Object.defineProperty(ZoomInTool.prototype, "tooltip", {
|
|
get: function () {
|
|
return this._get_dim_tooltip(this.tool_name, this.dimensions);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return ZoomInTool;
|
|
}(action_tool_1.ActionTool));
|
|
exports.ZoomInTool = ZoomInTool;
|
|
ZoomInTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/actions/zoom_out_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var action_tool_1 = require(242) /* ./action_tool */;
|
|
var zoom_1 = require(48) /* ../../../core/util/zoom */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var ZoomOutToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ZoomOutToolView, _super);
|
|
function ZoomOutToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ZoomOutToolView.prototype.doit = function () {
|
|
var frame = this.plot_view.frame;
|
|
var dims = this.model.dimensions;
|
|
// restrict to axis configured in tool's dimensions property
|
|
var h_axis = dims == 'width' || dims == 'both';
|
|
var v_axis = dims == 'height' || dims == 'both';
|
|
// zooming out requires a negative factor to scale_range
|
|
var zoom_info = zoom_1.scale_range(frame, -this.model.factor, h_axis, v_axis);
|
|
this.plot_view.push_state('zoom_out', { range: zoom_info });
|
|
this.plot_view.update_range(zoom_info, false, true);
|
|
if (this.model.document)
|
|
this.model.document.interactive_start(this.plot_model);
|
|
};
|
|
return ZoomOutToolView;
|
|
}(action_tool_1.ActionToolView));
|
|
exports.ZoomOutToolView = ZoomOutToolView;
|
|
var ZoomOutTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ZoomOutTool, _super);
|
|
function ZoomOutTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Zoom Out";
|
|
_this.icon = "bk-tool-icon-zoom-out";
|
|
return _this;
|
|
}
|
|
ZoomOutTool.initClass = function () {
|
|
this.prototype.type = "ZoomOutTool";
|
|
this.prototype.default_view = ZoomOutToolView;
|
|
this.define({
|
|
factor: [p.Percent, 0.1],
|
|
dimensions: [p.Dimensions, "both"],
|
|
});
|
|
};
|
|
Object.defineProperty(ZoomOutTool.prototype, "tooltip", {
|
|
get: function () {
|
|
return this._get_dim_tooltip(this.tool_name, this.dimensions);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return ZoomOutTool;
|
|
}(action_tool_1.ActionTool));
|
|
exports.ZoomOutTool = ZoomOutTool;
|
|
ZoomOutTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/button_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var dom_view_1 = require(6) /* ../../core/dom_view */;
|
|
var tool_1 = require(276) /* ./tool */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var string_1 = require(40) /* ../../core/util/string */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var ButtonToolButtonView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ButtonToolButtonView, _super);
|
|
function ButtonToolButtonView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ButtonToolButtonView.prototype.initialize = function () {
|
|
var _this = this;
|
|
_super.prototype.initialize.call(this);
|
|
this.connect(this.model.change, function () { return _this.render(); });
|
|
this.el.addEventListener("click", function () { return _this._clicked(); });
|
|
this.render(); // XXX: this isn't governed by layout, for now
|
|
};
|
|
ButtonToolButtonView.prototype.css_classes = function () {
|
|
return _super.prototype.css_classes.call(this).concat("bk-toolbar-button");
|
|
};
|
|
ButtonToolButtonView.prototype.render = function () {
|
|
dom_1.empty(this.el);
|
|
var icon = this.model.computed_icon;
|
|
if (types_1.isString(icon)) {
|
|
if (string_1.startsWith(icon, "data:image"))
|
|
this.el.style.backgroundImage = "url('" + icon + "')";
|
|
else
|
|
this.el.classList.add(icon);
|
|
}
|
|
this.el.title = this.model.tooltip;
|
|
};
|
|
return ButtonToolButtonView;
|
|
}(dom_view_1.DOMView));
|
|
exports.ButtonToolButtonView = ButtonToolButtonView;
|
|
var ButtonToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ButtonToolView, _super);
|
|
function ButtonToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return ButtonToolView;
|
|
}(tool_1.ToolView));
|
|
exports.ButtonToolView = ButtonToolView;
|
|
var ButtonTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ButtonTool, _super);
|
|
function ButtonTool(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ButtonTool.initClass = function () {
|
|
this.prototype.type = "ButtonTool";
|
|
this.internal({
|
|
disabled: [p.Boolean, false],
|
|
});
|
|
};
|
|
Object.defineProperty(ButtonTool.prototype, "tooltip", {
|
|
get: function () {
|
|
return this.tool_name;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(ButtonTool.prototype, "computed_icon", {
|
|
get: function () {
|
|
return this.icon;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return ButtonTool;
|
|
}(tool_1.Tool));
|
|
exports.ButtonTool = ButtonTool;
|
|
ButtonTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/edit/box_edit_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var dom_1 = require(5) /* ../../../core/dom */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var edit_tool_1 = require(253) /* ./edit_tool */;
|
|
var BoxEditToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BoxEditToolView, _super);
|
|
function BoxEditToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
BoxEditToolView.prototype._tap = function (ev) {
|
|
if ((this._draw_basepoint != null) || (this._basepoint != null))
|
|
return;
|
|
var append = ev.shiftKey;
|
|
this._select_event(ev, append, this.model.renderers);
|
|
};
|
|
BoxEditToolView.prototype._keyup = function (ev) {
|
|
if (!this.model.active || !this._mouse_in_frame)
|
|
return;
|
|
for (var _i = 0, _a = this.model.renderers; _i < _a.length; _i++) {
|
|
var renderer = _a[_i];
|
|
if (ev.keyCode === dom_1.Keys.Backspace) {
|
|
this._delete_selected(renderer);
|
|
}
|
|
else if (ev.keyCode == dom_1.Keys.Esc) {
|
|
// Type properly once selection_manager is typed
|
|
var cds = renderer.data_source;
|
|
cds.selection_manager.clear();
|
|
}
|
|
}
|
|
};
|
|
BoxEditToolView.prototype._set_extent = function (_a, _b, append, emit) {
|
|
var sx0 = _a[0], sx1 = _a[1];
|
|
var sy0 = _b[0], sy1 = _b[1];
|
|
if (emit === void 0) {
|
|
emit = false;
|
|
}
|
|
var renderer = this.model.renderers[0];
|
|
var frame = this.plot_view.frame;
|
|
// Type once dataspecs are typed
|
|
var glyph = renderer.glyph;
|
|
var cds = renderer.data_source;
|
|
var xscale = frame.xscales[renderer.x_range_name];
|
|
var yscale = frame.yscales[renderer.y_range_name];
|
|
var _c = xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];
|
|
var _d = yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];
|
|
var _e = [(x0 + x1) / 2., (y0 + y1) / 2.], x = _e[0], y = _e[1];
|
|
var _f = [x1 - x0, y1 - y0], w = _f[0], h = _f[1];
|
|
var _g = [glyph.x.field, glyph.y.field], xkey = _g[0], ykey = _g[1];
|
|
var _h = [glyph.width.field, glyph.height.field], wkey = _h[0], hkey = _h[1];
|
|
if (append) {
|
|
this._pop_glyphs(cds, this.model.num_objects);
|
|
if (xkey)
|
|
cds.get_array(xkey).push(x);
|
|
if (ykey)
|
|
cds.get_array(ykey).push(y);
|
|
if (wkey)
|
|
cds.get_array(wkey).push(w);
|
|
if (hkey)
|
|
cds.get_array(hkey).push(h);
|
|
this._pad_empty_columns(cds, [xkey, ykey, wkey, hkey]);
|
|
}
|
|
else {
|
|
var index = cds.data[xkey].length - 1;
|
|
if (xkey)
|
|
cds.data[xkey][index] = x;
|
|
if (ykey)
|
|
cds.data[ykey][index] = y;
|
|
if (wkey)
|
|
cds.data[wkey][index] = w;
|
|
if (hkey)
|
|
cds.data[hkey][index] = h;
|
|
}
|
|
this._emit_cds_changes(cds, true, false, emit);
|
|
};
|
|
BoxEditToolView.prototype._update_box = function (ev, append, emit) {
|
|
if (append === void 0) {
|
|
append = false;
|
|
}
|
|
if (emit === void 0) {
|
|
emit = false;
|
|
}
|
|
if (this._draw_basepoint == null)
|
|
return;
|
|
var curpoint = [ev.sx, ev.sy];
|
|
var frame = this.plot_view.frame;
|
|
var dims = this.model.dimensions;
|
|
var limits = this.model._get_dim_limits(this._draw_basepoint, curpoint, frame, dims);
|
|
if (limits != null) {
|
|
var sxlim = limits[0], sylim = limits[1];
|
|
this._set_extent(sxlim, sylim, append, emit);
|
|
}
|
|
};
|
|
BoxEditToolView.prototype._doubletap = function (ev) {
|
|
if (!this.model.active)
|
|
return;
|
|
if (this._draw_basepoint != null) {
|
|
this._update_box(ev, false, true);
|
|
this._draw_basepoint = null;
|
|
}
|
|
else {
|
|
this._draw_basepoint = [ev.sx, ev.sy];
|
|
this._select_event(ev, true, this.model.renderers);
|
|
this._update_box(ev, true, false);
|
|
}
|
|
};
|
|
BoxEditToolView.prototype._move = function (ev) {
|
|
this._update_box(ev, false, false);
|
|
};
|
|
BoxEditToolView.prototype._pan_start = function (ev) {
|
|
if (ev.shiftKey) {
|
|
if (this._draw_basepoint != null)
|
|
return;
|
|
this._draw_basepoint = [ev.sx, ev.sy];
|
|
this._update_box(ev, true, false);
|
|
}
|
|
else {
|
|
if (this._basepoint != null)
|
|
return;
|
|
this._select_event(ev, true, this.model.renderers);
|
|
this._basepoint = [ev.sx, ev.sy];
|
|
}
|
|
};
|
|
BoxEditToolView.prototype._pan = function (ev, append, emit) {
|
|
if (append === void 0) {
|
|
append = false;
|
|
}
|
|
if (emit === void 0) {
|
|
emit = false;
|
|
}
|
|
if (ev.shiftKey) {
|
|
if (this._draw_basepoint == null)
|
|
return;
|
|
this._update_box(ev, append, emit);
|
|
}
|
|
else {
|
|
if (this._basepoint == null)
|
|
return;
|
|
this._drag_points(ev, this.model.renderers);
|
|
}
|
|
};
|
|
BoxEditToolView.prototype._pan_end = function (ev) {
|
|
this._pan(ev, false, true);
|
|
if (ev.shiftKey) {
|
|
this._draw_basepoint = null;
|
|
}
|
|
else {
|
|
this._basepoint = null;
|
|
for (var _i = 0, _a = this.model.renderers; _i < _a.length; _i++) {
|
|
var renderer = _a[_i];
|
|
this._emit_cds_changes(renderer.data_source, false, true, true);
|
|
}
|
|
}
|
|
};
|
|
return BoxEditToolView;
|
|
}(edit_tool_1.EditToolView));
|
|
exports.BoxEditToolView = BoxEditToolView;
|
|
var BoxEditTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BoxEditTool, _super);
|
|
function BoxEditTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Box Edit Tool";
|
|
_this.icon = "bk-tool-icon-box-edit";
|
|
_this.event_type = ["tap", "pan", "move"];
|
|
_this.default_order = 1;
|
|
return _this;
|
|
}
|
|
BoxEditTool.initClass = function () {
|
|
this.prototype.type = "BoxEditTool";
|
|
this.prototype.default_view = BoxEditToolView;
|
|
this.define({
|
|
dimensions: [p.Dimensions, "both"],
|
|
num_objects: [p.Int, 0],
|
|
});
|
|
};
|
|
return BoxEditTool;
|
|
}(edit_tool_1.EditTool));
|
|
exports.BoxEditTool = BoxEditTool;
|
|
BoxEditTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/edit/edit_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var array_1 = require(24) /* ../../../core/util/array */;
|
|
var types_1 = require(46) /* ../../../core/util/types */;
|
|
var gesture_tool_1 = require(261) /* ../gestures/gesture_tool */;
|
|
var EditToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(EditToolView, _super);
|
|
function EditToolView() {
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
_this._mouse_in_frame = true;
|
|
return _this;
|
|
}
|
|
EditToolView.prototype._move_enter = function (_e) {
|
|
this._mouse_in_frame = true;
|
|
};
|
|
EditToolView.prototype._move_exit = function (_e) {
|
|
this._mouse_in_frame = false;
|
|
};
|
|
EditToolView.prototype._map_drag = function (sx, sy, renderer) {
|
|
// Maps screen to data coordinates
|
|
var frame = this.plot_view.frame;
|
|
if (!frame.bbox.contains(sx, sy)) {
|
|
return null;
|
|
}
|
|
var x = frame.xscales[renderer.x_range_name].invert(sx);
|
|
var y = frame.yscales[renderer.y_range_name].invert(sy);
|
|
return [x, y];
|
|
};
|
|
EditToolView.prototype._delete_selected = function (renderer) {
|
|
// Deletes all selected rows in the ColumnDataSource
|
|
var cds = renderer.data_source;
|
|
var indices = cds.selected.indices;
|
|
indices.sort();
|
|
for (var _i = 0, _a = cds.columns(); _i < _a.length; _i++) {
|
|
var column = _a[_i];
|
|
var values = cds.get_array(column);
|
|
for (var index = 0; index < indices.length; index++) {
|
|
var ind = indices[index];
|
|
values.splice(ind - index, 1);
|
|
}
|
|
}
|
|
this._emit_cds_changes(cds);
|
|
};
|
|
EditToolView.prototype._pop_glyphs = function (cds, num_objects) {
|
|
// Pops rows in the CDS until only num_objects are left
|
|
var columns = cds.columns();
|
|
if (!num_objects || !columns.length)
|
|
return;
|
|
for (var _i = 0, columns_1 = columns; _i < columns_1.length; _i++) {
|
|
var column = columns_1[_i];
|
|
var array = cds.get_array(column);
|
|
var drop = array.length - num_objects + 1;
|
|
if (drop < 1)
|
|
continue;
|
|
if (!types_1.isArray(array)) {
|
|
array = Array.from(array);
|
|
cds.data[column] = array;
|
|
}
|
|
array.splice(0, drop);
|
|
}
|
|
};
|
|
EditToolView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {
|
|
if (redraw === void 0) {
|
|
redraw = true;
|
|
}
|
|
if (clear === void 0) {
|
|
clear = true;
|
|
}
|
|
if (emit === void 0) {
|
|
emit = true;
|
|
}
|
|
if (clear)
|
|
cds.selection_manager.clear();
|
|
if (redraw)
|
|
cds.change.emit();
|
|
if (emit) {
|
|
cds.data = cds.data;
|
|
cds.properties.data.change.emit();
|
|
}
|
|
};
|
|
EditToolView.prototype._drag_points = function (ev, renderers) {
|
|
if (this._basepoint == null)
|
|
return;
|
|
var _a = this._basepoint, bx = _a[0], by = _a[1];
|
|
for (var _i = 0, renderers_1 = renderers; _i < renderers_1.length; _i++) {
|
|
var renderer = renderers_1[_i];
|
|
var basepoint = this._map_drag(bx, by, renderer);
|
|
var point = this._map_drag(ev.sx, ev.sy, renderer);
|
|
if (point == null || basepoint == null) {
|
|
continue;
|
|
}
|
|
var x = point[0], y = point[1];
|
|
var px = basepoint[0], py = basepoint[1];
|
|
var _b = [x - px, y - py], dx = _b[0], dy = _b[1];
|
|
// Type once dataspecs are typed
|
|
var glyph = renderer.glyph;
|
|
var cds = renderer.data_source;
|
|
var _c = [glyph.x.field, glyph.y.field], xkey = _c[0], ykey = _c[1];
|
|
for (var _d = 0, _f = cds.selected.indices; _d < _f.length; _d++) {
|
|
var index = _f[_d];
|
|
if (xkey)
|
|
cds.data[xkey][index] += dx;
|
|
if (ykey)
|
|
cds.data[ykey][index] += dy;
|
|
}
|
|
cds.change.emit();
|
|
}
|
|
this._basepoint = [ev.sx, ev.sy];
|
|
};
|
|
EditToolView.prototype._pad_empty_columns = function (cds, coord_columns) {
|
|
// Pad ColumnDataSource non-coordinate columns with empty_value
|
|
for (var _i = 0, _a = cds.columns(); _i < _a.length; _i++) {
|
|
var column = _a[_i];
|
|
if (!array_1.includes(coord_columns, column))
|
|
cds.get_array(column).push(this.model.empty_value);
|
|
}
|
|
};
|
|
EditToolView.prototype._select_event = function (ev, append, renderers) {
|
|
// Process selection event on the supplied renderers and return selected renderers
|
|
var frame = this.plot_view.frame;
|
|
var sx = ev.sx, sy = ev.sy;
|
|
if (!frame.bbox.contains(sx, sy)) {
|
|
return [];
|
|
}
|
|
var geometry = { type: 'point', sx: sx, sy: sy };
|
|
var selected = [];
|
|
for (var _i = 0, renderers_2 = renderers; _i < renderers_2.length; _i++) {
|
|
var renderer = renderers_2[_i];
|
|
var sm = renderer.get_selection_manager();
|
|
var cds = renderer.data_source;
|
|
var views = [this.plot_view.renderer_views[renderer.id]];
|
|
var did_hit = sm.select(views, geometry, true, append);
|
|
if (did_hit) {
|
|
selected.push(renderer);
|
|
}
|
|
cds.properties.selected.change.emit();
|
|
}
|
|
return selected;
|
|
};
|
|
return EditToolView;
|
|
}(gesture_tool_1.GestureToolView));
|
|
exports.EditToolView = EditToolView;
|
|
var EditTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(EditTool, _super);
|
|
function EditTool(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
EditTool.initClass = function () {
|
|
this.prototype.type = "EditTool";
|
|
this.define({
|
|
custom_icon: [p.String,],
|
|
custom_tooltip: [p.String,],
|
|
empty_value: [p.Any,],
|
|
renderers: [p.Array, []],
|
|
});
|
|
};
|
|
Object.defineProperty(EditTool.prototype, "tooltip", {
|
|
get: function () {
|
|
return this.custom_tooltip || this.tool_name;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(EditTool.prototype, "computed_icon", {
|
|
get: function () {
|
|
return this.custom_icon || this.icon;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return EditTool;
|
|
}(gesture_tool_1.GestureTool));
|
|
exports.EditTool = EditTool;
|
|
EditTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/edit/freehand_draw_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var dom_1 = require(5) /* ../../../core/dom */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var types_1 = require(46) /* ../../../core/util/types */;
|
|
var edit_tool_1 = require(253) /* ./edit_tool */;
|
|
var FreehandDrawToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(FreehandDrawToolView, _super);
|
|
function FreehandDrawToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
FreehandDrawToolView.prototype._draw = function (ev, mode, emit) {
|
|
if (emit === void 0) {
|
|
emit = false;
|
|
}
|
|
if (!this.model.active)
|
|
return;
|
|
var renderer = this.model.renderers[0];
|
|
var point = this._map_drag(ev.sx, ev.sy, renderer);
|
|
if (point == null)
|
|
return;
|
|
var x = point[0], y = point[1];
|
|
var cds = renderer.data_source;
|
|
var glyph = renderer.glyph;
|
|
var _a = [glyph.xs.field, glyph.ys.field], xkey = _a[0], ykey = _a[1];
|
|
if (mode == 'new') {
|
|
this._pop_glyphs(cds, this.model.num_objects);
|
|
if (xkey)
|
|
cds.get_array(xkey).push([x]);
|
|
if (ykey)
|
|
cds.get_array(ykey).push([y]);
|
|
this._pad_empty_columns(cds, [xkey, ykey]);
|
|
}
|
|
else if (mode == 'add') {
|
|
if (xkey) {
|
|
var xidx = cds.data[xkey].length - 1;
|
|
var xs = cds.get_array(xkey)[xidx];
|
|
if (!types_1.isArray(xs)) {
|
|
xs = Array.from(xs);
|
|
cds.data[xkey][xidx] = xs;
|
|
}
|
|
xs.push(x);
|
|
}
|
|
if (ykey) {
|
|
var yidx = cds.data[ykey].length - 1;
|
|
var ys = cds.get_array(ykey)[yidx];
|
|
if (!types_1.isArray(ys)) {
|
|
ys = Array.from(ys);
|
|
cds.data[ykey][yidx] = ys;
|
|
}
|
|
ys.push(y);
|
|
}
|
|
}
|
|
this._emit_cds_changes(cds, true, true, emit);
|
|
};
|
|
FreehandDrawToolView.prototype._pan_start = function (ev) {
|
|
this._draw(ev, 'new');
|
|
};
|
|
FreehandDrawToolView.prototype._pan = function (ev) {
|
|
this._draw(ev, 'add');
|
|
};
|
|
FreehandDrawToolView.prototype._pan_end = function (ev) {
|
|
this._draw(ev, 'add', true);
|
|
};
|
|
FreehandDrawToolView.prototype._tap = function (ev) {
|
|
this._select_event(ev, ev.shiftKey, this.model.renderers);
|
|
};
|
|
FreehandDrawToolView.prototype._keyup = function (ev) {
|
|
if (!this.model.active || !this._mouse_in_frame)
|
|
return;
|
|
for (var _i = 0, _a = this.model.renderers; _i < _a.length; _i++) {
|
|
var renderer = _a[_i];
|
|
if (ev.keyCode === dom_1.Keys.Esc) {
|
|
renderer.data_source.selection_manager.clear();
|
|
}
|
|
else if (ev.keyCode === dom_1.Keys.Backspace) {
|
|
this._delete_selected(renderer);
|
|
}
|
|
}
|
|
};
|
|
return FreehandDrawToolView;
|
|
}(edit_tool_1.EditToolView));
|
|
exports.FreehandDrawToolView = FreehandDrawToolView;
|
|
var FreehandDrawTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(FreehandDrawTool, _super);
|
|
function FreehandDrawTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Freehand Draw Tool";
|
|
_this.icon = "bk-tool-icon-freehand-draw";
|
|
_this.event_type = ["pan", "tap"];
|
|
_this.default_order = 3;
|
|
return _this;
|
|
}
|
|
FreehandDrawTool.initClass = function () {
|
|
this.prototype.type = "FreehandDrawTool";
|
|
this.prototype.default_view = FreehandDrawToolView;
|
|
this.define({
|
|
num_objects: [p.Int, 0],
|
|
});
|
|
};
|
|
return FreehandDrawTool;
|
|
}(edit_tool_1.EditTool));
|
|
exports.FreehandDrawTool = FreehandDrawTool;
|
|
FreehandDrawTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/edit/point_draw_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var dom_1 = require(5) /* ../../../core/dom */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var edit_tool_1 = require(253) /* ./edit_tool */;
|
|
var PointDrawToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PointDrawToolView, _super);
|
|
function PointDrawToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
PointDrawToolView.prototype._tap = function (ev) {
|
|
var append = ev.shiftKey;
|
|
var renderers = this._select_event(ev, append, this.model.renderers);
|
|
if (renderers.length || !this.model.add) {
|
|
return;
|
|
}
|
|
var renderer = this.model.renderers[0];
|
|
var point = this._map_drag(ev.sx, ev.sy, renderer);
|
|
if (point == null)
|
|
return;
|
|
// Type once dataspecs are typed
|
|
var glyph = renderer.glyph;
|
|
var cds = renderer.data_source;
|
|
var _a = [glyph.x.field, glyph.y.field], xkey = _a[0], ykey = _a[1];
|
|
var x = point[0], y = point[1];
|
|
this._pop_glyphs(cds, this.model.num_objects);
|
|
if (xkey)
|
|
cds.get_array(xkey).push(x);
|
|
if (ykey)
|
|
cds.get_array(ykey).push(y);
|
|
this._pad_empty_columns(cds, [xkey, ykey]);
|
|
cds.change.emit();
|
|
cds.data = cds.data;
|
|
cds.properties.data.change.emit();
|
|
};
|
|
PointDrawToolView.prototype._keyup = function (ev) {
|
|
if (!this.model.active || !this._mouse_in_frame)
|
|
return;
|
|
for (var _i = 0, _a = this.model.renderers; _i < _a.length; _i++) {
|
|
var renderer = _a[_i];
|
|
if (ev.keyCode === dom_1.Keys.Backspace) {
|
|
this._delete_selected(renderer);
|
|
}
|
|
else if (ev.keyCode == dom_1.Keys.Esc) {
|
|
renderer.data_source.selection_manager.clear();
|
|
}
|
|
}
|
|
};
|
|
PointDrawToolView.prototype._pan_start = function (ev) {
|
|
if (!this.model.drag)
|
|
return;
|
|
this._select_event(ev, true, this.model.renderers);
|
|
this._basepoint = [ev.sx, ev.sy];
|
|
};
|
|
PointDrawToolView.prototype._pan = function (ev) {
|
|
if (!this.model.drag || this._basepoint == null)
|
|
return;
|
|
this._drag_points(ev, this.model.renderers);
|
|
};
|
|
PointDrawToolView.prototype._pan_end = function (ev) {
|
|
if (!this.model.drag)
|
|
return;
|
|
this._pan(ev);
|
|
for (var _i = 0, _a = this.model.renderers; _i < _a.length; _i++) {
|
|
var renderer = _a[_i];
|
|
this._emit_cds_changes(renderer.data_source, false, true, true);
|
|
}
|
|
this._basepoint = null;
|
|
};
|
|
return PointDrawToolView;
|
|
}(edit_tool_1.EditToolView));
|
|
exports.PointDrawToolView = PointDrawToolView;
|
|
var PointDrawTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PointDrawTool, _super);
|
|
function PointDrawTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Point Draw Tool";
|
|
_this.icon = "bk-tool-icon-point-draw";
|
|
_this.event_type = ["tap", "pan", "move"];
|
|
_this.default_order = 2;
|
|
return _this;
|
|
}
|
|
PointDrawTool.initClass = function () {
|
|
this.prototype.type = "PointDrawTool";
|
|
this.prototype.default_view = PointDrawToolView;
|
|
this.define({
|
|
add: [p.Boolean, true],
|
|
drag: [p.Boolean, true],
|
|
num_objects: [p.Int, 0],
|
|
});
|
|
};
|
|
return PointDrawTool;
|
|
}(edit_tool_1.EditTool));
|
|
exports.PointDrawTool = PointDrawTool;
|
|
PointDrawTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/edit/poly_draw_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var dom_1 = require(5) /* ../../../core/dom */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var types_1 = require(46) /* ../../../core/util/types */;
|
|
var poly_tool_1 = require(258) /* ./poly_tool */;
|
|
var PolyDrawToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PolyDrawToolView, _super);
|
|
function PolyDrawToolView() {
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
_this._drawing = false;
|
|
_this._initialized = false;
|
|
return _this;
|
|
}
|
|
PolyDrawToolView.prototype._tap = function (ev) {
|
|
if (this._drawing)
|
|
this._draw(ev, 'add', true);
|
|
else
|
|
this._select_event(ev, ev.shiftKey, this.model.renderers);
|
|
};
|
|
PolyDrawToolView.prototype._draw = function (ev, mode, emit) {
|
|
if (emit === void 0) {
|
|
emit = false;
|
|
}
|
|
var renderer = this.model.renderers[0];
|
|
var point = this._map_drag(ev.sx, ev.sy, renderer);
|
|
if (!this._initialized)
|
|
this.activate(); // Ensure that activate has been called
|
|
if (point == null)
|
|
return;
|
|
var _a = this._snap_to_vertex.apply(this, [ev].concat(point)), x = _a[0], y = _a[1];
|
|
var cds = renderer.data_source;
|
|
var glyph = renderer.glyph;
|
|
var _b = [glyph.xs.field, glyph.ys.field], xkey = _b[0], ykey = _b[1];
|
|
if (mode == 'new') {
|
|
this._pop_glyphs(cds, this.model.num_objects);
|
|
if (xkey)
|
|
cds.get_array(xkey).push([x, x]);
|
|
if (ykey)
|
|
cds.get_array(ykey).push([y, y]);
|
|
this._pad_empty_columns(cds, [xkey, ykey]);
|
|
}
|
|
else if (mode == 'edit') {
|
|
if (xkey) {
|
|
var xs = cds.data[xkey][cds.data[xkey].length - 1];
|
|
xs[xs.length - 1] = x;
|
|
}
|
|
if (ykey) {
|
|
var ys = cds.data[ykey][cds.data[ykey].length - 1];
|
|
ys[ys.length - 1] = y;
|
|
}
|
|
}
|
|
else if (mode == 'add') {
|
|
if (xkey) {
|
|
var xidx = cds.data[xkey].length - 1;
|
|
var xs = cds.get_array(xkey)[xidx];
|
|
var nx = xs[xs.length - 1];
|
|
xs[xs.length - 1] = x;
|
|
if (!types_1.isArray(xs)) {
|
|
xs = Array.from(xs);
|
|
cds.data[xkey][xidx] = xs;
|
|
}
|
|
xs.push(nx);
|
|
}
|
|
if (ykey) {
|
|
var yidx = cds.data[ykey].length - 1;
|
|
var ys = cds.get_array(ykey)[yidx];
|
|
var ny = ys[ys.length - 1];
|
|
ys[ys.length - 1] = y;
|
|
if (!types_1.isArray(ys)) {
|
|
ys = Array.from(ys);
|
|
cds.data[ykey][yidx] = ys;
|
|
}
|
|
ys.push(ny);
|
|
}
|
|
}
|
|
this._emit_cds_changes(cds, true, false, emit);
|
|
};
|
|
PolyDrawToolView.prototype._show_vertices = function () {
|
|
if (!this.model.active) {
|
|
return;
|
|
}
|
|
var xs = [];
|
|
var ys = [];
|
|
for (var i = 0; i < this.model.renderers.length; i++) {
|
|
var renderer = this.model.renderers[i];
|
|
var cds = renderer.data_source;
|
|
var glyph = renderer.glyph;
|
|
var _a = [glyph.xs.field, glyph.ys.field], xkey = _a[0], ykey = _a[1];
|
|
if (xkey) {
|
|
for (var _i = 0, _b = cds.get_array(xkey); _i < _b.length; _i++) {
|
|
var array = _b[_i];
|
|
Array.prototype.push.apply(xs, array);
|
|
}
|
|
}
|
|
if (ykey) {
|
|
for (var _c = 0, _d = cds.get_array(ykey); _c < _d.length; _c++) {
|
|
var array = _d[_c];
|
|
Array.prototype.push.apply(ys, array);
|
|
}
|
|
}
|
|
if (this._drawing && (i == (this.model.renderers.length - 1))) {
|
|
// Skip currently drawn vertex
|
|
xs.splice(xs.length - 1, 1);
|
|
ys.splice(ys.length - 1, 1);
|
|
}
|
|
}
|
|
this._set_vertices(xs, ys);
|
|
};
|
|
PolyDrawToolView.prototype._doubletap = function (ev) {
|
|
if (!this.model.active)
|
|
return;
|
|
if (this._drawing) {
|
|
this._drawing = false;
|
|
this._draw(ev, 'edit', true);
|
|
}
|
|
else {
|
|
this._drawing = true;
|
|
this._draw(ev, 'new', true);
|
|
}
|
|
};
|
|
PolyDrawToolView.prototype._move = function (ev) {
|
|
if (this._drawing) {
|
|
this._draw(ev, 'edit');
|
|
}
|
|
};
|
|
PolyDrawToolView.prototype._remove = function () {
|
|
var renderer = this.model.renderers[0];
|
|
var cds = renderer.data_source;
|
|
var glyph = renderer.glyph;
|
|
var _a = [glyph.xs.field, glyph.ys.field], xkey = _a[0], ykey = _a[1];
|
|
if (xkey) {
|
|
var xidx = cds.data[xkey].length - 1;
|
|
var xs = cds.get_array(xkey)[xidx];
|
|
xs.splice(xs.length - 1, 1);
|
|
}
|
|
if (ykey) {
|
|
var yidx = cds.data[ykey].length - 1;
|
|
var ys = cds.get_array(ykey)[yidx];
|
|
ys.splice(ys.length - 1, 1);
|
|
}
|
|
this._emit_cds_changes(cds);
|
|
};
|
|
PolyDrawToolView.prototype._keyup = function (ev) {
|
|
if (!this.model.active || !this._mouse_in_frame)
|
|
return;
|
|
for (var _i = 0, _a = this.model.renderers; _i < _a.length; _i++) {
|
|
var renderer = _a[_i];
|
|
if (ev.keyCode === dom_1.Keys.Backspace) {
|
|
this._delete_selected(renderer);
|
|
}
|
|
else if (ev.keyCode == dom_1.Keys.Esc) {
|
|
if (this._drawing) {
|
|
this._remove();
|
|
this._drawing = false;
|
|
}
|
|
renderer.data_source.selection_manager.clear();
|
|
}
|
|
}
|
|
};
|
|
PolyDrawToolView.prototype._pan_start = function (ev) {
|
|
if (!this.model.drag)
|
|
return;
|
|
this._select_event(ev, true, this.model.renderers);
|
|
this._basepoint = [ev.sx, ev.sy];
|
|
};
|
|
PolyDrawToolView.prototype._pan = function (ev) {
|
|
if (this._basepoint == null || !this.model.drag)
|
|
return;
|
|
var _a = this._basepoint, bx = _a[0], by = _a[1];
|
|
// Process polygon/line dragging
|
|
for (var _i = 0, _b = this.model.renderers; _i < _b.length; _i++) {
|
|
var renderer = _b[_i];
|
|
var basepoint = this._map_drag(bx, by, renderer);
|
|
var point = this._map_drag(ev.sx, ev.sy, renderer);
|
|
if (point == null || basepoint == null)
|
|
continue;
|
|
var cds = renderer.data_source;
|
|
// Type once dataspecs are typed
|
|
var glyph = renderer.glyph;
|
|
var _c = [glyph.xs.field, glyph.ys.field], xkey = _c[0], ykey = _c[1];
|
|
if (!xkey && !ykey)
|
|
continue;
|
|
var x = point[0], y = point[1];
|
|
var px = basepoint[0], py = basepoint[1];
|
|
var _d = [x - px, y - py], dx = _d[0], dy = _d[1];
|
|
for (var _e = 0, _f = cds.selected.indices; _e < _f.length; _e++) {
|
|
var index = _f[_e];
|
|
var length_1 = void 0, xs = void 0, ys = void 0;
|
|
if (xkey)
|
|
xs = cds.data[xkey][index];
|
|
if (ykey) {
|
|
ys = cds.data[ykey][index];
|
|
length_1 = ys.length;
|
|
}
|
|
else {
|
|
length_1 = xs.length;
|
|
}
|
|
for (var i = 0; i < length_1; i++) {
|
|
if (xs)
|
|
xs[i] += dx;
|
|
if (ys)
|
|
ys[i] += dy;
|
|
}
|
|
}
|
|
cds.change.emit();
|
|
}
|
|
this._basepoint = [ev.sx, ev.sy];
|
|
};
|
|
PolyDrawToolView.prototype._pan_end = function (ev) {
|
|
if (!this.model.drag)
|
|
return;
|
|
this._pan(ev);
|
|
for (var _i = 0, _a = this.model.renderers; _i < _a.length; _i++) {
|
|
var renderer = _a[_i];
|
|
this._emit_cds_changes(renderer.data_source);
|
|
}
|
|
this._basepoint = null;
|
|
};
|
|
PolyDrawToolView.prototype.activate = function () {
|
|
var _this = this;
|
|
if (!this.model.vertex_renderer || !this.model.active)
|
|
return;
|
|
this._show_vertices();
|
|
if (!this._initialized) {
|
|
for (var _i = 0, _a = this.model.renderers; _i < _a.length; _i++) {
|
|
var renderer = _a[_i];
|
|
var cds = renderer.data_source;
|
|
cds.connect(cds.properties.data.change, function () { return _this._show_vertices(); });
|
|
}
|
|
}
|
|
this._initialized = true;
|
|
};
|
|
PolyDrawToolView.prototype.deactivate = function () {
|
|
if (this._drawing) {
|
|
this._remove();
|
|
this._drawing = false;
|
|
}
|
|
if (this.model.vertex_renderer)
|
|
this._hide_vertices();
|
|
};
|
|
return PolyDrawToolView;
|
|
}(poly_tool_1.PolyToolView));
|
|
exports.PolyDrawToolView = PolyDrawToolView;
|
|
var PolyDrawTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PolyDrawTool, _super);
|
|
function PolyDrawTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Polygon Draw Tool";
|
|
_this.icon = "bk-tool-icon-poly-draw";
|
|
_this.event_type = ["pan", "tap", "move"];
|
|
_this.default_order = 3;
|
|
return _this;
|
|
}
|
|
PolyDrawTool.initClass = function () {
|
|
this.prototype.type = "PolyDrawTool";
|
|
this.prototype.default_view = PolyDrawToolView;
|
|
this.define({
|
|
drag: [p.Boolean, true],
|
|
num_objects: [p.Int, 0],
|
|
});
|
|
};
|
|
return PolyDrawTool;
|
|
}(poly_tool_1.PolyTool));
|
|
exports.PolyDrawTool = PolyDrawTool;
|
|
PolyDrawTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/edit/poly_edit_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var dom_1 = require(5) /* ../../../core/dom */;
|
|
var types_1 = require(46) /* ../../../core/util/types */;
|
|
var poly_tool_1 = require(258) /* ./poly_tool */;
|
|
var PolyEditToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PolyEditToolView, _super);
|
|
function PolyEditToolView() {
|
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
_this._drawing = false;
|
|
return _this;
|
|
}
|
|
PolyEditToolView.prototype._doubletap = function (ev) {
|
|
if (!this.model.active)
|
|
return;
|
|
var point = this._map_drag(ev.sx, ev.sy, this.model.vertex_renderer);
|
|
if (point == null)
|
|
return;
|
|
var x = point[0], y = point[1];
|
|
// Perform hit testing
|
|
var vertex_selected = this._select_event(ev, false, [this.model.vertex_renderer]);
|
|
var point_cds = this.model.vertex_renderer.data_source;
|
|
// Type once dataspecs are typed
|
|
var point_glyph = this.model.vertex_renderer.glyph;
|
|
var _a = [point_glyph.x.field, point_glyph.y.field], pxkey = _a[0], pykey = _a[1];
|
|
if (vertex_selected.length && this._selected_renderer != null) {
|
|
// Insert a new point after the selected vertex and enter draw mode
|
|
var index = point_cds.selected.indices[0];
|
|
if (this._drawing) {
|
|
this._drawing = false;
|
|
point_cds.selection_manager.clear();
|
|
}
|
|
else {
|
|
point_cds.selected.indices = [index + 1];
|
|
if (pxkey)
|
|
point_cds.get_array(pxkey).splice(index + 1, 0, x);
|
|
if (pykey)
|
|
point_cds.get_array(pykey).splice(index + 1, 0, y);
|
|
this._drawing = true;
|
|
}
|
|
point_cds.change.emit();
|
|
this._emit_cds_changes(this._selected_renderer.data_source);
|
|
}
|
|
else {
|
|
this._show_vertices(ev);
|
|
}
|
|
};
|
|
PolyEditToolView.prototype._show_vertices = function (ev) {
|
|
if (!this.model.active)
|
|
return;
|
|
var renderers = this._select_event(ev, false, this.model.renderers);
|
|
if (!renderers.length) {
|
|
this._set_vertices([], []);
|
|
this._selected_renderer = null;
|
|
this._drawing = false;
|
|
return;
|
|
}
|
|
var renderer = renderers[0];
|
|
var glyph = renderer.glyph;
|
|
var cds = renderer.data_source;
|
|
var index = cds.selected.indices[0];
|
|
var _a = [glyph.xs.field, glyph.ys.field], xkey = _a[0], ykey = _a[1];
|
|
var xs;
|
|
var ys;
|
|
if (xkey) {
|
|
xs = cds.data[xkey][index];
|
|
if (!types_1.isArray(xs))
|
|
cds.data[xkey][index] = xs = Array.from(xs);
|
|
}
|
|
else {
|
|
xs = glyph.xs.value;
|
|
}
|
|
if (ykey) {
|
|
ys = cds.data[ykey][index];
|
|
if (!types_1.isArray(ys))
|
|
cds.data[ykey][index] = ys = Array.from(ys);
|
|
}
|
|
else {
|
|
ys = glyph.ys.value;
|
|
}
|
|
this._selected_renderer = renderer;
|
|
this._set_vertices(xs, ys);
|
|
};
|
|
PolyEditToolView.prototype._move = function (ev) {
|
|
var _a;
|
|
if (this._drawing && this._selected_renderer != null) {
|
|
var renderer = this.model.vertex_renderer;
|
|
var cds = renderer.data_source;
|
|
var glyph = renderer.glyph;
|
|
var point = this._map_drag(ev.sx, ev.sy, renderer);
|
|
if (point == null)
|
|
return;
|
|
var x = point[0], y = point[1];
|
|
var indices = cds.selected.indices;
|
|
_a = this._snap_to_vertex(ev, x, y), x = _a[0], y = _a[1];
|
|
cds.selected.indices = indices;
|
|
var _b = [glyph.x.field, glyph.y.field], xkey = _b[0], ykey = _b[1];
|
|
var index = indices[0];
|
|
if (xkey)
|
|
cds.data[xkey][index] = x;
|
|
if (ykey)
|
|
cds.data[ykey][index] = y;
|
|
cds.change.emit();
|
|
this._selected_renderer.data_source.change.emit();
|
|
}
|
|
};
|
|
PolyEditToolView.prototype._tap = function (ev) {
|
|
var _a;
|
|
var renderer = this.model.vertex_renderer;
|
|
var point = this._map_drag(ev.sx, ev.sy, renderer);
|
|
if (point == null)
|
|
return;
|
|
else if (this._drawing && this._selected_renderer) {
|
|
var x = point[0], y = point[1];
|
|
var cds = renderer.data_source;
|
|
// Type once dataspecs are typed
|
|
var glyph = renderer.glyph;
|
|
var _b = [glyph.x.field, glyph.y.field], xkey = _b[0], ykey = _b[1];
|
|
var indices = cds.selected.indices;
|
|
_a = this._snap_to_vertex(ev, x, y), x = _a[0], y = _a[1];
|
|
var index = indices[0];
|
|
cds.selected.indices = [index + 1];
|
|
if (xkey) {
|
|
var xs = cds.get_array(xkey);
|
|
var nx = xs[index];
|
|
xs[index] = x;
|
|
xs.splice(index + 1, 0, nx);
|
|
}
|
|
if (ykey) {
|
|
var ys = cds.get_array(ykey);
|
|
var ny = ys[index];
|
|
ys[index] = y;
|
|
ys.splice(index + 1, 0, ny);
|
|
}
|
|
cds.change.emit();
|
|
this._emit_cds_changes(this._selected_renderer.data_source, true, false, true);
|
|
return;
|
|
}
|
|
var append = ev.shiftKey;
|
|
this._select_event(ev, append, [renderer]);
|
|
this._select_event(ev, append, this.model.renderers);
|
|
};
|
|
PolyEditToolView.prototype._remove_vertex = function () {
|
|
if (!this._drawing || !this._selected_renderer)
|
|
return;
|
|
var renderer = this.model.vertex_renderer;
|
|
var cds = renderer.data_source;
|
|
// Type once dataspecs are typed
|
|
var glyph = renderer.glyph;
|
|
var index = cds.selected.indices[0];
|
|
var _a = [glyph.x.field, glyph.y.field], xkey = _a[0], ykey = _a[1];
|
|
if (xkey)
|
|
cds.get_array(xkey).splice(index, 1);
|
|
if (ykey)
|
|
cds.get_array(ykey).splice(index, 1);
|
|
cds.change.emit();
|
|
this._emit_cds_changes(this._selected_renderer.data_source);
|
|
};
|
|
PolyEditToolView.prototype._pan_start = function (ev) {
|
|
this._select_event(ev, true, [this.model.vertex_renderer]);
|
|
this._basepoint = [ev.sx, ev.sy];
|
|
};
|
|
PolyEditToolView.prototype._pan = function (ev) {
|
|
if (this._basepoint == null)
|
|
return;
|
|
this._drag_points(ev, [this.model.vertex_renderer]);
|
|
if (this._selected_renderer)
|
|
this._selected_renderer.data_source.change.emit();
|
|
};
|
|
PolyEditToolView.prototype._pan_end = function (ev) {
|
|
if (this._basepoint == null)
|
|
return;
|
|
this._drag_points(ev, [this.model.vertex_renderer]);
|
|
this._emit_cds_changes(this.model.vertex_renderer.data_source, false, true, true);
|
|
if (this._selected_renderer) {
|
|
this._emit_cds_changes(this._selected_renderer.data_source);
|
|
}
|
|
this._basepoint = null;
|
|
};
|
|
PolyEditToolView.prototype._keyup = function (ev) {
|
|
if (!this.model.active || !this._mouse_in_frame)
|
|
return;
|
|
var renderers;
|
|
if (this._selected_renderer) {
|
|
renderers = [this.model.vertex_renderer];
|
|
}
|
|
else {
|
|
renderers = this.model.renderers;
|
|
}
|
|
for (var _i = 0, renderers_1 = renderers; _i < renderers_1.length; _i++) {
|
|
var renderer = renderers_1[_i];
|
|
if (ev.keyCode === dom_1.Keys.Backspace) {
|
|
this._delete_selected(renderer);
|
|
if (this._selected_renderer) {
|
|
this._emit_cds_changes(this._selected_renderer.data_source);
|
|
}
|
|
}
|
|
else if (ev.keyCode == dom_1.Keys.Esc) {
|
|
if (this._drawing) {
|
|
this._remove_vertex();
|
|
this._drawing = false;
|
|
}
|
|
else if (this._selected_renderer) {
|
|
this._hide_vertices();
|
|
}
|
|
renderer.data_source.selection_manager.clear();
|
|
}
|
|
}
|
|
};
|
|
PolyEditToolView.prototype.deactivate = function () {
|
|
if (!this._selected_renderer) {
|
|
return;
|
|
}
|
|
else if (this._drawing) {
|
|
this._remove_vertex();
|
|
this._drawing = false;
|
|
}
|
|
this._hide_vertices();
|
|
};
|
|
return PolyEditToolView;
|
|
}(poly_tool_1.PolyToolView));
|
|
exports.PolyEditToolView = PolyEditToolView;
|
|
var PolyEditTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PolyEditTool, _super);
|
|
function PolyEditTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Poly Edit Tool";
|
|
_this.icon = "bk-tool-icon-poly-edit";
|
|
_this.event_type = ["tap", "pan", "move"];
|
|
_this.default_order = 4;
|
|
return _this;
|
|
}
|
|
PolyEditTool.initClass = function () {
|
|
this.prototype.type = "PolyEditTool";
|
|
this.prototype.default_view = PolyEditToolView;
|
|
};
|
|
return PolyEditTool;
|
|
}(poly_tool_1.PolyTool));
|
|
exports.PolyEditTool = PolyEditTool;
|
|
PolyEditTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/edit/poly_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var types_1 = require(46) /* ../../../core/util/types */;
|
|
var edit_tool_1 = require(253) /* ./edit_tool */;
|
|
var PolyToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PolyToolView, _super);
|
|
function PolyToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
PolyToolView.prototype._set_vertices = function (xs, ys) {
|
|
var point_glyph = this.model.vertex_renderer.glyph;
|
|
var point_cds = this.model.vertex_renderer.data_source;
|
|
var _a = [point_glyph.x.field, point_glyph.y.field], pxkey = _a[0], pykey = _a[1];
|
|
if (pxkey) {
|
|
if (types_1.isArray(xs))
|
|
point_cds.data[pxkey] = xs;
|
|
else
|
|
point_glyph.x = { value: xs };
|
|
}
|
|
if (pykey) {
|
|
if (types_1.isArray(ys))
|
|
point_cds.data[pykey] = ys;
|
|
else
|
|
point_glyph.y = { value: ys };
|
|
}
|
|
this._emit_cds_changes(point_cds, true, true, false);
|
|
};
|
|
PolyToolView.prototype._hide_vertices = function () {
|
|
this._set_vertices([], []);
|
|
};
|
|
PolyToolView.prototype._snap_to_vertex = function (ev, x, y) {
|
|
if (this.model.vertex_renderer) {
|
|
// If an existing vertex is hit snap to it
|
|
var vertex_selected = this._select_event(ev, false, [this.model.vertex_renderer]);
|
|
var point_ds = this.model.vertex_renderer.data_source;
|
|
// Type once dataspecs are typed
|
|
var point_glyph = this.model.vertex_renderer.glyph;
|
|
var _a = [point_glyph.x.field, point_glyph.y.field], pxkey = _a[0], pykey = _a[1];
|
|
if (vertex_selected.length) {
|
|
var index = point_ds.selected.indices[0];
|
|
if (pxkey)
|
|
x = point_ds.data[pxkey][index];
|
|
if (pykey)
|
|
y = point_ds.data[pykey][index];
|
|
point_ds.selection_manager.clear();
|
|
}
|
|
}
|
|
return [x, y];
|
|
};
|
|
return PolyToolView;
|
|
}(edit_tool_1.EditToolView));
|
|
exports.PolyToolView = PolyToolView;
|
|
var PolyTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PolyTool, _super);
|
|
function PolyTool(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
PolyTool.initClass = function () {
|
|
this.prototype.type = "PolyTool";
|
|
this.prototype.default_view = PolyToolView;
|
|
this.define({
|
|
vertex_renderer: [p.Instance],
|
|
});
|
|
};
|
|
return PolyTool;
|
|
}(edit_tool_1.EditTool));
|
|
exports.PolyTool = PolyTool;
|
|
PolyTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/gestures/box_select_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var select_tool_1 = require(266) /* ./select_tool */;
|
|
var box_annotation_1 = require(67) /* ../../annotations/box_annotation */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var BoxSelectToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BoxSelectToolView, _super);
|
|
function BoxSelectToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
BoxSelectToolView.prototype._compute_limits = function (curpoint) {
|
|
var frame = this.plot_view.frame;
|
|
var dims = this.model.dimensions;
|
|
var base_point = this._base_point;
|
|
if (this.model.origin == "center") {
|
|
var cx = base_point[0], cy = base_point[1];
|
|
var dx = curpoint[0], dy = curpoint[1];
|
|
base_point = [cx - (dx - cx), cy - (dy - cy)];
|
|
}
|
|
return this.model._get_dim_limits(base_point, curpoint, frame, dims);
|
|
};
|
|
BoxSelectToolView.prototype._pan_start = function (ev) {
|
|
var sx = ev.sx, sy = ev.sy;
|
|
this._base_point = [sx, sy];
|
|
};
|
|
BoxSelectToolView.prototype._pan = function (ev) {
|
|
var sx = ev.sx, sy = ev.sy;
|
|
var curpoint = [sx, sy];
|
|
var _a = this._compute_limits(curpoint), sxlim = _a[0], sylim = _a[1];
|
|
this.model.overlay.update({ left: sxlim[0], right: sxlim[1], top: sylim[0], bottom: sylim[1] });
|
|
if (this.model.select_every_mousemove) {
|
|
var append = ev.shiftKey;
|
|
this._do_select(sxlim, sylim, false, append);
|
|
}
|
|
};
|
|
BoxSelectToolView.prototype._pan_end = function (ev) {
|
|
var sx = ev.sx, sy = ev.sy;
|
|
var curpoint = [sx, sy];
|
|
var _a = this._compute_limits(curpoint), sxlim = _a[0], sylim = _a[1];
|
|
var append = ev.shiftKey;
|
|
this._do_select(sxlim, sylim, true, append);
|
|
this.model.overlay.update({ left: null, right: null, top: null, bottom: null });
|
|
this._base_point = null;
|
|
this.plot_view.push_state('box_select', { selection: this.plot_view.get_selection() });
|
|
};
|
|
BoxSelectToolView.prototype._do_select = function (_a, _b, final, append) {
|
|
var sx0 = _a[0], sx1 = _a[1];
|
|
var sy0 = _b[0], sy1 = _b[1];
|
|
if (append === void 0) {
|
|
append = false;
|
|
}
|
|
var geometry = { type: 'rect', sx0: sx0, sx1: sx1, sy0: sy0, sy1: sy1 };
|
|
this._select(geometry, final, append);
|
|
};
|
|
BoxSelectToolView.prototype._emit_callback = function (geometry) {
|
|
var r = this.computed_renderers[0];
|
|
var frame = this.plot_view.frame;
|
|
var xscale = frame.xscales[r.x_range_name];
|
|
var yscale = frame.yscales[r.y_range_name];
|
|
var sx0 = geometry.sx0, sx1 = geometry.sx1, sy0 = geometry.sy0, sy1 = geometry.sy1;
|
|
var _a = xscale.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
var _b = yscale.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
var g = tslib_1.__assign({ x0: x0, y0: y0, x1: x1, y1: y1 }, geometry);
|
|
if (this.model.callback != null)
|
|
this.model.callback.execute(this.model, { geometry: g });
|
|
};
|
|
return BoxSelectToolView;
|
|
}(select_tool_1.SelectToolView));
|
|
exports.BoxSelectToolView = BoxSelectToolView;
|
|
var DEFAULT_BOX_OVERLAY = function () {
|
|
return new box_annotation_1.BoxAnnotation({
|
|
level: "overlay",
|
|
render_mode: "css",
|
|
top_units: "screen",
|
|
left_units: "screen",
|
|
bottom_units: "screen",
|
|
right_units: "screen",
|
|
fill_color: { value: "lightgrey" },
|
|
fill_alpha: { value: 0.5 },
|
|
line_color: { value: "black" },
|
|
line_alpha: { value: 1.0 },
|
|
line_width: { value: 2 },
|
|
line_dash: { value: [4, 4] },
|
|
});
|
|
};
|
|
var BoxSelectTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BoxSelectTool, _super);
|
|
function BoxSelectTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Box Select";
|
|
_this.icon = "bk-tool-icon-box-select";
|
|
_this.event_type = "pan";
|
|
_this.default_order = 30;
|
|
return _this;
|
|
}
|
|
BoxSelectTool.initClass = function () {
|
|
this.prototype.type = "BoxSelectTool";
|
|
this.prototype.default_view = BoxSelectToolView;
|
|
this.define({
|
|
dimensions: [p.Dimensions, "both"],
|
|
select_every_mousemove: [p.Boolean, false],
|
|
callback: [p.Any],
|
|
overlay: [p.Instance, DEFAULT_BOX_OVERLAY],
|
|
origin: [p.BoxOrigin, "corner"],
|
|
});
|
|
};
|
|
Object.defineProperty(BoxSelectTool.prototype, "tooltip", {
|
|
get: function () {
|
|
return this._get_dim_tooltip(this.tool_name, this.dimensions);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return BoxSelectTool;
|
|
}(select_tool_1.SelectTool));
|
|
exports.BoxSelectTool = BoxSelectTool;
|
|
BoxSelectTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/gestures/box_zoom_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var gesture_tool_1 = require(261) /* ./gesture_tool */;
|
|
var box_annotation_1 = require(67) /* ../../annotations/box_annotation */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var BoxZoomToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BoxZoomToolView, _super);
|
|
function BoxZoomToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
BoxZoomToolView.prototype._match_aspect = function (base_point, curpoint, frame) {
|
|
// aspect ratio of plot frame
|
|
var a = frame.bbox.aspect;
|
|
var hend = frame.bbox.h_range.end;
|
|
var hstart = frame.bbox.h_range.start;
|
|
var vend = frame.bbox.v_range.end;
|
|
var vstart = frame.bbox.v_range.start;
|
|
// current aspect of cursor-defined box
|
|
var vw = Math.abs(base_point[0] - curpoint[0]);
|
|
var vh = Math.abs(base_point[1] - curpoint[1]);
|
|
var va = vh == 0 ? 0 : vw / vh;
|
|
var xmod = (va >= a ? [1, va / a] : [a / va, 1])[0];
|
|
// OK the code blocks below merit some explanation. They do:
|
|
//
|
|
// compute left/right, pin to frame if necessary
|
|
// compute top/bottom (based on new left/right), pin to frame if necessary
|
|
// recompute left/right (based on top/bottom), in case top/bottom were pinned
|
|
// base_point[0] is left
|
|
var left;
|
|
var right;
|
|
if (base_point[0] <= curpoint[0]) {
|
|
left = base_point[0];
|
|
right = base_point[0] + vw * xmod;
|
|
if (right > hend)
|
|
right = hend;
|
|
// base_point[0] is right
|
|
}
|
|
else {
|
|
right = base_point[0];
|
|
left = base_point[0] - vw * xmod;
|
|
if (left < hstart)
|
|
left = hstart;
|
|
}
|
|
vw = Math.abs(right - left);
|
|
// base_point[1] is bottom
|
|
var top;
|
|
var bottom;
|
|
if (base_point[1] <= curpoint[1]) {
|
|
bottom = base_point[1];
|
|
top = base_point[1] + vw / a;
|
|
if (top > vend)
|
|
top = vend;
|
|
// base_point[1] is top
|
|
}
|
|
else {
|
|
top = base_point[1];
|
|
bottom = base_point[1] - vw / a;
|
|
if (bottom < vstart)
|
|
bottom = vstart;
|
|
}
|
|
vh = Math.abs(top - bottom);
|
|
// base_point[0] is left
|
|
if (base_point[0] <= curpoint[0])
|
|
right = base_point[0] + a * vh;
|
|
// base_point[0] is right
|
|
else
|
|
left = base_point[0] - a * vh;
|
|
return [[left, right], [bottom, top]];
|
|
};
|
|
BoxZoomToolView.prototype._compute_limits = function (curpoint) {
|
|
var _a, _b;
|
|
var frame = this.plot_view.frame;
|
|
var dims = this.model.dimensions;
|
|
var base_point = this._base_point;
|
|
if (this.model.origin == "center") {
|
|
var cx = base_point[0], cy = base_point[1];
|
|
var dx = curpoint[0], dy = curpoint[1];
|
|
base_point = [cx - (dx - cx), cy - (dy - cy)];
|
|
}
|
|
var sx;
|
|
var sy;
|
|
if (this.model.match_aspect && dims == 'both')
|
|
_a = this._match_aspect(base_point, curpoint, frame), sx = _a[0], sy = _a[1];
|
|
else
|
|
_b = this.model._get_dim_limits(base_point, curpoint, frame, dims), sx = _b[0], sy = _b[1];
|
|
return [sx, sy];
|
|
};
|
|
BoxZoomToolView.prototype._pan_start = function (ev) {
|
|
this._base_point = [ev.sx, ev.sy];
|
|
};
|
|
BoxZoomToolView.prototype._pan = function (ev) {
|
|
var curpoint = [ev.sx, ev.sy];
|
|
var _a = this._compute_limits(curpoint), sx = _a[0], sy = _a[1];
|
|
this.model.overlay.update({ left: sx[0], right: sx[1], top: sy[0], bottom: sy[1] });
|
|
};
|
|
BoxZoomToolView.prototype._pan_end = function (ev) {
|
|
var curpoint = [ev.sx, ev.sy];
|
|
var _a = this._compute_limits(curpoint), sx = _a[0], sy = _a[1];
|
|
this._update(sx, sy);
|
|
this.model.overlay.update({ left: null, right: null, top: null, bottom: null });
|
|
this._base_point = null;
|
|
};
|
|
BoxZoomToolView.prototype._update = function (_a, _b) {
|
|
var sx0 = _a[0], sx1 = _a[1];
|
|
var sy0 = _b[0], sy1 = _b[1];
|
|
// If the viewing window is too small, no-op: it is likely that the user did
|
|
// not intend to make this box zoom and instead was trying to cancel out of the
|
|
// zoom, a la matplotlib's ToolZoom. Like matplotlib, set the threshold at 5 pixels.
|
|
if (Math.abs(sx1 - sx0) <= 5 || Math.abs(sy1 - sy0) <= 5)
|
|
return;
|
|
var _c = this.plot_view.frame, xscales = _c.xscales, yscales = _c.yscales;
|
|
var xrs = {};
|
|
for (var name_1 in xscales) {
|
|
var scale = xscales[name_1];
|
|
var _d = scale.r_invert(sx0, sx1), start = _d[0], end = _d[1];
|
|
xrs[name_1] = { start: start, end: end };
|
|
}
|
|
var yrs = {};
|
|
for (var name_2 in yscales) {
|
|
var scale = yscales[name_2];
|
|
var _e = scale.r_invert(sy0, sy1), start = _e[0], end = _e[1];
|
|
yrs[name_2] = { start: start, end: end };
|
|
}
|
|
var zoom_info = { xrs: xrs, yrs: yrs };
|
|
this.plot_view.push_state('box_zoom', { range: zoom_info });
|
|
this.plot_view.update_range(zoom_info);
|
|
};
|
|
return BoxZoomToolView;
|
|
}(gesture_tool_1.GestureToolView));
|
|
exports.BoxZoomToolView = BoxZoomToolView;
|
|
var DEFAULT_BOX_OVERLAY = function () {
|
|
return new box_annotation_1.BoxAnnotation({
|
|
level: "overlay",
|
|
render_mode: "css",
|
|
top_units: "screen",
|
|
left_units: "screen",
|
|
bottom_units: "screen",
|
|
right_units: "screen",
|
|
fill_color: { value: "lightgrey" },
|
|
fill_alpha: { value: 0.5 },
|
|
line_color: { value: "black" },
|
|
line_alpha: { value: 1.0 },
|
|
line_width: { value: 2 },
|
|
line_dash: { value: [4, 4] },
|
|
});
|
|
};
|
|
var BoxZoomTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(BoxZoomTool, _super);
|
|
function BoxZoomTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Box Zoom";
|
|
_this.icon = "bk-tool-icon-box-zoom";
|
|
_this.event_type = "pan";
|
|
_this.default_order = 20;
|
|
return _this;
|
|
}
|
|
BoxZoomTool.initClass = function () {
|
|
this.prototype.type = "BoxZoomTool";
|
|
this.prototype.default_view = BoxZoomToolView;
|
|
this.define({
|
|
dimensions: [p.Dimensions, "both"],
|
|
overlay: [p.Instance, DEFAULT_BOX_OVERLAY],
|
|
match_aspect: [p.Boolean, false],
|
|
origin: [p.BoxOrigin, "corner"],
|
|
});
|
|
};
|
|
Object.defineProperty(BoxZoomTool.prototype, "tooltip", {
|
|
get: function () {
|
|
return this._get_dim_tooltip(this.tool_name, this.dimensions);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return BoxZoomTool;
|
|
}(gesture_tool_1.GestureTool));
|
|
exports.BoxZoomTool = BoxZoomTool;
|
|
BoxZoomTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/gestures/gesture_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var button_tool_1 = require(251) /* ../button_tool */;
|
|
var on_off_button_1 = require(275) /* ../on_off_button */;
|
|
var GestureToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GestureToolView, _super);
|
|
function GestureToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return GestureToolView;
|
|
}(button_tool_1.ButtonToolView));
|
|
exports.GestureToolView = GestureToolView;
|
|
var GestureTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(GestureTool, _super);
|
|
function GestureTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.button_view = on_off_button_1.OnOffButtonView;
|
|
return _this;
|
|
}
|
|
GestureTool.initClass = function () {
|
|
this.prototype.type = "GestureTool";
|
|
};
|
|
return GestureTool;
|
|
}(button_tool_1.ButtonTool));
|
|
exports.GestureTool = GestureTool;
|
|
GestureTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/gestures/lasso_select_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var select_tool_1 = require(266) /* ./select_tool */;
|
|
var poly_annotation_1 = require(74) /* ../../annotations/poly_annotation */;
|
|
var dom_1 = require(5) /* ../../../core/dom */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var LassoSelectToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LassoSelectToolView, _super);
|
|
function LassoSelectToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
LassoSelectToolView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.data = null;
|
|
};
|
|
LassoSelectToolView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.properties.active.change, function () { return _this._active_change(); });
|
|
};
|
|
LassoSelectToolView.prototype._active_change = function () {
|
|
if (!this.model.active)
|
|
this._clear_overlay();
|
|
};
|
|
LassoSelectToolView.prototype._keyup = function (ev) {
|
|
if (ev.keyCode == dom_1.Keys.Enter)
|
|
this._clear_overlay();
|
|
};
|
|
LassoSelectToolView.prototype._pan_start = function (ev) {
|
|
var sx = ev.sx, sy = ev.sy;
|
|
this.data = { sx: [sx], sy: [sy] };
|
|
};
|
|
LassoSelectToolView.prototype._pan = function (ev) {
|
|
var _sx = ev.sx, _sy = ev.sy;
|
|
var _a = this.plot_view.frame.bbox.clip(_sx, _sy), sx = _a[0], sy = _a[1];
|
|
this.data.sx.push(sx);
|
|
this.data.sy.push(sy);
|
|
var overlay = this.model.overlay;
|
|
overlay.update({ xs: this.data.sx, ys: this.data.sy });
|
|
if (this.model.select_every_mousemove) {
|
|
var append = ev.shiftKey;
|
|
this._do_select(this.data.sx, this.data.sy, false, append);
|
|
}
|
|
};
|
|
LassoSelectToolView.prototype._pan_end = function (ev) {
|
|
this._clear_overlay();
|
|
var append = ev.shiftKey;
|
|
this._do_select(this.data.sx, this.data.sy, true, append);
|
|
this.plot_view.push_state('lasso_select', { selection: this.plot_view.get_selection() });
|
|
};
|
|
LassoSelectToolView.prototype._clear_overlay = function () {
|
|
this.model.overlay.update({ xs: [], ys: [] });
|
|
};
|
|
LassoSelectToolView.prototype._do_select = function (sx, sy, final, append) {
|
|
var geometry = { type: 'poly', sx: sx, sy: sy };
|
|
this._select(geometry, final, append);
|
|
};
|
|
LassoSelectToolView.prototype._emit_callback = function (geometry) {
|
|
var r = this.computed_renderers[0];
|
|
var frame = this.plot_view.frame;
|
|
var xscale = frame.xscales[r.x_range_name];
|
|
var yscale = frame.yscales[r.y_range_name];
|
|
var x = xscale.v_invert(geometry.sx);
|
|
var y = yscale.v_invert(geometry.sy);
|
|
var g = tslib_1.__assign({ x: x, y: y }, geometry);
|
|
if (this.model.callback != null)
|
|
this.model.callback.execute(this.model, { geometry: g });
|
|
};
|
|
return LassoSelectToolView;
|
|
}(select_tool_1.SelectToolView));
|
|
exports.LassoSelectToolView = LassoSelectToolView;
|
|
var DEFAULT_POLY_OVERLAY = function () {
|
|
return new poly_annotation_1.PolyAnnotation({
|
|
level: "overlay",
|
|
xs_units: "screen",
|
|
ys_units: "screen",
|
|
fill_color: { value: "lightgrey" },
|
|
fill_alpha: { value: 0.5 },
|
|
line_color: { value: "black" },
|
|
line_alpha: { value: 1.0 },
|
|
line_width: { value: 2 },
|
|
line_dash: { value: [4, 4] },
|
|
});
|
|
};
|
|
var LassoSelectTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LassoSelectTool, _super);
|
|
function LassoSelectTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Lasso Select";
|
|
_this.icon = "bk-tool-icon-lasso-select";
|
|
_this.event_type = "pan";
|
|
_this.default_order = 12;
|
|
return _this;
|
|
}
|
|
LassoSelectTool.initClass = function () {
|
|
this.prototype.type = "LassoSelectTool";
|
|
this.prototype.default_view = LassoSelectToolView;
|
|
this.define({
|
|
select_every_mousemove: [p.Boolean, true],
|
|
callback: [p.Any],
|
|
overlay: [p.Instance, DEFAULT_POLY_OVERLAY],
|
|
});
|
|
};
|
|
return LassoSelectTool;
|
|
}(select_tool_1.SelectTool));
|
|
exports.LassoSelectTool = LassoSelectTool;
|
|
LassoSelectTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/gestures/pan_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var gesture_tool_1 = require(261) /* ./gesture_tool */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var PanToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PanToolView, _super);
|
|
function PanToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
PanToolView.prototype._pan_start = function (ev) {
|
|
this.last_dx = 0;
|
|
this.last_dy = 0;
|
|
var sx = ev.sx, sy = ev.sy;
|
|
var bbox = this.plot_view.frame.bbox;
|
|
if (!bbox.contains(sx, sy)) {
|
|
var hr = bbox.h_range;
|
|
var vr = bbox.v_range;
|
|
if (sx < hr.start || sx > hr.end)
|
|
this.v_axis_only = true;
|
|
if (sy < vr.start || sy > vr.end)
|
|
this.h_axis_only = true;
|
|
}
|
|
if (this.model.document != null)
|
|
this.model.document.interactive_start(this.plot_model);
|
|
};
|
|
PanToolView.prototype._pan = function (ev) {
|
|
this._update(ev.deltaX, ev.deltaY);
|
|
if (this.model.document != null)
|
|
this.model.document.interactive_start(this.plot_model);
|
|
};
|
|
PanToolView.prototype._pan_end = function (_e) {
|
|
this.h_axis_only = false;
|
|
this.v_axis_only = false;
|
|
if (this.pan_info != null)
|
|
this.plot_view.push_state('pan', { range: this.pan_info });
|
|
};
|
|
PanToolView.prototype._update = function (dx, dy) {
|
|
var frame = this.plot_view.frame;
|
|
var new_dx = dx - this.last_dx;
|
|
var new_dy = dy - this.last_dy;
|
|
var hr = frame.bbox.h_range;
|
|
var sx_low = hr.start - new_dx;
|
|
var sx_high = hr.end - new_dx;
|
|
var vr = frame.bbox.v_range;
|
|
var sy_low = vr.start - new_dy;
|
|
var sy_high = vr.end - new_dy;
|
|
var dims = this.model.dimensions;
|
|
var sx0;
|
|
var sx1;
|
|
var sdx;
|
|
if ((dims == 'width' || dims == 'both') && !this.v_axis_only) {
|
|
sx0 = sx_low;
|
|
sx1 = sx_high;
|
|
sdx = -new_dx;
|
|
}
|
|
else {
|
|
sx0 = hr.start;
|
|
sx1 = hr.end;
|
|
sdx = 0;
|
|
}
|
|
var sy0;
|
|
var sy1;
|
|
var sdy;
|
|
if ((dims == 'height' || dims == 'both') && !this.h_axis_only) {
|
|
sy0 = sy_low;
|
|
sy1 = sy_high;
|
|
sdy = -new_dy;
|
|
}
|
|
else {
|
|
sy0 = vr.start;
|
|
sy1 = vr.end;
|
|
sdy = 0;
|
|
}
|
|
this.last_dx = dx;
|
|
this.last_dy = dy;
|
|
var xscales = frame.xscales, yscales = frame.yscales;
|
|
var xrs = {};
|
|
for (var name_1 in xscales) {
|
|
var scale = xscales[name_1];
|
|
var _a = scale.r_invert(sx0, sx1), start = _a[0], end = _a[1];
|
|
xrs[name_1] = { start: start, end: end };
|
|
}
|
|
var yrs = {};
|
|
for (var name_2 in yscales) {
|
|
var scale = yscales[name_2];
|
|
var _b = scale.r_invert(sy0, sy1), start = _b[0], end = _b[1];
|
|
yrs[name_2] = { start: start, end: end };
|
|
}
|
|
this.pan_info = { xrs: xrs, yrs: yrs, sdx: sdx, sdy: sdy };
|
|
this.plot_view.update_range(this.pan_info, true);
|
|
};
|
|
return PanToolView;
|
|
}(gesture_tool_1.GestureToolView));
|
|
exports.PanToolView = PanToolView;
|
|
var PanTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PanTool, _super);
|
|
function PanTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Pan";
|
|
_this.event_type = "pan";
|
|
_this.default_order = 10;
|
|
return _this;
|
|
}
|
|
PanTool.initClass = function () {
|
|
this.prototype.type = "PanTool";
|
|
this.prototype.default_view = PanToolView;
|
|
this.define({
|
|
dimensions: [p.Dimensions, "both"],
|
|
});
|
|
};
|
|
Object.defineProperty(PanTool.prototype, "tooltip", {
|
|
get: function () {
|
|
return this._get_dim_tooltip("Pan", this.dimensions);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(PanTool.prototype, "icon", {
|
|
get: function () {
|
|
switch (this.dimensions) {
|
|
case "both": return "bk-tool-icon-pan";
|
|
case "width": return "bk-tool-icon-xpan";
|
|
case "height": return "bk-tool-icon-ypan";
|
|
}
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return PanTool;
|
|
}(gesture_tool_1.GestureTool));
|
|
exports.PanTool = PanTool;
|
|
PanTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/gestures/poly_select_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var select_tool_1 = require(266) /* ./select_tool */;
|
|
var poly_annotation_1 = require(74) /* ../../annotations/poly_annotation */;
|
|
var dom_1 = require(5) /* ../../../core/dom */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var array_1 = require(24) /* ../../../core/util/array */;
|
|
var PolySelectToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PolySelectToolView, _super);
|
|
function PolySelectToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
PolySelectToolView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.data = { sx: [], sy: [] };
|
|
};
|
|
PolySelectToolView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.properties.active.change, function () { return _this._active_change(); });
|
|
};
|
|
PolySelectToolView.prototype._active_change = function () {
|
|
if (!this.model.active)
|
|
this._clear_data();
|
|
};
|
|
PolySelectToolView.prototype._keyup = function (ev) {
|
|
if (ev.keyCode == dom_1.Keys.Enter)
|
|
this._clear_data();
|
|
};
|
|
PolySelectToolView.prototype._doubletap = function (ev) {
|
|
var append = ev.shiftKey;
|
|
this._do_select(this.data.sx, this.data.sy, true, append);
|
|
this.plot_view.push_state('poly_select', { selection: this.plot_view.get_selection() });
|
|
this._clear_data();
|
|
};
|
|
PolySelectToolView.prototype._clear_data = function () {
|
|
this.data = { sx: [], sy: [] };
|
|
this.model.overlay.update({ xs: [], ys: [] });
|
|
};
|
|
PolySelectToolView.prototype._tap = function (ev) {
|
|
var sx = ev.sx, sy = ev.sy;
|
|
var frame = this.plot_view.frame;
|
|
if (!frame.bbox.contains(sx, sy))
|
|
return;
|
|
this.data.sx.push(sx);
|
|
this.data.sy.push(sy);
|
|
this.model.overlay.update({ xs: array_1.copy(this.data.sx), ys: array_1.copy(this.data.sy) });
|
|
};
|
|
PolySelectToolView.prototype._do_select = function (sx, sy, final, append) {
|
|
var geometry = { type: 'poly', sx: sx, sy: sy };
|
|
this._select(geometry, final, append);
|
|
};
|
|
PolySelectToolView.prototype._emit_callback = function (geometry) {
|
|
var r = this.computed_renderers[0];
|
|
var frame = this.plot_view.frame;
|
|
var xscale = frame.xscales[r.x_range_name];
|
|
var yscale = frame.yscales[r.y_range_name];
|
|
var x = xscale.v_invert(geometry.sx);
|
|
var y = yscale.v_invert(geometry.sy);
|
|
var g = tslib_1.__assign({ x: x, y: y }, geometry);
|
|
if (this.model.callback != null)
|
|
this.model.callback.execute(this.model, { geometry: g });
|
|
};
|
|
return PolySelectToolView;
|
|
}(select_tool_1.SelectToolView));
|
|
exports.PolySelectToolView = PolySelectToolView;
|
|
var DEFAULT_POLY_OVERLAY = function () {
|
|
return new poly_annotation_1.PolyAnnotation({
|
|
level: "overlay",
|
|
xs_units: "screen",
|
|
ys_units: "screen",
|
|
fill_color: { value: "lightgrey" },
|
|
fill_alpha: { value: 0.5 },
|
|
line_color: { value: "black" },
|
|
line_alpha: { value: 1.0 },
|
|
line_width: { value: 2 },
|
|
line_dash: { value: [4, 4] },
|
|
});
|
|
};
|
|
var PolySelectTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(PolySelectTool, _super);
|
|
function PolySelectTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Poly Select";
|
|
_this.icon = "bk-tool-icon-polygon-select";
|
|
_this.event_type = "tap";
|
|
_this.default_order = 11;
|
|
return _this;
|
|
}
|
|
PolySelectTool.initClass = function () {
|
|
this.prototype.type = "PolySelectTool";
|
|
this.prototype.default_view = PolySelectToolView;
|
|
this.define({
|
|
callback: [p.Any],
|
|
overlay: [p.Instance, DEFAULT_POLY_OVERLAY],
|
|
});
|
|
};
|
|
return PolySelectTool;
|
|
}(select_tool_1.SelectTool));
|
|
exports.PolySelectTool = PolySelectTool;
|
|
PolySelectTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/gestures/range_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var box_annotation_1 = require(67) /* ../../annotations/box_annotation */;
|
|
var logging_1 = require(17) /* ../../../core/logging */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var gesture_tool_1 = require(261) /* ./gesture_tool */;
|
|
function flip_side(side) {
|
|
switch (side) {
|
|
case 1 /* Left */: return 2 /* Right */;
|
|
case 2 /* Right */: return 1 /* Left */;
|
|
case 4 /* Bottom */: return 5 /* Top */;
|
|
case 5 /* Top */: return 4 /* Bottom */;
|
|
default: return side;
|
|
}
|
|
}
|
|
exports.flip_side = flip_side;
|
|
// TODO (bev) This would be better directly with BoxAnnotation, but hard
|
|
// to test on a view. Move when "View Models" are implemented
|
|
function is_near(pos, value, scale, tolerance) {
|
|
if (value == null)
|
|
return false;
|
|
var svalue = scale.compute(value);
|
|
return Math.abs(pos - svalue) < tolerance;
|
|
}
|
|
exports.is_near = is_near;
|
|
// TODO (bev) This would be better directly with BoxAnnotation, but hard
|
|
// to test on a view. Move when "View Models" are implemented
|
|
function is_inside(sx, sy, xscale, yscale, overlay) {
|
|
var result = true;
|
|
if (overlay.left != null && overlay.right != null) {
|
|
var x = xscale.invert(sx);
|
|
if (x < overlay.left || x > overlay.right)
|
|
result = false;
|
|
}
|
|
if (overlay.bottom != null && overlay.top != null) {
|
|
var y = yscale.invert(sy);
|
|
if (y < overlay.bottom || y > overlay.top)
|
|
result = false;
|
|
}
|
|
return result;
|
|
}
|
|
exports.is_inside = is_inside;
|
|
function sides_inside(start, end, range) {
|
|
var result = 0;
|
|
if (start >= range.start && start <= range.end)
|
|
result += 1;
|
|
if (end >= range.start && end <= range.end)
|
|
result += 1;
|
|
return result;
|
|
}
|
|
exports.sides_inside = sides_inside;
|
|
function compute_value(value, scale, sdelta, range) {
|
|
var svalue = scale.compute(value);
|
|
var new_value = scale.invert(svalue + sdelta);
|
|
if (new_value >= range.start && new_value <= range.end)
|
|
return new_value;
|
|
return value;
|
|
}
|
|
exports.compute_value = compute_value;
|
|
function compute_end_side(end, range, side) {
|
|
if (end > range.start) {
|
|
range.end = end;
|
|
return side;
|
|
}
|
|
else {
|
|
range.end = range.start;
|
|
range.start = end;
|
|
return flip_side(side);
|
|
}
|
|
}
|
|
exports.compute_end_side = compute_end_side;
|
|
function compute_start_side(start, range, side) {
|
|
if (start < range.end) {
|
|
range.start = start;
|
|
return side;
|
|
}
|
|
else {
|
|
range.start = range.end;
|
|
range.end = start;
|
|
return flip_side(side);
|
|
}
|
|
}
|
|
exports.compute_start_side = compute_start_side;
|
|
function update_range(range, scale, delta, plot_range) {
|
|
var _a = scale.r_compute(range.start, range.end), sstart = _a[0], send = _a[1];
|
|
var _b = scale.r_invert(sstart + delta, send + delta), start = _b[0], end = _b[1];
|
|
var initial_sides_inside = sides_inside(range.start, range.end, plot_range);
|
|
var final_sides_inside = sides_inside(start, end, plot_range);
|
|
// Allow the update as long as the number of sides in-bounds does not decrease
|
|
if (final_sides_inside >= initial_sides_inside) {
|
|
range.start = start;
|
|
range.end = end;
|
|
}
|
|
}
|
|
exports.update_range = update_range;
|
|
var RangeToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(RangeToolView, _super);
|
|
function RangeToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
RangeToolView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.side = 0 /* None */;
|
|
this.model.update_overlay_from_ranges();
|
|
};
|
|
RangeToolView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
if (this.model.x_range != null)
|
|
this.connect(this.model.x_range.change, function () { return _this.model.update_overlay_from_ranges(); });
|
|
if (this.model.y_range != null)
|
|
this.connect(this.model.y_range.change, function () { return _this.model.update_overlay_from_ranges(); });
|
|
};
|
|
RangeToolView.prototype._pan_start = function (ev) {
|
|
this.last_dx = 0;
|
|
this.last_dy = 0;
|
|
var xr = this.model.x_range;
|
|
var yr = this.model.y_range;
|
|
var frame = this.plot_view.frame;
|
|
var xscale = frame.xscales.default;
|
|
var yscale = frame.yscales.default;
|
|
var overlay = this.model.overlay;
|
|
var left = overlay.left, right = overlay.right, top = overlay.top, bottom = overlay.bottom;
|
|
var tolerance = this.model.overlay.properties.line_width.value() + box_annotation_1.EDGE_TOLERANCE;
|
|
if (xr != null && this.model.x_interaction) {
|
|
if (is_near(ev.sx, left, xscale, tolerance))
|
|
this.side = 1 /* Left */;
|
|
else if (is_near(ev.sx, right, xscale, tolerance))
|
|
this.side = 2 /* Right */;
|
|
else if (is_inside(ev.sx, ev.sy, xscale, yscale, overlay)) {
|
|
this.side = 3 /* LeftRight */;
|
|
}
|
|
}
|
|
if (yr != null && this.model.y_interaction) {
|
|
if (this.side == 0 /* None */ && is_near(ev.sy, bottom, yscale, tolerance))
|
|
this.side = 4 /* Bottom */;
|
|
if (this.side == 0 /* None */ && is_near(ev.sy, top, yscale, tolerance))
|
|
this.side = 5 /* Top */;
|
|
else if (is_inside(ev.sx, ev.sy, xscale, yscale, this.model.overlay)) {
|
|
if (this.side == 3 /* LeftRight */)
|
|
this.side = 7 /* LeftRightBottomTop */;
|
|
else
|
|
this.side = 6 /* BottomTop */;
|
|
}
|
|
}
|
|
};
|
|
RangeToolView.prototype._pan = function (ev) {
|
|
var frame = this.plot_view.frame;
|
|
var new_dx = ev.deltaX - this.last_dx;
|
|
var new_dy = ev.deltaY - this.last_dy;
|
|
var xr = this.model.x_range;
|
|
var yr = this.model.y_range;
|
|
var xscale = frame.xscales.default;
|
|
var yscale = frame.yscales.default;
|
|
if (xr != null) {
|
|
if (this.side == 3 /* LeftRight */ || this.side == 7 /* LeftRightBottomTop */)
|
|
update_range(xr, xscale, new_dx, frame.x_range);
|
|
else if (this.side == 1 /* Left */) {
|
|
var start = compute_value(xr.start, xscale, new_dx, frame.x_range);
|
|
this.side = compute_start_side(start, xr, this.side);
|
|
}
|
|
else if (this.side == 2 /* Right */) {
|
|
var end = compute_value(xr.end, xscale, new_dx, frame.x_range);
|
|
this.side = compute_end_side(end, xr, this.side);
|
|
}
|
|
}
|
|
if (yr != null) {
|
|
if (this.side == 6 /* BottomTop */ || this.side == 7 /* LeftRightBottomTop */)
|
|
update_range(yr, yscale, new_dy, frame.y_range);
|
|
else if (this.side == 4 /* Bottom */) {
|
|
yr.start = compute_value(yr.start, yscale, new_dy, frame.y_range);
|
|
var start = compute_value(yr.start, yscale, new_dy, frame.y_range);
|
|
this.side = compute_start_side(start, yr, this.side);
|
|
}
|
|
else if (this.side == 5 /* Top */) {
|
|
yr.end = compute_value(yr.end, yscale, new_dy, frame.y_range);
|
|
var end = compute_value(yr.end, yscale, new_dy, frame.y_range);
|
|
this.side = compute_end_side(end, yr, this.side);
|
|
}
|
|
}
|
|
this.last_dx = ev.deltaX;
|
|
this.last_dy = ev.deltaY;
|
|
};
|
|
RangeToolView.prototype._pan_end = function (_ev) {
|
|
this.side = 0 /* None */;
|
|
};
|
|
return RangeToolView;
|
|
}(gesture_tool_1.GestureToolView));
|
|
exports.RangeToolView = RangeToolView;
|
|
var DEFAULT_RANGE_OVERLAY = function () {
|
|
return new box_annotation_1.BoxAnnotation({
|
|
level: "overlay",
|
|
render_mode: "canvas",
|
|
fill_color: "lightgrey",
|
|
fill_alpha: { value: 0.5 },
|
|
line_color: { value: "black" },
|
|
line_alpha: { value: 1.0 },
|
|
line_width: { value: 0.5 },
|
|
line_dash: [2, 2],
|
|
});
|
|
};
|
|
var RangeTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(RangeTool, _super);
|
|
function RangeTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Range Tool";
|
|
_this.icon = "bk-tool-icon-range";
|
|
_this.event_type = "pan";
|
|
_this.default_order = 1;
|
|
return _this;
|
|
}
|
|
RangeTool.initClass = function () {
|
|
this.prototype.type = "RangeTool";
|
|
this.prototype.default_view = RangeToolView;
|
|
this.define({
|
|
x_range: [p.Instance, null],
|
|
x_interaction: [p.Boolean, true],
|
|
y_range: [p.Instance, null],
|
|
y_interaction: [p.Boolean, true],
|
|
overlay: [p.Instance, DEFAULT_RANGE_OVERLAY],
|
|
});
|
|
};
|
|
RangeTool.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.overlay.in_cursor = "grab";
|
|
this.overlay.ew_cursor = this.x_range != null && this.x_interaction ? "ew-resize" : null;
|
|
this.overlay.ns_cursor = this.y_range != null && this.y_interaction ? "ns-resize" : null;
|
|
};
|
|
RangeTool.prototype.update_overlay_from_ranges = function () {
|
|
if (this.x_range == null && this.y_range == null) {
|
|
this.overlay.left = null;
|
|
this.overlay.right = null;
|
|
this.overlay.bottom = null;
|
|
this.overlay.top = null;
|
|
logging_1.logger.warn('RangeTool not configured with any Ranges.');
|
|
}
|
|
if (this.x_range == null) {
|
|
this.overlay.left = null;
|
|
this.overlay.right = null;
|
|
}
|
|
else {
|
|
this.overlay.left = this.x_range.start;
|
|
this.overlay.right = this.x_range.end;
|
|
}
|
|
if (this.y_range == null) {
|
|
this.overlay.bottom = null;
|
|
this.overlay.top = null;
|
|
}
|
|
else {
|
|
this.overlay.bottom = this.y_range.start;
|
|
this.overlay.top = this.y_range.end;
|
|
}
|
|
};
|
|
return RangeTool;
|
|
}(gesture_tool_1.GestureTool));
|
|
exports.RangeTool = RangeTool;
|
|
RangeTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/gestures/select_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var gesture_tool_1 = require(261) /* ./gesture_tool */;
|
|
var glyph_renderer_1 = require(193) /* ../../renderers/glyph_renderer */;
|
|
var graph_renderer_1 = require(194) /* ../../renderers/graph_renderer */;
|
|
var util_1 = require(281) /* ../util */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var dom_1 = require(5) /* ../../../core/dom */;
|
|
var bokeh_events_1 = require(3) /* ../../../core/bokeh_events */;
|
|
var SelectToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(SelectToolView, _super);
|
|
function SelectToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Object.defineProperty(SelectToolView.prototype, "computed_renderers", {
|
|
get: function () {
|
|
var renderers = this.model.renderers;
|
|
var all_renderers = this.plot_model.renderers;
|
|
var names = this.model.names;
|
|
return util_1.compute_renderers(renderers, all_renderers, names);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
SelectToolView.prototype._computed_renderers_by_data_source = function () {
|
|
var renderers_by_source = {};
|
|
for (var _i = 0, _a = this.computed_renderers; _i < _a.length; _i++) {
|
|
var r = _a[_i];
|
|
var source_id = void 0;
|
|
if (r instanceof glyph_renderer_1.GlyphRenderer)
|
|
source_id = r.data_source.id;
|
|
else if (r instanceof graph_renderer_1.GraphRenderer)
|
|
source_id = r.node_renderer.data_source.id;
|
|
else
|
|
continue;
|
|
if (!(source_id in renderers_by_source))
|
|
renderers_by_source[source_id] = [];
|
|
renderers_by_source[source_id].push(r);
|
|
}
|
|
return renderers_by_source;
|
|
};
|
|
SelectToolView.prototype._keyup = function (ev) {
|
|
if (ev.keyCode == dom_1.Keys.Esc) {
|
|
for (var _i = 0, _a = this.computed_renderers; _i < _a.length; _i++) {
|
|
var r = _a[_i];
|
|
r.get_selection_manager().clear();
|
|
}
|
|
this.plot_view.request_render();
|
|
}
|
|
};
|
|
SelectToolView.prototype._select = function (geometry, final, append) {
|
|
var renderers_by_source = this._computed_renderers_by_data_source();
|
|
for (var id in renderers_by_source) {
|
|
var renderers = renderers_by_source[id];
|
|
var sm = renderers[0].get_selection_manager();
|
|
var r_views = [];
|
|
for (var _i = 0, renderers_1 = renderers; _i < renderers_1.length; _i++) {
|
|
var r = renderers_1[_i];
|
|
if (r.id in this.plot_view.renderer_views)
|
|
r_views.push(this.plot_view.renderer_views[r.id]);
|
|
}
|
|
sm.select(r_views, geometry, final, append);
|
|
}
|
|
// XXX: messed up class structure
|
|
if (this.model.callback != null)
|
|
this._emit_callback(geometry);
|
|
this._emit_selection_event(geometry, final);
|
|
};
|
|
SelectToolView.prototype._emit_selection_event = function (geometry, final) {
|
|
if (final === void 0) {
|
|
final = true;
|
|
}
|
|
var frame = this.plot_view.frame;
|
|
var xm = frame.xscales.default;
|
|
var ym = frame.yscales.default;
|
|
var g; // XXX: Geometry & something
|
|
switch (geometry.type) {
|
|
case 'point': {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x = xm.invert(sx);
|
|
var y = ym.invert(sy);
|
|
g = tslib_1.__assign({}, geometry, { x: x, y: y });
|
|
break;
|
|
}
|
|
case 'rect': {
|
|
var sx0 = geometry.sx0, sx1 = geometry.sx1, sy0 = geometry.sy0, sy1 = geometry.sy1;
|
|
var _a = xm.r_invert(sx0, sx1), x0 = _a[0], x1 = _a[1];
|
|
var _b = ym.r_invert(sy0, sy1), y0 = _b[0], y1 = _b[1];
|
|
g = tslib_1.__assign({}, geometry, { x0: x0, y0: y0, x1: x1, y1: y1 });
|
|
break;
|
|
}
|
|
case 'poly': {
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var x = xm.v_invert(sx);
|
|
var y = ym.v_invert(sy);
|
|
g = tslib_1.__assign({}, geometry, { x: x, y: y });
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("Unrecognized selection geometry type: '" + geometry.type + "'");
|
|
}
|
|
this.plot_model.trigger_event(new bokeh_events_1.SelectionGeometry(g, final));
|
|
};
|
|
return SelectToolView;
|
|
}(gesture_tool_1.GestureToolView));
|
|
exports.SelectToolView = SelectToolView;
|
|
var SelectTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(SelectTool, _super);
|
|
function SelectTool(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
SelectTool.initClass = function () {
|
|
this.prototype.type = "SelectTool";
|
|
this.define({
|
|
renderers: [p.Any, 'auto'],
|
|
names: [p.Array, []],
|
|
});
|
|
};
|
|
return SelectTool;
|
|
}(gesture_tool_1.GestureTool));
|
|
exports.SelectTool = SelectTool;
|
|
SelectTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/gestures/tap_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var select_tool_1 = require(266) /* ./select_tool */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var TapToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TapToolView, _super);
|
|
function TapToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
TapToolView.prototype._tap = function (ev) {
|
|
var sx = ev.sx, sy = ev.sy;
|
|
var geometry = { type: 'point', sx: sx, sy: sy };
|
|
var append = ev.shiftKey;
|
|
this._select(geometry, true, append);
|
|
};
|
|
TapToolView.prototype._select = function (geometry, final, append) {
|
|
var _this = this;
|
|
var callback = this.model.callback;
|
|
if (this.model.behavior == "select") {
|
|
var renderers_by_source = this._computed_renderers_by_data_source();
|
|
for (var id in renderers_by_source) {
|
|
var renderers = renderers_by_source[id];
|
|
var sm = renderers[0].get_selection_manager();
|
|
var r_views = renderers.map(function (r) { return _this.plot_view.renderer_views[r.id]; });
|
|
var did_hit = sm.select(r_views, geometry, final, append);
|
|
if (did_hit && callback != null) {
|
|
var frame = this.plot_view.frame;
|
|
var xscale = frame.xscales[renderers[0].x_range_name];
|
|
var yscale = frame.yscales[renderers[0].y_range_name];
|
|
var x = xscale.invert(geometry.sx);
|
|
var y = yscale.invert(geometry.sy);
|
|
var data = { geometries: tslib_1.__assign({}, geometry, { x: x, y: y }), source: sm.source };
|
|
callback.execute(this.model, data);
|
|
}
|
|
}
|
|
this._emit_selection_event(geometry);
|
|
this.plot_view.push_state('tap', { selection: this.plot_view.get_selection() });
|
|
}
|
|
else {
|
|
for (var _i = 0, _a = this.computed_renderers; _i < _a.length; _i++) {
|
|
var r = _a[_i];
|
|
var sm = r.get_selection_manager();
|
|
var did_hit = sm.inspect(this.plot_view.renderer_views[r.id], geometry);
|
|
if (did_hit && callback != null) {
|
|
var frame = this.plot_view.frame;
|
|
var xscale = frame.xscales[r.x_range_name];
|
|
var yscale = frame.yscales[r.y_range_name];
|
|
var x = xscale.invert(geometry.sx);
|
|
var y = yscale.invert(geometry.sy);
|
|
var data = { geometries: tslib_1.__assign({}, geometry, { x: x, y: y }), source: sm.source };
|
|
callback.execute(this.model, data);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
return TapToolView;
|
|
}(select_tool_1.SelectToolView));
|
|
exports.TapToolView = TapToolView;
|
|
var TapTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(TapTool, _super);
|
|
function TapTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Tap";
|
|
_this.icon = "bk-tool-icon-tap-select";
|
|
_this.event_type = "tap";
|
|
_this.default_order = 10;
|
|
return _this;
|
|
}
|
|
TapTool.initClass = function () {
|
|
this.prototype.type = "TapTool";
|
|
this.prototype.default_view = TapToolView;
|
|
this.define({
|
|
behavior: [p.TapBehavior, "select"],
|
|
callback: [p.Any],
|
|
});
|
|
};
|
|
return TapTool;
|
|
}(select_tool_1.SelectTool));
|
|
exports.TapTool = TapTool;
|
|
TapTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/gestures/wheel_pan_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var gesture_tool_1 = require(261) /* ./gesture_tool */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var WheelPanToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(WheelPanToolView, _super);
|
|
function WheelPanToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
WheelPanToolView.prototype._scroll = function (ev) {
|
|
var factor = this.model.speed * ev.delta;
|
|
// clamp the magnitude of factor, if it is > 1 bad things happen
|
|
if (factor > 0.9)
|
|
factor = 0.9;
|
|
else if (factor < -0.9)
|
|
factor = -0.9;
|
|
this._update_ranges(factor);
|
|
};
|
|
WheelPanToolView.prototype._update_ranges = function (factor) {
|
|
var frame = this.plot_view.frame;
|
|
var hr = frame.bbox.h_range;
|
|
var vr = frame.bbox.v_range;
|
|
var _a = [hr.start, hr.end], sx_low = _a[0], sx_high = _a[1];
|
|
var _b = [vr.start, vr.end], sy_low = _b[0], sy_high = _b[1];
|
|
var sx0;
|
|
var sx1;
|
|
var sy0;
|
|
var sy1;
|
|
switch (this.model.dimension) {
|
|
case "height": {
|
|
var sy_range = Math.abs(sy_high - sy_low);
|
|
sx0 = sx_low;
|
|
sx1 = sx_high;
|
|
sy0 = sy_low - sy_range * factor;
|
|
sy1 = sy_high - sy_range * factor;
|
|
break;
|
|
}
|
|
case "width": {
|
|
var sx_range = Math.abs(sx_high - sx_low);
|
|
sx0 = sx_low - sx_range * factor;
|
|
sx1 = sx_high - sx_range * factor;
|
|
sy0 = sy_low;
|
|
sy1 = sy_high;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("this shouldn't have happened");
|
|
}
|
|
var xscales = frame.xscales, yscales = frame.yscales;
|
|
var xrs = {};
|
|
for (var name_1 in xscales) {
|
|
var scale = xscales[name_1];
|
|
var _c = scale.r_invert(sx0, sx1), start = _c[0], end = _c[1];
|
|
xrs[name_1] = { start: start, end: end };
|
|
}
|
|
var yrs = {};
|
|
for (var name_2 in yscales) {
|
|
var scale = yscales[name_2];
|
|
var _d = scale.r_invert(sy0, sy1), start = _d[0], end = _d[1];
|
|
yrs[name_2] = { start: start, end: end };
|
|
}
|
|
// OK this sucks we can't set factor independently in each direction. It is used
|
|
// for GMap plots, and GMap plots always preserve aspect, so effective the value
|
|
// of 'dimensions' is ignored.
|
|
var pan_info = { xrs: xrs, yrs: yrs, factor: factor };
|
|
this.plot_view.push_state('wheel_pan', { range: pan_info });
|
|
this.plot_view.update_range(pan_info, false, true);
|
|
if (this.model.document != null)
|
|
this.model.document.interactive_start(this.plot_model);
|
|
};
|
|
return WheelPanToolView;
|
|
}(gesture_tool_1.GestureToolView));
|
|
exports.WheelPanToolView = WheelPanToolView;
|
|
var WheelPanTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(WheelPanTool, _super);
|
|
function WheelPanTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Wheel Pan";
|
|
_this.icon = "bk-tool-icon-wheel-pan";
|
|
_this.event_type = "scroll";
|
|
_this.default_order = 12;
|
|
return _this;
|
|
}
|
|
WheelPanTool.initClass = function () {
|
|
this.prototype.type = 'WheelPanTool';
|
|
this.prototype.default_view = WheelPanToolView;
|
|
this.define({
|
|
dimension: [p.Dimension, "width"],
|
|
});
|
|
this.internal({
|
|
speed: [p.Number, 1 / 1000],
|
|
});
|
|
};
|
|
Object.defineProperty(WheelPanTool.prototype, "tooltip", {
|
|
get: function () {
|
|
return this._get_dim_tooltip(this.tool_name, this.dimension);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return WheelPanTool;
|
|
}(gesture_tool_1.GestureTool));
|
|
exports.WheelPanTool = WheelPanTool;
|
|
WheelPanTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/gestures/wheel_zoom_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var gesture_tool_1 = require(261) /* ./gesture_tool */;
|
|
var zoom_1 = require(48) /* ../../../core/util/zoom */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var compat_1 = require(31) /* ../../../core/util/compat */;
|
|
var WheelZoomToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(WheelZoomToolView, _super);
|
|
function WheelZoomToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
WheelZoomToolView.prototype._pinch = function (ev) {
|
|
// TODO (bev) this can probably be done much better
|
|
var sx = ev.sx, sy = ev.sy, scale = ev.scale;
|
|
var delta;
|
|
if (scale >= 1)
|
|
delta = (scale - 1) * 20.0;
|
|
else
|
|
delta = -20.0 / scale;
|
|
this._scroll({ type: "wheel", sx: sx, sy: sy, delta: delta });
|
|
};
|
|
WheelZoomToolView.prototype._scroll = function (ev) {
|
|
var frame = this.plot_view.frame;
|
|
var hr = frame.bbox.h_range;
|
|
var vr = frame.bbox.v_range;
|
|
var sx = ev.sx, sy = ev.sy;
|
|
var dims = this.model.dimensions;
|
|
// restrict to axis configured in tool's dimensions property and if
|
|
// zoom origin is inside of frame range/domain
|
|
var h_axis = (dims == 'width' || dims == 'both') && hr.start < sx && sx < hr.end;
|
|
var v_axis = (dims == 'height' || dims == 'both') && vr.start < sy && sy < vr.end;
|
|
if ((!h_axis || !v_axis) && !this.model.zoom_on_axis) {
|
|
return;
|
|
}
|
|
var factor = this.model.speed * ev.delta;
|
|
var zoom_info = zoom_1.scale_range(frame, factor, h_axis, v_axis, { x: sx, y: sy });
|
|
this.plot_view.push_state('wheel_zoom', { range: zoom_info });
|
|
this.plot_view.update_range(zoom_info, false, true, this.model.maintain_focus);
|
|
if (this.model.document != null)
|
|
this.model.document.interactive_start(this.plot_model);
|
|
};
|
|
return WheelZoomToolView;
|
|
}(gesture_tool_1.GestureToolView));
|
|
exports.WheelZoomToolView = WheelZoomToolView;
|
|
var WheelZoomTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(WheelZoomTool, _super);
|
|
function WheelZoomTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Wheel Zoom";
|
|
_this.icon = "bk-tool-icon-wheel-zoom";
|
|
_this.event_type = compat_1.is_mobile ? "pinch" : "scroll";
|
|
_this.default_order = 10;
|
|
return _this;
|
|
}
|
|
WheelZoomTool.initClass = function () {
|
|
this.prototype.type = "WheelZoomTool";
|
|
this.prototype.default_view = WheelZoomToolView;
|
|
this.define({
|
|
dimensions: [p.Dimensions, "both"],
|
|
maintain_focus: [p.Boolean, true],
|
|
zoom_on_axis: [p.Boolean, true],
|
|
speed: [p.Number, 1 / 600],
|
|
});
|
|
};
|
|
Object.defineProperty(WheelZoomTool.prototype, "tooltip", {
|
|
get: function () {
|
|
return this._get_dim_tooltip(this.tool_name, this.dimensions);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return WheelZoomTool;
|
|
}(gesture_tool_1.GestureTool));
|
|
exports.WheelZoomTool = WheelZoomTool;
|
|
WheelZoomTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/index */ function _(require, module, exports) {
|
|
var action_tool_1 = require(242) /* ./actions/action_tool */;
|
|
exports.ActionTool = action_tool_1.ActionTool;
|
|
var custom_action_1 = require(243) /* ./actions/custom_action */;
|
|
exports.CustomAction = custom_action_1.CustomAction;
|
|
var help_tool_1 = require(244) /* ./actions/help_tool */;
|
|
exports.HelpTool = help_tool_1.HelpTool;
|
|
var redo_tool_1 = require(245) /* ./actions/redo_tool */;
|
|
exports.RedoTool = redo_tool_1.RedoTool;
|
|
var reset_tool_1 = require(246) /* ./actions/reset_tool */;
|
|
exports.ResetTool = reset_tool_1.ResetTool;
|
|
var save_tool_1 = require(247) /* ./actions/save_tool */;
|
|
exports.SaveTool = save_tool_1.SaveTool;
|
|
var undo_tool_1 = require(248) /* ./actions/undo_tool */;
|
|
exports.UndoTool = undo_tool_1.UndoTool;
|
|
var zoom_in_tool_1 = require(249) /* ./actions/zoom_in_tool */;
|
|
exports.ZoomInTool = zoom_in_tool_1.ZoomInTool;
|
|
var zoom_out_tool_1 = require(250) /* ./actions/zoom_out_tool */;
|
|
exports.ZoomOutTool = zoom_out_tool_1.ZoomOutTool;
|
|
var button_tool_1 = require(251) /* ./button_tool */;
|
|
exports.ButtonTool = button_tool_1.ButtonTool;
|
|
var edit_tool_1 = require(253) /* ./edit/edit_tool */;
|
|
exports.EditTool = edit_tool_1.EditTool;
|
|
var box_edit_tool_1 = require(252) /* ./edit/box_edit_tool */;
|
|
exports.BoxEditTool = box_edit_tool_1.BoxEditTool;
|
|
var freehand_draw_tool_1 = require(254) /* ./edit/freehand_draw_tool */;
|
|
exports.FreehandDrawTool = freehand_draw_tool_1.FreehandDrawTool;
|
|
var point_draw_tool_1 = require(255) /* ./edit/point_draw_tool */;
|
|
exports.PointDrawTool = point_draw_tool_1.PointDrawTool;
|
|
var poly_draw_tool_1 = require(256) /* ./edit/poly_draw_tool */;
|
|
exports.PolyDrawTool = poly_draw_tool_1.PolyDrawTool;
|
|
var poly_tool_1 = require(258) /* ./edit/poly_tool */;
|
|
exports.PolyTool = poly_tool_1.PolyTool;
|
|
var poly_edit_tool_1 = require(257) /* ./edit/poly_edit_tool */;
|
|
exports.PolyEditTool = poly_edit_tool_1.PolyEditTool;
|
|
var box_select_tool_1 = require(259) /* ./gestures/box_select_tool */;
|
|
exports.BoxSelectTool = box_select_tool_1.BoxSelectTool;
|
|
var box_zoom_tool_1 = require(260) /* ./gestures/box_zoom_tool */;
|
|
exports.BoxZoomTool = box_zoom_tool_1.BoxZoomTool;
|
|
var gesture_tool_1 = require(261) /* ./gestures/gesture_tool */;
|
|
exports.GestureTool = gesture_tool_1.GestureTool;
|
|
var lasso_select_tool_1 = require(262) /* ./gestures/lasso_select_tool */;
|
|
exports.LassoSelectTool = lasso_select_tool_1.LassoSelectTool;
|
|
var pan_tool_1 = require(263) /* ./gestures/pan_tool */;
|
|
exports.PanTool = pan_tool_1.PanTool;
|
|
var poly_select_tool_1 = require(264) /* ./gestures/poly_select_tool */;
|
|
exports.PolySelectTool = poly_select_tool_1.PolySelectTool;
|
|
var range_tool_1 = require(265) /* ./gestures/range_tool */;
|
|
exports.RangeTool = range_tool_1.RangeTool;
|
|
var select_tool_1 = require(266) /* ./gestures/select_tool */;
|
|
exports.SelectTool = select_tool_1.SelectTool;
|
|
var tap_tool_1 = require(267) /* ./gestures/tap_tool */;
|
|
exports.TapTool = tap_tool_1.TapTool;
|
|
var wheel_pan_tool_1 = require(268) /* ./gestures/wheel_pan_tool */;
|
|
exports.WheelPanTool = wheel_pan_tool_1.WheelPanTool;
|
|
var wheel_zoom_tool_1 = require(269) /* ./gestures/wheel_zoom_tool */;
|
|
exports.WheelZoomTool = wheel_zoom_tool_1.WheelZoomTool;
|
|
var crosshair_tool_1 = require(271) /* ./inspectors/crosshair_tool */;
|
|
exports.CrosshairTool = crosshair_tool_1.CrosshairTool;
|
|
var customjs_hover_1 = require(272) /* ./inspectors/customjs_hover */;
|
|
exports.CustomJSHover = customjs_hover_1.CustomJSHover;
|
|
var hover_tool_1 = require(273) /* ./inspectors/hover_tool */;
|
|
exports.HoverTool = hover_tool_1.HoverTool;
|
|
var inspect_tool_1 = require(274) /* ./inspectors/inspect_tool */;
|
|
exports.InspectTool = inspect_tool_1.InspectTool;
|
|
var tool_1 = require(276) /* ./tool */;
|
|
exports.Tool = tool_1.Tool;
|
|
var tool_proxy_1 = require(277) /* ./tool_proxy */;
|
|
exports.ToolProxy = tool_proxy_1.ToolProxy;
|
|
var toolbar_1 = require(278) /* ./toolbar */;
|
|
exports.Toolbar = toolbar_1.Toolbar;
|
|
var toolbar_base_1 = require(279) /* ./toolbar_base */;
|
|
exports.ToolbarBase = toolbar_base_1.ToolbarBase;
|
|
var toolbar_box_1 = require(280) /* ./toolbar_box */;
|
|
exports.ProxyToolbar = toolbar_box_1.ProxyToolbar;
|
|
var toolbar_box_2 = require(280) /* ./toolbar_box */;
|
|
exports.ToolbarBox = toolbar_box_2.ToolbarBox;
|
|
}
|
|
,
|
|
/* models/tools/inspectors/crosshair_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var inspect_tool_1 = require(274) /* ./inspect_tool */;
|
|
var span_1 = require(76) /* ../../annotations/span */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var object_1 = require(35) /* ../../../core/util/object */;
|
|
var CrosshairToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CrosshairToolView, _super);
|
|
function CrosshairToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
CrosshairToolView.prototype._move = function (ev) {
|
|
if (!this.model.active)
|
|
return;
|
|
var sx = ev.sx, sy = ev.sy;
|
|
if (!this.plot_view.frame.bbox.contains(sx, sy))
|
|
this._update_spans(null, null);
|
|
else
|
|
this._update_spans(sx, sy);
|
|
};
|
|
CrosshairToolView.prototype._move_exit = function (_e) {
|
|
this._update_spans(null, null);
|
|
};
|
|
CrosshairToolView.prototype._update_spans = function (x, y) {
|
|
var dims = this.model.dimensions;
|
|
if (dims == "width" || dims == "both")
|
|
this.model.spans.width.computed_location = y;
|
|
if (dims == "height" || dims == "both")
|
|
this.model.spans.height.computed_location = x;
|
|
};
|
|
return CrosshairToolView;
|
|
}(inspect_tool_1.InspectToolView));
|
|
exports.CrosshairToolView = CrosshairToolView;
|
|
var CrosshairTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CrosshairTool, _super);
|
|
function CrosshairTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Crosshair";
|
|
_this.icon = "bk-tool-icon-crosshair";
|
|
return _this;
|
|
}
|
|
CrosshairTool.initClass = function () {
|
|
this.prototype.type = "CrosshairTool";
|
|
this.prototype.default_view = CrosshairToolView;
|
|
this.define({
|
|
dimensions: [p.Dimensions, "both"],
|
|
line_color: [p.Color, 'black'],
|
|
line_width: [p.Number, 1],
|
|
line_alpha: [p.Number, 1.0],
|
|
});
|
|
this.internal({
|
|
location_units: [p.SpatialUnits, "screen"],
|
|
render_mode: [p.RenderMode, "css"],
|
|
spans: [p.Any],
|
|
});
|
|
};
|
|
Object.defineProperty(CrosshairTool.prototype, "tooltip", {
|
|
get: function () {
|
|
return this._get_dim_tooltip("Crosshair", this.dimensions);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(CrosshairTool.prototype, "synthetic_renderers", {
|
|
get: function () {
|
|
return object_1.values(this.spans);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
CrosshairTool.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.spans = {
|
|
width: new span_1.Span({
|
|
for_hover: true,
|
|
dimension: "width",
|
|
render_mode: this.render_mode,
|
|
location_units: this.location_units,
|
|
line_color: this.line_color,
|
|
line_width: this.line_width,
|
|
line_alpha: this.line_alpha,
|
|
}),
|
|
height: new span_1.Span({
|
|
for_hover: true,
|
|
dimension: "height",
|
|
render_mode: this.render_mode,
|
|
location_units: this.location_units,
|
|
line_color: this.line_color,
|
|
line_width: this.line_width,
|
|
line_alpha: this.line_alpha,
|
|
}),
|
|
};
|
|
};
|
|
return CrosshairTool;
|
|
}(inspect_tool_1.InspectTool));
|
|
exports.CrosshairTool = CrosshairTool;
|
|
CrosshairTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/inspectors/customjs_hover */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../../model */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var object_1 = require(35) /* ../../../core/util/object */;
|
|
var string_1 = require(40) /* ../../../core/util/string */;
|
|
var CustomJSHover = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CustomJSHover, _super);
|
|
function CustomJSHover(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CustomJSHover.initClass = function () {
|
|
this.prototype.type = 'CustomJSHover';
|
|
this.define({
|
|
args: [p.Any, {}],
|
|
code: [p.String, ""],
|
|
});
|
|
};
|
|
Object.defineProperty(CustomJSHover.prototype, "values", {
|
|
get: function () {
|
|
return object_1.values(this.args);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
/*protected*/ CustomJSHover.prototype._make_code = function (valname, formatname, varsname, fn) {
|
|
// this relies on keys(args) and values(args) returning keys and values
|
|
// in the same order
|
|
return new (Function.bind.apply(Function, [void 0].concat(object_1.keys(this.args), [valname, formatname, varsname, "require", "exports", string_1.use_strict(fn)])))();
|
|
};
|
|
CustomJSHover.prototype.format = function (value, format, special_vars) {
|
|
var formatter = this._make_code("value", "format", "special_vars", this.code);
|
|
return formatter.apply(void 0, this.values.concat([value, format, special_vars, require, exports]));
|
|
};
|
|
return CustomJSHover;
|
|
}(model_1.Model));
|
|
exports.CustomJSHover = CustomJSHover;
|
|
CustomJSHover.initClass();
|
|
}
|
|
,
|
|
/* models/tools/inspectors/hover_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var inspect_tool_1 = require(274) /* ./inspect_tool */;
|
|
var tooltip_1 = require(80) /* ../../annotations/tooltip */;
|
|
var glyph_renderer_1 = require(193) /* ../../renderers/glyph_renderer */;
|
|
var graph_renderer_1 = require(194) /* ../../renderers/graph_renderer */;
|
|
var util_1 = require(281) /* ../util */;
|
|
var hittest = require(9) /* ../../../core/hittest */;
|
|
var templating_1 = require(42) /* ../../../core/util/templating */;
|
|
var dom_1 = require(5) /* ../../../core/dom */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var color_1 = require(30) /* ../../../core/util/color */;
|
|
var object_1 = require(35) /* ../../../core/util/object */;
|
|
var types_1 = require(46) /* ../../../core/util/types */;
|
|
var build_views_1 = require(4) /* ../../../core/build_views */;
|
|
function _nearest_line_hit(i, geometry, sx, sy, dx, dy) {
|
|
var d1 = { x: dx[i], y: dy[i] };
|
|
var d2 = { x: dx[i + 1], y: dy[i + 1] };
|
|
var dist1;
|
|
var dist2;
|
|
if (geometry.type == "span") {
|
|
if (geometry.direction == "h") {
|
|
dist1 = Math.abs(d1.x - sx);
|
|
dist2 = Math.abs(d2.x - sx);
|
|
}
|
|
else {
|
|
dist1 = Math.abs(d1.y - sy);
|
|
dist2 = Math.abs(d2.y - sy);
|
|
}
|
|
}
|
|
else {
|
|
var s = { x: sx, y: sy };
|
|
dist1 = hittest.dist_2_pts(d1, s);
|
|
dist2 = hittest.dist_2_pts(d2, s);
|
|
}
|
|
if (dist1 < dist2)
|
|
return [[d1.x, d1.y], i];
|
|
else
|
|
return [[d2.x, d2.y], i + 1];
|
|
}
|
|
exports._nearest_line_hit = _nearest_line_hit;
|
|
function _line_hit(xs, ys, ind) {
|
|
return [[xs[ind], ys[ind]], ind];
|
|
}
|
|
exports._line_hit = _line_hit;
|
|
var HoverToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(HoverToolView, _super);
|
|
function HoverToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
HoverToolView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.ttviews = {};
|
|
};
|
|
HoverToolView.prototype.remove = function () {
|
|
build_views_1.remove_views(this.ttviews);
|
|
_super.prototype.remove.call(this);
|
|
};
|
|
HoverToolView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
for (var _i = 0, _a = this.computed_renderers; _i < _a.length; _i++) {
|
|
var r = _a[_i];
|
|
if (r instanceof glyph_renderer_1.GlyphRenderer)
|
|
this.connect(r.data_source.inspect, this._update);
|
|
else if (r instanceof graph_renderer_1.GraphRenderer) {
|
|
this.connect(r.node_renderer.data_source.inspect, this._update);
|
|
this.connect(r.edge_renderer.data_source.inspect, this._update);
|
|
}
|
|
}
|
|
// TODO: this.connect(this.plot_model.properties.renderers.change, () => this._computed_renderers = this._ttmodels = null)
|
|
this.connect(this.model.properties.renderers.change, function () { return _this._computed_renderers = _this._ttmodels = null; });
|
|
this.connect(this.model.properties.names.change, function () { return _this._computed_renderers = _this._ttmodels = null; });
|
|
this.connect(this.model.properties.tooltips.change, function () { return _this._ttmodels = null; });
|
|
};
|
|
HoverToolView.prototype._compute_ttmodels = function () {
|
|
var ttmodels = {};
|
|
var tooltips = this.model.tooltips;
|
|
if (tooltips != null) {
|
|
for (var _i = 0, _a = this.computed_renderers; _i < _a.length; _i++) {
|
|
var r = _a[_i];
|
|
if (r instanceof glyph_renderer_1.GlyphRenderer) {
|
|
var tooltip = new tooltip_1.Tooltip({
|
|
custom: types_1.isString(tooltips) || types_1.isFunction(tooltips),
|
|
attachment: this.model.attachment,
|
|
show_arrow: this.model.show_arrow,
|
|
});
|
|
ttmodels[r.id] = tooltip;
|
|
}
|
|
else if (r instanceof graph_renderer_1.GraphRenderer) {
|
|
var tooltip = new tooltip_1.Tooltip({
|
|
custom: types_1.isString(tooltips) || types_1.isFunction(tooltips),
|
|
attachment: this.model.attachment,
|
|
show_arrow: this.model.show_arrow,
|
|
});
|
|
ttmodels[r.node_renderer.id] = tooltip;
|
|
ttmodels[r.edge_renderer.id] = tooltip;
|
|
}
|
|
}
|
|
}
|
|
build_views_1.build_views(this.ttviews, object_1.values(ttmodels), { parent: this.plot_view });
|
|
return ttmodels;
|
|
};
|
|
Object.defineProperty(HoverToolView.prototype, "computed_renderers", {
|
|
get: function () {
|
|
if (this._computed_renderers == null) {
|
|
var renderers = this.model.renderers;
|
|
var all_renderers = this.plot_model.renderers;
|
|
var names = this.model.names;
|
|
this._computed_renderers = util_1.compute_renderers(renderers, all_renderers, names);
|
|
}
|
|
return this._computed_renderers;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(HoverToolView.prototype, "ttmodels", {
|
|
get: function () {
|
|
if (this._ttmodels == null)
|
|
this._ttmodels = this._compute_ttmodels();
|
|
return this._ttmodels;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
HoverToolView.prototype._clear = function () {
|
|
this._inspect(Infinity, Infinity);
|
|
for (var rid in this.ttmodels) {
|
|
var tt = this.ttmodels[rid];
|
|
tt.clear();
|
|
}
|
|
};
|
|
HoverToolView.prototype._move = function (ev) {
|
|
if (!this.model.active)
|
|
return;
|
|
var sx = ev.sx, sy = ev.sy;
|
|
if (!this.plot_view.frame.bbox.contains(sx, sy))
|
|
this._clear();
|
|
else
|
|
this._inspect(sx, sy);
|
|
};
|
|
HoverToolView.prototype._move_exit = function () {
|
|
this._clear();
|
|
};
|
|
HoverToolView.prototype._inspect = function (sx, sy) {
|
|
var geometry;
|
|
if (this.model.mode == 'mouse')
|
|
geometry = { type: 'point', sx: sx, sy: sy };
|
|
else {
|
|
var direction = this.model.mode == 'vline' ? 'h' : 'v';
|
|
geometry = { type: 'span', direction: direction, sx: sx, sy: sy };
|
|
}
|
|
for (var _i = 0, _a = this.computed_renderers; _i < _a.length; _i++) {
|
|
var r = _a[_i];
|
|
var sm = r.get_selection_manager();
|
|
sm.inspect(this.plot_view.renderer_views[r.id], geometry);
|
|
}
|
|
if (this.model.callback != null)
|
|
this._emit_callback(geometry);
|
|
};
|
|
HoverToolView.prototype._update = function (_a) {
|
|
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
var renderer_view = _a[0], geometry = _a[1].geometry;
|
|
if (!this.model.active)
|
|
return;
|
|
if (!(renderer_view instanceof glyph_renderer_1.GlyphRendererView || renderer_view instanceof graph_renderer_1.GraphRendererView))
|
|
return;
|
|
var renderer = renderer_view.model;
|
|
var tooltip = this.ttmodels[renderer.id];
|
|
if (tooltip == null)
|
|
return;
|
|
tooltip.clear();
|
|
var selection_manager = renderer.get_selection_manager();
|
|
var indices = selection_manager.inspectors[renderer.id];
|
|
if (renderer instanceof glyph_renderer_1.GlyphRenderer)
|
|
indices = renderer.view.convert_selection_to_subset(indices);
|
|
if (indices.is_empty())
|
|
return;
|
|
var ds = selection_manager.source;
|
|
var frame = this.plot_view.frame;
|
|
var sx = geometry.sx, sy = geometry.sy;
|
|
var xscale = frame.xscales[renderer.x_range_name];
|
|
var yscale = frame.yscales[renderer.y_range_name];
|
|
var x = xscale.invert(sx);
|
|
var y = yscale.invert(sy);
|
|
var glyph = renderer_view.glyph; // XXX
|
|
for (var _i = 0, _t = indices.line_indices; _i < _t.length; _i++) {
|
|
var i = _t[_i];
|
|
var data_x = glyph._x[i + 1];
|
|
var data_y = glyph._y[i + 1];
|
|
var ii = i;
|
|
var rx = void 0;
|
|
var ry = void 0;
|
|
switch (this.model.line_policy) {
|
|
case "interp": { // and renderer.get_interpolation_hit?
|
|
_b = glyph.get_interpolation_hit(i, geometry), data_x = _b[0], data_y = _b[1];
|
|
rx = xscale.compute(data_x);
|
|
ry = yscale.compute(data_y);
|
|
break;
|
|
}
|
|
case "prev": {
|
|
_c = _line_hit(glyph.sx, glyph.sy, i), _d = _c[0], rx = _d[0], ry = _d[1], ii = _c[1];
|
|
break;
|
|
}
|
|
case "next": {
|
|
_e = _line_hit(glyph.sx, glyph.sy, i + 1), _f = _e[0], rx = _f[0], ry = _f[1], ii = _e[1];
|
|
break;
|
|
}
|
|
case "nearest": {
|
|
_g = _nearest_line_hit(i, geometry, sx, sy, glyph.sx, glyph.sy), _h = _g[0], rx = _h[0], ry = _h[1], ii = _g[1];
|
|
data_x = glyph._x[ii];
|
|
data_y = glyph._y[ii];
|
|
break;
|
|
}
|
|
default: {
|
|
_j = [sx, sy], rx = _j[0], ry = _j[1];
|
|
}
|
|
}
|
|
var vars = {
|
|
index: ii,
|
|
x: x, y: y, sx: sx, sy: sy, data_x: data_x, data_y: data_y, rx: rx, ry: ry,
|
|
indices: indices.line_indices,
|
|
name: renderer_view.model.name,
|
|
};
|
|
tooltip.add(rx, ry, this._render_tooltips(ds, ii, vars));
|
|
}
|
|
for (var _u = 0, _v = indices.image_indices; _u < _v.length; _u++) {
|
|
var struct = _v[_u];
|
|
var vars = { index: struct.index, x: x, y: y, sx: sx, sy: sy };
|
|
var rendered = this._render_tooltips(ds, struct, vars);
|
|
tooltip.add(sx, sy, rendered);
|
|
}
|
|
for (var _w = 0, _z = indices.indices; _w < _z.length; _w++) {
|
|
var i = _z[_w];
|
|
// multiglyphs set additional indices, e.g. multiline_indices for different tooltips
|
|
if (!object_1.isEmpty(indices.multiline_indices)) {
|
|
for (var _0 = 0, _1 = indices.multiline_indices[i.toString()]; _0 < _1.length; _0++) {
|
|
var j = _1[_0];
|
|
var data_x = glyph._xs[i][j];
|
|
var data_y = glyph._ys[i][j];
|
|
var jj = j;
|
|
var rx = void 0;
|
|
var ry = void 0;
|
|
switch (this.model.line_policy) {
|
|
case "interp": { // and renderer.get_interpolation_hit?
|
|
_k = glyph.get_interpolation_hit(i, j, geometry), data_x = _k[0], data_y = _k[1];
|
|
rx = xscale.compute(data_x);
|
|
ry = yscale.compute(data_y);
|
|
break;
|
|
}
|
|
case "prev": {
|
|
_l = _line_hit(glyph.sxs[i], glyph.sys[i], j), _m = _l[0], rx = _m[0], ry = _m[1], jj = _l[1];
|
|
break;
|
|
}
|
|
case "next": {
|
|
_o = _line_hit(glyph.sxs[i], glyph.sys[i], j + 1), _p = _o[0], rx = _p[0], ry = _p[1], jj = _o[1];
|
|
break;
|
|
}
|
|
case "nearest": {
|
|
_q = _nearest_line_hit(j, geometry, sx, sy, glyph.sxs[i], glyph.sys[i]), _r = _q[0], rx = _r[0], ry = _r[1], jj = _q[1];
|
|
data_x = glyph._xs[i][jj];
|
|
data_y = glyph._ys[i][jj];
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("should't have happened");
|
|
}
|
|
var index = void 0;
|
|
if (renderer instanceof glyph_renderer_1.GlyphRenderer)
|
|
index = renderer.view.convert_indices_from_subset([i])[0];
|
|
else
|
|
index = i;
|
|
var vars = {
|
|
index: index, x: x, y: y, sx: sx, sy: sy, data_x: data_x, data_y: data_y,
|
|
segment_index: jj,
|
|
indices: indices.multiline_indices,
|
|
name: renderer_view.model.name,
|
|
};
|
|
tooltip.add(rx, ry, this._render_tooltips(ds, index, vars));
|
|
}
|
|
}
|
|
else {
|
|
// handle non-multiglyphs
|
|
var data_x = glyph._x != null ? glyph._x[i] : undefined;
|
|
var data_y = glyph._y != null ? glyph._y[i] : undefined;
|
|
var rx = void 0;
|
|
var ry = void 0;
|
|
if (this.model.point_policy == 'snap_to_data') { // and renderer.glyph.sx? and renderer.glyph.sy?
|
|
// Pass in our screen position so we can determine which patch we're
|
|
// over if there are discontinuous patches.
|
|
var pt = glyph.get_anchor_point(this.model.anchor, i, [sx, sy]);
|
|
if (pt == null)
|
|
pt = glyph.get_anchor_point("center", i, [sx, sy]);
|
|
rx = pt.x;
|
|
ry = pt.y;
|
|
}
|
|
else
|
|
_s = [sx, sy], rx = _s[0], ry = _s[1];
|
|
var index = void 0;
|
|
if (renderer instanceof glyph_renderer_1.GlyphRenderer)
|
|
index = renderer.view.convert_indices_from_subset([i])[0];
|
|
else
|
|
index = i;
|
|
var vars = {
|
|
index: index, x: x, y: y, sx: sx, sy: sy, data_x: data_x, data_y: data_y,
|
|
indices: indices.indices,
|
|
name: renderer_view.model.name,
|
|
};
|
|
tooltip.add(rx, ry, this._render_tooltips(ds, index, vars));
|
|
}
|
|
}
|
|
};
|
|
HoverToolView.prototype._emit_callback = function (geometry) {
|
|
for (var _i = 0, _a = this.computed_renderers; _i < _a.length; _i++) {
|
|
var r = _a[_i];
|
|
var index = r.data_source.inspected;
|
|
var frame = this.plot_view.frame;
|
|
var xscale = frame.xscales[r.x_range_name];
|
|
var yscale = frame.yscales[r.y_range_name];
|
|
var x = xscale.invert(geometry.sx);
|
|
var y = yscale.invert(geometry.sy);
|
|
var g = tslib_1.__assign({ x: x, y: y }, geometry);
|
|
this.model.callback.execute(this.model, { index: index, geometry: g, renderer: r });
|
|
}
|
|
};
|
|
HoverToolView.prototype._render_tooltips = function (ds, i, vars) {
|
|
var tooltips = this.model.tooltips;
|
|
if (types_1.isString(tooltips)) {
|
|
var el = dom_1.div();
|
|
el.innerHTML = templating_1.replace_placeholders(tooltips, ds, i, this.model.formatters, vars);
|
|
return el;
|
|
}
|
|
else if (types_1.isFunction(tooltips)) {
|
|
return tooltips(ds, vars);
|
|
}
|
|
else {
|
|
var rows = dom_1.div({ style: { display: "table", borderSpacing: "2px" } });
|
|
for (var _i = 0, tooltips_1 = tooltips; _i < tooltips_1.length; _i++) {
|
|
var _a = tooltips_1[_i], label = _a[0], value = _a[1];
|
|
var row = dom_1.div({ style: { display: "table-row" } });
|
|
rows.appendChild(row);
|
|
var cell = void 0;
|
|
cell = dom_1.div({ style: { display: "table-cell" }, class: 'bk-tooltip-row-label' }, label.length != 0 ? label + ": " : "");
|
|
row.appendChild(cell);
|
|
cell = dom_1.div({ style: { display: "table-cell" }, class: 'bk-tooltip-row-value' });
|
|
row.appendChild(cell);
|
|
if (value.indexOf("$color") >= 0) {
|
|
var _b = value.match(/\$color(\[.*\])?:(\w*)/), _c = _b[1], opts = _c === void 0 ? "" : _c, colname = _b[2]; // XXX!
|
|
var column = ds.get_column(colname); // XXX: change to columnar ds
|
|
if (column == null) {
|
|
var el_1 = dom_1.span({}, colname + " unknown");
|
|
cell.appendChild(el_1);
|
|
continue;
|
|
}
|
|
var hex = opts.indexOf("hex") >= 0;
|
|
var swatch = opts.indexOf("swatch") >= 0;
|
|
var color = types_1.isNumber(i) ? column[i] : null;
|
|
if (color == null) {
|
|
var el_2 = dom_1.span({}, "(null)");
|
|
cell.appendChild(el_2);
|
|
continue;
|
|
}
|
|
if (hex)
|
|
color = color_1.color2hex(color);
|
|
var el = dom_1.span({}, color);
|
|
cell.appendChild(el);
|
|
if (swatch) {
|
|
el = dom_1.span({ class: 'bk-tooltip-color-block', style: { backgroundColor: color } }, " ");
|
|
cell.appendChild(el);
|
|
}
|
|
}
|
|
else {
|
|
var el = dom_1.span();
|
|
el.innerHTML = templating_1.replace_placeholders(value.replace("$~", "$data_"), ds, i, this.model.formatters, vars);
|
|
cell.appendChild(el);
|
|
}
|
|
}
|
|
return rows;
|
|
}
|
|
};
|
|
return HoverToolView;
|
|
}(inspect_tool_1.InspectToolView));
|
|
exports.HoverToolView = HoverToolView;
|
|
var HoverTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(HoverTool, _super);
|
|
function HoverTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.tool_name = "Hover";
|
|
_this.icon = "bk-tool-icon-hover";
|
|
return _this;
|
|
}
|
|
HoverTool.initClass = function () {
|
|
this.prototype.type = "HoverTool";
|
|
this.prototype.default_view = HoverToolView;
|
|
this.define({
|
|
tooltips: [p.Any, [
|
|
["index", "$index"],
|
|
["data (x, y)", "($x, $y)"],
|
|
["screen (x, y)", "($sx, $sy)"],
|
|
]],
|
|
formatters: [p.Any, {}],
|
|
renderers: [p.Any, 'auto'],
|
|
names: [p.Array, []],
|
|
mode: [p.HoverMode, 'mouse'],
|
|
point_policy: [p.PointPolicy, 'snap_to_data'],
|
|
line_policy: [p.LinePolicy, 'nearest'],
|
|
show_arrow: [p.Boolean, true],
|
|
anchor: [p.Anchor, 'center'],
|
|
attachment: [p.TooltipAttachment, 'horizontal'],
|
|
callback: [p.Any],
|
|
});
|
|
};
|
|
return HoverTool;
|
|
}(inspect_tool_1.InspectTool));
|
|
exports.HoverTool = HoverTool;
|
|
HoverTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/inspectors/inspect_tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var button_tool_1 = require(251) /* ../button_tool */;
|
|
var on_off_button_1 = require(275) /* ../on_off_button */;
|
|
var p = require(18) /* ../../../core/properties */;
|
|
var InspectToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(InspectToolView, _super);
|
|
function InspectToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
return InspectToolView;
|
|
}(button_tool_1.ButtonToolView));
|
|
exports.InspectToolView = InspectToolView;
|
|
var InspectTool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(InspectTool, _super);
|
|
function InspectTool(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this.event_type = "move";
|
|
return _this;
|
|
}
|
|
InspectTool.initClass = function () {
|
|
this.prototype.type = "InspectTool";
|
|
this.prototype.button_view = on_off_button_1.OnOffButtonView;
|
|
this.define({
|
|
toggleable: [p.Boolean, true],
|
|
});
|
|
this.override({
|
|
active: true,
|
|
});
|
|
};
|
|
return InspectTool;
|
|
}(button_tool_1.ButtonTool));
|
|
exports.InspectTool = InspectTool;
|
|
InspectTool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/on_off_button */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var button_tool_1 = require(251) /* ./button_tool */;
|
|
var OnOffButtonView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(OnOffButtonView, _super);
|
|
function OnOffButtonView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
OnOffButtonView.prototype.render = function () {
|
|
_super.prototype.render.call(this);
|
|
if (this.model.active)
|
|
this.el.classList.add('bk-active');
|
|
else
|
|
this.el.classList.remove('bk-active');
|
|
};
|
|
OnOffButtonView.prototype._clicked = function () {
|
|
var active = this.model.active;
|
|
this.model.active = !active;
|
|
};
|
|
return OnOffButtonView;
|
|
}(button_tool_1.ButtonToolButtonView));
|
|
exports.OnOffButtonView = OnOffButtonView;
|
|
}
|
|
,
|
|
/* models/tools/tool */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var view_1 = require(50) /* ../../core/view */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var ToolView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ToolView, _super);
|
|
function ToolView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
Object.defineProperty(ToolView.prototype, "plot_view", {
|
|
get: function () {
|
|
return this.parent;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(ToolView.prototype, "plot_model", {
|
|
get: function () {
|
|
return this.parent.model;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
ToolView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.properties.active.change, function () {
|
|
if (_this.model.active)
|
|
_this.activate();
|
|
else
|
|
_this.deactivate();
|
|
});
|
|
};
|
|
// activate is triggered by toolbar ui actions
|
|
ToolView.prototype.activate = function () { };
|
|
// deactivate is triggered by toolbar ui actions
|
|
ToolView.prototype.deactivate = function () { };
|
|
return ToolView;
|
|
}(view_1.View));
|
|
exports.ToolView = ToolView;
|
|
var Tool = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Tool, _super);
|
|
function Tool(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Tool.initClass = function () {
|
|
this.prototype.type = "Tool";
|
|
this.internal({
|
|
active: [p.Boolean, false],
|
|
});
|
|
};
|
|
Object.defineProperty(Tool.prototype, "synthetic_renderers", {
|
|
get: function () {
|
|
return [];
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
// utility function to return a tool name, modified
|
|
// by the active dimenions. Used by tools that have dimensions
|
|
Tool.prototype._get_dim_tooltip = function (name, dims) {
|
|
switch (dims) {
|
|
case "width": return name + " (x-axis)";
|
|
case "height": return name + " (y-axis)";
|
|
case "both": return name;
|
|
}
|
|
};
|
|
// utility function to get limits along both dimensions, given
|
|
// optional dimensional constraints
|
|
Tool.prototype._get_dim_limits = function (_a, _b, frame, dims) {
|
|
var sx0 = _a[0], sy0 = _a[1];
|
|
var sx1 = _b[0], sy1 = _b[1];
|
|
var hr = frame.bbox.h_range;
|
|
var sxlim;
|
|
if (dims == 'width' || dims == 'both') {
|
|
sxlim = [array_1.min([sx0, sx1]), array_1.max([sx0, sx1])];
|
|
sxlim = [array_1.max([sxlim[0], hr.start]), array_1.min([sxlim[1], hr.end])];
|
|
}
|
|
else
|
|
sxlim = [hr.start, hr.end];
|
|
var vr = frame.bbox.v_range;
|
|
var sylim;
|
|
if (dims == 'height' || dims == 'both') {
|
|
sylim = [array_1.min([sy0, sy1]), array_1.max([sy0, sy1])];
|
|
sylim = [array_1.max([sylim[0], vr.start]), array_1.min([sylim[1], vr.end])];
|
|
}
|
|
else
|
|
sylim = [vr.start, vr.end];
|
|
return [sxlim, sylim];
|
|
};
|
|
return Tool;
|
|
}(model_1.Model));
|
|
exports.Tool = Tool;
|
|
Tool.initClass();
|
|
}
|
|
,
|
|
/* models/tools/tool_proxy */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var signaling_1 = require(22) /* ../../core/signaling */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var inspect_tool_1 = require(274) /* ./inspectors/inspect_tool */;
|
|
var ToolProxy = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ToolProxy, _super);
|
|
function ToolProxy(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ToolProxy.initClass = function () {
|
|
this.prototype.type = "ToolProxy";
|
|
this.define({
|
|
tools: [p.Array, []],
|
|
active: [p.Boolean, false],
|
|
disabled: [p.Boolean, false],
|
|
});
|
|
};
|
|
Object.defineProperty(ToolProxy.prototype, "button_view", {
|
|
// Operates all the tools given only one button
|
|
get: function () {
|
|
return this.tools[0].button_view;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(ToolProxy.prototype, "event_type", {
|
|
get: function () {
|
|
return this.tools[0].event_type;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(ToolProxy.prototype, "tooltip", {
|
|
get: function () {
|
|
return this.tools[0].tooltip;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(ToolProxy.prototype, "tool_name", {
|
|
get: function () {
|
|
return this.tools[0].tool_name;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(ToolProxy.prototype, "icon", {
|
|
get: function () {
|
|
return this.tools[0].computed_icon;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(ToolProxy.prototype, "computed_icon", {
|
|
get: function () {
|
|
return this.icon;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(ToolProxy.prototype, "toggleable", {
|
|
get: function () {
|
|
var tool = this.tools[0];
|
|
return tool instanceof inspect_tool_1.InspectTool && tool.toggleable;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
ToolProxy.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this.do = new signaling_1.Signal0(this, "do");
|
|
};
|
|
ToolProxy.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.do, function () { return _this.doit(); });
|
|
this.connect(this.properties.active.change, function () { return _this.set_active(); });
|
|
};
|
|
ToolProxy.prototype.doit = function () {
|
|
for (var _i = 0, _a = this.tools; _i < _a.length; _i++) {
|
|
var tool = _a[_i];
|
|
tool.do.emit();
|
|
}
|
|
};
|
|
ToolProxy.prototype.set_active = function () {
|
|
for (var _i = 0, _a = this.tools; _i < _a.length; _i++) {
|
|
var tool = _a[_i];
|
|
tool.active = this.active;
|
|
}
|
|
};
|
|
return ToolProxy;
|
|
}(model_1.Model));
|
|
exports.ToolProxy = ToolProxy;
|
|
ToolProxy.initClass();
|
|
}
|
|
,
|
|
/* models/tools/toolbar */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var action_tool_1 = require(242) /* ./actions/action_tool */;
|
|
var help_tool_1 = require(244) /* ./actions/help_tool */;
|
|
var gesture_tool_1 = require(261) /* ./gestures/gesture_tool */;
|
|
var inspect_tool_1 = require(274) /* ./inspectors/inspect_tool */;
|
|
var toolbar_base_1 = require(279) /* ./toolbar_base */;
|
|
var Toolbar = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Toolbar, _super);
|
|
function Toolbar(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Toolbar.initClass = function () {
|
|
this.prototype.type = 'Toolbar';
|
|
this.prototype.default_view = toolbar_base_1.ToolbarBaseView;
|
|
this.define({
|
|
active_drag: [p.Any, 'auto'],
|
|
active_inspect: [p.Any, 'auto'],
|
|
active_scroll: [p.Any, 'auto'],
|
|
active_tap: [p.Any, 'auto'],
|
|
active_multi: [p.Any, null],
|
|
});
|
|
};
|
|
Toolbar.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this._init_tools();
|
|
};
|
|
Toolbar.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.properties.tools.change, function () { return _this._init_tools(); });
|
|
};
|
|
Toolbar.prototype._init_tools = function () {
|
|
var _this = this;
|
|
var _loop_1 = function (tool) {
|
|
if (tool instanceof inspect_tool_1.InspectTool) {
|
|
if (!array_1.some(this_1.inspectors, function (t) { return t.id == tool.id; })) {
|
|
this_1.inspectors = this_1.inspectors.concat([tool]);
|
|
}
|
|
}
|
|
else if (tool instanceof help_tool_1.HelpTool) {
|
|
if (!array_1.some(this_1.help, function (t) { return t.id == tool.id; })) {
|
|
this_1.help = this_1.help.concat([tool]);
|
|
}
|
|
}
|
|
else if (tool instanceof action_tool_1.ActionTool) {
|
|
if (!array_1.some(this_1.actions, function (t) { return t.id == tool.id; })) {
|
|
this_1.actions = this_1.actions.concat([tool]);
|
|
}
|
|
}
|
|
else if (tool instanceof gesture_tool_1.GestureTool) {
|
|
var event_types = void 0;
|
|
var multi = void 0;
|
|
if (types_1.isString(tool.event_type)) {
|
|
event_types = [tool.event_type];
|
|
multi = false;
|
|
}
|
|
else {
|
|
event_types = tool.event_type || [];
|
|
multi = true;
|
|
}
|
|
for (var _i = 0, event_types_1 = event_types; _i < event_types_1.length; _i++) {
|
|
var et = event_types_1[_i];
|
|
if (!(et in this_1.gestures)) {
|
|
logging_1.logger.warn("Toolbar: unknown event type '" + et + "' for tool: " + tool.type + " (" + tool.id + ")");
|
|
continue;
|
|
}
|
|
if (multi)
|
|
et = "multi";
|
|
if (!array_1.some(this_1.gestures[et].tools, function (t) { return t.id == tool.id; }))
|
|
this_1.gestures[et].tools = this_1.gestures[et].tools.concat([tool]);
|
|
this_1.connect(tool.properties.active.change, this_1._active_change.bind(this_1, tool));
|
|
}
|
|
}
|
|
};
|
|
var this_1 = this;
|
|
for (var _i = 0, _a = this.tools; _i < _a.length; _i++) {
|
|
var tool = _a[_i];
|
|
_loop_1(tool);
|
|
}
|
|
if (this.active_inspect == 'auto') {
|
|
// do nothing as all tools are active be default
|
|
}
|
|
else if (this.active_inspect instanceof inspect_tool_1.InspectTool) {
|
|
for (var _b = 0, _c = this.inspectors; _b < _c.length; _b++) {
|
|
var inspector = _c[_b];
|
|
if (inspector != this.active_inspect)
|
|
inspector.active = false;
|
|
}
|
|
}
|
|
else if (types_1.isArray(this.active_inspect)) {
|
|
for (var _d = 0, _e = this.inspectors; _d < _e.length; _d++) {
|
|
var inspector = _e[_d];
|
|
if (!array_1.includes(this.active_inspect, inspector))
|
|
inspector.active = false;
|
|
}
|
|
}
|
|
else if (this.active_inspect == null) {
|
|
for (var _f = 0, _g = this.inspectors; _f < _g.length; _f++) {
|
|
var inspector = _g[_f];
|
|
inspector.active = false;
|
|
}
|
|
}
|
|
var _activate_gesture = function (tool) {
|
|
if (tool.active) {
|
|
// tool was activated by a proxy, but we need to finish configuration manually
|
|
_this._active_change(tool);
|
|
}
|
|
else
|
|
tool.active = true;
|
|
};
|
|
for (var et in this.gestures) {
|
|
var gesture = this.gestures[et];
|
|
if (gesture.tools.length == 0)
|
|
continue;
|
|
gesture.tools = array_1.sort_by(gesture.tools, function (tool) { return tool.default_order; });
|
|
if (et == 'tap') {
|
|
if (this.active_tap == null)
|
|
continue;
|
|
if (this.active_tap == 'auto')
|
|
_activate_gesture(gesture.tools[0]);
|
|
else
|
|
_activate_gesture(this.active_tap);
|
|
}
|
|
if (et == 'pan') {
|
|
if (this.active_drag == null)
|
|
continue;
|
|
if (this.active_drag == 'auto')
|
|
_activate_gesture(gesture.tools[0]);
|
|
else
|
|
_activate_gesture(this.active_drag);
|
|
}
|
|
if (et == 'pinch' || et == 'scroll') {
|
|
if (this.active_scroll == null || this.active_scroll == 'auto')
|
|
continue;
|
|
_activate_gesture(this.active_scroll);
|
|
}
|
|
if (this.active_multi != null)
|
|
_activate_gesture(this.active_multi);
|
|
}
|
|
};
|
|
return Toolbar;
|
|
}(toolbar_base_1.ToolbarBase));
|
|
exports.Toolbar = Toolbar;
|
|
Toolbar.initClass();
|
|
}
|
|
,
|
|
/* models/tools/toolbar_base */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var dom_1 = require(5) /* ../../core/dom */;
|
|
var build_views_1 = require(4) /* ../../core/build_views */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var dom_view_1 = require(6) /* ../../core/dom_view */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var ToolbarViewModel = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ToolbarViewModel, _super);
|
|
function ToolbarViewModel(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ToolbarViewModel.initClass = function () {
|
|
this.prototype.type = 'ToolbarBase';
|
|
this.define({
|
|
_visible: [p.Any, null],
|
|
autohide: [p.Boolean, false],
|
|
});
|
|
};
|
|
Object.defineProperty(ToolbarViewModel.prototype, "visible", {
|
|
get: function () {
|
|
return (!this.autohide) ? true : (this._visible == null) ? false : this._visible;
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
return ToolbarViewModel;
|
|
}(model_1.Model));
|
|
exports.ToolbarViewModel = ToolbarViewModel;
|
|
ToolbarViewModel.initClass();
|
|
var ToolbarBaseView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ToolbarBaseView, _super);
|
|
function ToolbarBaseView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ToolbarBaseView.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this._tool_button_views = {};
|
|
this._build_tool_button_views();
|
|
this._toolbar_view_model = new ToolbarViewModel({ autohide: this.model.autohide });
|
|
};
|
|
ToolbarBaseView.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.model.properties.tools.change, function () { return _this._build_tool_button_views(); });
|
|
this.connect(this.model.properties.autohide.change, function () {
|
|
_this._toolbar_view_model.autohide = _this.model.autohide;
|
|
_this._on_visible_change();
|
|
});
|
|
this.connect(this._toolbar_view_model.properties._visible.change, function () { return _this._on_visible_change(); });
|
|
};
|
|
ToolbarBaseView.prototype.remove = function () {
|
|
build_views_1.remove_views(this._tool_button_views);
|
|
_super.prototype.remove.call(this);
|
|
};
|
|
ToolbarBaseView.prototype._build_tool_button_views = function () {
|
|
var tools = (this.model._proxied_tools != null ? this.model._proxied_tools : this.model.tools); // XXX
|
|
build_views_1.build_views(this._tool_button_views, tools, { parent: this }, function (tool) { return tool.button_view; });
|
|
};
|
|
ToolbarBaseView.prototype.set_visibility = function (visible) {
|
|
if (visible != this._toolbar_view_model._visible) {
|
|
this._toolbar_view_model._visible = visible;
|
|
}
|
|
};
|
|
ToolbarBaseView.prototype._on_visible_change = function () {
|
|
var visible = this._toolbar_view_model.visible;
|
|
var hidden_class = "bk-toolbar-hidden";
|
|
if (this.el.classList.contains(hidden_class) && visible) {
|
|
this.el.classList.remove(hidden_class);
|
|
}
|
|
else if (!visible) {
|
|
this.el.classList.add(hidden_class);
|
|
}
|
|
};
|
|
ToolbarBaseView.prototype.render = function () {
|
|
var _this = this;
|
|
dom_1.empty(this.el);
|
|
this.el.classList.add("bk-toolbar");
|
|
this.el.classList.add("bk-toolbar-" + this.model.toolbar_location);
|
|
this._toolbar_view_model.autohide = this.model.autohide;
|
|
this._on_visible_change();
|
|
if (this.model.logo != null) {
|
|
var cls = this.model.logo === "grey" ? "bk-grey" : null;
|
|
var logo = dom_1.a({ href: "https://bokeh.pydata.org/", target: "_blank", class: ["bk-logo", "bk-logo-small", cls] });
|
|
this.el.appendChild(logo);
|
|
}
|
|
var bars = [];
|
|
var el = function (tool) {
|
|
return _this._tool_button_views[tool.id].el;
|
|
};
|
|
var gestures = this.model.gestures;
|
|
for (var et in gestures) {
|
|
bars.push(gestures[et].tools.map(el));
|
|
}
|
|
bars.push(this.model.actions.map(el));
|
|
bars.push(this.model.inspectors.filter(function (tool) { return tool.toggleable; }).map(el));
|
|
bars.push(this.model.help.map(el));
|
|
for (var _i = 0, bars_1 = bars; _i < bars_1.length; _i++) {
|
|
var bar = bars_1[_i];
|
|
if (bar.length !== 0) {
|
|
var el_1 = dom_1.div({ class: 'bk-button-bar' }, bar);
|
|
this.el.appendChild(el_1);
|
|
}
|
|
}
|
|
};
|
|
ToolbarBaseView.prototype.update_layout = function () { };
|
|
ToolbarBaseView.prototype.update_position = function () { };
|
|
ToolbarBaseView.prototype.after_layout = function () {
|
|
this._has_finished = true;
|
|
};
|
|
return ToolbarBaseView;
|
|
}(dom_view_1.DOMView));
|
|
exports.ToolbarBaseView = ToolbarBaseView;
|
|
var ToolbarBase = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ToolbarBase, _super);
|
|
function ToolbarBase(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ToolbarBase.initClass = function () {
|
|
this.prototype.type = 'ToolbarBase';
|
|
this.prototype.default_view = ToolbarBaseView;
|
|
this.define({
|
|
tools: [p.Array, []],
|
|
logo: [p.Logo, 'normal'],
|
|
autohide: [p.Boolean, false],
|
|
});
|
|
this.internal({
|
|
gestures: [p.Any, function () {
|
|
return ({
|
|
pan: { tools: [], active: null },
|
|
scroll: { tools: [], active: null },
|
|
pinch: { tools: [], active: null },
|
|
tap: { tools: [], active: null },
|
|
doubletap: { tools: [], active: null },
|
|
press: { tools: [], active: null },
|
|
rotate: { tools: [], active: null },
|
|
move: { tools: [], active: null },
|
|
multi: { tools: [], active: null },
|
|
});
|
|
}],
|
|
actions: [p.Array, []],
|
|
inspectors: [p.Array, []],
|
|
help: [p.Array, []],
|
|
toolbar_location: [p.Location, 'right'],
|
|
});
|
|
};
|
|
Object.defineProperty(ToolbarBase.prototype, "horizontal", {
|
|
get: function () {
|
|
return this.toolbar_location === "above" || this.toolbar_location === "below";
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(ToolbarBase.prototype, "vertical", {
|
|
get: function () {
|
|
return this.toolbar_location === "left" || this.toolbar_location === "right";
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
ToolbarBase.prototype._active_change = function (tool) {
|
|
var event_type = tool.event_type;
|
|
if (event_type == null)
|
|
return;
|
|
var event_types = types_1.isString(event_type) ? [event_type] : event_type;
|
|
for (var _i = 0, event_types_1 = event_types; _i < event_types_1.length; _i++) {
|
|
var et = event_types_1[_i];
|
|
if (tool.active) {
|
|
var currently_active_tool = this.gestures[et].active;
|
|
if (currently_active_tool != null && tool != currently_active_tool) {
|
|
logging_1.logger.debug("Toolbar: deactivating tool: " + currently_active_tool.type + " (" + currently_active_tool.id + ") for event type '" + et + "'");
|
|
currently_active_tool.active = false;
|
|
}
|
|
this.gestures[et].active = tool;
|
|
logging_1.logger.debug("Toolbar: activating tool: " + tool.type + " (" + tool.id + ") for event type '" + et + "'");
|
|
}
|
|
else
|
|
this.gestures[et].active = null;
|
|
}
|
|
};
|
|
return ToolbarBase;
|
|
}(model_1.Model));
|
|
exports.ToolbarBase = ToolbarBase;
|
|
ToolbarBase.initClass();
|
|
}
|
|
,
|
|
/* models/tools/toolbar_box */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var logging_1 = require(17) /* ../../core/logging */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var action_tool_1 = require(242) /* ./actions/action_tool */;
|
|
var help_tool_1 = require(244) /* ./actions/help_tool */;
|
|
var gesture_tool_1 = require(261) /* ./gestures/gesture_tool */;
|
|
var inspect_tool_1 = require(274) /* ./inspectors/inspect_tool */;
|
|
var toolbar_base_1 = require(279) /* ./toolbar_base */;
|
|
var tool_proxy_1 = require(277) /* ./tool_proxy */;
|
|
var layout_dom_1 = require(163) /* ../layouts/layout_dom */;
|
|
var layout_1 = require(13) /* ../../core/layout */;
|
|
var ProxyToolbar = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ProxyToolbar, _super);
|
|
function ProxyToolbar(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ProxyToolbar.initClass = function () {
|
|
this.prototype.type = "ProxyToolbar";
|
|
};
|
|
ProxyToolbar.prototype.initialize = function () {
|
|
_super.prototype.initialize.call(this);
|
|
this._init_tools();
|
|
this._merge_tools();
|
|
};
|
|
ProxyToolbar.prototype._init_tools = function () {
|
|
var _loop_1 = function (tool) {
|
|
if (tool instanceof inspect_tool_1.InspectTool) {
|
|
if (!array_1.some(this_1.inspectors, function (t) { return t.id == tool.id; }))
|
|
this_1.inspectors = this_1.inspectors.concat([tool]);
|
|
}
|
|
else if (tool instanceof help_tool_1.HelpTool) {
|
|
if (!array_1.some(this_1.help, function (t) { return t.id == tool.id; }))
|
|
this_1.help = this_1.help.concat([tool]);
|
|
}
|
|
else if (tool instanceof action_tool_1.ActionTool) {
|
|
if (!array_1.some(this_1.actions, function (t) { return t.id == tool.id; }))
|
|
this_1.actions = this_1.actions.concat([tool]);
|
|
}
|
|
else if (tool instanceof gesture_tool_1.GestureTool) {
|
|
var event_types = void 0;
|
|
var multi = void 0;
|
|
if (types_1.isString(tool.event_type)) {
|
|
event_types = [tool.event_type];
|
|
multi = false;
|
|
}
|
|
else {
|
|
event_types = tool.event_type || [];
|
|
multi = true;
|
|
}
|
|
for (var _i = 0, event_types_1 = event_types; _i < event_types_1.length; _i++) {
|
|
var et = event_types_1[_i];
|
|
if (!(et in this_1.gestures)) {
|
|
logging_1.logger.warn("Toolbar: unknown event type '" + et + "' for tool: " + tool.type + " (" + tool.id + ")");
|
|
continue;
|
|
}
|
|
if (multi)
|
|
et = "multi";
|
|
if (!array_1.some(this_1.gestures[et].tools, function (t) { return t.id == tool.id; }))
|
|
this_1.gestures[et].tools = this_1.gestures[et].tools.concat([tool]);
|
|
}
|
|
}
|
|
};
|
|
var this_1 = this;
|
|
for (var _i = 0, _a = this.tools; _i < _a.length; _i++) {
|
|
var tool = _a[_i];
|
|
_loop_1(tool);
|
|
}
|
|
};
|
|
ProxyToolbar.prototype._merge_tools = function () {
|
|
var _this = this;
|
|
var _a;
|
|
// Go through all the tools on the toolbar and replace them with
|
|
// a proxy e.g. PanTool, BoxSelectTool, etc.
|
|
this._proxied_tools = [];
|
|
var inspectors = {};
|
|
var actions = {};
|
|
var gestures = {};
|
|
var new_help_tools = [];
|
|
var new_help_urls = [];
|
|
for (var _i = 0, _b = this.help; _i < _b.length; _i++) {
|
|
var helptool = _b[_i];
|
|
if (!array_1.includes(new_help_urls, helptool.redirect)) {
|
|
new_help_tools.push(helptool);
|
|
new_help_urls.push(helptool.redirect);
|
|
}
|
|
}
|
|
(_a = this._proxied_tools).push.apply(_a, new_help_tools);
|
|
this.help = new_help_tools;
|
|
for (var event_type in this.gestures) {
|
|
var gesture = this.gestures[event_type];
|
|
if (!(event_type in gestures)) {
|
|
gestures[event_type] = {};
|
|
}
|
|
for (var _c = 0, _d = gesture.tools; _c < _d.length; _c++) {
|
|
var tool = _d[_c];
|
|
if (!(tool.type in gestures[event_type])) {
|
|
gestures[event_type][tool.type] = [];
|
|
}
|
|
gestures[event_type][tool.type].push(tool);
|
|
}
|
|
}
|
|
for (var _e = 0, _f = this.inspectors; _e < _f.length; _e++) {
|
|
var tool = _f[_e];
|
|
if (!(tool.type in inspectors)) {
|
|
inspectors[tool.type] = [];
|
|
}
|
|
inspectors[tool.type].push(tool);
|
|
}
|
|
for (var _g = 0, _h = this.actions; _g < _h.length; _g++) {
|
|
var tool = _h[_g];
|
|
if (!(tool.type in actions)) {
|
|
actions[tool.type] = [];
|
|
}
|
|
actions[tool.type].push(tool);
|
|
}
|
|
// Add a proxy for each of the groups of tools.
|
|
var make_proxy = function (tools, active) {
|
|
if (active === void 0) {
|
|
active = false;
|
|
}
|
|
var proxy = new tool_proxy_1.ToolProxy({ tools: tools, active: active });
|
|
_this._proxied_tools.push(proxy);
|
|
return proxy;
|
|
};
|
|
for (var event_type in gestures) {
|
|
var gesture = this.gestures[event_type];
|
|
gesture.tools = [];
|
|
for (var tool_type in gestures[event_type]) {
|
|
var tools = gestures[event_type][tool_type];
|
|
if (tools.length > 0) {
|
|
if (event_type == 'multi') {
|
|
for (var _j = 0, tools_1 = tools; _j < tools_1.length; _j++) {
|
|
var tool = tools_1[_j];
|
|
var proxy = make_proxy([tool]);
|
|
gesture.tools.push(proxy);
|
|
this.connect(proxy.properties.active.change, this._active_change.bind(this, proxy));
|
|
}
|
|
}
|
|
else {
|
|
var proxy = make_proxy(tools);
|
|
gesture.tools.push(proxy);
|
|
this.connect(proxy.properties.active.change, this._active_change.bind(this, proxy));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.actions = [];
|
|
for (var tool_type in actions) {
|
|
var tools = actions[tool_type];
|
|
if (tool_type == 'CustomAction') {
|
|
for (var _k = 0, tools_2 = tools; _k < tools_2.length; _k++) {
|
|
var tool = tools_2[_k];
|
|
this.actions.push(make_proxy([tool]));
|
|
}
|
|
}
|
|
else if (tools.length > 0) {
|
|
this.actions.push(make_proxy(tools)); // XXX
|
|
}
|
|
}
|
|
this.inspectors = [];
|
|
for (var tool_type in inspectors) {
|
|
var tools = inspectors[tool_type];
|
|
if (tools.length > 0)
|
|
this.inspectors.push(make_proxy(tools, true)); // XXX
|
|
}
|
|
for (var et in this.gestures) {
|
|
var gesture = this.gestures[et];
|
|
if (gesture.tools.length == 0)
|
|
continue;
|
|
gesture.tools = array_1.sort_by(gesture.tools, function (tool) { return tool.default_order; });
|
|
if (!(et == 'pinch' || et == 'scroll' || et == 'multi'))
|
|
gesture.tools[0].active = true;
|
|
}
|
|
};
|
|
return ProxyToolbar;
|
|
}(toolbar_base_1.ToolbarBase));
|
|
exports.ProxyToolbar = ProxyToolbar;
|
|
ProxyToolbar.initClass();
|
|
var ToolbarBoxView = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ToolbarBoxView, _super);
|
|
function ToolbarBoxView() {
|
|
return _super !== null && _super.apply(this, arguments) || this;
|
|
}
|
|
ToolbarBoxView.prototype.initialize = function () {
|
|
this.model.toolbar.toolbar_location = this.model.toolbar_location;
|
|
_super.prototype.initialize.call(this);
|
|
};
|
|
Object.defineProperty(ToolbarBoxView.prototype, "child_models", {
|
|
get: function () {
|
|
return [this.model.toolbar]; // XXX
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
ToolbarBoxView.prototype._update_layout = function () {
|
|
this.layout = new layout_1.ContentBox(this.child_views[0].el);
|
|
var toolbar = this.model.toolbar;
|
|
if (toolbar.horizontal) {
|
|
this.layout.set_sizing({
|
|
width_policy: "fit", min_width: 100, height_policy: "fixed",
|
|
});
|
|
}
|
|
else {
|
|
this.layout.set_sizing({
|
|
width_policy: "fixed", height_policy: "fit", min_height: 100,
|
|
});
|
|
}
|
|
};
|
|
return ToolbarBoxView;
|
|
}(layout_dom_1.LayoutDOMView));
|
|
exports.ToolbarBoxView = ToolbarBoxView;
|
|
var ToolbarBox = /** @class */ (function (_super) {
|
|
tslib_1.__extends(ToolbarBox, _super);
|
|
function ToolbarBox(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
ToolbarBox.initClass = function () {
|
|
this.prototype.type = 'ToolbarBox';
|
|
this.prototype.default_view = ToolbarBoxView;
|
|
this.define({
|
|
toolbar: [p.Instance],
|
|
toolbar_location: [p.Location, "right"],
|
|
});
|
|
};
|
|
return ToolbarBox;
|
|
}(layout_dom_1.LayoutDOM));
|
|
exports.ToolbarBox = ToolbarBox;
|
|
ToolbarBox.initClass();
|
|
}
|
|
,
|
|
/* models/tools/util */ function _(require, module, exports) {
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
function compute_renderers(renderers, all_renderers, names) {
|
|
if (renderers == null)
|
|
return [];
|
|
var result = renderers == 'auto' ? all_renderers : renderers;
|
|
if (names.length > 0)
|
|
result = result.filter(function (r) { return array_1.includes(names, r.name); });
|
|
return result;
|
|
}
|
|
exports.compute_renderers = compute_renderers;
|
|
}
|
|
,
|
|
/* models/transforms/customjs_transform */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var transform_1 = require(289) /* ./transform */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var object_1 = require(35) /* ../../core/util/object */;
|
|
var string_1 = require(40) /* ../../core/util/string */;
|
|
var CustomJSTransform = /** @class */ (function (_super) {
|
|
tslib_1.__extends(CustomJSTransform, _super);
|
|
function CustomJSTransform(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
CustomJSTransform.initClass = function () {
|
|
this.prototype.type = 'CustomJSTransform';
|
|
this.define({
|
|
args: [p.Any, {}],
|
|
func: [p.String, ""],
|
|
v_func: [p.String, ""],
|
|
use_strict: [p.Boolean, false],
|
|
});
|
|
};
|
|
Object.defineProperty(CustomJSTransform.prototype, "names", {
|
|
get: function () {
|
|
return object_1.keys(this.args);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(CustomJSTransform.prototype, "values", {
|
|
get: function () {
|
|
return object_1.values(this.args);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
CustomJSTransform.prototype._make_transform = function (name, func) {
|
|
var code = this.use_strict ? string_1.use_strict(func) : func;
|
|
return new (Function.bind.apply(Function, [void 0].concat(this.names, [name, "require", "exports", code])))();
|
|
};
|
|
Object.defineProperty(CustomJSTransform.prototype, "scalar_transform", {
|
|
get: function () {
|
|
return this._make_transform("x", this.func);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(CustomJSTransform.prototype, "vector_transform", {
|
|
get: function () {
|
|
return this._make_transform("xs", this.v_func);
|
|
},
|
|
enumerable: true,
|
|
configurable: true
|
|
});
|
|
CustomJSTransform.prototype.compute = function (x) {
|
|
return this.scalar_transform.apply(this, this.values.concat([x, require, {}]));
|
|
};
|
|
CustomJSTransform.prototype.v_compute = function (xs) {
|
|
return this.vector_transform.apply(this, this.values.concat([xs, require, {}]));
|
|
};
|
|
return CustomJSTransform;
|
|
}(transform_1.Transform));
|
|
exports.CustomJSTransform = CustomJSTransform;
|
|
CustomJSTransform.initClass();
|
|
}
|
|
,
|
|
/* models/transforms/dodge */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var transform_1 = require(289) /* ./transform */;
|
|
var factor_range_1 = require(188) /* ../ranges/factor_range */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var Dodge = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Dodge, _super);
|
|
function Dodge(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Dodge.initClass = function () {
|
|
this.prototype.type = "Dodge";
|
|
this.define({
|
|
value: [p.Number, 0],
|
|
range: [p.Instance],
|
|
});
|
|
};
|
|
// XXX: this is repeated in ./jitter.ts
|
|
Dodge.prototype.v_compute = function (xs0) {
|
|
var xs;
|
|
if (this.range instanceof factor_range_1.FactorRange)
|
|
xs = this.range.v_synthetic(xs0);
|
|
else if (types_1.isArrayableOf(xs0, types_1.isNumber))
|
|
xs = xs0;
|
|
else
|
|
throw new Error("unexpected");
|
|
var result = new Float64Array(xs.length);
|
|
for (var i = 0; i < xs.length; i++) {
|
|
var x = xs[i];
|
|
result[i] = this._compute(x);
|
|
}
|
|
return result;
|
|
};
|
|
Dodge.prototype.compute = function (x) {
|
|
if (this.range instanceof factor_range_1.FactorRange)
|
|
return this._compute(this.range.synthetic(x));
|
|
else if (types_1.isNumber(x))
|
|
return this._compute(x);
|
|
else
|
|
throw new Error("unexpected");
|
|
};
|
|
Dodge.prototype._compute = function (x) {
|
|
return x + this.value;
|
|
};
|
|
return Dodge;
|
|
}(transform_1.Transform));
|
|
exports.Dodge = Dodge;
|
|
Dodge.initClass();
|
|
}
|
|
,
|
|
/* models/transforms/index */ function _(require, module, exports) {
|
|
var customjs_transform_1 = require(282) /* ./customjs_transform */;
|
|
exports.CustomJSTransform = customjs_transform_1.CustomJSTransform;
|
|
var dodge_1 = require(283) /* ./dodge */;
|
|
exports.Dodge = dodge_1.Dodge;
|
|
var interpolator_1 = require(285) /* ./interpolator */;
|
|
exports.Interpolator = interpolator_1.Interpolator;
|
|
var jitter_1 = require(286) /* ./jitter */;
|
|
exports.Jitter = jitter_1.Jitter;
|
|
var linear_interpolator_1 = require(287) /* ./linear_interpolator */;
|
|
exports.LinearInterpolator = linear_interpolator_1.LinearInterpolator;
|
|
var step_interpolator_1 = require(288) /* ./step_interpolator */;
|
|
exports.StepInterpolator = step_interpolator_1.StepInterpolator;
|
|
var transform_1 = require(289) /* ./transform */;
|
|
exports.Transform = transform_1.Transform;
|
|
}
|
|
,
|
|
/* models/transforms/interpolator */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var transform_1 = require(289) /* ./transform */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var Interpolator = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Interpolator, _super);
|
|
function Interpolator(attrs) {
|
|
var _this = _super.call(this, attrs) || this;
|
|
_this._sorted_dirty = true;
|
|
return _this;
|
|
}
|
|
Interpolator.initClass = function () {
|
|
this.prototype.type = "Interpolator";
|
|
this.define({
|
|
x: [p.Any],
|
|
y: [p.Any],
|
|
data: [p.Any],
|
|
clip: [p.Boolean, true],
|
|
});
|
|
};
|
|
Interpolator.prototype.connect_signals = function () {
|
|
var _this = this;
|
|
_super.prototype.connect_signals.call(this);
|
|
this.connect(this.change, function () { return _this._sorted_dirty = true; });
|
|
};
|
|
Interpolator.prototype.v_compute = function (xs) {
|
|
var result = new Float64Array(xs.length);
|
|
for (var i = 0; i < xs.length; i++) {
|
|
var x = xs[i];
|
|
result[i] = this.compute(x);
|
|
}
|
|
return result;
|
|
};
|
|
Interpolator.prototype.sort = function (descending) {
|
|
if (descending === void 0) {
|
|
descending = false;
|
|
}
|
|
if (!this._sorted_dirty)
|
|
return;
|
|
var tsx;
|
|
var tsy;
|
|
if (types_1.isString(this.x) && types_1.isString(this.y) && this.data != null) {
|
|
var column_names = this.data.columns();
|
|
if (!array_1.includes(column_names, this.x))
|
|
throw new Error("The x parameter does not correspond to a valid column name defined in the data parameter");
|
|
if (!array_1.includes(column_names, this.y))
|
|
throw new Error("The y parameter does not correspond to a valid column name defined in the data parameter");
|
|
tsx = this.data.get_column(this.x);
|
|
tsy = this.data.get_column(this.y);
|
|
}
|
|
else if (types_1.isArray(this.x) && types_1.isArray(this.y)) {
|
|
tsx = this.x;
|
|
tsy = this.y;
|
|
}
|
|
else {
|
|
throw new Error("parameters 'x' and 'y' must be both either string fields or arrays");
|
|
}
|
|
if (tsx.length !== tsy.length)
|
|
throw new Error("The length for x and y do not match");
|
|
if (tsx.length < 2)
|
|
throw new Error("x and y must have at least two elements to support interpolation");
|
|
// The following sorting code is referenced from:
|
|
// http://stackoverflow.com/questions/11499268/sort-two-arrays-the-same-way
|
|
var list = [];
|
|
for (var j in tsx) {
|
|
list.push({ x: tsx[j], y: tsy[j] });
|
|
}
|
|
if (descending)
|
|
list.sort(function (a, b) { return a.x > b.x ? -1 : (a.x == b.x ? 0 : 1); });
|
|
else
|
|
list.sort(function (a, b) { return a.x < b.x ? -1 : (a.x == b.x ? 0 : 1); });
|
|
this._x_sorted = [];
|
|
this._y_sorted = [];
|
|
for (var _i = 0, list_1 = list; _i < list_1.length; _i++) {
|
|
var _a = list_1[_i], x = _a.x, y = _a.y;
|
|
this._x_sorted.push(x);
|
|
this._y_sorted.push(y);
|
|
}
|
|
this._sorted_dirty = false;
|
|
};
|
|
return Interpolator;
|
|
}(transform_1.Transform));
|
|
exports.Interpolator = Interpolator;
|
|
Interpolator.initClass();
|
|
}
|
|
,
|
|
/* models/transforms/jitter */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var transform_1 = require(289) /* ./transform */;
|
|
var factor_range_1 = require(188) /* ../ranges/factor_range */;
|
|
var types_1 = require(46) /* ../../core/util/types */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var bokeh_math = require(34) /* ../../core/util/math */;
|
|
var Jitter = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Jitter, _super);
|
|
function Jitter(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Jitter.initClass = function () {
|
|
this.prototype.type = "Jitter";
|
|
this.define({
|
|
mean: [p.Number, 0],
|
|
width: [p.Number, 1],
|
|
distribution: [p.Distribution, 'uniform'],
|
|
range: [p.Instance],
|
|
});
|
|
this.internal({
|
|
previous_values: [p.Array],
|
|
});
|
|
};
|
|
Jitter.prototype.v_compute = function (xs0) {
|
|
if (this.previous_values != null && this.previous_values.length == xs0.length)
|
|
return this.previous_values;
|
|
var xs;
|
|
if (this.range instanceof factor_range_1.FactorRange)
|
|
xs = this.range.v_synthetic(xs0);
|
|
else if (types_1.isArrayableOf(xs0, types_1.isNumber))
|
|
xs = xs0;
|
|
else
|
|
throw new Error("unexpected");
|
|
var result = new Float64Array(xs.length);
|
|
for (var i = 0; i < xs.length; i++) {
|
|
var x = xs[i];
|
|
result[i] = this._compute(x);
|
|
}
|
|
this.previous_values = result;
|
|
return result;
|
|
};
|
|
Jitter.prototype.compute = function (x) {
|
|
if (this.range instanceof factor_range_1.FactorRange)
|
|
return this._compute(this.range.synthetic(x));
|
|
else if (types_1.isNumber(x))
|
|
return this._compute(x);
|
|
else
|
|
throw new Error("unexpected");
|
|
};
|
|
Jitter.prototype._compute = function (x) {
|
|
switch (this.distribution) {
|
|
case "uniform":
|
|
return x + this.mean + (bokeh_math.random() - 0.5) * this.width;
|
|
case "normal":
|
|
return x + bokeh_math.rnorm(this.mean, this.width);
|
|
}
|
|
};
|
|
return Jitter;
|
|
}(transform_1.Transform));
|
|
exports.Jitter = Jitter;
|
|
Jitter.initClass();
|
|
}
|
|
,
|
|
/* models/transforms/linear_interpolator */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var interpolator_1 = require(285) /* ./interpolator */;
|
|
var LinearInterpolator = /** @class */ (function (_super) {
|
|
tslib_1.__extends(LinearInterpolator, _super);
|
|
function LinearInterpolator(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
LinearInterpolator.initClass = function () {
|
|
this.prototype.type = "LinearInterpolator";
|
|
};
|
|
LinearInterpolator.prototype.compute = function (x) {
|
|
this.sort(false);
|
|
if (this.clip) {
|
|
if (x < this._x_sorted[0] || x > this._x_sorted[this._x_sorted.length - 1])
|
|
return NaN;
|
|
}
|
|
else {
|
|
if (x < this._x_sorted[0])
|
|
return this._y_sorted[0];
|
|
if (x > this._x_sorted[this._x_sorted.length - 1])
|
|
return this._y_sorted[this._y_sorted.length - 1];
|
|
}
|
|
if (x == this._x_sorted[0])
|
|
return this._y_sorted[0];
|
|
var ind = array_1.find_last_index(this._x_sorted, function (num) { return num < x; });
|
|
var x1 = this._x_sorted[ind];
|
|
var x2 = this._x_sorted[ind + 1];
|
|
var y1 = this._y_sorted[ind];
|
|
var y2 = this._y_sorted[ind + 1];
|
|
return y1 + (((x - x1) / (x2 - x1)) * (y2 - y1));
|
|
};
|
|
return LinearInterpolator;
|
|
}(interpolator_1.Interpolator));
|
|
exports.LinearInterpolator = LinearInterpolator;
|
|
LinearInterpolator.initClass();
|
|
}
|
|
,
|
|
/* models/transforms/step_interpolator */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var interpolator_1 = require(285) /* ./interpolator */;
|
|
var p = require(18) /* ../../core/properties */;
|
|
var array_1 = require(24) /* ../../core/util/array */;
|
|
var StepInterpolator = /** @class */ (function (_super) {
|
|
tslib_1.__extends(StepInterpolator, _super);
|
|
function StepInterpolator(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
StepInterpolator.initClass = function () {
|
|
this.prototype.type = "StepInterpolator";
|
|
this.define({
|
|
mode: [p.StepMode, "after"],
|
|
});
|
|
};
|
|
StepInterpolator.prototype.compute = function (x) {
|
|
this.sort(false);
|
|
if (this.clip) {
|
|
if (x < this._x_sorted[0] || x > this._x_sorted[this._x_sorted.length - 1])
|
|
return NaN;
|
|
}
|
|
else {
|
|
if (x < this._x_sorted[0])
|
|
return this._y_sorted[0];
|
|
if (x > this._x_sorted[this._x_sorted.length - 1])
|
|
return this._y_sorted[this._y_sorted.length - 1];
|
|
}
|
|
var ind;
|
|
switch (this.mode) {
|
|
case "after": {
|
|
ind = array_1.find_last_index(this._x_sorted, function (num) { return x >= num; });
|
|
break;
|
|
}
|
|
case "before": {
|
|
ind = array_1.find_index(this._x_sorted, function (num) { return x <= num; });
|
|
break;
|
|
}
|
|
case "center": {
|
|
var diffs = this._x_sorted.map(function (tx) { return Math.abs(tx - x); });
|
|
var mdiff_1 = array_1.min(diffs);
|
|
ind = array_1.find_index(diffs, function (num) { return mdiff_1 === num; });
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error("unknown mode: " + this.mode);
|
|
}
|
|
return ind != -1 ? this._y_sorted[ind] : NaN;
|
|
};
|
|
return StepInterpolator;
|
|
}(interpolator_1.Interpolator));
|
|
exports.StepInterpolator = StepInterpolator;
|
|
StepInterpolator.initClass();
|
|
}
|
|
,
|
|
/* models/transforms/transform */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
var model_1 = require(62) /* ../../model */;
|
|
var Transform = /** @class */ (function (_super) {
|
|
tslib_1.__extends(Transform, _super);
|
|
function Transform(attrs) {
|
|
return _super.call(this, attrs) || this;
|
|
}
|
|
Transform.initClass = function () {
|
|
this.prototype.type = "Transform";
|
|
};
|
|
return Transform;
|
|
}(model_1.Model));
|
|
exports.Transform = Transform;
|
|
Transform.initClass();
|
|
}
|
|
,
|
|
/* polyfill */ function _(require, module, exports) {
|
|
if (typeof Map === "undefined") {
|
|
require(351) /* es6-map/implement */;
|
|
}
|
|
if (typeof WeakMap === "undefined") {
|
|
require(363) /* es6-weak-map/implement */;
|
|
}
|
|
if (typeof Promise === "undefined") {
|
|
require(357) /* es6-promise */.polyfill();
|
|
}
|
|
if (typeof Math.log10 === "undefined") {
|
|
Math.log10 = function (x) {
|
|
return Math.log(x) * Math.LOG10E;
|
|
};
|
|
}
|
|
// ref: https://github.com/bokeh/bokeh/issues/7373
|
|
if (typeof Number.isInteger === "undefined") {
|
|
Number.isInteger = function (value) {
|
|
return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
|
|
};
|
|
}
|
|
if (typeof String.prototype.repeat === "undefined") {
|
|
String.prototype.repeat = function (count) {
|
|
if (this == null) {
|
|
throw new TypeError('can\'t convert ' + this + ' to object');
|
|
}
|
|
var str = '' + this;
|
|
count = +count;
|
|
if (count != count) {
|
|
count = 0;
|
|
}
|
|
if (count < 0) {
|
|
throw new RangeError('repeat count must be non-negative');
|
|
}
|
|
if (count == Infinity) {
|
|
throw new RangeError('repeat count must be less than infinity');
|
|
}
|
|
count = Math.floor(count);
|
|
if (str.length == 0 || count == 0) {
|
|
return '';
|
|
}
|
|
// Ensuring count is a 31-bit integer allows us to heavily optimize the
|
|
// main part. But anyway, most current (August 2014) browsers can't handle
|
|
// strings 1 << 28 chars or longer, so:
|
|
if (str.length * count >= 1 << 28) {
|
|
throw new RangeError('repeat count must not overflow maximum string size');
|
|
}
|
|
var rpt = '';
|
|
for (;;) {
|
|
if ((count & 1) == 1) {
|
|
rpt += str;
|
|
}
|
|
count >>>= 1;
|
|
if (count == 0) {
|
|
break;
|
|
}
|
|
str += str;
|
|
}
|
|
// Could we try:
|
|
// return Array(count + 1).join(this)
|
|
return rpt;
|
|
};
|
|
}
|
|
// Production steps of ECMA-262, Edition 6, 22.1.2.1
|
|
if (typeof Array.from === "undefined") {
|
|
Array.from = (function () {
|
|
var toStr = Object.prototype.toString;
|
|
var isCallable = function (fn) {
|
|
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
|
|
};
|
|
var toInteger = function (value) {
|
|
var number = Number(value);
|
|
if (isNaN(number)) {
|
|
return 0;
|
|
}
|
|
if (number === 0 || !isFinite(number)) {
|
|
return number;
|
|
}
|
|
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
|
|
};
|
|
var maxSafeInteger = Math.pow(2, 53) - 1;
|
|
var toLength = function (value) {
|
|
var len = toInteger(value);
|
|
return Math.min(Math.max(len, 0), maxSafeInteger);
|
|
};
|
|
// The length property of the from method is 1.
|
|
return function from(arrayLike /*, mapFn, thisArg */) {
|
|
// 1. Let C be the this value.
|
|
var C = this;
|
|
// 2. Let items be ToObject(arrayLike).
|
|
var items = Object(arrayLike);
|
|
// 3. ReturnIfAbrupt(items).
|
|
if (arrayLike == null) {
|
|
throw new TypeError('Array.from requires an array-like object - not null or undefined');
|
|
}
|
|
// 4. If mapfn is undefined, then let mapping be false.
|
|
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
|
|
var T;
|
|
if (typeof mapFn !== 'undefined') {
|
|
// 5. else
|
|
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
|
|
if (!isCallable(mapFn)) {
|
|
throw new TypeError('Array.from: when provided, the second argument must be a function');
|
|
}
|
|
// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
|
if (arguments.length > 2) {
|
|
T = arguments[2];
|
|
}
|
|
}
|
|
// 10. Let lenValue be Get(items, "length").
|
|
// 11. Let len be ToLength(lenValue).
|
|
var len = toLength(items.length);
|
|
// 13. If IsConstructor(C) is true, then
|
|
// 13. a. Let A be the result of calling the [[Construct]] internal method
|
|
// of C with an argument list containing the single item len.
|
|
// 14. a. Else, Let A be ArrayCreate(len).
|
|
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
|
|
// 16. Let k be 0.
|
|
var k = 0;
|
|
// 17. Repeat, while k < len… (also steps a - h)
|
|
while (k < len) {
|
|
var kValue = items[k];
|
|
if (mapFn) {
|
|
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
|
|
}
|
|
else {
|
|
A[k] = kValue;
|
|
}
|
|
k += 1;
|
|
}
|
|
// 18. Let putStatus be Put(A, "length", len, true).
|
|
A.length = len;
|
|
// 20. Return A.
|
|
return A;
|
|
};
|
|
}());
|
|
}
|
|
}
|
|
,
|
|
/* protocol/index */ function _(require, module, exports) {
|
|
var tslib_1 = require(400) /* tslib */;
|
|
tslib_1.__exportStar(require(292) /* ./message */, exports);
|
|
tslib_1.__exportStar(require(293) /* ./receiver */, exports);
|
|
}
|
|
,
|
|
/* protocol/message */ function _(require, module, exports) {
|
|
var string_1 = require(40) /* ../core/util/string */;
|
|
var Message = /** @class */ (function () {
|
|
function Message(header, metadata, content) {
|
|
this.header = header;
|
|
this.metadata = metadata;
|
|
this.content = content;
|
|
this.buffers = [];
|
|
}
|
|
Message.assemble = function (header_json, metadata_json, content_json) {
|
|
var header = JSON.parse(header_json);
|
|
var metadata = JSON.parse(metadata_json);
|
|
var content = JSON.parse(content_json);
|
|
return new Message(header, metadata, content);
|
|
};
|
|
Message.prototype.assemble_buffer = function (buf_header, buf_payload) {
|
|
var nb = this.header.num_buffers != null ? this.header.num_buffers : 0;
|
|
if (nb <= this.buffers.length)
|
|
throw new Error("too many buffers received, expecting #{nb}");
|
|
this.buffers.push([buf_header, buf_payload]);
|
|
};
|
|
// not defined for BokehJS, only *receiving* buffers is supported
|
|
// add_buffer: (buf_header, buf_payload) ->
|
|
// write_buffers: (socket)
|
|
Message.create = function (msgtype, metadata, content) {
|
|
if (content === void 0) {
|
|
content = {};
|
|
}
|
|
var header = Message.create_header(msgtype);
|
|
return new Message(header, metadata, content);
|
|
};
|
|
Message.create_header = function (msgtype) {
|
|
return {
|
|
msgid: string_1.uniqueId(),
|
|
msgtype: msgtype,
|
|
};
|
|
};
|
|
Message.prototype.complete = function () {
|
|
if (this.header != null && this.metadata != null && this.content != null) {
|
|
if ('num_buffers' in this.header)
|
|
return this.buffers.length === this.header.num_buffers;
|
|
else
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
};
|
|
Message.prototype.send = function (socket) {
|
|
var nb = this.header.num_buffers != null ? this.header.num_buffers : 0;
|
|
if (nb > 0)
|
|
throw new Error("BokehJS only supports receiving buffers, not sending");
|
|
var header_json = JSON.stringify(this.header);
|
|
var metadata_json = JSON.stringify(this.metadata);
|
|
var content_json = JSON.stringify(this.content);
|
|
socket.send(header_json);
|
|
socket.send(metadata_json);
|
|
socket.send(content_json);
|
|
};
|
|
Message.prototype.msgid = function () {
|
|
return this.header.msgid;
|
|
};
|
|
Message.prototype.msgtype = function () {
|
|
return this.header.msgtype;
|
|
};
|
|
Message.prototype.reqid = function () {
|
|
return this.header.reqid;
|
|
};
|
|
// return the reason we should close on bad protocol, if there is one
|
|
Message.prototype.problem = function () {
|
|
if (!('msgid' in this.header))
|
|
return "No msgid in header";
|
|
else if (!('msgtype' in this.header))
|
|
return "No msgtype in header";
|
|
else
|
|
return null;
|
|
};
|
|
return Message;
|
|
}());
|
|
exports.Message = Message;
|
|
}
|
|
,
|
|
/* protocol/receiver */ function _(require, module, exports) {
|
|
var message_1 = require(292) /* ./message */;
|
|
var Receiver = /** @class */ (function () {
|
|
function Receiver() {
|
|
this.message = null;
|
|
this._partial = null;
|
|
this._fragments = [];
|
|
this._buf_header = null;
|
|
this._current_consumer = this._HEADER;
|
|
}
|
|
Receiver.prototype.consume = function (fragment) {
|
|
this._current_consumer(fragment);
|
|
};
|
|
Receiver.prototype._HEADER = function (fragment) {
|
|
this._assume_text(fragment);
|
|
this.message = null;
|
|
this._partial = null;
|
|
this._fragments = [fragment];
|
|
this._buf_header = null;
|
|
this._current_consumer = this._METADATA;
|
|
};
|
|
Receiver.prototype._METADATA = function (fragment) {
|
|
this._assume_text(fragment);
|
|
this._fragments.push(fragment);
|
|
this._current_consumer = this._CONTENT;
|
|
};
|
|
Receiver.prototype._CONTENT = function (fragment) {
|
|
this._assume_text(fragment);
|
|
this._fragments.push(fragment);
|
|
var _a = this._fragments.slice(0, 3), header_json = _a[0], metadata_json = _a[1], content_json = _a[2];
|
|
this._partial = message_1.Message.assemble(header_json, metadata_json, content_json);
|
|
this._check_complete();
|
|
};
|
|
Receiver.prototype._BUFFER_HEADER = function (fragment) {
|
|
this._assume_text(fragment);
|
|
this._buf_header = fragment; // XXX: assume text but Header is expected
|
|
this._current_consumer = this._BUFFER_PAYLOAD;
|
|
};
|
|
Receiver.prototype._BUFFER_PAYLOAD = function (fragment) {
|
|
this._assume_binary(fragment);
|
|
this._partial.assemble_buffer(this._buf_header, fragment);
|
|
this._check_complete();
|
|
};
|
|
Receiver.prototype._assume_text = function (fragment) {
|
|
if (fragment instanceof ArrayBuffer)
|
|
throw new Error("Expected text fragment but received binary fragment");
|
|
};
|
|
Receiver.prototype._assume_binary = function (fragment) {
|
|
if (!(fragment instanceof ArrayBuffer))
|
|
throw new Error("Expected binary fragment but received text fragment");
|
|
};
|
|
Receiver.prototype._check_complete = function () {
|
|
if (this._partial.complete()) {
|
|
this.message = this._partial;
|
|
this._current_consumer = this._HEADER;
|
|
}
|
|
else
|
|
this._current_consumer = this._BUFFER_HEADER;
|
|
};
|
|
return Receiver;
|
|
}());
|
|
exports.Receiver = Receiver;
|
|
}
|
|
,
|
|
/* safely */ function _(require, module, exports) {
|
|
function _burst_into_flames(error) {
|
|
// Make box
|
|
var box = document.createElement("div");
|
|
box.style.backgroundColor = "#f2dede";
|
|
box.style.border = "1px solid #a94442";
|
|
box.style.borderRadius = "4px";
|
|
box.style.display = "inline-block";
|
|
box.style.fontFamily = "sans-serif";
|
|
box.style.marginTop = "5px";
|
|
box.style.minWidth = "200px";
|
|
box.style.padding = "5px 5px 5px 10px";
|
|
box.classList.add("bokeh-error-box-into-flames");
|
|
// Make button
|
|
var button = document.createElement("span");
|
|
button.style.backgroundColor = "#a94442";
|
|
button.style.borderRadius = "0px 4px 0px 0px";
|
|
button.style.color = "white";
|
|
button.style.cursor = "pointer";
|
|
button.style.cssFloat = "right";
|
|
button.style.fontSize = "0.8em";
|
|
button.style.margin = "-6px -6px 0px 0px";
|
|
button.style.padding = "2px 5px 4px 5px";
|
|
button.title = "close";
|
|
button.setAttribute("aria-label", "close");
|
|
button.appendChild(document.createTextNode("x"));
|
|
button.addEventListener("click", function () { return body.removeChild(box); });
|
|
// Make title
|
|
var title = document.createElement("h3");
|
|
title.style.color = "#a94442";
|
|
title.style.margin = "8px 0px 0px 0px";
|
|
title.style.padding = "0px";
|
|
title.appendChild(document.createTextNode("Bokeh Error"));
|
|
// Make message
|
|
var message = document.createElement("pre");
|
|
message.style.whiteSpace = "unset";
|
|
message.style.overflowX = "auto";
|
|
var text = error instanceof Error ? error.message : error;
|
|
message.appendChild(document.createTextNode(text));
|
|
// Add pieces to box
|
|
box.appendChild(button);
|
|
box.appendChild(title);
|
|
box.appendChild(message);
|
|
// Put box in doc
|
|
var body = document.getElementsByTagName("body")[0];
|
|
body.insertBefore(box, body.firstChild);
|
|
}
|
|
function safely(fn, silent) {
|
|
if (silent === void 0) {
|
|
silent = false;
|
|
}
|
|
try {
|
|
return fn();
|
|
}
|
|
catch (error) {
|
|
_burst_into_flames(error);
|
|
if (!silent)
|
|
throw error;
|
|
else
|
|
return;
|
|
}
|
|
}
|
|
exports.safely = safely;
|
|
}
|
|
,
|
|
/* testing */ function _(require, module, exports) {
|
|
// Just a dumb key/value record for collecting arbitrary info for tests
|
|
exports.results = {};
|
|
// Selenium has race conditions that make it difficult to read out the
|
|
// results structure. This function deletes/creates a div that can act as
|
|
// a semaphore. Tests should wait for the previous div to be stale, then
|
|
// find the new div. At that point the results should be available
|
|
function _update_test_div() {
|
|
var body = document.getElementsByTagName("body")[0];
|
|
var col = document.getElementsByClassName("bokeh-test-div");
|
|
if (col.length == 1) {
|
|
body.removeChild(col[0]);
|
|
delete col[0];
|
|
}
|
|
var box = document.createElement("div");
|
|
box.classList.add("bokeh-test-div");
|
|
box.style.display = "none";
|
|
body.insertBefore(box, body.firstChild);
|
|
}
|
|
function init() {
|
|
_update_test_div();
|
|
}
|
|
exports.init = init;
|
|
function record(key, value) {
|
|
exports.results[key] = value;
|
|
_update_test_div();
|
|
}
|
|
exports.record = record;
|
|
function count(key) {
|
|
if (exports.results[key] == undefined)
|
|
exports.results[key] = 0;
|
|
exports.results[key] += 1;
|
|
_update_test_div();
|
|
}
|
|
exports.count = count;
|
|
function clear() {
|
|
for (var _i = 0, _a = Object.keys(exports.results); _i < _a.length; _i++) {
|
|
var prop = _a[_i];
|
|
delete exports.results[prop];
|
|
}
|
|
_update_test_div();
|
|
}
|
|
exports.clear = clear;
|
|
}
|
|
,
|
|
/* version */ function _(require, module, exports) {
|
|
exports.version = '1.1.0';
|
|
}
|
|
,
|
|
/* canvas2svg/canvas2svg */ function _(require, module, exports) {
|
|
/*!!
|
|
* Canvas 2 Svg v1.0.21
|
|
* A low level canvas to SVG converter. Uses a mock canvas context to build an SVG document.
|
|
*
|
|
* Licensed under the MIT license:
|
|
* http://www.opensource.org/licenses/mit-license.php
|
|
*
|
|
* Author:
|
|
* Kerry Liu
|
|
*
|
|
* Copyright (c) 2014 Gliffy Inc.
|
|
*/
|
|
;
|
|
(function () {
|
|
"use strict";
|
|
var STYLES, ctx, CanvasGradient, CanvasPattern, namedEntities;
|
|
//helper function to format a string
|
|
function format(str, args) {
|
|
var keys = Object.keys(args), i;
|
|
for (i = 0; i < keys.length; i++) {
|
|
str = str.replace(new RegExp("\\{" + keys[i] + "\\}", "gi"), args[keys[i]]);
|
|
}
|
|
return str;
|
|
}
|
|
//helper function that generates a random string
|
|
function randomString(holder) {
|
|
var chars, randomstring, i;
|
|
if (!holder) {
|
|
throw new Error("cannot create a random attribute name for an undefined object");
|
|
}
|
|
chars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
|
|
randomstring = "";
|
|
do {
|
|
randomstring = "";
|
|
for (i = 0; i < 12; i++) {
|
|
randomstring += chars[Math.floor(Math.random() * chars.length)];
|
|
}
|
|
} while (holder[randomstring]);
|
|
return randomstring;
|
|
}
|
|
//helper function to map named to numbered entities
|
|
function createNamedToNumberedLookup(items, radix) {
|
|
var i, entity, lookup = {}, base10, base16;
|
|
items = items.split(',');
|
|
radix = radix || 10;
|
|
// Map from named to numbered entities.
|
|
for (i = 0; i < items.length; i += 2) {
|
|
entity = '&' + items[i + 1] + ';';
|
|
base10 = parseInt(items[i], radix);
|
|
lookup[entity] = '&#' + base10 + ';';
|
|
}
|
|
//FF and IE need to create a regex from hex values ie == \xa0
|
|
lookup["\\xa0"] = ' ';
|
|
return lookup;
|
|
}
|
|
//helper function to map canvas-textAlign to svg-textAnchor
|
|
function getTextAnchor(textAlign) {
|
|
//TODO: support rtl languages
|
|
var mapping = { "left": "start", "right": "end", "center": "middle", "start": "start", "end": "end" };
|
|
return mapping[textAlign] || mapping.start;
|
|
}
|
|
//helper function to map canvas-textBaseline to svg-dominantBaseline
|
|
function getDominantBaseline(textBaseline) {
|
|
//INFO: not supported in all browsers
|
|
var mapping = { "alphabetic": "alphabetic", "hanging": "hanging", "top": "text-before-edge", "bottom": "text-after-edge", "middle": "central" };
|
|
return mapping[textBaseline] || mapping.alphabetic;
|
|
}
|
|
// Unpack entities lookup where the numbers are in radix 32 to reduce the size
|
|
// entity mapping courtesy of tinymce
|
|
namedEntities = createNamedToNumberedLookup('50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' +
|
|
'5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' +
|
|
'5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' +
|
|
'5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' +
|
|
'68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' +
|
|
'6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' +
|
|
'6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' +
|
|
'75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' +
|
|
'7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' +
|
|
'7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' +
|
|
'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' +
|
|
'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' +
|
|
't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' +
|
|
'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' +
|
|
'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' +
|
|
'81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' +
|
|
'8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' +
|
|
'8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' +
|
|
'8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' +
|
|
'8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' +
|
|
'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' +
|
|
'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' +
|
|
'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' +
|
|
'80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' +
|
|
'811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32);
|
|
//Some basic mappings for attributes and default values.
|
|
STYLES = {
|
|
"strokeStyle": {
|
|
svgAttr: "stroke",
|
|
canvas: "#000000",
|
|
svg: "none",
|
|
apply: "stroke" //apply on stroke() or fill()
|
|
},
|
|
"fillStyle": {
|
|
svgAttr: "fill",
|
|
canvas: "#000000",
|
|
svg: null,
|
|
apply: "fill"
|
|
},
|
|
"lineCap": {
|
|
svgAttr: "stroke-linecap",
|
|
canvas: "butt",
|
|
svg: "butt",
|
|
apply: "stroke"
|
|
},
|
|
"lineJoin": {
|
|
svgAttr: "stroke-linejoin",
|
|
canvas: "miter",
|
|
svg: "miter",
|
|
apply: "stroke"
|
|
},
|
|
"miterLimit": {
|
|
svgAttr: "stroke-miterlimit",
|
|
canvas: 10,
|
|
svg: 4,
|
|
apply: "stroke"
|
|
},
|
|
"lineWidth": {
|
|
svgAttr: "stroke-width",
|
|
canvas: 1,
|
|
svg: 1,
|
|
apply: "stroke"
|
|
},
|
|
"globalAlpha": {
|
|
svgAttr: "opacity",
|
|
canvas: 1,
|
|
svg: 1,
|
|
apply: "fill stroke"
|
|
},
|
|
"font": {
|
|
//font converts to multiple svg attributes, there is custom logic for this
|
|
canvas: "10px sans-serif"
|
|
},
|
|
"shadowColor": {
|
|
canvas: "#000000"
|
|
},
|
|
"shadowOffsetX": {
|
|
canvas: 0
|
|
},
|
|
"shadowOffsetY": {
|
|
canvas: 0
|
|
},
|
|
"shadowBlur": {
|
|
canvas: 0
|
|
},
|
|
"textAlign": {
|
|
canvas: "start"
|
|
},
|
|
"textBaseline": {
|
|
canvas: "alphabetic"
|
|
},
|
|
"lineDash": {
|
|
svgAttr: "stroke-dasharray",
|
|
canvas: [],
|
|
svg: null,
|
|
apply: "stroke"
|
|
}
|
|
};
|
|
/**
|
|
*
|
|
* @param gradientNode - reference to the gradient
|
|
* @constructor
|
|
*/
|
|
CanvasGradient = function (gradientNode, ctx) {
|
|
this.__root = gradientNode;
|
|
this.__ctx = ctx;
|
|
};
|
|
/**
|
|
* Adds a color stop to the gradient root
|
|
*/
|
|
CanvasGradient.prototype.addColorStop = function (offset, color) {
|
|
var stop = this.__ctx.__createElement("stop"), regex, matches;
|
|
stop.setAttribute("offset", offset);
|
|
if (color.indexOf("rgba") !== -1) {
|
|
//separate alpha value, since webkit can't handle it
|
|
regex = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d?\.?\d*)\s*\)/gi;
|
|
matches = regex.exec(color);
|
|
stop.setAttribute("stop-color", format("rgb({r},{g},{b})", { r: matches[1], g: matches[2], b: matches[3] }));
|
|
stop.setAttribute("stop-opacity", matches[4]);
|
|
}
|
|
else {
|
|
stop.setAttribute("stop-color", color);
|
|
}
|
|
this.__root.appendChild(stop);
|
|
};
|
|
CanvasPattern = function (pattern, ctx) {
|
|
this.__root = pattern;
|
|
this.__ctx = ctx;
|
|
};
|
|
/**
|
|
* The mock canvas context
|
|
* @param o - options include:
|
|
* ctx - existing Context2D to wrap around
|
|
* width - width of your canvas (defaults to 500)
|
|
* height - height of your canvas (defaults to 500)
|
|
* enableMirroring - enables canvas mirroring (get image data) (defaults to false)
|
|
* document - the document object (defaults to the current document)
|
|
*/
|
|
ctx = function (o) {
|
|
var defaultOptions = { width: 500, height: 500, enableMirroring: false }, options;
|
|
//keep support for this way of calling C2S: new C2S(width,height)
|
|
if (arguments.length > 1) {
|
|
options = defaultOptions;
|
|
options.width = arguments[0];
|
|
options.height = arguments[1];
|
|
}
|
|
else if (!o) {
|
|
options = defaultOptions;
|
|
}
|
|
else {
|
|
options = o;
|
|
}
|
|
if (!(this instanceof ctx)) {
|
|
//did someone call this without new?
|
|
return new ctx(options);
|
|
}
|
|
//setup options
|
|
this.width = options.width || defaultOptions.width;
|
|
this.height = options.height || defaultOptions.height;
|
|
this.enableMirroring = options.enableMirroring !== undefined ? options.enableMirroring : defaultOptions.enableMirroring;
|
|
this.canvas = this; ///point back to this instance!
|
|
this.__document = options.document || document;
|
|
// allow passing in an existing context to wrap around
|
|
// if a context is passed in, we know a canvas already exist
|
|
if (options.ctx) {
|
|
this.__ctx = options.ctx;
|
|
}
|
|
else {
|
|
this.__canvas = this.__document.createElement("canvas");
|
|
this.__ctx = this.__canvas.getContext("2d");
|
|
}
|
|
this.__setDefaultStyles();
|
|
this.__stack = [this.__getStyleState()];
|
|
this.__groupStack = [];
|
|
//the root svg element
|
|
this.__root = this.__document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
this.__root.setAttribute("version", 1.1);
|
|
this.__root.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
this.__root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
|
|
this.__root.setAttribute("width", this.width);
|
|
this.__root.setAttribute("height", this.height);
|
|
//make sure we don't generate the same ids in defs
|
|
this.__ids = {};
|
|
//defs tag
|
|
this.__defs = this.__document.createElementNS("http://www.w3.org/2000/svg", "defs");
|
|
this.__root.appendChild(this.__defs);
|
|
//also add a group child. the svg element can't use the transform attribute
|
|
this.__currentElement = this.__document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
this.__root.appendChild(this.__currentElement);
|
|
};
|
|
/**
|
|
* Creates the specified svg element
|
|
* @private
|
|
*/
|
|
ctx.prototype.__createElement = function (elementName, properties, resetFill) {
|
|
if (typeof properties === "undefined") {
|
|
properties = {};
|
|
}
|
|
var element = this.__document.createElementNS("http://www.w3.org/2000/svg", elementName), keys = Object.keys(properties), i, key;
|
|
if (resetFill) {
|
|
//if fill or stroke is not specified, the svg element should not display. By default SVG's fill is black.
|
|
element.setAttribute("fill", "none");
|
|
element.setAttribute("stroke", "none");
|
|
}
|
|
for (i = 0; i < keys.length; i++) {
|
|
key = keys[i];
|
|
element.setAttribute(key, properties[key]);
|
|
}
|
|
return element;
|
|
};
|
|
/**
|
|
* Applies default canvas styles to the context
|
|
* @private
|
|
*/
|
|
ctx.prototype.__setDefaultStyles = function () {
|
|
//default 2d canvas context properties see:http://www.w3.org/TR/2dcontext/
|
|
var keys = Object.keys(STYLES), i, key;
|
|
for (i = 0; i < keys.length; i++) {
|
|
key = keys[i];
|
|
this[key] = STYLES[key].canvas;
|
|
}
|
|
};
|
|
/**
|
|
* Applies styles on restore
|
|
* @param styleState
|
|
* @private
|
|
*/
|
|
ctx.prototype.__applyStyleState = function (styleState) {
|
|
var keys = Object.keys(styleState), i, key;
|
|
for (i = 0; i < keys.length; i++) {
|
|
key = keys[i];
|
|
this[key] = styleState[key];
|
|
}
|
|
};
|
|
/**
|
|
* Gets the current style state
|
|
* @return {Object}
|
|
* @private
|
|
*/
|
|
ctx.prototype.__getStyleState = function () {
|
|
var i, styleState = {}, keys = Object.keys(STYLES), key;
|
|
for (i = 0; i < keys.length; i++) {
|
|
key = keys[i];
|
|
styleState[key] = this[key];
|
|
}
|
|
return styleState;
|
|
};
|
|
/**
|
|
* Apples the current styles to the current SVG element. On "ctx.fill" or "ctx.stroke"
|
|
* @param type
|
|
* @private
|
|
*/
|
|
ctx.prototype.__applyStyleToCurrentElement = function (type) {
|
|
var currentElement = this.__currentElement;
|
|
var currentStyleGroup = this.__currentElementsToStyle;
|
|
if (currentStyleGroup) {
|
|
currentElement.setAttribute(type, "");
|
|
currentElement = currentStyleGroup.element;
|
|
currentStyleGroup.children.forEach(function (node) {
|
|
node.setAttribute(type, "");
|
|
});
|
|
}
|
|
var keys = Object.keys(STYLES), i, style, value, id, regex, matches;
|
|
for (i = 0; i < keys.length; i++) {
|
|
style = STYLES[keys[i]];
|
|
value = this[keys[i]];
|
|
if (style.apply) {
|
|
//is this a gradient or pattern?
|
|
if (value instanceof CanvasPattern) {
|
|
//pattern
|
|
if (value.__ctx) {
|
|
//copy over defs
|
|
while (value.__ctx.__defs.childNodes.length) {
|
|
id = value.__ctx.__defs.childNodes[0].getAttribute("id");
|
|
this.__ids[id] = id;
|
|
this.__defs.appendChild(value.__ctx.__defs.childNodes[0]);
|
|
}
|
|
}
|
|
currentElement.setAttribute(style.apply, format("url(#{id})", { id: value.__root.getAttribute("id") }));
|
|
}
|
|
else if (value instanceof CanvasGradient) {
|
|
//gradient
|
|
currentElement.setAttribute(style.apply, format("url(#{id})", { id: value.__root.getAttribute("id") }));
|
|
}
|
|
else if (style.apply.indexOf(type) !== -1 && style.svg !== value) {
|
|
if ((style.svgAttr === "stroke" || style.svgAttr === "fill") && value.indexOf("rgba") !== -1) {
|
|
//separate alpha value, since illustrator can't handle it
|
|
regex = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d?\.?\d*)\s*\)/gi;
|
|
matches = regex.exec(value);
|
|
currentElement.setAttribute(style.svgAttr, format("rgb({r},{g},{b})", { r: matches[1], g: matches[2], b: matches[3] }));
|
|
//should take globalAlpha here
|
|
var opacity = matches[4];
|
|
var globalAlpha = this.globalAlpha;
|
|
if (globalAlpha != null) {
|
|
opacity *= globalAlpha;
|
|
}
|
|
currentElement.setAttribute(style.svgAttr + "-opacity", opacity);
|
|
}
|
|
else {
|
|
var attr = style.svgAttr;
|
|
if (keys[i] === 'globalAlpha') {
|
|
attr = type + '-' + style.svgAttr;
|
|
if (currentElement.getAttribute(attr)) {
|
|
//fill-opacity or stroke-opacity has already been set by stroke or fill.
|
|
continue;
|
|
}
|
|
}
|
|
//otherwise only update attribute if right type, and not svg default
|
|
currentElement.setAttribute(attr, value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
/**
|
|
* Will return the closest group or svg node. May return the current element.
|
|
* @private
|
|
*/
|
|
ctx.prototype.__closestGroupOrSvg = function (node) {
|
|
node = node || this.__currentElement;
|
|
if (node.nodeName === "g" || node.nodeName === "svg") {
|
|
return node;
|
|
}
|
|
else {
|
|
return this.__closestGroupOrSvg(node.parentNode);
|
|
}
|
|
};
|
|
/**
|
|
* Returns the serialized value of the svg so far
|
|
* @param fixNamedEntities - Standalone SVG doesn't support named entities, which document.createTextNode encodes.
|
|
* If true, we attempt to find all named entities and encode it as a numeric entity.
|
|
* @return serialized svg
|
|
*/
|
|
ctx.prototype.getSerializedSvg = function (fixNamedEntities) {
|
|
var serialized = new XMLSerializer().serializeToString(this.__root), keys, i, key, value, regexp, xmlns;
|
|
//IE search for a duplicate xmnls because they didn't implement setAttributeNS correctly
|
|
xmlns = /xmlns="http:\/\/www\.w3\.org\/2000\/svg".+xmlns="http:\/\/www\.w3\.org\/2000\/svg/gi;
|
|
if (xmlns.test(serialized)) {
|
|
serialized = serialized.replace('xmlns="http://www.w3.org/2000/svg', 'xmlns:xlink="http://www.w3.org/1999/xlink');
|
|
}
|
|
if (fixNamedEntities) {
|
|
keys = Object.keys(namedEntities);
|
|
//loop over each named entity and replace with the proper equivalent.
|
|
for (i = 0; i < keys.length; i++) {
|
|
key = keys[i];
|
|
value = namedEntities[key];
|
|
regexp = new RegExp(key, "gi");
|
|
if (regexp.test(serialized)) {
|
|
serialized = serialized.replace(regexp, value);
|
|
}
|
|
}
|
|
}
|
|
return serialized;
|
|
};
|
|
/**
|
|
* Returns the root svg
|
|
* @return
|
|
*/
|
|
ctx.prototype.getSvg = function () {
|
|
return this.__root;
|
|
};
|
|
/**
|
|
* Will generate a group tag.
|
|
*/
|
|
ctx.prototype.save = function () {
|
|
var group = this.__createElement("g");
|
|
var parent = this.__closestGroupOrSvg();
|
|
this.__groupStack.push(parent);
|
|
parent.appendChild(group);
|
|
this.__currentElement = group;
|
|
this.__stack.push(this.__getStyleState());
|
|
};
|
|
/**
|
|
* Sets current element to parent, or just root if already root
|
|
*/
|
|
ctx.prototype.restore = function () {
|
|
this.__currentElement = this.__groupStack.pop();
|
|
this.__currentElementsToStyle = null;
|
|
//Clearing canvas will make the poped group invalid, currentElement is set to the root group node.
|
|
if (!this.__currentElement) {
|
|
this.__currentElement = this.__root.childNodes[1];
|
|
}
|
|
var state = this.__stack.pop();
|
|
this.__applyStyleState(state);
|
|
};
|
|
/**
|
|
* Helper method to add transform
|
|
* @private
|
|
*/
|
|
ctx.prototype.__addTransform = function (t) {
|
|
//if the current element has siblings, add another group
|
|
var parent = this.__closestGroupOrSvg();
|
|
if (parent.childNodes.length > 0) {
|
|
if (this.__currentElement.nodeName === "path") {
|
|
if (!this.__currentElementsToStyle)
|
|
this.__currentElementsToStyle = { element: parent, children: [] };
|
|
this.__currentElementsToStyle.children.push(this.__currentElement);
|
|
this.__applyCurrentDefaultPath();
|
|
}
|
|
var group = this.__createElement("g");
|
|
parent.appendChild(group);
|
|
this.__currentElement = group;
|
|
}
|
|
var transform = this.__currentElement.getAttribute("transform");
|
|
if (transform) {
|
|
transform += " ";
|
|
}
|
|
else {
|
|
transform = "";
|
|
}
|
|
transform += t;
|
|
this.__currentElement.setAttribute("transform", transform);
|
|
};
|
|
/**
|
|
* scales the current element
|
|
*/
|
|
ctx.prototype.scale = function (x, y) {
|
|
if (y === undefined) {
|
|
y = x;
|
|
}
|
|
this.__addTransform(format("scale({x},{y})", { x: x, y: y }));
|
|
};
|
|
/**
|
|
* rotates the current element
|
|
*/
|
|
ctx.prototype.rotate = function (angle) {
|
|
var degrees = (angle * 180 / Math.PI);
|
|
this.__addTransform(format("rotate({angle},{cx},{cy})", { angle: degrees, cx: 0, cy: 0 }));
|
|
};
|
|
/**
|
|
* translates the current element
|
|
*/
|
|
ctx.prototype.translate = function (x, y) {
|
|
this.__addTransform(format("translate({x},{y})", { x: x, y: y }));
|
|
};
|
|
/**
|
|
* applies a transform to the current element
|
|
*/
|
|
ctx.prototype.transform = function (a, b, c, d, e, f) {
|
|
this.__addTransform(format("matrix({a},{b},{c},{d},{e},{f})", { a: a, b: b, c: c, d: d, e: e, f: f }));
|
|
};
|
|
/**
|
|
* Create a new Path Element
|
|
*/
|
|
ctx.prototype.beginPath = function () {
|
|
var path, parent;
|
|
// Note that there is only one current default path, it is not part of the drawing state.
|
|
// See also: https://html.spec.whatwg.org/multipage/scripting.html#current-default-path
|
|
this.__currentDefaultPath = "";
|
|
this.__currentPosition = {};
|
|
path = this.__createElement("path", {}, true);
|
|
parent = this.__closestGroupOrSvg();
|
|
parent.appendChild(path);
|
|
this.__currentElement = path;
|
|
};
|
|
/**
|
|
* Helper function to apply currentDefaultPath to current path element
|
|
* @private
|
|
*/
|
|
ctx.prototype.__applyCurrentDefaultPath = function () {
|
|
var currentElement = this.__currentElement;
|
|
if (currentElement.nodeName === "path") {
|
|
currentElement.setAttribute("d", this.__currentDefaultPath);
|
|
}
|
|
else {
|
|
console.error("Attempted to apply path command to node", currentElement.nodeName);
|
|
}
|
|
};
|
|
/**
|
|
* Helper function to add path command
|
|
* @private
|
|
*/
|
|
ctx.prototype.__addPathCommand = function (command) {
|
|
this.__currentDefaultPath += " ";
|
|
this.__currentDefaultPath += command;
|
|
};
|
|
/**
|
|
* Adds the move command to the current path element,
|
|
* if the currentPathElement is not empty create a new path element
|
|
*/
|
|
ctx.prototype.moveTo = function (x, y) {
|
|
if (this.__currentElement.nodeName !== "path") {
|
|
this.beginPath();
|
|
}
|
|
// creates a new subpath with the given point
|
|
this.__currentPosition = { x: x, y: y };
|
|
this.__addPathCommand(format("M {x} {y}", { x: x, y: y }));
|
|
};
|
|
/**
|
|
* Closes the current path
|
|
*/
|
|
ctx.prototype.closePath = function () {
|
|
if (this.__currentDefaultPath) {
|
|
this.__addPathCommand("Z");
|
|
}
|
|
};
|
|
/**
|
|
* Adds a line to command
|
|
*/
|
|
ctx.prototype.lineTo = function (x, y) {
|
|
this.__currentPosition = { x: x, y: y };
|
|
if (this.__currentDefaultPath.indexOf('M') > -1) {
|
|
this.__addPathCommand(format("L {x} {y}", { x: x, y: y }));
|
|
}
|
|
else {
|
|
this.__addPathCommand(format("M {x} {y}", { x: x, y: y }));
|
|
}
|
|
};
|
|
/**
|
|
* Add a bezier command
|
|
*/
|
|
ctx.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {
|
|
this.__currentPosition = { x: x, y: y };
|
|
this.__addPathCommand(format("C {cp1x} {cp1y} {cp2x} {cp2y} {x} {y}", { cp1x: cp1x, cp1y: cp1y, cp2x: cp2x, cp2y: cp2y, x: x, y: y }));
|
|
};
|
|
/**
|
|
* Adds a quadratic curve to command
|
|
*/
|
|
ctx.prototype.quadraticCurveTo = function (cpx, cpy, x, y) {
|
|
this.__currentPosition = { x: x, y: y };
|
|
this.__addPathCommand(format("Q {cpx} {cpy} {x} {y}", { cpx: cpx, cpy: cpy, x: x, y: y }));
|
|
};
|
|
/**
|
|
* Return a new normalized vector of given vector
|
|
*/
|
|
var normalize = function (vector) {
|
|
var len = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]);
|
|
return [vector[0] / len, vector[1] / len];
|
|
};
|
|
/**
|
|
* Adds the arcTo to the current path
|
|
*
|
|
* @see http://www.w3.org/TR/2015/WD-2dcontext-20150514/#dom-context-2d-arcto
|
|
*/
|
|
ctx.prototype.arcTo = function (x1, y1, x2, y2, radius) {
|
|
// Let the point (x0, y0) be the last point in the subpath.
|
|
var x0 = this.__currentPosition && this.__currentPosition.x;
|
|
var y0 = this.__currentPosition && this.__currentPosition.y;
|
|
// First ensure there is a subpath for (x1, y1).
|
|
if (typeof x0 == "undefined" || typeof y0 == "undefined") {
|
|
return;
|
|
}
|
|
// Negative values for radius must cause the implementation to throw an IndexSizeError exception.
|
|
if (radius < 0) {
|
|
throw new Error("IndexSizeError: The radius provided (" + radius + ") is negative.");
|
|
}
|
|
// If the point (x0, y0) is equal to the point (x1, y1),
|
|
// or if the point (x1, y1) is equal to the point (x2, y2),
|
|
// or if the radius radius is zero,
|
|
// then the method must add the point (x1, y1) to the subpath,
|
|
// and connect that point to the previous point (x0, y0) by a straight line.
|
|
if (((x0 === x1) && (y0 === y1))
|
|
|| ((x1 === x2) && (y1 === y2))
|
|
|| (radius === 0)) {
|
|
this.lineTo(x1, y1);
|
|
return;
|
|
}
|
|
// Otherwise, if the points (x0, y0), (x1, y1), and (x2, y2) all lie on a single straight line,
|
|
// then the method must add the point (x1, y1) to the subpath,
|
|
// and connect that point to the previous point (x0, y0) by a straight line.
|
|
var unit_vec_p1_p0 = normalize([x0 - x1, y0 - y1]);
|
|
var unit_vec_p1_p2 = normalize([x2 - x1, y2 - y1]);
|
|
if (unit_vec_p1_p0[0] * unit_vec_p1_p2[1] === unit_vec_p1_p0[1] * unit_vec_p1_p2[0]) {
|
|
this.lineTo(x1, y1);
|
|
return;
|
|
}
|
|
// Otherwise, let The Arc be the shortest arc given by circumference of the circle that has radius radius,
|
|
// and that has one point tangent to the half-infinite line that crosses the point (x0, y0) and ends at the point (x1, y1),
|
|
// and that has a different point tangent to the half-infinite line that ends at the point (x1, y1), and crosses the point (x2, y2).
|
|
// The points at which this circle touches these two lines are called the start and end tangent points respectively.
|
|
// note that both vectors are unit vectors, so the length is 1
|
|
var cos = (unit_vec_p1_p0[0] * unit_vec_p1_p2[0] + unit_vec_p1_p0[1] * unit_vec_p1_p2[1]);
|
|
var theta = Math.acos(Math.abs(cos));
|
|
// Calculate origin
|
|
var unit_vec_p1_origin = normalize([
|
|
unit_vec_p1_p0[0] + unit_vec_p1_p2[0],
|
|
unit_vec_p1_p0[1] + unit_vec_p1_p2[1]
|
|
]);
|
|
var len_p1_origin = radius / Math.sin(theta / 2);
|
|
var x = x1 + len_p1_origin * unit_vec_p1_origin[0];
|
|
var y = y1 + len_p1_origin * unit_vec_p1_origin[1];
|
|
// Calculate start angle and end angle
|
|
// rotate 90deg clockwise (note that y axis points to its down)
|
|
var unit_vec_origin_start_tangent = [
|
|
-unit_vec_p1_p0[1],
|
|
unit_vec_p1_p0[0]
|
|
];
|
|
// rotate 90deg counter clockwise (note that y axis points to its down)
|
|
var unit_vec_origin_end_tangent = [
|
|
unit_vec_p1_p2[1],
|
|
-unit_vec_p1_p2[0]
|
|
];
|
|
var getAngle = function (vector) {
|
|
// get angle (clockwise) between vector and (1, 0)
|
|
var x = vector[0];
|
|
var y = vector[1];
|
|
if (y >= 0) { // note that y axis points to its down
|
|
return Math.acos(x);
|
|
}
|
|
else {
|
|
return -Math.acos(x);
|
|
}
|
|
};
|
|
var startAngle = getAngle(unit_vec_origin_start_tangent);
|
|
var endAngle = getAngle(unit_vec_origin_end_tangent);
|
|
// Connect the point (x0, y0) to the start tangent point by a straight line
|
|
this.lineTo(x + unit_vec_origin_start_tangent[0] * radius, y + unit_vec_origin_start_tangent[1] * radius);
|
|
// Connect the start tangent point to the end tangent point by arc
|
|
// and adding the end tangent point to the subpath.
|
|
this.arc(x, y, radius, startAngle, endAngle);
|
|
};
|
|
/**
|
|
* Sets the stroke property on the current element
|
|
*/
|
|
ctx.prototype.stroke = function () {
|
|
if (this.__currentElement.nodeName === "path") {
|
|
this.__currentElement.setAttribute("paint-order", "fill stroke markers");
|
|
}
|
|
this.__applyCurrentDefaultPath();
|
|
this.__applyStyleToCurrentElement("stroke");
|
|
};
|
|
/**
|
|
* Sets fill properties on the current element
|
|
*/
|
|
ctx.prototype.fill = function () {
|
|
if (this.__currentElement.nodeName === "path") {
|
|
this.__currentElement.setAttribute("paint-order", "stroke fill markers");
|
|
}
|
|
this.__applyCurrentDefaultPath();
|
|
this.__applyStyleToCurrentElement("fill");
|
|
};
|
|
/**
|
|
* Adds a rectangle to the path.
|
|
*/
|
|
ctx.prototype.rect = function (x, y, width, height) {
|
|
if (this.__currentElement.nodeName !== "path") {
|
|
this.beginPath();
|
|
}
|
|
this.moveTo(x, y);
|
|
this.lineTo(x + width, y);
|
|
this.lineTo(x + width, y + height);
|
|
this.lineTo(x, y + height);
|
|
this.lineTo(x, y);
|
|
this.closePath();
|
|
};
|
|
/**
|
|
* adds a rectangle element
|
|
*/
|
|
ctx.prototype.fillRect = function (x, y, width, height) {
|
|
var rect, parent;
|
|
rect = this.__createElement("rect", {
|
|
x: x,
|
|
y: y,
|
|
width: width,
|
|
height: height
|
|
}, true);
|
|
parent = this.__closestGroupOrSvg();
|
|
parent.appendChild(rect);
|
|
this.__currentElement = rect;
|
|
this.__applyStyleToCurrentElement("fill");
|
|
};
|
|
/**
|
|
* Draws a rectangle with no fill
|
|
* @param x
|
|
* @param y
|
|
* @param width
|
|
* @param height
|
|
*/
|
|
ctx.prototype.strokeRect = function (x, y, width, height) {
|
|
var rect, parent;
|
|
rect = this.__createElement("rect", {
|
|
x: x,
|
|
y: y,
|
|
width: width,
|
|
height: height
|
|
}, true);
|
|
parent = this.__closestGroupOrSvg();
|
|
parent.appendChild(rect);
|
|
this.__currentElement = rect;
|
|
this.__applyStyleToCurrentElement("stroke");
|
|
};
|
|
/**
|
|
* Clear entire canvas:
|
|
* 1. save current transforms
|
|
* 2. remove all the childNodes of the root g element
|
|
*/
|
|
ctx.prototype.__clearCanvas = function () {
|
|
var current = this.__closestGroupOrSvg(), transform = current.getAttribute("transform");
|
|
var rootGroup = this.__root.childNodes[1];
|
|
var childNodes = rootGroup.childNodes;
|
|
for (var i = childNodes.length - 1; i >= 0; i--) {
|
|
if (childNodes[i]) {
|
|
rootGroup.removeChild(childNodes[i]);
|
|
}
|
|
}
|
|
this.__currentElement = rootGroup;
|
|
//reset __groupStack as all the child group nodes are all removed.
|
|
this.__groupStack = [];
|
|
if (transform) {
|
|
this.__addTransform(transform);
|
|
}
|
|
};
|
|
/**
|
|
* "Clears" a canvas by just drawing a white rectangle in the current group.
|
|
*/
|
|
ctx.prototype.clearRect = function (x, y, width, height) {
|
|
//clear entire canvas
|
|
if (x === 0 && y === 0 && width === this.width && height === this.height) {
|
|
this.__clearCanvas();
|
|
return;
|
|
}
|
|
var rect, parent = this.__closestGroupOrSvg();
|
|
rect = this.__createElement("rect", {
|
|
x: x,
|
|
y: y,
|
|
width: width,
|
|
height: height,
|
|
fill: "#FFFFFF"
|
|
}, true);
|
|
parent.appendChild(rect);
|
|
};
|
|
/**
|
|
* Adds a linear gradient to a defs tag.
|
|
* Returns a canvas gradient object that has a reference to it's parent def
|
|
*/
|
|
ctx.prototype.createLinearGradient = function (x1, y1, x2, y2) {
|
|
var grad = this.__createElement("linearGradient", {
|
|
id: randomString(this.__ids),
|
|
x1: x1 + "px",
|
|
x2: x2 + "px",
|
|
y1: y1 + "px",
|
|
y2: y2 + "px",
|
|
"gradientUnits": "userSpaceOnUse"
|
|
}, false);
|
|
this.__defs.appendChild(grad);
|
|
return new CanvasGradient(grad, this);
|
|
};
|
|
/**
|
|
* Adds a radial gradient to a defs tag.
|
|
* Returns a canvas gradient object that has a reference to it's parent def
|
|
*/
|
|
ctx.prototype.createRadialGradient = function (x0, y0, r0, x1, y1, r1) {
|
|
var grad = this.__createElement("radialGradient", {
|
|
id: randomString(this.__ids),
|
|
cx: x1 + "px",
|
|
cy: y1 + "px",
|
|
r: r1 + "px",
|
|
fx: x0 + "px",
|
|
fy: y0 + "px",
|
|
"gradientUnits": "userSpaceOnUse"
|
|
}, false);
|
|
this.__defs.appendChild(grad);
|
|
return new CanvasGradient(grad, this);
|
|
};
|
|
/**
|
|
* Parses the font string and returns svg mapping
|
|
* @private
|
|
*/
|
|
ctx.prototype.__parseFont = function () {
|
|
var regex = /^\s*(?=(?:(?:[-a-z]+\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\1|\2|\3)\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\d]+(?:\%|in|[cem]m|ex|p[ctx]))(?:\s*\/\s*(normal|[.\d]+(?:\%|in|[cem]m|ex|p[ctx])))?\s*([-,\'\"\sa-z0-9]+?)\s*$/i;
|
|
var fontPart = regex.exec(this.font);
|
|
var data = {
|
|
style: fontPart[1] || 'normal',
|
|
size: fontPart[4] || '10px',
|
|
family: fontPart[6] || 'sans-serif',
|
|
weight: fontPart[3] || 'normal',
|
|
decoration: fontPart[2] || 'normal',
|
|
href: null
|
|
};
|
|
//canvas doesn't support underline natively, but we can pass this attribute
|
|
if (this.__fontUnderline === "underline") {
|
|
data.decoration = "underline";
|
|
}
|
|
//canvas also doesn't support linking, but we can pass this as well
|
|
if (this.__fontHref) {
|
|
data.href = this.__fontHref;
|
|
}
|
|
return data;
|
|
};
|
|
/**
|
|
* Helper to link text fragments
|
|
* @param font
|
|
* @param element
|
|
* @return {*}
|
|
* @private
|
|
*/
|
|
ctx.prototype.__wrapTextLink = function (font, element) {
|
|
if (font.href) {
|
|
var a = this.__createElement("a");
|
|
a.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", font.href);
|
|
a.appendChild(element);
|
|
return a;
|
|
}
|
|
return element;
|
|
};
|
|
/**
|
|
* Fills or strokes text
|
|
* @param text
|
|
* @param x
|
|
* @param y
|
|
* @param action - stroke or fill
|
|
* @private
|
|
*/
|
|
ctx.prototype.__applyText = function (text, x, y, action) {
|
|
var font = this.__parseFont(), parent = this.__closestGroupOrSvg(), textElement = this.__createElement("text", {
|
|
"font-family": font.family,
|
|
"font-size": font.size,
|
|
"font-style": font.style,
|
|
"font-weight": font.weight,
|
|
"text-decoration": font.decoration,
|
|
"x": x,
|
|
"y": y,
|
|
"text-anchor": getTextAnchor(this.textAlign),
|
|
"dominant-baseline": getDominantBaseline(this.textBaseline)
|
|
}, true);
|
|
textElement.appendChild(this.__document.createTextNode(text));
|
|
this.__currentElement = textElement;
|
|
this.__applyStyleToCurrentElement(action);
|
|
parent.appendChild(this.__wrapTextLink(font, textElement));
|
|
};
|
|
/**
|
|
* Creates a text element
|
|
* @param text
|
|
* @param x
|
|
* @param y
|
|
*/
|
|
ctx.prototype.fillText = function (text, x, y) {
|
|
this.__applyText(text, x, y, "fill");
|
|
};
|
|
/**
|
|
* Strokes text
|
|
* @param text
|
|
* @param x
|
|
* @param y
|
|
*/
|
|
ctx.prototype.strokeText = function (text, x, y) {
|
|
this.__applyText(text, x, y, "stroke");
|
|
};
|
|
/**
|
|
* No need to implement this for svg.
|
|
* @param text
|
|
* @return {TextMetrics}
|
|
*/
|
|
ctx.prototype.measureText = function (text) {
|
|
this.__ctx.font = this.font;
|
|
return this.__ctx.measureText(text);
|
|
};
|
|
/**
|
|
* Arc command!
|
|
*/
|
|
ctx.prototype.arc = function (x, y, radius, startAngle, endAngle, counterClockwise) {
|
|
// in canvas no circle is drawn if no angle is provided.
|
|
if (startAngle === endAngle) {
|
|
return;
|
|
}
|
|
startAngle = startAngle % (2 * Math.PI);
|
|
endAngle = endAngle % (2 * Math.PI);
|
|
if (startAngle === endAngle) {
|
|
//circle time! subtract some of the angle so svg is happy (svg elliptical arc can't draw a full circle)
|
|
endAngle = ((endAngle + (2 * Math.PI)) - 0.001 * (counterClockwise ? -1 : 1)) % (2 * Math.PI);
|
|
}
|
|
var endX = x + radius * Math.cos(endAngle), endY = y + radius * Math.sin(endAngle), startX = x + radius * Math.cos(startAngle), startY = y + radius * Math.sin(startAngle), sweepFlag = counterClockwise ? 0 : 1, largeArcFlag = 0, diff = endAngle - startAngle;
|
|
// https://github.com/gliffy/canvas2svg/issues/4
|
|
if (diff < 0) {
|
|
diff += 2 * Math.PI;
|
|
}
|
|
if (counterClockwise) {
|
|
largeArcFlag = diff > Math.PI ? 0 : 1;
|
|
}
|
|
else {
|
|
largeArcFlag = diff > Math.PI ? 1 : 0;
|
|
}
|
|
this.lineTo(startX, startY);
|
|
this.__addPathCommand(format("A {rx} {ry} {xAxisRotation} {largeArcFlag} {sweepFlag} {endX} {endY}", { rx: radius, ry: radius, xAxisRotation: 0, largeArcFlag: largeArcFlag, sweepFlag: sweepFlag, endX: endX, endY: endY }));
|
|
this.__currentPosition = { x: endX, y: endY };
|
|
};
|
|
/**
|
|
* Generates a ClipPath from the clip command.
|
|
*/
|
|
ctx.prototype.clip = function () {
|
|
var group = this.__closestGroupOrSvg(), clipPath = this.__createElement("clipPath"), id = randomString(this.__ids), newGroup = this.__createElement("g");
|
|
this.__applyCurrentDefaultPath();
|
|
group.removeChild(this.__currentElement);
|
|
clipPath.setAttribute("id", id);
|
|
clipPath.appendChild(this.__currentElement);
|
|
this.__defs.appendChild(clipPath);
|
|
//set the clip path to this group
|
|
group.setAttribute("clip-path", format("url(#{id})", { id: id }));
|
|
//clip paths can be scaled and transformed, we need to add another wrapper group to avoid later transformations
|
|
// to this path
|
|
group.appendChild(newGroup);
|
|
this.__currentElement = newGroup;
|
|
};
|
|
/**
|
|
* Draws a canvas, image or mock context to this canvas.
|
|
* Note that all svg dom manipulation uses node.childNodes rather than node.children for IE support.
|
|
* http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage
|
|
*/
|
|
ctx.prototype.drawImage = function () {
|
|
//convert arguments to a real array
|
|
var args = Array.prototype.slice.call(arguments), image = args[0], dx, dy, dw, dh, sx = 0, sy = 0, sw, sh, parent, svg, defs, group, currentElement, svgImage, canvas, context, id;
|
|
if (args.length === 3) {
|
|
dx = args[1];
|
|
dy = args[2];
|
|
sw = image.width;
|
|
sh = image.height;
|
|
dw = sw;
|
|
dh = sh;
|
|
}
|
|
else if (args.length === 5) {
|
|
dx = args[1];
|
|
dy = args[2];
|
|
dw = args[3];
|
|
dh = args[4];
|
|
sw = image.width;
|
|
sh = image.height;
|
|
}
|
|
else if (args.length === 9) {
|
|
sx = args[1];
|
|
sy = args[2];
|
|
sw = args[3];
|
|
sh = args[4];
|
|
dx = args[5];
|
|
dy = args[6];
|
|
dw = args[7];
|
|
dh = args[8];
|
|
}
|
|
else {
|
|
throw new Error("Inavlid number of arguments passed to drawImage: " + arguments.length);
|
|
}
|
|
parent = this.__closestGroupOrSvg();
|
|
currentElement = this.__currentElement;
|
|
var translateDirective = "translate(" + dx + ", " + dy + ")";
|
|
if (image instanceof ctx) {
|
|
//canvas2svg mock canvas context. In the future we may want to clone nodes instead.
|
|
//also I'm currently ignoring dw, dh, sw, sh, sx, sy for a mock context.
|
|
svg = image.getSvg().cloneNode(true);
|
|
if (svg.childNodes && svg.childNodes.length > 1) {
|
|
defs = svg.childNodes[0];
|
|
while (defs.childNodes.length) {
|
|
id = defs.childNodes[0].getAttribute("id");
|
|
this.__ids[id] = id;
|
|
this.__defs.appendChild(defs.childNodes[0]);
|
|
}
|
|
group = svg.childNodes[1];
|
|
if (group) {
|
|
//save original transform
|
|
var originTransform = group.getAttribute("transform");
|
|
var transformDirective;
|
|
if (originTransform) {
|
|
transformDirective = originTransform + " " + translateDirective;
|
|
}
|
|
else {
|
|
transformDirective = translateDirective;
|
|
}
|
|
group.setAttribute("transform", transformDirective);
|
|
parent.appendChild(group);
|
|
}
|
|
}
|
|
}
|
|
else if (image.nodeName === "IMG") {
|
|
svgImage = this.__createElement("image");
|
|
svgImage.setAttribute("width", dw);
|
|
svgImage.setAttribute("height", dh);
|
|
svgImage.setAttribute("preserveAspectRatio", "none");
|
|
if (sx || sy || sw !== image.width || sh !== image.height) {
|
|
//crop the image using a temporary canvas
|
|
canvas = this.__document.createElement("canvas");
|
|
canvas.width = dw;
|
|
canvas.height = dh;
|
|
context = canvas.getContext("2d");
|
|
context.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh);
|
|
image = canvas;
|
|
}
|
|
svgImage.setAttribute("transform", translateDirective);
|
|
svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src"));
|
|
parent.appendChild(svgImage);
|
|
}
|
|
else if (image.nodeName === "CANVAS") {
|
|
svgImage = this.__createElement("image");
|
|
svgImage.setAttribute("width", dw);
|
|
svgImage.setAttribute("height", dh);
|
|
svgImage.setAttribute("preserveAspectRatio", "none");
|
|
// draw canvas onto temporary canvas so that smoothing can be handled
|
|
canvas = this.__document.createElement("canvas");
|
|
canvas.width = dw;
|
|
canvas.height = dh;
|
|
context = canvas.getContext("2d");
|
|
context.imageSmoothingEnabled = false;
|
|
context.mozImageSmoothingEnabled = false;
|
|
context.oImageSmoothingEnabled = false;
|
|
context.webkitImageSmoothingEnabled = false;
|
|
context.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh);
|
|
image = canvas;
|
|
svgImage.setAttribute("transform", translateDirective);
|
|
svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", image.toDataURL());
|
|
parent.appendChild(svgImage);
|
|
}
|
|
};
|
|
/**
|
|
* Generates a pattern tag
|
|
*/
|
|
ctx.prototype.createPattern = function (image, repetition) {
|
|
var pattern = this.__document.createElementNS("http://www.w3.org/2000/svg", "pattern"), id = randomString(this.__ids), img;
|
|
pattern.setAttribute("id", id);
|
|
pattern.setAttribute("width", image.width);
|
|
pattern.setAttribute("height", image.height);
|
|
if (image.nodeName === "CANVAS" || image.nodeName === "IMG") {
|
|
img = this.__document.createElementNS("http://www.w3.org/2000/svg", "image");
|
|
img.setAttribute("width", image.width);
|
|
img.setAttribute("height", image.height);
|
|
img.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src"));
|
|
pattern.appendChild(img);
|
|
this.__defs.appendChild(pattern);
|
|
}
|
|
else if (image instanceof ctx) {
|
|
pattern.appendChild(image.__root.childNodes[1]);
|
|
this.__defs.appendChild(pattern);
|
|
}
|
|
return new CanvasPattern(pattern, this);
|
|
};
|
|
ctx.prototype.setLineDash = function (dashArray) {
|
|
if (dashArray && dashArray.length > 0) {
|
|
this.lineDash = dashArray.join(",");
|
|
}
|
|
else {
|
|
this.lineDash = null;
|
|
}
|
|
};
|
|
/**
|
|
* Not yet implemented
|
|
*/
|
|
ctx.prototype.drawFocusRing = function () { };
|
|
ctx.prototype.createImageData = function () { };
|
|
ctx.prototype.getImageData = function () { };
|
|
ctx.prototype.putImageData = function () { };
|
|
ctx.prototype.globalCompositeOperation = function () { };
|
|
ctx.prototype.setTransform = function () { };
|
|
//add options for alternative namespace
|
|
if (typeof window === "object") {
|
|
window.C2S = ctx;
|
|
}
|
|
// CommonJS/Browserify
|
|
if (typeof module === "object" && typeof module.exports === "object") {
|
|
module.exports = ctx;
|
|
}
|
|
}());
|
|
}
|
|
,
|
|
/* d/auto-bind */ function _(require, module, exports) {
|
|
var copy = require(321) /* es5-ext/object/copy */, normalizeOptions = require(331) /* es5-ext/object/normalize-options */, ensureCallable = require(336) /* es5-ext/object/valid-callable */, map = require(330) /* es5-ext/object/map */, callable = require(336) /* es5-ext/object/valid-callable */, validValue = require(338) /* es5-ext/object/valid-value */, bind = Function.prototype.bind, defineProperty = Object.defineProperty, hasOwnProperty = Object.prototype.hasOwnProperty, define;
|
|
define = function (name, desc, options) {
|
|
var value = validValue(desc) && callable(desc.value), dgs;
|
|
dgs = copy(desc);
|
|
delete dgs.writable;
|
|
delete dgs.value;
|
|
dgs.get = function () {
|
|
if (!options.overwriteDefinition && hasOwnProperty.call(this, name))
|
|
return value;
|
|
desc.value = bind.call(value, options.resolveContext ? options.resolveContext(this) : this);
|
|
defineProperty(this, name, desc);
|
|
return this[name];
|
|
};
|
|
return dgs;
|
|
};
|
|
module.exports = function (props /*, options*/) {
|
|
var options = normalizeOptions(arguments[1]);
|
|
if (options.resolveContext != null)
|
|
ensureCallable(options.resolveContext);
|
|
return map(props, function (desc, name) { return define(name, desc, options); });
|
|
};
|
|
}
|
|
,
|
|
/* d/index */ function _(require, module, exports) {
|
|
var assign = require(318) /* es5-ext/object/assign */, normalizeOpts = require(331) /* es5-ext/object/normalize-options */, isCallable = require(324) /* es5-ext/object/is-callable */, contains = require(339) /* es5-ext/string/#/contains */, d;
|
|
d = module.exports = function (dscr, value /*, options*/) {
|
|
var c, e, w, options, desc;
|
|
if ((arguments.length < 2) || (typeof dscr !== 'string')) {
|
|
options = value;
|
|
value = dscr;
|
|
dscr = null;
|
|
}
|
|
else {
|
|
options = arguments[2];
|
|
}
|
|
if (dscr == null) {
|
|
c = w = true;
|
|
e = false;
|
|
}
|
|
else {
|
|
c = contains.call(dscr, 'c');
|
|
e = contains.call(dscr, 'e');
|
|
w = contains.call(dscr, 'w');
|
|
}
|
|
desc = { value: value, configurable: c, enumerable: e, writable: w };
|
|
return !options ? desc : assign(normalizeOpts(options), desc);
|
|
};
|
|
d.gs = function (dscr, get, set /*, options*/) {
|
|
var c, e, options, desc;
|
|
if (typeof dscr !== 'string') {
|
|
options = set;
|
|
set = get;
|
|
get = dscr;
|
|
dscr = null;
|
|
}
|
|
else {
|
|
options = arguments[3];
|
|
}
|
|
if (get == null) {
|
|
get = undefined;
|
|
}
|
|
else if (!isCallable(get)) {
|
|
options = get;
|
|
get = set = undefined;
|
|
}
|
|
else if (set == null) {
|
|
set = undefined;
|
|
}
|
|
else if (!isCallable(set)) {
|
|
options = set;
|
|
set = undefined;
|
|
}
|
|
if (dscr == null) {
|
|
c = true;
|
|
e = false;
|
|
}
|
|
else {
|
|
c = contains.call(dscr, 'c');
|
|
e = contains.call(dscr, 'e');
|
|
}
|
|
desc = { get: get, set: set, configurable: c, enumerable: e };
|
|
return !options ? desc : assign(normalizeOpts(options), desc);
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/array/#/clear */ function _(require, module, exports) {
|
|
var value = require(338) /* ../../object/valid-value */;
|
|
module.exports = function () {
|
|
value(this).length = 0;
|
|
return this;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/array/#/e-index-of */ function _(require, module, exports) {
|
|
var numberIsNaN = require(312) /* ../../number/is-nan */, toPosInt = require(316) /* ../../number/to-pos-integer */, value = require(338) /* ../../object/valid-value */, indexOf = Array.prototype.indexOf, objHasOwnProperty = Object.prototype.hasOwnProperty, abs = Math.abs, floor = Math.floor;
|
|
module.exports = function (searchElement /*, fromIndex*/) {
|
|
var i, length, fromIndex, val;
|
|
if (!numberIsNaN(searchElement))
|
|
return indexOf.apply(this, arguments);
|
|
length = toPosInt(value(this).length);
|
|
fromIndex = arguments[1];
|
|
if (isNaN(fromIndex))
|
|
fromIndex = 0;
|
|
else if (fromIndex >= 0)
|
|
fromIndex = floor(fromIndex);
|
|
else
|
|
fromIndex = toPosInt(this.length) - floor(abs(fromIndex));
|
|
for (i = fromIndex; i < length; ++i) {
|
|
if (objHasOwnProperty.call(this, i)) {
|
|
val = this[i];
|
|
if (numberIsNaN(val))
|
|
return i; // Jslint: ignore
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/array/from/index */ function _(require, module, exports) {
|
|
module.exports = require(303) /* ./is-implemented */()
|
|
? Array.from
|
|
: require(304) /* ./shim */;
|
|
}
|
|
,
|
|
/* es5-ext/array/from/is-implemented */ function _(require, module, exports) {
|
|
module.exports = function () {
|
|
var from = Array.from, arr, result;
|
|
if (typeof from !== "function")
|
|
return false;
|
|
arr = ["raz", "dwa"];
|
|
result = from(arr);
|
|
return Boolean(result && (result !== arr) && (result[1] === "dwa"));
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/array/from/shim */ function _(require, module, exports) {
|
|
var iteratorSymbol = require(358) /* es6-symbol */.iterator, isArguments = require(305) /* ../../function/is-arguments */, isFunction = require(306) /* ../../function/is-function */, toPosInt = require(316) /* ../../number/to-pos-integer */, callable = require(336) /* ../../object/valid-callable */, validValue = require(338) /* ../../object/valid-value */, isValue = require(326) /* ../../object/is-value */, isString = require(342) /* ../../string/is-string */, isArray = Array.isArray, call = Function.prototype.call, desc = { configurable: true, enumerable: true, writable: true, value: null }, defineProperty = Object.defineProperty;
|
|
// eslint-disable-next-line complexity
|
|
module.exports = function (arrayLike /*, mapFn, thisArg*/) {
|
|
var mapFn = arguments[1], thisArg = arguments[2], Context, i, j, arr, length, code, iterator, result, getIterator, value;
|
|
arrayLike = Object(validValue(arrayLike));
|
|
if (isValue(mapFn))
|
|
callable(mapFn);
|
|
if (!this || this === Array || !isFunction(this)) {
|
|
// Result: Plain array
|
|
if (!mapFn) {
|
|
if (isArguments(arrayLike)) {
|
|
// Source: Arguments
|
|
length = arrayLike.length;
|
|
if (length !== 1)
|
|
return Array.apply(null, arrayLike);
|
|
arr = new Array(1);
|
|
arr[0] = arrayLike[0];
|
|
return arr;
|
|
}
|
|
if (isArray(arrayLike)) {
|
|
// Source: Array
|
|
arr = new Array(length = arrayLike.length);
|
|
for (i = 0; i < length; ++i)
|
|
arr[i] = arrayLike[i];
|
|
return arr;
|
|
}
|
|
}
|
|
arr = [];
|
|
}
|
|
else {
|
|
// Result: Non plain array
|
|
Context = this;
|
|
}
|
|
if (!isArray(arrayLike)) {
|
|
if ((getIterator = arrayLike[iteratorSymbol]) !== undefined) {
|
|
// Source: Iterator
|
|
iterator = callable(getIterator).call(arrayLike);
|
|
if (Context)
|
|
arr = new Context();
|
|
result = iterator.next();
|
|
i = 0;
|
|
while (!result.done) {
|
|
value = mapFn ? call.call(mapFn, thisArg, result.value, i) : result.value;
|
|
if (Context) {
|
|
desc.value = value;
|
|
defineProperty(arr, i, desc);
|
|
}
|
|
else {
|
|
arr[i] = value;
|
|
}
|
|
result = iterator.next();
|
|
++i;
|
|
}
|
|
length = i;
|
|
}
|
|
else if (isString(arrayLike)) {
|
|
// Source: String
|
|
length = arrayLike.length;
|
|
if (Context)
|
|
arr = new Context();
|
|
for (i = 0, j = 0; i < length; ++i) {
|
|
value = arrayLike[i];
|
|
if (i + 1 < length) {
|
|
code = value.charCodeAt(0);
|
|
// eslint-disable-next-line max-depth
|
|
if (code >= 0xd800 && code <= 0xdbff)
|
|
value += arrayLike[++i];
|
|
}
|
|
value = mapFn ? call.call(mapFn, thisArg, value, j) : value;
|
|
if (Context) {
|
|
desc.value = value;
|
|
defineProperty(arr, j, desc);
|
|
}
|
|
else {
|
|
arr[j] = value;
|
|
}
|
|
++j;
|
|
}
|
|
length = j;
|
|
}
|
|
}
|
|
if (length === undefined) {
|
|
// Source: array or array-like
|
|
length = toPosInt(arrayLike.length);
|
|
if (Context)
|
|
arr = new Context(length);
|
|
for (i = 0; i < length; ++i) {
|
|
value = mapFn ? call.call(mapFn, thisArg, arrayLike[i], i) : arrayLike[i];
|
|
if (Context) {
|
|
desc.value = value;
|
|
defineProperty(arr, i, desc);
|
|
}
|
|
else {
|
|
arr[i] = value;
|
|
}
|
|
}
|
|
}
|
|
if (Context) {
|
|
desc.value = null;
|
|
arr.length = length;
|
|
}
|
|
return arr;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/function/is-arguments */ function _(require, module, exports) {
|
|
var objToString = Object.prototype.toString, id = objToString.call((function () {
|
|
return arguments;
|
|
})());
|
|
module.exports = function (value) {
|
|
return objToString.call(value) === id;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/function/is-function */ function _(require, module, exports) {
|
|
var objToString = Object.prototype.toString, id = objToString.call(require(307) /* ./noop */);
|
|
module.exports = function (value) {
|
|
return typeof value === "function" && objToString.call(value) === id;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/function/noop */ function _(require, module, exports) {
|
|
// eslint-disable-next-line no-empty-function
|
|
module.exports = function () { };
|
|
}
|
|
,
|
|
/* es5-ext/global */ function _(require, module, exports) {
|
|
/* eslint strict: "off" */
|
|
module.exports = (function () {
|
|
return this;
|
|
}());
|
|
}
|
|
,
|
|
/* es5-ext/math/sign/index */ function _(require, module, exports) {
|
|
module.exports = require(310) /* ./is-implemented */()
|
|
? Math.sign
|
|
: require(311) /* ./shim */;
|
|
}
|
|
,
|
|
/* es5-ext/math/sign/is-implemented */ function _(require, module, exports) {
|
|
module.exports = function () {
|
|
var sign = Math.sign;
|
|
if (typeof sign !== "function")
|
|
return false;
|
|
return (sign(10) === 1) && (sign(-20) === -1);
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/math/sign/shim */ function _(require, module, exports) {
|
|
module.exports = function (value) {
|
|
value = Number(value);
|
|
if (isNaN(value) || (value === 0))
|
|
return value;
|
|
return value > 0 ? 1 : -1;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/number/is-nan/index */ function _(require, module, exports) {
|
|
module.exports = require(313) /* ./is-implemented */()
|
|
? Number.isNaN
|
|
: require(314) /* ./shim */;
|
|
}
|
|
,
|
|
/* es5-ext/number/is-nan/is-implemented */ function _(require, module, exports) {
|
|
module.exports = function () {
|
|
var numberIsNaN = Number.isNaN;
|
|
if (typeof numberIsNaN !== "function")
|
|
return false;
|
|
return !numberIsNaN({}) && numberIsNaN(NaN) && !numberIsNaN(34);
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/number/is-nan/shim */ function _(require, module, exports) {
|
|
module.exports = function (value) {
|
|
// eslint-disable-next-line no-self-compare
|
|
return value !== value;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/number/to-integer */ function _(require, module, exports) {
|
|
var sign = require(309) /* ../math/sign */, abs = Math.abs, floor = Math.floor;
|
|
module.exports = function (value) {
|
|
if (isNaN(value))
|
|
return 0;
|
|
value = Number(value);
|
|
if ((value === 0) || !isFinite(value))
|
|
return value;
|
|
return sign(value) * floor(abs(value));
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/number/to-pos-integer */ function _(require, module, exports) {
|
|
var toInteger = require(315) /* ./to-integer */, max = Math.max;
|
|
module.exports = function (value) {
|
|
return max(0, toInteger(value));
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/_iterate */ function _(require, module, exports) {
|
|
var callable = require(336) /* ./valid-callable */, value = require(338) /* ./valid-value */, bind = Function.prototype.bind, call = Function.prototype.call, keys = Object.keys, objPropertyIsEnumerable = Object.prototype.propertyIsEnumerable;
|
|
module.exports = function (method, defVal) {
|
|
return function (obj, cb /*, thisArg, compareFn*/) {
|
|
var list, thisArg = arguments[2], compareFn = arguments[3];
|
|
obj = Object(value(obj));
|
|
callable(cb);
|
|
list = keys(obj);
|
|
if (compareFn) {
|
|
list.sort(typeof compareFn === "function" ? bind.call(compareFn, obj) : undefined);
|
|
}
|
|
if (typeof method !== "function")
|
|
method = list[method];
|
|
return call.call(method, list, function (key, index) {
|
|
if (!objPropertyIsEnumerable.call(obj, key))
|
|
return defVal;
|
|
return call.call(cb, thisArg, obj[key], key, obj, index);
|
|
});
|
|
};
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/assign/index */ function _(require, module, exports) {
|
|
module.exports = require(319) /* ./is-implemented */()
|
|
? Object.assign
|
|
: require(320) /* ./shim */;
|
|
}
|
|
,
|
|
/* es5-ext/object/assign/is-implemented */ function _(require, module, exports) {
|
|
module.exports = function () {
|
|
var assign = Object.assign, obj;
|
|
if (typeof assign !== "function")
|
|
return false;
|
|
obj = { foo: "raz" };
|
|
assign(obj, { bar: "dwa" }, { trzy: "trzy" });
|
|
return (obj.foo + obj.bar + obj.trzy) === "razdwatrzy";
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/assign/shim */ function _(require, module, exports) {
|
|
var keys = require(327) /* ../keys */, value = require(338) /* ../valid-value */, max = Math.max;
|
|
module.exports = function (dest, src /*, …srcn*/) {
|
|
var error, i, length = max(arguments.length, 2), assign;
|
|
dest = Object(value(dest));
|
|
assign = function (key) {
|
|
try {
|
|
dest[key] = src[key];
|
|
}
|
|
catch (e) {
|
|
if (!error)
|
|
error = e;
|
|
}
|
|
};
|
|
for (i = 1; i < length; ++i) {
|
|
src = arguments[i];
|
|
keys(src).forEach(assign);
|
|
}
|
|
if (error !== undefined)
|
|
throw error;
|
|
return dest;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/copy */ function _(require, module, exports) {
|
|
var aFrom = require(302) /* ../array/from */, assign = require(318) /* ./assign */, value = require(338) /* ./valid-value */;
|
|
module.exports = function (obj /*, propertyNames, options*/) {
|
|
var copy = Object(value(obj)), propertyNames = arguments[1], options = Object(arguments[2]);
|
|
if (copy !== obj && !propertyNames)
|
|
return copy;
|
|
var result = {};
|
|
if (propertyNames) {
|
|
aFrom(propertyNames, function (propertyName) {
|
|
if (options.ensure || propertyName in obj)
|
|
result[propertyName] = obj[propertyName];
|
|
});
|
|
}
|
|
else {
|
|
assign(result, obj);
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/create */ function _(require, module, exports) {
|
|
var create = Object.create, shim;
|
|
if (!require(334) /* ./set-prototype-of/is-implemented */()) {
|
|
shim = require(335) /* ./set-prototype-of/shim */;
|
|
}
|
|
module.exports = (function () {
|
|
var nullObject, polyProps, desc;
|
|
if (!shim)
|
|
return create;
|
|
if (shim.level !== 1)
|
|
return create;
|
|
nullObject = {};
|
|
polyProps = {};
|
|
desc = {
|
|
configurable: false,
|
|
enumerable: false,
|
|
writable: true,
|
|
value: undefined
|
|
};
|
|
Object.getOwnPropertyNames(Object.prototype).forEach(function (name) {
|
|
if (name === "__proto__") {
|
|
polyProps[name] = {
|
|
configurable: true,
|
|
enumerable: false,
|
|
writable: true,
|
|
value: undefined
|
|
};
|
|
return;
|
|
}
|
|
polyProps[name] = desc;
|
|
});
|
|
Object.defineProperties(nullObject, polyProps);
|
|
Object.defineProperty(shim, "nullPolyfill", {
|
|
configurable: false,
|
|
enumerable: false,
|
|
writable: false,
|
|
value: nullObject
|
|
});
|
|
return function (prototype, props) {
|
|
return create(prototype === null ? nullObject : prototype, props);
|
|
};
|
|
}());
|
|
}
|
|
,
|
|
/* es5-ext/object/for-each */ function _(require, module, exports) {
|
|
module.exports = require(317) /* ./_iterate */("forEach");
|
|
}
|
|
,
|
|
/* es5-ext/object/is-callable */ function _(require, module, exports) {
|
|
module.exports = function (obj) {
|
|
return typeof obj === "function";
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/is-object */ function _(require, module, exports) {
|
|
var isValue = require(326) /* ./is-value */;
|
|
var map = { function: true, object: true };
|
|
module.exports = function (value) {
|
|
return (isValue(value) && map[typeof value]) || false;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/is-value */ function _(require, module, exports) {
|
|
var _undefined = require(307) /* ../function/noop */(); // Support ES3 engines
|
|
module.exports = function (val) {
|
|
return (val !== _undefined) && (val !== null);
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/keys/index */ function _(require, module, exports) {
|
|
module.exports = require(328) /* ./is-implemented */()
|
|
? Object.keys
|
|
: require(329) /* ./shim */;
|
|
}
|
|
,
|
|
/* es5-ext/object/keys/is-implemented */ function _(require, module, exports) {
|
|
module.exports = function () {
|
|
try {
|
|
Object.keys("primitive");
|
|
return true;
|
|
}
|
|
catch (e) {
|
|
return false;
|
|
}
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/keys/shim */ function _(require, module, exports) {
|
|
var isValue = require(326) /* ../is-value */;
|
|
var keys = Object.keys;
|
|
module.exports = function (object) {
|
|
return keys(isValue(object) ? Object(object) : object);
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/map */ function _(require, module, exports) {
|
|
var callable = require(336) /* ./valid-callable */, forEach = require(323) /* ./for-each */, call = Function.prototype.call;
|
|
module.exports = function (obj, cb /*, thisArg*/) {
|
|
var result = {}, thisArg = arguments[2];
|
|
callable(cb);
|
|
forEach(obj, function (value, key, targetObj, index) {
|
|
result[key] = call.call(cb, thisArg, value, key, targetObj, index);
|
|
});
|
|
return result;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/normalize-options */ function _(require, module, exports) {
|
|
var isValue = require(326) /* ./is-value */;
|
|
var forEach = Array.prototype.forEach, create = Object.create;
|
|
var process = function (src, obj) {
|
|
var key;
|
|
for (key in src)
|
|
obj[key] = src[key];
|
|
};
|
|
// eslint-disable-next-line no-unused-vars
|
|
module.exports = function (opts1 /*, …options*/) {
|
|
var result = create(null);
|
|
forEach.call(arguments, function (options) {
|
|
if (!isValue(options))
|
|
return;
|
|
process(Object(options), result);
|
|
});
|
|
return result;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/primitive-set */ function _(require, module, exports) {
|
|
var forEach = Array.prototype.forEach, create = Object.create;
|
|
// eslint-disable-next-line no-unused-vars
|
|
module.exports = function (arg /*, …args*/) {
|
|
var set = create(null);
|
|
forEach.call(arguments, function (name) {
|
|
set[name] = true;
|
|
});
|
|
return set;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/set-prototype-of/index */ function _(require, module, exports) {
|
|
module.exports = require(334) /* ./is-implemented */()
|
|
? Object.setPrototypeOf
|
|
: require(335) /* ./shim */;
|
|
}
|
|
,
|
|
/* es5-ext/object/set-prototype-of/is-implemented */ function _(require, module, exports) {
|
|
var create = Object.create, getPrototypeOf = Object.getPrototypeOf, plainObject = {};
|
|
module.exports = function ( /* CustomCreate*/) {
|
|
var setPrototypeOf = Object.setPrototypeOf, customCreate = arguments[0] || create;
|
|
if (typeof setPrototypeOf !== "function")
|
|
return false;
|
|
return getPrototypeOf(setPrototypeOf(customCreate(null), plainObject)) === plainObject;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/set-prototype-of/shim */ function _(require, module, exports) {
|
|
var isObject = require(325) /* ../is-object */, value = require(338) /* ../valid-value */, objIsPrototypeOf = Object.prototype.isPrototypeOf, defineProperty = Object.defineProperty, nullDesc = {
|
|
configurable: true,
|
|
enumerable: false,
|
|
writable: true,
|
|
value: undefined
|
|
}, validate;
|
|
validate = function (obj, prototype) {
|
|
value(obj);
|
|
if (prototype === null || isObject(prototype))
|
|
return obj;
|
|
throw new TypeError("Prototype must be null or an object");
|
|
};
|
|
module.exports = (function (status) {
|
|
var fn, set;
|
|
if (!status)
|
|
return null;
|
|
if (status.level === 2) {
|
|
if (status.set) {
|
|
set = status.set;
|
|
fn = function (obj, prototype) {
|
|
set.call(validate(obj, prototype), prototype);
|
|
return obj;
|
|
};
|
|
}
|
|
else {
|
|
fn = function (obj, prototype) {
|
|
validate(obj, prototype).__proto__ = prototype;
|
|
return obj;
|
|
};
|
|
}
|
|
}
|
|
else {
|
|
fn = function self(obj, prototype) {
|
|
var isNullBase;
|
|
validate(obj, prototype);
|
|
isNullBase = objIsPrototypeOf.call(self.nullPolyfill, obj);
|
|
if (isNullBase)
|
|
delete self.nullPolyfill.__proto__;
|
|
if (prototype === null)
|
|
prototype = self.nullPolyfill;
|
|
obj.__proto__ = prototype;
|
|
if (isNullBase)
|
|
defineProperty(self.nullPolyfill, "__proto__", nullDesc);
|
|
return obj;
|
|
};
|
|
}
|
|
return Object.defineProperty(fn, "level", {
|
|
configurable: false,
|
|
enumerable: false,
|
|
writable: false,
|
|
value: status.level
|
|
});
|
|
}((function () {
|
|
var tmpObj1 = Object.create(null), tmpObj2 = {}, set, desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
|
|
if (desc) {
|
|
try {
|
|
set = desc.set; // Opera crashes at this point
|
|
set.call(tmpObj1, tmpObj2);
|
|
}
|
|
catch (ignore) { }
|
|
if (Object.getPrototypeOf(tmpObj1) === tmpObj2)
|
|
return { set: set, level: 2 };
|
|
}
|
|
tmpObj1.__proto__ = tmpObj2;
|
|
if (Object.getPrototypeOf(tmpObj1) === tmpObj2)
|
|
return { level: 2 };
|
|
tmpObj1 = {};
|
|
tmpObj1.__proto__ = tmpObj2;
|
|
if (Object.getPrototypeOf(tmpObj1) === tmpObj2)
|
|
return { level: 1 };
|
|
return false;
|
|
})()));
|
|
require(322) /* ../create */;
|
|
}
|
|
,
|
|
/* es5-ext/object/valid-callable */ function _(require, module, exports) {
|
|
module.exports = function (fn) {
|
|
if (typeof fn !== "function")
|
|
throw new TypeError(fn + " is not a function");
|
|
return fn;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/valid-object */ function _(require, module, exports) {
|
|
var isObject = require(325) /* ./is-object */;
|
|
module.exports = function (value) {
|
|
if (!isObject(value))
|
|
throw new TypeError(value + " is not an Object");
|
|
return value;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/object/valid-value */ function _(require, module, exports) {
|
|
var isValue = require(326) /* ./is-value */;
|
|
module.exports = function (value) {
|
|
if (!isValue(value))
|
|
throw new TypeError("Cannot use null or undefined");
|
|
return value;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/string/#/contains/index */ function _(require, module, exports) {
|
|
module.exports = require(340) /* ./is-implemented */()
|
|
? String.prototype.contains
|
|
: require(341) /* ./shim */;
|
|
}
|
|
,
|
|
/* es5-ext/string/#/contains/is-implemented */ function _(require, module, exports) {
|
|
var str = "razdwatrzy";
|
|
module.exports = function () {
|
|
if (typeof str.contains !== "function")
|
|
return false;
|
|
return (str.contains("dwa") === true) && (str.contains("foo") === false);
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/string/#/contains/shim */ function _(require, module, exports) {
|
|
var indexOf = String.prototype.indexOf;
|
|
module.exports = function (searchString /*, position*/) {
|
|
return indexOf.call(this, searchString, arguments[1]) > -1;
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/string/is-string */ function _(require, module, exports) {
|
|
var objToString = Object.prototype.toString, id = objToString.call("");
|
|
module.exports = function (value) {
|
|
return (typeof value === "string" ||
|
|
(value &&
|
|
typeof value === "object" &&
|
|
(value instanceof String || objToString.call(value) === id)) ||
|
|
false);
|
|
};
|
|
}
|
|
,
|
|
/* es5-ext/string/random-uniq */ function _(require, module, exports) {
|
|
var generated = Object.create(null), random = Math.random;
|
|
module.exports = function () {
|
|
var str;
|
|
do {
|
|
str = random()
|
|
.toString(36)
|
|
.slice(2);
|
|
} while (generated[str]);
|
|
return str;
|
|
};
|
|
}
|
|
,
|
|
/* es6-iterator/array */ function _(require, module, exports) {
|
|
var setPrototypeOf = require(333) /* es5-ext/object/set-prototype-of */, contains = require(339) /* es5-ext/string/#/contains */, d = require(299) /* d */, Symbol = require(358) /* es6-symbol */, Iterator = require(347) /* ./ */;
|
|
var defineProperty = Object.defineProperty, ArrayIterator;
|
|
ArrayIterator = module.exports = function (arr, kind) {
|
|
if (!(this instanceof ArrayIterator))
|
|
throw new TypeError("Constructor requires 'new'");
|
|
Iterator.call(this, arr);
|
|
if (!kind)
|
|
kind = "value";
|
|
else if (contains.call(kind, "key+value"))
|
|
kind = "key+value";
|
|
else if (contains.call(kind, "key"))
|
|
kind = "key";
|
|
else
|
|
kind = "value";
|
|
defineProperty(this, "__kind__", d("", kind));
|
|
};
|
|
if (setPrototypeOf)
|
|
setPrototypeOf(ArrayIterator, Iterator);
|
|
// Internal %ArrayIteratorPrototype% doesn't expose its constructor
|
|
delete ArrayIterator.prototype.constructor;
|
|
ArrayIterator.prototype = Object.create(Iterator.prototype, {
|
|
_resolve: d(function (i) {
|
|
if (this.__kind__ === "value")
|
|
return this.__list__[i];
|
|
if (this.__kind__ === "key+value")
|
|
return [i, this.__list__[i]];
|
|
return i;
|
|
})
|
|
});
|
|
defineProperty(ArrayIterator.prototype, Symbol.toStringTag, d("c", "Array Iterator"));
|
|
}
|
|
,
|
|
/* es6-iterator/for-of */ function _(require, module, exports) {
|
|
var isArguments = require(305) /* es5-ext/function/is-arguments */, callable = require(336) /* es5-ext/object/valid-callable */, isString = require(342) /* es5-ext/string/is-string */, get = require(346) /* ./get */;
|
|
var isArray = Array.isArray, call = Function.prototype.call, some = Array.prototype.some;
|
|
module.exports = function (iterable, cb /*, thisArg*/) {
|
|
var mode, thisArg = arguments[2], result, doBreak, broken, i, length, char, code;
|
|
if (isArray(iterable) || isArguments(iterable))
|
|
mode = "array";
|
|
else if (isString(iterable))
|
|
mode = "string";
|
|
else
|
|
iterable = get(iterable);
|
|
callable(cb);
|
|
doBreak = function () {
|
|
broken = true;
|
|
};
|
|
if (mode === "array") {
|
|
some.call(iterable, function (value) {
|
|
call.call(cb, thisArg, value, doBreak);
|
|
return broken;
|
|
});
|
|
return;
|
|
}
|
|
if (mode === "string") {
|
|
length = iterable.length;
|
|
for (i = 0; i < length; ++i) {
|
|
char = iterable[i];
|
|
if (i + 1 < length) {
|
|
code = char.charCodeAt(0);
|
|
if (code >= 0xd800 && code <= 0xdbff)
|
|
char += iterable[++i];
|
|
}
|
|
call.call(cb, thisArg, char, doBreak);
|
|
if (broken)
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
result = iterable.next();
|
|
while (!result.done) {
|
|
call.call(cb, thisArg, result.value, doBreak);
|
|
if (broken)
|
|
return;
|
|
result = iterable.next();
|
|
}
|
|
};
|
|
}
|
|
,
|
|
/* es6-iterator/get */ function _(require, module, exports) {
|
|
var isArguments = require(305) /* es5-ext/function/is-arguments */, isString = require(342) /* es5-ext/string/is-string */, ArrayIterator = require(344) /* ./array */, StringIterator = require(349) /* ./string */, iterable = require(350) /* ./valid-iterable */, iteratorSymbol = require(358) /* es6-symbol */.iterator;
|
|
module.exports = function (obj) {
|
|
if (typeof iterable(obj)[iteratorSymbol] === "function")
|
|
return obj[iteratorSymbol]();
|
|
if (isArguments(obj))
|
|
return new ArrayIterator(obj);
|
|
if (isString(obj))
|
|
return new StringIterator(obj);
|
|
return new ArrayIterator(obj);
|
|
};
|
|
}
|
|
,
|
|
/* es6-iterator/index */ function _(require, module, exports) {
|
|
var clear = require(300) /* es5-ext/array/#/clear */, assign = require(318) /* es5-ext/object/assign */, callable = require(336) /* es5-ext/object/valid-callable */, value = require(338) /* es5-ext/object/valid-value */, d = require(299) /* d */, autoBind = require(298) /* d/auto-bind */, Symbol = require(358) /* es6-symbol */;
|
|
var defineProperty = Object.defineProperty, defineProperties = Object.defineProperties, Iterator;
|
|
module.exports = Iterator = function (list, context) {
|
|
if (!(this instanceof Iterator))
|
|
throw new TypeError("Constructor requires 'new'");
|
|
defineProperties(this, {
|
|
__list__: d("w", value(list)),
|
|
__context__: d("w", context),
|
|
__nextIndex__: d("w", 0)
|
|
});
|
|
if (!context)
|
|
return;
|
|
callable(context.on);
|
|
context.on("_add", this._onAdd);
|
|
context.on("_delete", this._onDelete);
|
|
context.on("_clear", this._onClear);
|
|
};
|
|
// Internal %IteratorPrototype% doesn't expose its constructor
|
|
delete Iterator.prototype.constructor;
|
|
defineProperties(Iterator.prototype, assign({
|
|
_next: d(function () {
|
|
var i;
|
|
if (!this.__list__)
|
|
return undefined;
|
|
if (this.__redo__) {
|
|
i = this.__redo__.shift();
|
|
if (i !== undefined)
|
|
return i;
|
|
}
|
|
if (this.__nextIndex__ < this.__list__.length)
|
|
return this.__nextIndex__++;
|
|
this._unBind();
|
|
return undefined;
|
|
}),
|
|
next: d(function () {
|
|
return this._createResult(this._next());
|
|
}),
|
|
_createResult: d(function (i) {
|
|
if (i === undefined)
|
|
return { done: true, value: undefined };
|
|
return { done: false, value: this._resolve(i) };
|
|
}),
|
|
_resolve: d(function (i) {
|
|
return this.__list__[i];
|
|
}),
|
|
_unBind: d(function () {
|
|
this.__list__ = null;
|
|
delete this.__redo__;
|
|
if (!this.__context__)
|
|
return;
|
|
this.__context__.off("_add", this._onAdd);
|
|
this.__context__.off("_delete", this._onDelete);
|
|
this.__context__.off("_clear", this._onClear);
|
|
this.__context__ = null;
|
|
}),
|
|
toString: d(function () {
|
|
return "[object " + (this[Symbol.toStringTag] || "Object") + "]";
|
|
})
|
|
}, autoBind({
|
|
_onAdd: d(function (index) {
|
|
if (index >= this.__nextIndex__)
|
|
return;
|
|
++this.__nextIndex__;
|
|
if (!this.__redo__) {
|
|
defineProperty(this, "__redo__", d("c", [index]));
|
|
return;
|
|
}
|
|
this.__redo__.forEach(function (redo, i) {
|
|
if (redo >= index)
|
|
this.__redo__[i] = ++redo;
|
|
}, this);
|
|
this.__redo__.push(index);
|
|
}),
|
|
_onDelete: d(function (index) {
|
|
var i;
|
|
if (index >= this.__nextIndex__)
|
|
return;
|
|
--this.__nextIndex__;
|
|
if (!this.__redo__)
|
|
return;
|
|
i = this.__redo__.indexOf(index);
|
|
if (i !== -1)
|
|
this.__redo__.splice(i, 1);
|
|
this.__redo__.forEach(function (redo, j) {
|
|
if (redo > index)
|
|
this.__redo__[j] = --redo;
|
|
}, this);
|
|
}),
|
|
_onClear: d(function () {
|
|
if (this.__redo__)
|
|
clear.call(this.__redo__);
|
|
this.__nextIndex__ = 0;
|
|
})
|
|
})));
|
|
defineProperty(Iterator.prototype, Symbol.iterator, d(function () {
|
|
return this;
|
|
}));
|
|
}
|
|
,
|
|
/* es6-iterator/is-iterable */ function _(require, module, exports) {
|
|
var isArguments = require(305) /* es5-ext/function/is-arguments */, isValue = require(326) /* es5-ext/object/is-value */, isString = require(342) /* es5-ext/string/is-string */;
|
|
var iteratorSymbol = require(358) /* es6-symbol */.iterator, isArray = Array.isArray;
|
|
module.exports = function (value) {
|
|
if (!isValue(value))
|
|
return false;
|
|
if (isArray(value))
|
|
return true;
|
|
if (isString(value))
|
|
return true;
|
|
if (isArguments(value))
|
|
return true;
|
|
return typeof value[iteratorSymbol] === "function";
|
|
};
|
|
}
|
|
,
|
|
/* es6-iterator/string */ function _(require, module, exports) {
|
|
var setPrototypeOf = require(333) /* es5-ext/object/set-prototype-of */, d = require(299) /* d */, Symbol = require(358) /* es6-symbol */, Iterator = require(347) /* ./ */;
|
|
var defineProperty = Object.defineProperty, StringIterator;
|
|
StringIterator = module.exports = function (str) {
|
|
if (!(this instanceof StringIterator))
|
|
throw new TypeError("Constructor requires 'new'");
|
|
str = String(str);
|
|
Iterator.call(this, str);
|
|
defineProperty(this, "__length__", d("", str.length));
|
|
};
|
|
if (setPrototypeOf)
|
|
setPrototypeOf(StringIterator, Iterator);
|
|
// Internal %ArrayIteratorPrototype% doesn't expose its constructor
|
|
delete StringIterator.prototype.constructor;
|
|
StringIterator.prototype = Object.create(Iterator.prototype, {
|
|
_next: d(function () {
|
|
if (!this.__list__)
|
|
return undefined;
|
|
if (this.__nextIndex__ < this.__length__)
|
|
return this.__nextIndex__++;
|
|
this._unBind();
|
|
return undefined;
|
|
}),
|
|
_resolve: d(function (i) {
|
|
var char = this.__list__[i], code;
|
|
if (this.__nextIndex__ === this.__length__)
|
|
return char;
|
|
code = char.charCodeAt(0);
|
|
if (code >= 0xd800 && code <= 0xdbff)
|
|
return char + this.__list__[this.__nextIndex__++];
|
|
return char;
|
|
})
|
|
});
|
|
defineProperty(StringIterator.prototype, Symbol.toStringTag, d("c", "String Iterator"));
|
|
}
|
|
,
|
|
/* es6-iterator/valid-iterable */ function _(require, module, exports) {
|
|
var isIterable = require(348) /* ./is-iterable */;
|
|
module.exports = function (value) {
|
|
if (!isIterable(value))
|
|
throw new TypeError(value + " is not iterable");
|
|
return value;
|
|
};
|
|
}
|
|
,
|
|
/* es6-map/implement */ function _(require, module, exports) {
|
|
if (!require(352) /* ./is-implemented */()) {
|
|
Object.defineProperty(require(308) /* es5-ext/global */, 'Map', { value: require(356) /* ./polyfill */, configurable: true, enumerable: false,
|
|
writable: true });
|
|
}
|
|
}
|
|
,
|
|
/* es6-map/is-implemented */ function _(require, module, exports) {
|
|
module.exports = function () {
|
|
var map, iterator, result;
|
|
if (typeof Map !== 'function')
|
|
return false;
|
|
try {
|
|
// WebKit doesn't support arguments and crashes
|
|
map = new Map([['raz', 'one'], ['dwa', 'two'], ['trzy', 'three']]);
|
|
}
|
|
catch (e) {
|
|
return false;
|
|
}
|
|
if (String(map) !== '[object Map]')
|
|
return false;
|
|
if (map.size !== 3)
|
|
return false;
|
|
if (typeof map.clear !== 'function')
|
|
return false;
|
|
if (typeof map.delete !== 'function')
|
|
return false;
|
|
if (typeof map.entries !== 'function')
|
|
return false;
|
|
if (typeof map.forEach !== 'function')
|
|
return false;
|
|
if (typeof map.get !== 'function')
|
|
return false;
|
|
if (typeof map.has !== 'function')
|
|
return false;
|
|
if (typeof map.keys !== 'function')
|
|
return false;
|
|
if (typeof map.set !== 'function')
|
|
return false;
|
|
if (typeof map.values !== 'function')
|
|
return false;
|
|
iterator = map.entries();
|
|
result = iterator.next();
|
|
if (result.done !== false)
|
|
return false;
|
|
if (!result.value)
|
|
return false;
|
|
if (result.value[0] !== 'raz')
|
|
return false;
|
|
if (result.value[1] !== 'one')
|
|
return false;
|
|
return true;
|
|
};
|
|
}
|
|
,
|
|
/* es6-map/is-native-implemented */ function _(require, module, exports) {
|
|
module.exports = (function () {
|
|
if (typeof Map === 'undefined')
|
|
return false;
|
|
return (Object.prototype.toString.call(new Map()) === '[object Map]');
|
|
}());
|
|
}
|
|
,
|
|
/* es6-map/lib/iterator-kinds */ function _(require, module, exports) {
|
|
module.exports = require(332) /* es5-ext/object/primitive-set */('key', 'value', 'key+value');
|
|
}
|
|
,
|
|
/* es6-map/lib/iterator */ function _(require, module, exports) {
|
|
var setPrototypeOf = require(333) /* es5-ext/object/set-prototype-of */, d = require(299) /* d */, Iterator = require(347) /* es6-iterator */, toStringTagSymbol = require(358) /* es6-symbol */.toStringTag, kinds = require(354) /* ./iterator-kinds */, defineProperties = Object.defineProperties, unBind = Iterator.prototype._unBind, MapIterator;
|
|
MapIterator = module.exports = function (map, kind) {
|
|
if (!(this instanceof MapIterator))
|
|
return new MapIterator(map, kind);
|
|
Iterator.call(this, map.__mapKeysData__, map);
|
|
if (!kind || !kinds[kind])
|
|
kind = 'key+value';
|
|
defineProperties(this, {
|
|
__kind__: d('', kind),
|
|
__values__: d('w', map.__mapValuesData__)
|
|
});
|
|
};
|
|
if (setPrototypeOf)
|
|
setPrototypeOf(MapIterator, Iterator);
|
|
MapIterator.prototype = Object.create(Iterator.prototype, {
|
|
constructor: d(MapIterator),
|
|
_resolve: d(function (i) {
|
|
if (this.__kind__ === 'value')
|
|
return this.__values__[i];
|
|
if (this.__kind__ === 'key')
|
|
return this.__list__[i];
|
|
return [this.__list__[i], this.__values__[i]];
|
|
}),
|
|
_unBind: d(function () {
|
|
this.__values__ = null;
|
|
unBind.call(this);
|
|
}),
|
|
toString: d(function () { return '[object Map Iterator]'; })
|
|
});
|
|
Object.defineProperty(MapIterator.prototype, toStringTagSymbol, d('c', 'Map Iterator'));
|
|
}
|
|
,
|
|
/* es6-map/polyfill */ function _(require, module, exports) {
|
|
var clear = require(300) /* es5-ext/array/#/clear */, eIndexOf = require(301) /* es5-ext/array/#/e-index-of */, setPrototypeOf = require(333) /* es5-ext/object/set-prototype-of */, callable = require(336) /* es5-ext/object/valid-callable */, validValue = require(338) /* es5-ext/object/valid-value */, d = require(299) /* d */, ee = require(367) /* event-emitter */, Symbol = require(358) /* es6-symbol */, iterator = require(350) /* es6-iterator/valid-iterable */, forOf = require(345) /* es6-iterator/for-of */, Iterator = require(355) /* ./lib/iterator */, isNative = require(353) /* ./is-native-implemented */, call = Function.prototype.call, defineProperties = Object.defineProperties, getPrototypeOf = Object.getPrototypeOf, MapPoly;
|
|
module.exports = MapPoly = function ( /*iterable*/) {
|
|
var iterable = arguments[0], keys, values, self;
|
|
if (!(this instanceof MapPoly))
|
|
throw new TypeError('Constructor requires \'new\'');
|
|
if (isNative && setPrototypeOf && (Map !== MapPoly)) {
|
|
self = setPrototypeOf(new Map(), getPrototypeOf(this));
|
|
}
|
|
else {
|
|
self = this;
|
|
}
|
|
if (iterable != null)
|
|
iterator(iterable);
|
|
defineProperties(self, {
|
|
__mapKeysData__: d('c', keys = []),
|
|
__mapValuesData__: d('c', values = [])
|
|
});
|
|
if (!iterable)
|
|
return self;
|
|
forOf(iterable, function (value) {
|
|
var key = validValue(value)[0];
|
|
value = value[1];
|
|
if (eIndexOf.call(keys, key) !== -1)
|
|
return;
|
|
keys.push(key);
|
|
values.push(value);
|
|
}, self);
|
|
return self;
|
|
};
|
|
if (isNative) {
|
|
if (setPrototypeOf)
|
|
setPrototypeOf(MapPoly, Map);
|
|
MapPoly.prototype = Object.create(Map.prototype, {
|
|
constructor: d(MapPoly)
|
|
});
|
|
}
|
|
ee(defineProperties(MapPoly.prototype, {
|
|
clear: d(function () {
|
|
if (!this.__mapKeysData__.length)
|
|
return;
|
|
clear.call(this.__mapKeysData__);
|
|
clear.call(this.__mapValuesData__);
|
|
this.emit('_clear');
|
|
}),
|
|
delete: d(function (key) {
|
|
var index = eIndexOf.call(this.__mapKeysData__, key);
|
|
if (index === -1)
|
|
return false;
|
|
this.__mapKeysData__.splice(index, 1);
|
|
this.__mapValuesData__.splice(index, 1);
|
|
this.emit('_delete', index, key);
|
|
return true;
|
|
}),
|
|
entries: d(function () { return new Iterator(this, 'key+value'); }),
|
|
forEach: d(function (cb /*, thisArg*/) {
|
|
var thisArg = arguments[1], iterator, result;
|
|
callable(cb);
|
|
iterator = this.entries();
|
|
result = iterator._next();
|
|
while (result !== undefined) {
|
|
call.call(cb, thisArg, this.__mapValuesData__[result], this.__mapKeysData__[result], this);
|
|
result = iterator._next();
|
|
}
|
|
}),
|
|
get: d(function (key) {
|
|
var index = eIndexOf.call(this.__mapKeysData__, key);
|
|
if (index === -1)
|
|
return;
|
|
return this.__mapValuesData__[index];
|
|
}),
|
|
has: d(function (key) {
|
|
return (eIndexOf.call(this.__mapKeysData__, key) !== -1);
|
|
}),
|
|
keys: d(function () { return new Iterator(this, 'key'); }),
|
|
set: d(function (key, value) {
|
|
var index = eIndexOf.call(this.__mapKeysData__, key), emit;
|
|
if (index === -1) {
|
|
index = this.__mapKeysData__.push(key) - 1;
|
|
emit = true;
|
|
}
|
|
this.__mapValuesData__[index] = value;
|
|
if (emit)
|
|
this.emit('_add', index, key);
|
|
return this;
|
|
}),
|
|
size: d.gs(function () { return this.__mapKeysData__.length; }),
|
|
values: d(function () { return new Iterator(this, 'value'); }),
|
|
toString: d(function () { return '[object Map]'; })
|
|
}));
|
|
Object.defineProperty(MapPoly.prototype, Symbol.iterator, d(function () {
|
|
return this.entries();
|
|
}));
|
|
Object.defineProperty(MapPoly.prototype, Symbol.toStringTag, d('c', 'Map'));
|
|
}
|
|
,
|
|
/* es6-promise/dist/es6-promise */ function _(require, module, exports) {
|
|
/*!
|
|
* @overview es6-promise - a tiny implementation of Promises/A+.
|
|
* @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
|
|
* @license Licensed under MIT license
|
|
* See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE
|
|
* @version v4.2.6+9869a4bc
|
|
*/
|
|
(function (global, factory) {
|
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
typeof define === 'function' && define.amd ? define(factory) :
|
|
(global.ES6Promise = factory());
|
|
}(this, (function () {
|
|
'use strict';
|
|
function objectOrFunction(x) {
|
|
var type = typeof x;
|
|
return x !== null && (type === 'object' || type === 'function');
|
|
}
|
|
function isFunction(x) {
|
|
return typeof x === 'function';
|
|
}
|
|
var _isArray = void 0;
|
|
if (Array.isArray) {
|
|
_isArray = Array.isArray;
|
|
}
|
|
else {
|
|
_isArray = function (x) {
|
|
return Object.prototype.toString.call(x) === '[object Array]';
|
|
};
|
|
}
|
|
var isArray = _isArray;
|
|
var len = 0;
|
|
var vertxNext = void 0;
|
|
var customSchedulerFn = void 0;
|
|
var asap = function asap(callback, arg) {
|
|
queue[len] = callback;
|
|
queue[len + 1] = arg;
|
|
len += 2;
|
|
if (len === 2) {
|
|
// If len is 2, that means that we need to schedule an async flush.
|
|
// If additional callbacks are queued before the queue is flushed, they
|
|
// will be processed by this flush that we are scheduling.
|
|
if (customSchedulerFn) {
|
|
customSchedulerFn(flush);
|
|
}
|
|
else {
|
|
scheduleFlush();
|
|
}
|
|
}
|
|
};
|
|
function setScheduler(scheduleFn) {
|
|
customSchedulerFn = scheduleFn;
|
|
}
|
|
function setAsap(asapFn) {
|
|
asap = asapFn;
|
|
}
|
|
var browserWindow = typeof window !== 'undefined' ? window : undefined;
|
|
var browserGlobal = browserWindow || {};
|
|
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
|
|
var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
|
|
// test for web worker but not in IE10
|
|
var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
|
|
// node
|
|
function useNextTick() {
|
|
// node version 0.10.x displays a deprecation warning when nextTick is used recursively
|
|
// see https://github.com/cujojs/when/issues/410 for details
|
|
return function () {
|
|
return process.nextTick(flush);
|
|
};
|
|
}
|
|
// vertx
|
|
function useVertxTimer() {
|
|
if (typeof vertxNext !== 'undefined') {
|
|
return function () {
|
|
vertxNext(flush);
|
|
};
|
|
}
|
|
return useSetTimeout();
|
|
}
|
|
function useMutationObserver() {
|
|
var iterations = 0;
|
|
var observer = new BrowserMutationObserver(flush);
|
|
var node = document.createTextNode('');
|
|
observer.observe(node, { characterData: true });
|
|
return function () {
|
|
node.data = iterations = ++iterations % 2;
|
|
};
|
|
}
|
|
// web worker
|
|
function useMessageChannel() {
|
|
var channel = new MessageChannel();
|
|
channel.port1.onmessage = flush;
|
|
return function () {
|
|
return channel.port2.postMessage(0);
|
|
};
|
|
}
|
|
function useSetTimeout() {
|
|
// Store setTimeout reference so es6-promise will be unaffected by
|
|
// other code modifying setTimeout (like sinon.useFakeTimers())
|
|
var globalSetTimeout = setTimeout;
|
|
return function () {
|
|
return globalSetTimeout(flush, 1);
|
|
};
|
|
}
|
|
var queue = new Array(1000);
|
|
function flush() {
|
|
for (var i = 0; i < len; i += 2) {
|
|
var callback = queue[i];
|
|
var arg = queue[i + 1];
|
|
callback(arg);
|
|
queue[i] = undefined;
|
|
queue[i + 1] = undefined;
|
|
}
|
|
len = 0;
|
|
}
|
|
function attemptVertx() {
|
|
try {
|
|
var vertx = Function('return this')().require('vertx');
|
|
vertxNext = vertx.runOnLoop || vertx.runOnContext;
|
|
return useVertxTimer();
|
|
}
|
|
catch (e) {
|
|
return useSetTimeout();
|
|
}
|
|
}
|
|
var scheduleFlush = void 0;
|
|
// Decide what async method to use to triggering processing of queued callbacks:
|
|
if (isNode) {
|
|
scheduleFlush = useNextTick();
|
|
}
|
|
else if (BrowserMutationObserver) {
|
|
scheduleFlush = useMutationObserver();
|
|
}
|
|
else if (isWorker) {
|
|
scheduleFlush = useMessageChannel();
|
|
}
|
|
else if (browserWindow === undefined && typeof require === 'function') {
|
|
scheduleFlush = attemptVertx();
|
|
}
|
|
else {
|
|
scheduleFlush = useSetTimeout();
|
|
}
|
|
function then(onFulfillment, onRejection) {
|
|
var parent = this;
|
|
var child = new this.constructor(noop);
|
|
if (child[PROMISE_ID] === undefined) {
|
|
makePromise(child);
|
|
}
|
|
var _state = parent._state;
|
|
if (_state) {
|
|
var callback = arguments[_state - 1];
|
|
asap(function () {
|
|
return invokeCallback(_state, child, callback, parent._result);
|
|
});
|
|
}
|
|
else {
|
|
subscribe(parent, child, onFulfillment, onRejection);
|
|
}
|
|
return child;
|
|
}
|
|
/**
|
|
`Promise.resolve` returns a promise that will become resolved with the
|
|
passed `value`. It is shorthand for the following:
|
|
|
|
```javascript
|
|
let promise = new Promise(function(resolve, reject){
|
|
resolve(1);
|
|
});
|
|
|
|
promise.then(function(value){
|
|
// value === 1
|
|
});
|
|
```
|
|
|
|
Instead of writing the above, your code now simply becomes the following:
|
|
|
|
```javascript
|
|
let promise = Promise.resolve(1);
|
|
|
|
promise.then(function(value){
|
|
// value === 1
|
|
});
|
|
```
|
|
|
|
@method resolve
|
|
@static
|
|
@param {Any} value value that the returned promise will be resolved with
|
|
Useful for tooling.
|
|
@return {Promise} a promise that will become fulfilled with the given
|
|
`value`
|
|
*/
|
|
function resolve$1(object) {
|
|
/*jshint validthis:true */
|
|
var Constructor = this;
|
|
if (object && typeof object === 'object' && object.constructor === Constructor) {
|
|
return object;
|
|
}
|
|
var promise = new Constructor(noop);
|
|
resolve(promise, object);
|
|
return promise;
|
|
}
|
|
var PROMISE_ID = Math.random().toString(36).substring(2);
|
|
function noop() { }
|
|
var PENDING = void 0;
|
|
var FULFILLED = 1;
|
|
var REJECTED = 2;
|
|
var TRY_CATCH_ERROR = { error: null };
|
|
function selfFulfillment() {
|
|
return new TypeError("You cannot resolve a promise with itself");
|
|
}
|
|
function cannotReturnOwn() {
|
|
return new TypeError('A promises callback cannot return that same promise.');
|
|
}
|
|
function getThen(promise) {
|
|
try {
|
|
return promise.then;
|
|
}
|
|
catch (error) {
|
|
TRY_CATCH_ERROR.error = error;
|
|
return TRY_CATCH_ERROR;
|
|
}
|
|
}
|
|
function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) {
|
|
try {
|
|
then$$1.call(value, fulfillmentHandler, rejectionHandler);
|
|
}
|
|
catch (e) {
|
|
return e;
|
|
}
|
|
}
|
|
function handleForeignThenable(promise, thenable, then$$1) {
|
|
asap(function (promise) {
|
|
var sealed = false;
|
|
var error = tryThen(then$$1, thenable, function (value) {
|
|
if (sealed) {
|
|
return;
|
|
}
|
|
sealed = true;
|
|
if (thenable !== value) {
|
|
resolve(promise, value);
|
|
}
|
|
else {
|
|
fulfill(promise, value);
|
|
}
|
|
}, function (reason) {
|
|
if (sealed) {
|
|
return;
|
|
}
|
|
sealed = true;
|
|
reject(promise, reason);
|
|
}, 'Settle: ' + (promise._label || ' unknown promise'));
|
|
if (!sealed && error) {
|
|
sealed = true;
|
|
reject(promise, error);
|
|
}
|
|
}, promise);
|
|
}
|
|
function handleOwnThenable(promise, thenable) {
|
|
if (thenable._state === FULFILLED) {
|
|
fulfill(promise, thenable._result);
|
|
}
|
|
else if (thenable._state === REJECTED) {
|
|
reject(promise, thenable._result);
|
|
}
|
|
else {
|
|
subscribe(thenable, undefined, function (value) {
|
|
return resolve(promise, value);
|
|
}, function (reason) {
|
|
return reject(promise, reason);
|
|
});
|
|
}
|
|
}
|
|
function handleMaybeThenable(promise, maybeThenable, then$$1) {
|
|
if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) {
|
|
handleOwnThenable(promise, maybeThenable);
|
|
}
|
|
else {
|
|
if (then$$1 === TRY_CATCH_ERROR) {
|
|
reject(promise, TRY_CATCH_ERROR.error);
|
|
TRY_CATCH_ERROR.error = null;
|
|
}
|
|
else if (then$$1 === undefined) {
|
|
fulfill(promise, maybeThenable);
|
|
}
|
|
else if (isFunction(then$$1)) {
|
|
handleForeignThenable(promise, maybeThenable, then$$1);
|
|
}
|
|
else {
|
|
fulfill(promise, maybeThenable);
|
|
}
|
|
}
|
|
}
|
|
function resolve(promise, value) {
|
|
if (promise === value) {
|
|
reject(promise, selfFulfillment());
|
|
}
|
|
else if (objectOrFunction(value)) {
|
|
handleMaybeThenable(promise, value, getThen(value));
|
|
}
|
|
else {
|
|
fulfill(promise, value);
|
|
}
|
|
}
|
|
function publishRejection(promise) {
|
|
if (promise._onerror) {
|
|
promise._onerror(promise._result);
|
|
}
|
|
publish(promise);
|
|
}
|
|
function fulfill(promise, value) {
|
|
if (promise._state !== PENDING) {
|
|
return;
|
|
}
|
|
promise._result = value;
|
|
promise._state = FULFILLED;
|
|
if (promise._subscribers.length !== 0) {
|
|
asap(publish, promise);
|
|
}
|
|
}
|
|
function reject(promise, reason) {
|
|
if (promise._state !== PENDING) {
|
|
return;
|
|
}
|
|
promise._state = REJECTED;
|
|
promise._result = reason;
|
|
asap(publishRejection, promise);
|
|
}
|
|
function subscribe(parent, child, onFulfillment, onRejection) {
|
|
var _subscribers = parent._subscribers;
|
|
var length = _subscribers.length;
|
|
parent._onerror = null;
|
|
_subscribers[length] = child;
|
|
_subscribers[length + FULFILLED] = onFulfillment;
|
|
_subscribers[length + REJECTED] = onRejection;
|
|
if (length === 0 && parent._state) {
|
|
asap(publish, parent);
|
|
}
|
|
}
|
|
function publish(promise) {
|
|
var subscribers = promise._subscribers;
|
|
var settled = promise._state;
|
|
if (subscribers.length === 0) {
|
|
return;
|
|
}
|
|
var child = void 0, callback = void 0, detail = promise._result;
|
|
for (var i = 0; i < subscribers.length; i += 3) {
|
|
child = subscribers[i];
|
|
callback = subscribers[i + settled];
|
|
if (child) {
|
|
invokeCallback(settled, child, callback, detail);
|
|
}
|
|
else {
|
|
callback(detail);
|
|
}
|
|
}
|
|
promise._subscribers.length = 0;
|
|
}
|
|
function tryCatch(callback, detail) {
|
|
try {
|
|
return callback(detail);
|
|
}
|
|
catch (e) {
|
|
TRY_CATCH_ERROR.error = e;
|
|
return TRY_CATCH_ERROR;
|
|
}
|
|
}
|
|
function invokeCallback(settled, promise, callback, detail) {
|
|
var hasCallback = isFunction(callback), value = void 0, error = void 0, succeeded = void 0, failed = void 0;
|
|
if (hasCallback) {
|
|
value = tryCatch(callback, detail);
|
|
if (value === TRY_CATCH_ERROR) {
|
|
failed = true;
|
|
error = value.error;
|
|
value.error = null;
|
|
}
|
|
else {
|
|
succeeded = true;
|
|
}
|
|
if (promise === value) {
|
|
reject(promise, cannotReturnOwn());
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
value = detail;
|
|
succeeded = true;
|
|
}
|
|
if (promise._state !== PENDING) {
|
|
// noop
|
|
}
|
|
else if (hasCallback && succeeded) {
|
|
resolve(promise, value);
|
|
}
|
|
else if (failed) {
|
|
reject(promise, error);
|
|
}
|
|
else if (settled === FULFILLED) {
|
|
fulfill(promise, value);
|
|
}
|
|
else if (settled === REJECTED) {
|
|
reject(promise, value);
|
|
}
|
|
}
|
|
function initializePromise(promise, resolver) {
|
|
try {
|
|
resolver(function resolvePromise(value) {
|
|
resolve(promise, value);
|
|
}, function rejectPromise(reason) {
|
|
reject(promise, reason);
|
|
});
|
|
}
|
|
catch (e) {
|
|
reject(promise, e);
|
|
}
|
|
}
|
|
var id = 0;
|
|
function nextId() {
|
|
return id++;
|
|
}
|
|
function makePromise(promise) {
|
|
promise[PROMISE_ID] = id++;
|
|
promise._state = undefined;
|
|
promise._result = undefined;
|
|
promise._subscribers = [];
|
|
}
|
|
function validationError() {
|
|
return new Error('Array Methods must be provided an Array');
|
|
}
|
|
var Enumerator = function () {
|
|
function Enumerator(Constructor, input) {
|
|
this._instanceConstructor = Constructor;
|
|
this.promise = new Constructor(noop);
|
|
if (!this.promise[PROMISE_ID]) {
|
|
makePromise(this.promise);
|
|
}
|
|
if (isArray(input)) {
|
|
this.length = input.length;
|
|
this._remaining = input.length;
|
|
this._result = new Array(this.length);
|
|
if (this.length === 0) {
|
|
fulfill(this.promise, this._result);
|
|
}
|
|
else {
|
|
this.length = this.length || 0;
|
|
this._enumerate(input);
|
|
if (this._remaining === 0) {
|
|
fulfill(this.promise, this._result);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
reject(this.promise, validationError());
|
|
}
|
|
}
|
|
Enumerator.prototype._enumerate = function _enumerate(input) {
|
|
for (var i = 0; this._state === PENDING && i < input.length; i++) {
|
|
this._eachEntry(input[i], i);
|
|
}
|
|
};
|
|
Enumerator.prototype._eachEntry = function _eachEntry(entry, i) {
|
|
var c = this._instanceConstructor;
|
|
var resolve$$1 = c.resolve;
|
|
if (resolve$$1 === resolve$1) {
|
|
var _then = getThen(entry);
|
|
if (_then === then && entry._state !== PENDING) {
|
|
this._settledAt(entry._state, i, entry._result);
|
|
}
|
|
else if (typeof _then !== 'function') {
|
|
this._remaining--;
|
|
this._result[i] = entry;
|
|
}
|
|
else if (c === Promise$1) {
|
|
var promise = new c(noop);
|
|
handleMaybeThenable(promise, entry, _then);
|
|
this._willSettleAt(promise, i);
|
|
}
|
|
else {
|
|
this._willSettleAt(new c(function (resolve$$1) {
|
|
return resolve$$1(entry);
|
|
}), i);
|
|
}
|
|
}
|
|
else {
|
|
this._willSettleAt(resolve$$1(entry), i);
|
|
}
|
|
};
|
|
Enumerator.prototype._settledAt = function _settledAt(state, i, value) {
|
|
var promise = this.promise;
|
|
if (promise._state === PENDING) {
|
|
this._remaining--;
|
|
if (state === REJECTED) {
|
|
reject(promise, value);
|
|
}
|
|
else {
|
|
this._result[i] = value;
|
|
}
|
|
}
|
|
if (this._remaining === 0) {
|
|
fulfill(promise, this._result);
|
|
}
|
|
};
|
|
Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) {
|
|
var enumerator = this;
|
|
subscribe(promise, undefined, function (value) {
|
|
return enumerator._settledAt(FULFILLED, i, value);
|
|
}, function (reason) {
|
|
return enumerator._settledAt(REJECTED, i, reason);
|
|
});
|
|
};
|
|
return Enumerator;
|
|
}();
|
|
/**
|
|
`Promise.all` accepts an array of promises, and returns a new promise which
|
|
is fulfilled with an array of fulfillment values for the passed promises, or
|
|
rejected with the reason of the first passed promise to be rejected. It casts all
|
|
elements of the passed iterable to promises as it runs this algorithm.
|
|
|
|
Example:
|
|
|
|
```javascript
|
|
let promise1 = resolve(1);
|
|
let promise2 = resolve(2);
|
|
let promise3 = resolve(3);
|
|
let promises = [ promise1, promise2, promise3 ];
|
|
|
|
Promise.all(promises).then(function(array){
|
|
// The array here would be [ 1, 2, 3 ];
|
|
});
|
|
```
|
|
|
|
If any of the `promises` given to `all` are rejected, the first promise
|
|
that is rejected will be given as an argument to the returned promises's
|
|
rejection handler. For example:
|
|
|
|
Example:
|
|
|
|
```javascript
|
|
let promise1 = resolve(1);
|
|
let promise2 = reject(new Error("2"));
|
|
let promise3 = reject(new Error("3"));
|
|
let promises = [ promise1, promise2, promise3 ];
|
|
|
|
Promise.all(promises).then(function(array){
|
|
// Code here never runs because there are rejected promises!
|
|
}, function(error) {
|
|
// error.message === "2"
|
|
});
|
|
```
|
|
|
|
@method all
|
|
@static
|
|
@param {Array} entries array of promises
|
|
@param {String} label optional string for labeling the promise.
|
|
Useful for tooling.
|
|
@return {Promise} promise that is fulfilled when all `promises` have been
|
|
fulfilled, or rejected if any of them become rejected.
|
|
@static
|
|
*/
|
|
function all(entries) {
|
|
return new Enumerator(this, entries).promise;
|
|
}
|
|
/**
|
|
`Promise.race` returns a new promise which is settled in the same way as the
|
|
first passed promise to settle.
|
|
|
|
Example:
|
|
|
|
```javascript
|
|
let promise1 = new Promise(function(resolve, reject){
|
|
setTimeout(function(){
|
|
resolve('promise 1');
|
|
}, 200);
|
|
});
|
|
|
|
let promise2 = new Promise(function(resolve, reject){
|
|
setTimeout(function(){
|
|
resolve('promise 2');
|
|
}, 100);
|
|
});
|
|
|
|
Promise.race([promise1, promise2]).then(function(result){
|
|
// result === 'promise 2' because it was resolved before promise1
|
|
// was resolved.
|
|
});
|
|
```
|
|
|
|
`Promise.race` is deterministic in that only the state of the first
|
|
settled promise matters. For example, even if other promises given to the
|
|
`promises` array argument are resolved, but the first settled promise has
|
|
become rejected before the other promises became fulfilled, the returned
|
|
promise will become rejected:
|
|
|
|
```javascript
|
|
let promise1 = new Promise(function(resolve, reject){
|
|
setTimeout(function(){
|
|
resolve('promise 1');
|
|
}, 200);
|
|
});
|
|
|
|
let promise2 = new Promise(function(resolve, reject){
|
|
setTimeout(function(){
|
|
reject(new Error('promise 2'));
|
|
}, 100);
|
|
});
|
|
|
|
Promise.race([promise1, promise2]).then(function(result){
|
|
// Code here never runs
|
|
}, function(reason){
|
|
// reason.message === 'promise 2' because promise 2 became rejected before
|
|
// promise 1 became fulfilled
|
|
});
|
|
```
|
|
|
|
An example real-world use case is implementing timeouts:
|
|
|
|
```javascript
|
|
Promise.race([ajax('foo.json'), timeout(5000)])
|
|
```
|
|
|
|
@method race
|
|
@static
|
|
@param {Array} promises array of promises to observe
|
|
Useful for tooling.
|
|
@return {Promise} a promise which settles in the same way as the first passed
|
|
promise to settle.
|
|
*/
|
|
function race(entries) {
|
|
/*jshint validthis:true */
|
|
var Constructor = this;
|
|
if (!isArray(entries)) {
|
|
return new Constructor(function (_, reject) {
|
|
return reject(new TypeError('You must pass an array to race.'));
|
|
});
|
|
}
|
|
else {
|
|
return new Constructor(function (resolve, reject) {
|
|
var length = entries.length;
|
|
for (var i = 0; i < length; i++) {
|
|
Constructor.resolve(entries[i]).then(resolve, reject);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
/**
|
|
`Promise.reject` returns a promise rejected with the passed `reason`.
|
|
It is shorthand for the following:
|
|
|
|
```javascript
|
|
let promise = new Promise(function(resolve, reject){
|
|
reject(new Error('WHOOPS'));
|
|
});
|
|
|
|
promise.then(function(value){
|
|
// Code here doesn't run because the promise is rejected!
|
|
}, function(reason){
|
|
// reason.message === 'WHOOPS'
|
|
});
|
|
```
|
|
|
|
Instead of writing the above, your code now simply becomes the following:
|
|
|
|
```javascript
|
|
let promise = Promise.reject(new Error('WHOOPS'));
|
|
|
|
promise.then(function(value){
|
|
// Code here doesn't run because the promise is rejected!
|
|
}, function(reason){
|
|
// reason.message === 'WHOOPS'
|
|
});
|
|
```
|
|
|
|
@method reject
|
|
@static
|
|
@param {Any} reason value that the returned promise will be rejected with.
|
|
Useful for tooling.
|
|
@return {Promise} a promise rejected with the given `reason`.
|
|
*/
|
|
function reject$1(reason) {
|
|
/*jshint validthis:true */
|
|
var Constructor = this;
|
|
var promise = new Constructor(noop);
|
|
reject(promise, reason);
|
|
return promise;
|
|
}
|
|
function needsResolver() {
|
|
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
|
|
}
|
|
function needsNew() {
|
|
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
|
|
}
|
|
/**
|
|
Promise objects represent the eventual result of an asynchronous operation. The
|
|
primary way of interacting with a promise is through its `then` method, which
|
|
registers callbacks to receive either a promise's eventual value or the reason
|
|
why the promise cannot be fulfilled.
|
|
|
|
Terminology
|
|
-----------
|
|
|
|
- `promise` is an object or function with a `then` method whose behavior conforms to this specification.
|
|
- `thenable` is an object or function that defines a `then` method.
|
|
- `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
|
|
- `exception` is a value that is thrown using the throw statement.
|
|
- `reason` is a value that indicates why a promise was rejected.
|
|
- `settled` the final resting state of a promise, fulfilled or rejected.
|
|
|
|
A promise can be in one of three states: pending, fulfilled, or rejected.
|
|
|
|
Promises that are fulfilled have a fulfillment value and are in the fulfilled
|
|
state. Promises that are rejected have a rejection reason and are in the
|
|
rejected state. A fulfillment value is never a thenable.
|
|
|
|
Promises can also be said to *resolve* a value. If this value is also a
|
|
promise, then the original promise's settled state will match the value's
|
|
settled state. So a promise that *resolves* a promise that rejects will
|
|
itself reject, and a promise that *resolves* a promise that fulfills will
|
|
itself fulfill.
|
|
|
|
|
|
Basic Usage:
|
|
------------
|
|
|
|
```js
|
|
let promise = new Promise(function(resolve, reject) {
|
|
// on success
|
|
resolve(value);
|
|
|
|
// on failure
|
|
reject(reason);
|
|
});
|
|
|
|
promise.then(function(value) {
|
|
// on fulfillment
|
|
}, function(reason) {
|
|
// on rejection
|
|
});
|
|
```
|
|
|
|
Advanced Usage:
|
|
---------------
|
|
|
|
Promises shine when abstracting away asynchronous interactions such as
|
|
`XMLHttpRequest`s.
|
|
|
|
```js
|
|
function getJSON(url) {
|
|
return new Promise(function(resolve, reject){
|
|
let xhr = new XMLHttpRequest();
|
|
|
|
xhr.open('GET', url);
|
|
xhr.onreadystatechange = handler;
|
|
xhr.responseType = 'json';
|
|
xhr.setRequestHeader('Accept', 'application/json');
|
|
xhr.send();
|
|
|
|
function handler() {
|
|
if (this.readyState === this.DONE) {
|
|
if (this.status === 200) {
|
|
resolve(this.response);
|
|
} else {
|
|
reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
|
|
}
|
|
}
|
|
};
|
|
});
|
|
}
|
|
|
|
getJSON('/posts.json').then(function(json) {
|
|
// on fulfillment
|
|
}, function(reason) {
|
|
// on rejection
|
|
});
|
|
```
|
|
|
|
Unlike callbacks, promises are great composable primitives.
|
|
|
|
```js
|
|
Promise.all([
|
|
getJSON('/posts'),
|
|
getJSON('/comments')
|
|
]).then(function(values){
|
|
values[0] // => postsJSON
|
|
values[1] // => commentsJSON
|
|
|
|
return values;
|
|
});
|
|
```
|
|
|
|
@class Promise
|
|
@param {Function} resolver
|
|
Useful for tooling.
|
|
@constructor
|
|
*/
|
|
var Promise$1 = function () {
|
|
function Promise(resolver) {
|
|
this[PROMISE_ID] = nextId();
|
|
this._result = this._state = undefined;
|
|
this._subscribers = [];
|
|
if (noop !== resolver) {
|
|
typeof resolver !== 'function' && needsResolver();
|
|
this instanceof Promise ? initializePromise(this, resolver) : needsNew();
|
|
}
|
|
}
|
|
/**
|
|
The primary way of interacting with a promise is through its `then` method,
|
|
which registers callbacks to receive either a promise's eventual value or the
|
|
reason why the promise cannot be fulfilled.
|
|
```js
|
|
findUser().then(function(user){
|
|
// user is available
|
|
}, function(reason){
|
|
// user is unavailable, and you are given the reason why
|
|
});
|
|
```
|
|
Chaining
|
|
--------
|
|
The return value of `then` is itself a promise. This second, 'downstream'
|
|
promise is resolved with the return value of the first promise's fulfillment
|
|
or rejection handler, or rejected if the handler throws an exception.
|
|
```js
|
|
findUser().then(function (user) {
|
|
return user.name;
|
|
}, function (reason) {
|
|
return 'default name';
|
|
}).then(function (userName) {
|
|
// If `findUser` fulfilled, `userName` will be the user's name, otherwise it
|
|
// will be `'default name'`
|
|
});
|
|
findUser().then(function (user) {
|
|
throw new Error('Found user, but still unhappy');
|
|
}, function (reason) {
|
|
throw new Error('`findUser` rejected and we're unhappy');
|
|
}).then(function (value) {
|
|
// never reached
|
|
}, function (reason) {
|
|
// if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
|
|
// If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
|
|
});
|
|
```
|
|
If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
|
|
```js
|
|
findUser().then(function (user) {
|
|
throw new PedagogicalException('Upstream error');
|
|
}).then(function (value) {
|
|
// never reached
|
|
}).then(function (value) {
|
|
// never reached
|
|
}, function (reason) {
|
|
// The `PedgagocialException` is propagated all the way down to here
|
|
});
|
|
```
|
|
Assimilation
|
|
------------
|
|
Sometimes the value you want to propagate to a downstream promise can only be
|
|
retrieved asynchronously. This can be achieved by returning a promise in the
|
|
fulfillment or rejection handler. The downstream promise will then be pending
|
|
until the returned promise is settled. This is called *assimilation*.
|
|
```js
|
|
findUser().then(function (user) {
|
|
return findCommentsByAuthor(user);
|
|
}).then(function (comments) {
|
|
// The user's comments are now available
|
|
});
|
|
```
|
|
If the assimliated promise rejects, then the downstream promise will also reject.
|
|
```js
|
|
findUser().then(function (user) {
|
|
return findCommentsByAuthor(user);
|
|
}).then(function (comments) {
|
|
// If `findCommentsByAuthor` fulfills, we'll have the value here
|
|
}, function (reason) {
|
|
// If `findCommentsByAuthor` rejects, we'll have the reason here
|
|
});
|
|
```
|
|
Simple Example
|
|
--------------
|
|
Synchronous Example
|
|
```javascript
|
|
let result;
|
|
try {
|
|
result = findResult();
|
|
// success
|
|
} catch(reason) {
|
|
// failure
|
|
}
|
|
```
|
|
Errback Example
|
|
```js
|
|
findResult(function(result, err){
|
|
if (err) {
|
|
// failure
|
|
} else {
|
|
// success
|
|
}
|
|
});
|
|
```
|
|
Promise Example;
|
|
```javascript
|
|
findResult().then(function(result){
|
|
// success
|
|
}, function(reason){
|
|
// failure
|
|
});
|
|
```
|
|
Advanced Example
|
|
--------------
|
|
Synchronous Example
|
|
```javascript
|
|
let author, books;
|
|
try {
|
|
author = findAuthor();
|
|
books = findBooksByAuthor(author);
|
|
// success
|
|
} catch(reason) {
|
|
// failure
|
|
}
|
|
```
|
|
Errback Example
|
|
```js
|
|
function foundBooks(books) {
|
|
}
|
|
function failure(reason) {
|
|
}
|
|
findAuthor(function(author, err){
|
|
if (err) {
|
|
failure(err);
|
|
// failure
|
|
} else {
|
|
try {
|
|
findBoooksByAuthor(author, function(books, err) {
|
|
if (err) {
|
|
failure(err);
|
|
} else {
|
|
try {
|
|
foundBooks(books);
|
|
} catch(reason) {
|
|
failure(reason);
|
|
}
|
|
}
|
|
});
|
|
} catch(error) {
|
|
failure(err);
|
|
}
|
|
// success
|
|
}
|
|
});
|
|
```
|
|
Promise Example;
|
|
```javascript
|
|
findAuthor().
|
|
then(findBooksByAuthor).
|
|
then(function(books){
|
|
// found books
|
|
}).catch(function(reason){
|
|
// something went wrong
|
|
});
|
|
```
|
|
@method then
|
|
@param {Function} onFulfilled
|
|
@param {Function} onRejected
|
|
Useful for tooling.
|
|
@return {Promise}
|
|
*/
|
|
/**
|
|
`catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
|
|
as the catch block of a try/catch statement.
|
|
```js
|
|
function findAuthor(){
|
|
throw new Error('couldn't find that author');
|
|
}
|
|
// synchronous
|
|
try {
|
|
findAuthor();
|
|
} catch(reason) {
|
|
// something went wrong
|
|
}
|
|
// async with promises
|
|
findAuthor().catch(function(reason){
|
|
// something went wrong
|
|
});
|
|
```
|
|
@method catch
|
|
@param {Function} onRejection
|
|
Useful for tooling.
|
|
@return {Promise}
|
|
*/
|
|
Promise.prototype.catch = function _catch(onRejection) {
|
|
return this.then(null, onRejection);
|
|
};
|
|
/**
|
|
`finally` will be invoked regardless of the promise's fate just as native
|
|
try/catch/finally behaves
|
|
|
|
Synchronous example:
|
|
|
|
```js
|
|
findAuthor() {
|
|
if (Math.random() > 0.5) {
|
|
throw new Error();
|
|
}
|
|
return new Author();
|
|
}
|
|
|
|
try {
|
|
return findAuthor(); // succeed or fail
|
|
} catch(error) {
|
|
return findOtherAuther();
|
|
} finally {
|
|
// always runs
|
|
// doesn't affect the return value
|
|
}
|
|
```
|
|
|
|
Asynchronous example:
|
|
|
|
```js
|
|
findAuthor().catch(function(reason){
|
|
return findOtherAuther();
|
|
}).finally(function(){
|
|
// author was either found, or not
|
|
});
|
|
```
|
|
|
|
@method finally
|
|
@param {Function} callback
|
|
@return {Promise}
|
|
*/
|
|
Promise.prototype.finally = function _finally(callback) {
|
|
var promise = this;
|
|
var constructor = promise.constructor;
|
|
if (isFunction(callback)) {
|
|
return promise.then(function (value) {
|
|
return constructor.resolve(callback()).then(function () {
|
|
return value;
|
|
});
|
|
}, function (reason) {
|
|
return constructor.resolve(callback()).then(function () {
|
|
throw reason;
|
|
});
|
|
});
|
|
}
|
|
return promise.then(callback, callback);
|
|
};
|
|
return Promise;
|
|
}();
|
|
Promise$1.prototype.then = then;
|
|
Promise$1.all = all;
|
|
Promise$1.race = race;
|
|
Promise$1.resolve = resolve$1;
|
|
Promise$1.reject = reject$1;
|
|
Promise$1._setScheduler = setScheduler;
|
|
Promise$1._setAsap = setAsap;
|
|
Promise$1._asap = asap;
|
|
/*global self*/
|
|
function polyfill() {
|
|
var local = void 0;
|
|
if (typeof global !== 'undefined') {
|
|
local = global;
|
|
}
|
|
else if (typeof self !== 'undefined') {
|
|
local = self;
|
|
}
|
|
else {
|
|
try {
|
|
local = Function('return this')();
|
|
}
|
|
catch (e) {
|
|
throw new Error('polyfill failed because global object is unavailable in this environment');
|
|
}
|
|
}
|
|
var P = local.Promise;
|
|
if (P) {
|
|
var promiseToString = null;
|
|
try {
|
|
promiseToString = Object.prototype.toString.call(P.resolve());
|
|
}
|
|
catch (e) {
|
|
// silently ignored
|
|
}
|
|
if (promiseToString === '[object Promise]' && !P.cast) {
|
|
return;
|
|
}
|
|
}
|
|
local.Promise = Promise$1;
|
|
}
|
|
// Strange compat..
|
|
Promise$1.polyfill = polyfill;
|
|
Promise$1.Promise = Promise$1;
|
|
return Promise$1;
|
|
})));
|
|
}
|
|
,
|
|
/* es6-symbol/index */ function _(require, module, exports) {
|
|
module.exports = require(359) /* ./is-implemented */() ? Symbol : require(361) /* ./polyfill */;
|
|
}
|
|
,
|
|
/* es6-symbol/is-implemented */ function _(require, module, exports) {
|
|
var validTypes = { object: true, symbol: true };
|
|
module.exports = function () {
|
|
var symbol;
|
|
if (typeof Symbol !== 'function')
|
|
return false;
|
|
symbol = Symbol('test symbol');
|
|
try {
|
|
String(symbol);
|
|
}
|
|
catch (e) {
|
|
return false;
|
|
}
|
|
// Return 'true' also for polyfills
|
|
if (!validTypes[typeof Symbol.iterator])
|
|
return false;
|
|
if (!validTypes[typeof Symbol.toPrimitive])
|
|
return false;
|
|
if (!validTypes[typeof Symbol.toStringTag])
|
|
return false;
|
|
return true;
|
|
};
|
|
}
|
|
,
|
|
/* es6-symbol/is-symbol */ function _(require, module, exports) {
|
|
module.exports = function (x) {
|
|
if (!x)
|
|
return false;
|
|
if (typeof x === 'symbol')
|
|
return true;
|
|
if (!x.constructor)
|
|
return false;
|
|
if (x.constructor.name !== 'Symbol')
|
|
return false;
|
|
return (x[x.constructor.toStringTag] === 'Symbol');
|
|
};
|
|
}
|
|
,
|
|
/* es6-symbol/polyfill */ function _(require, module, exports) {
|
|
var d = require(299) /* d */, validateSymbol = require(362) /* ./validate-symbol */, create = Object.create, defineProperties = Object.defineProperties, defineProperty = Object.defineProperty, objPrototype = Object.prototype, NativeSymbol, SymbolPolyfill, HiddenSymbol, globalSymbols = create(null), isNativeSafe;
|
|
if (typeof Symbol === 'function') {
|
|
NativeSymbol = Symbol;
|
|
try {
|
|
String(NativeSymbol());
|
|
isNativeSafe = true;
|
|
}
|
|
catch (ignore) { }
|
|
}
|
|
var generateName = (function () {
|
|
var created = create(null);
|
|
return function (desc) {
|
|
var postfix = 0, name, ie11BugWorkaround;
|
|
while (created[desc + (postfix || '')])
|
|
++postfix;
|
|
desc += (postfix || '');
|
|
created[desc] = true;
|
|
name = '@@' + desc;
|
|
defineProperty(objPrototype, name, d.gs(null, function (value) {
|
|
// For IE11 issue see:
|
|
// https://connect.microsoft.com/IE/feedbackdetail/view/1928508/
|
|
// ie11-broken-getters-on-dom-objects
|
|
// https://github.com/medikoo/es6-symbol/issues/12
|
|
if (ie11BugWorkaround)
|
|
return;
|
|
ie11BugWorkaround = true;
|
|
defineProperty(this, name, d(value));
|
|
ie11BugWorkaround = false;
|
|
}));
|
|
return name;
|
|
};
|
|
}());
|
|
// Internal constructor (not one exposed) for creating Symbol instances.
|
|
// This one is used to ensure that `someSymbol instanceof Symbol` always return false
|
|
HiddenSymbol = function Symbol(description) {
|
|
if (this instanceof HiddenSymbol)
|
|
throw new TypeError('Symbol is not a constructor');
|
|
return SymbolPolyfill(description);
|
|
};
|
|
// Exposed `Symbol` constructor
|
|
// (returns instances of HiddenSymbol)
|
|
module.exports = SymbolPolyfill = function Symbol(description) {
|
|
var symbol;
|
|
if (this instanceof Symbol)
|
|
throw new TypeError('Symbol is not a constructor');
|
|
if (isNativeSafe)
|
|
return NativeSymbol(description);
|
|
symbol = create(HiddenSymbol.prototype);
|
|
description = (description === undefined ? '' : String(description));
|
|
return defineProperties(symbol, {
|
|
__description__: d('', description),
|
|
__name__: d('', generateName(description))
|
|
});
|
|
};
|
|
defineProperties(SymbolPolyfill, {
|
|
for: d(function (key) {
|
|
if (globalSymbols[key])
|
|
return globalSymbols[key];
|
|
return (globalSymbols[key] = SymbolPolyfill(String(key)));
|
|
}),
|
|
keyFor: d(function (s) {
|
|
var key;
|
|
validateSymbol(s);
|
|
for (key in globalSymbols)
|
|
if (globalSymbols[key] === s)
|
|
return key;
|
|
}),
|
|
// To ensure proper interoperability with other native functions (e.g. Array.from)
|
|
// fallback to eventual native implementation of given symbol
|
|
hasInstance: d('', (NativeSymbol && NativeSymbol.hasInstance) || SymbolPolyfill('hasInstance')),
|
|
isConcatSpreadable: d('', (NativeSymbol && NativeSymbol.isConcatSpreadable) ||
|
|
SymbolPolyfill('isConcatSpreadable')),
|
|
iterator: d('', (NativeSymbol && NativeSymbol.iterator) || SymbolPolyfill('iterator')),
|
|
match: d('', (NativeSymbol && NativeSymbol.match) || SymbolPolyfill('match')),
|
|
replace: d('', (NativeSymbol && NativeSymbol.replace) || SymbolPolyfill('replace')),
|
|
search: d('', (NativeSymbol && NativeSymbol.search) || SymbolPolyfill('search')),
|
|
species: d('', (NativeSymbol && NativeSymbol.species) || SymbolPolyfill('species')),
|
|
split: d('', (NativeSymbol && NativeSymbol.split) || SymbolPolyfill('split')),
|
|
toPrimitive: d('', (NativeSymbol && NativeSymbol.toPrimitive) || SymbolPolyfill('toPrimitive')),
|
|
toStringTag: d('', (NativeSymbol && NativeSymbol.toStringTag) || SymbolPolyfill('toStringTag')),
|
|
unscopables: d('', (NativeSymbol && NativeSymbol.unscopables) || SymbolPolyfill('unscopables'))
|
|
});
|
|
// Internal tweaks for real symbol producer
|
|
defineProperties(HiddenSymbol.prototype, {
|
|
constructor: d(SymbolPolyfill),
|
|
toString: d('', function () { return this.__name__; })
|
|
});
|
|
// Proper implementation of methods exposed on Symbol.prototype
|
|
// They won't be accessible on produced symbol instances as they derive from HiddenSymbol.prototype
|
|
defineProperties(SymbolPolyfill.prototype, {
|
|
toString: d(function () { return 'Symbol (' + validateSymbol(this).__description__ + ')'; }),
|
|
valueOf: d(function () { return validateSymbol(this); })
|
|
});
|
|
defineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toPrimitive, d('', function () {
|
|
var symbol = validateSymbol(this);
|
|
if (typeof symbol === 'symbol')
|
|
return symbol;
|
|
return symbol.toString();
|
|
}));
|
|
defineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toStringTag, d('c', 'Symbol'));
|
|
// Proper implementaton of toPrimitive and toStringTag for returned symbol instances
|
|
defineProperty(HiddenSymbol.prototype, SymbolPolyfill.toStringTag, d('c', SymbolPolyfill.prototype[SymbolPolyfill.toStringTag]));
|
|
// Note: It's important to define `toPrimitive` as last one, as some implementations
|
|
// implement `toPrimitive` natively without implementing `toStringTag` (or other specified symbols)
|
|
// And that may invoke error in definition flow:
|
|
// See: https://github.com/medikoo/es6-symbol/issues/13#issuecomment-164146149
|
|
defineProperty(HiddenSymbol.prototype, SymbolPolyfill.toPrimitive, d('c', SymbolPolyfill.prototype[SymbolPolyfill.toPrimitive]));
|
|
}
|
|
,
|
|
/* es6-symbol/validate-symbol */ function _(require, module, exports) {
|
|
var isSymbol = require(360) /* ./is-symbol */;
|
|
module.exports = function (value) {
|
|
if (!isSymbol(value))
|
|
throw new TypeError(value + " is not a symbol");
|
|
return value;
|
|
};
|
|
}
|
|
,
|
|
/* es6-weak-map/implement */ function _(require, module, exports) {
|
|
if (!require(364) /* ./is-implemented */()) {
|
|
Object.defineProperty(require(308) /* es5-ext/global */, 'WeakMap', { value: require(366) /* ./polyfill */, configurable: true, enumerable: false,
|
|
writable: true });
|
|
}
|
|
}
|
|
,
|
|
/* es6-weak-map/is-implemented */ function _(require, module, exports) {
|
|
module.exports = function () {
|
|
var weakMap, x;
|
|
if (typeof WeakMap !== 'function')
|
|
return false;
|
|
try {
|
|
// WebKit doesn't support arguments and crashes
|
|
weakMap = new WeakMap([[x = {}, 'one'], [{}, 'two'], [{}, 'three']]);
|
|
}
|
|
catch (e) {
|
|
return false;
|
|
}
|
|
if (String(weakMap) !== '[object WeakMap]')
|
|
return false;
|
|
if (typeof weakMap.set !== 'function')
|
|
return false;
|
|
if (weakMap.set({}, 1) !== weakMap)
|
|
return false;
|
|
if (typeof weakMap.delete !== 'function')
|
|
return false;
|
|
if (typeof weakMap.has !== 'function')
|
|
return false;
|
|
if (weakMap.get(x) !== 'one')
|
|
return false;
|
|
return true;
|
|
};
|
|
}
|
|
,
|
|
/* es6-weak-map/is-native-implemented */ function _(require, module, exports) {
|
|
module.exports = (function () {
|
|
if (typeof WeakMap !== 'function')
|
|
return false;
|
|
return (Object.prototype.toString.call(new WeakMap()) === '[object WeakMap]');
|
|
}());
|
|
}
|
|
,
|
|
/* es6-weak-map/polyfill */ function _(require, module, exports) {
|
|
var setPrototypeOf = require(333) /* es5-ext/object/set-prototype-of */, object = require(337) /* es5-ext/object/valid-object */, value = require(338) /* es5-ext/object/valid-value */, randomUniq = require(343) /* es5-ext/string/random-uniq */, d = require(299) /* d */, getIterator = require(346) /* es6-iterator/get */, forOf = require(345) /* es6-iterator/for-of */, toStringTagSymbol = require(358) /* es6-symbol */.toStringTag, isNative = require(365) /* ./is-native-implemented */, isArray = Array.isArray, defineProperty = Object.defineProperty, hasOwnProperty = Object.prototype.hasOwnProperty, getPrototypeOf = Object.getPrototypeOf, WeakMapPoly;
|
|
module.exports = WeakMapPoly = function ( /*iterable*/) {
|
|
var iterable = arguments[0], self;
|
|
if (!(this instanceof WeakMapPoly))
|
|
throw new TypeError('Constructor requires \'new\'');
|
|
if (isNative && setPrototypeOf && (WeakMap !== WeakMapPoly)) {
|
|
self = setPrototypeOf(new WeakMap(), getPrototypeOf(this));
|
|
}
|
|
else {
|
|
self = this;
|
|
}
|
|
if (iterable != null) {
|
|
if (!isArray(iterable))
|
|
iterable = getIterator(iterable);
|
|
}
|
|
defineProperty(self, '__weakMapData__', d('c', '$weakMap$' + randomUniq()));
|
|
if (!iterable)
|
|
return self;
|
|
forOf(iterable, function (val) {
|
|
value(val);
|
|
self.set(val[0], val[1]);
|
|
});
|
|
return self;
|
|
};
|
|
if (isNative) {
|
|
if (setPrototypeOf)
|
|
setPrototypeOf(WeakMapPoly, WeakMap);
|
|
WeakMapPoly.prototype = Object.create(WeakMap.prototype, {
|
|
constructor: d(WeakMapPoly)
|
|
});
|
|
}
|
|
Object.defineProperties(WeakMapPoly.prototype, {
|
|
delete: d(function (key) {
|
|
if (hasOwnProperty.call(object(key), this.__weakMapData__)) {
|
|
delete key[this.__weakMapData__];
|
|
return true;
|
|
}
|
|
return false;
|
|
}),
|
|
get: d(function (key) {
|
|
if (hasOwnProperty.call(object(key), this.__weakMapData__)) {
|
|
return key[this.__weakMapData__];
|
|
}
|
|
}),
|
|
has: d(function (key) {
|
|
return hasOwnProperty.call(object(key), this.__weakMapData__);
|
|
}),
|
|
set: d(function (key, value) {
|
|
defineProperty(object(key), this.__weakMapData__, d('c', value));
|
|
return this;
|
|
}),
|
|
toString: d(function () { return '[object WeakMap]'; })
|
|
});
|
|
defineProperty(WeakMapPoly.prototype, toStringTagSymbol, d('c', 'WeakMap'));
|
|
}
|
|
,
|
|
/* event-emitter/index */ function _(require, module, exports) {
|
|
var d = require(299) /* d */, callable = require(336) /* es5-ext/object/valid-callable */, apply = Function.prototype.apply, call = Function.prototype.call, create = Object.create, defineProperty = Object.defineProperty, defineProperties = Object.defineProperties, hasOwnProperty = Object.prototype.hasOwnProperty, descriptor = { configurable: true, enumerable: false, writable: true }, on, once, off, emit, methods, descriptors, base;
|
|
on = function (type, listener) {
|
|
var data;
|
|
callable(listener);
|
|
if (!hasOwnProperty.call(this, '__ee__')) {
|
|
data = descriptor.value = create(null);
|
|
defineProperty(this, '__ee__', descriptor);
|
|
descriptor.value = null;
|
|
}
|
|
else {
|
|
data = this.__ee__;
|
|
}
|
|
if (!data[type])
|
|
data[type] = listener;
|
|
else if (typeof data[type] === 'object')
|
|
data[type].push(listener);
|
|
else
|
|
data[type] = [data[type], listener];
|
|
return this;
|
|
};
|
|
once = function (type, listener) {
|
|
var once, self;
|
|
callable(listener);
|
|
self = this;
|
|
on.call(this, type, once = function () {
|
|
off.call(self, type, once);
|
|
apply.call(listener, this, arguments);
|
|
});
|
|
once.__eeOnceListener__ = listener;
|
|
return this;
|
|
};
|
|
off = function (type, listener) {
|
|
var data, listeners, candidate, i;
|
|
callable(listener);
|
|
if (!hasOwnProperty.call(this, '__ee__'))
|
|
return this;
|
|
data = this.__ee__;
|
|
if (!data[type])
|
|
return this;
|
|
listeners = data[type];
|
|
if (typeof listeners === 'object') {
|
|
for (i = 0; (candidate = listeners[i]); ++i) {
|
|
if ((candidate === listener) ||
|
|
(candidate.__eeOnceListener__ === listener)) {
|
|
if (listeners.length === 2)
|
|
data[type] = listeners[i ? 0 : 1];
|
|
else
|
|
listeners.splice(i, 1);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if ((listeners === listener) ||
|
|
(listeners.__eeOnceListener__ === listener)) {
|
|
delete data[type];
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
emit = function (type) {
|
|
var i, l, listener, listeners, args;
|
|
if (!hasOwnProperty.call(this, '__ee__'))
|
|
return;
|
|
listeners = this.__ee__[type];
|
|
if (!listeners)
|
|
return;
|
|
if (typeof listeners === 'object') {
|
|
l = arguments.length;
|
|
args = new Array(l - 1);
|
|
for (i = 1; i < l; ++i)
|
|
args[i - 1] = arguments[i];
|
|
listeners = listeners.slice();
|
|
for (i = 0; (listener = listeners[i]); ++i) {
|
|
apply.call(listener, this, args);
|
|
}
|
|
}
|
|
else {
|
|
switch (arguments.length) {
|
|
case 1:
|
|
call.call(listeners, this);
|
|
break;
|
|
case 2:
|
|
call.call(listeners, this, arguments[1]);
|
|
break;
|
|
case 3:
|
|
call.call(listeners, this, arguments[1], arguments[2]);
|
|
break;
|
|
default:
|
|
l = arguments.length;
|
|
args = new Array(l - 1);
|
|
for (i = 1; i < l; ++i) {
|
|
args[i - 1] = arguments[i];
|
|
}
|
|
apply.call(listeners, this, args);
|
|
}
|
|
}
|
|
};
|
|
methods = {
|
|
on: on,
|
|
once: once,
|
|
off: off,
|
|
emit: emit
|
|
};
|
|
descriptors = {
|
|
on: d(on),
|
|
once: d(once),
|
|
off: d(off),
|
|
emit: d(emit)
|
|
};
|
|
base = defineProperties({}, descriptors);
|
|
module.exports = exports = function (o) {
|
|
return (o == null) ? create(base) : defineProperties(Object(o), descriptors);
|
|
};
|
|
exports.methods = methods;
|
|
}
|
|
,
|
|
/* flatbush/flatbush */ function _(require, module, exports) {
|
|
(function (global, factory) {
|
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
typeof define === 'function' && define.amd ? define(factory) :
|
|
(global = global || self, global.Flatbush = factory());
|
|
}(this, function () {
|
|
'use strict';
|
|
var FlatQueue = function FlatQueue() {
|
|
this.ids = [];
|
|
this.values = [];
|
|
this.length = 0;
|
|
};
|
|
FlatQueue.prototype.clear = function clear() {
|
|
this.length = this.ids.length = this.values.length = 0;
|
|
};
|
|
FlatQueue.prototype.push = function push(id, value) {
|
|
this.ids.push(id);
|
|
this.values.push(value);
|
|
var pos = this.length++;
|
|
while (pos > 0) {
|
|
var parent = (pos - 1) >> 1;
|
|
var parentValue = this.values[parent];
|
|
if (value >= parentValue) {
|
|
break;
|
|
}
|
|
this.ids[pos] = this.ids[parent];
|
|
this.values[pos] = parentValue;
|
|
pos = parent;
|
|
}
|
|
this.ids[pos] = id;
|
|
this.values[pos] = value;
|
|
};
|
|
FlatQueue.prototype.pop = function pop() {
|
|
if (this.length === 0) {
|
|
return undefined;
|
|
}
|
|
var top = this.ids[0];
|
|
this.length--;
|
|
if (this.length > 0) {
|
|
var id = this.ids[0] = this.ids[this.length];
|
|
var value = this.values[0] = this.values[this.length];
|
|
var halfLength = this.length >> 1;
|
|
var pos = 0;
|
|
while (pos < halfLength) {
|
|
var left = (pos << 1) + 1;
|
|
var right = left + 1;
|
|
var bestIndex = this.ids[left];
|
|
var bestValue = this.values[left];
|
|
var rightValue = this.values[right];
|
|
if (right < this.length && rightValue < bestValue) {
|
|
left = right;
|
|
bestIndex = this.ids[right];
|
|
bestValue = rightValue;
|
|
}
|
|
if (bestValue >= value) {
|
|
break;
|
|
}
|
|
this.ids[pos] = bestIndex;
|
|
this.values[pos] = bestValue;
|
|
pos = left;
|
|
}
|
|
this.ids[pos] = id;
|
|
this.values[pos] = value;
|
|
}
|
|
this.ids.pop();
|
|
this.values.pop();
|
|
return top;
|
|
};
|
|
FlatQueue.prototype.peek = function peek() {
|
|
return this.ids[0];
|
|
};
|
|
FlatQueue.prototype.peekValue = function peekValue() {
|
|
return this.values[0];
|
|
};
|
|
var ARRAY_TYPES = [
|
|
Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array,
|
|
Int32Array, Uint32Array, Float32Array, Float64Array
|
|
];
|
|
var VERSION = 3; // serialized format version
|
|
var Flatbush = function Flatbush(numItems, nodeSize, ArrayType, data) {
|
|
if (nodeSize === void 0)
|
|
nodeSize = 16;
|
|
if (ArrayType === void 0)
|
|
ArrayType = Float64Array;
|
|
if (numItems === undefined) {
|
|
throw new Error('Missing required argument: numItems.');
|
|
}
|
|
if (isNaN(numItems) || numItems <= 0) {
|
|
throw new Error(("Unpexpected numItems value: " + numItems + "."));
|
|
}
|
|
this.numItems = +numItems;
|
|
this.nodeSize = Math.min(Math.max(+nodeSize, 2), 65535);
|
|
// calculate the total number of nodes in the R-tree to allocate space for
|
|
// and the index of each tree level (used in search later)
|
|
var n = numItems;
|
|
var numNodes = n;
|
|
this._levelBounds = [n * 4];
|
|
do {
|
|
n = Math.ceil(n / this.nodeSize);
|
|
numNodes += n;
|
|
this._levelBounds.push(numNodes * 4);
|
|
} while (n !== 1);
|
|
this.ArrayType = ArrayType || Float64Array;
|
|
this.IndexArrayType = numNodes < 16384 ? Uint16Array : Uint32Array;
|
|
var arrayTypeIndex = ARRAY_TYPES.indexOf(this.ArrayType);
|
|
var nodesByteSize = numNodes * 4 * this.ArrayType.BYTES_PER_ELEMENT;
|
|
if (arrayTypeIndex < 0) {
|
|
throw new Error(("Unexpected typed array class: " + ArrayType + "."));
|
|
}
|
|
if (data && (data instanceof ArrayBuffer)) {
|
|
this.data = data;
|
|
this._boxes = new this.ArrayType(this.data, 8, numNodes * 4);
|
|
this._indices = new this.IndexArrayType(this.data, 8 + nodesByteSize, numNodes);
|
|
this._pos = numNodes * 4;
|
|
this.minX = this._boxes[this._pos - 4];
|
|
this.minY = this._boxes[this._pos - 3];
|
|
this.maxX = this._boxes[this._pos - 2];
|
|
this.maxY = this._boxes[this._pos - 1];
|
|
}
|
|
else {
|
|
this.data = new ArrayBuffer(8 + nodesByteSize + numNodes * this.IndexArrayType.BYTES_PER_ELEMENT);
|
|
this._boxes = new this.ArrayType(this.data, 8, numNodes * 4);
|
|
this._indices = new this.IndexArrayType(this.data, 8 + nodesByteSize, numNodes);
|
|
this._pos = 0;
|
|
this.minX = Infinity;
|
|
this.minY = Infinity;
|
|
this.maxX = -Infinity;
|
|
this.maxY = -Infinity;
|
|
new Uint8Array(this.data, 0, 2).set([0xfb, (VERSION << 4) + arrayTypeIndex]);
|
|
new Uint16Array(this.data, 2, 1)[0] = nodeSize;
|
|
new Uint32Array(this.data, 4, 1)[0] = numItems;
|
|
}
|
|
// a priority queue for k-nearest-neighbors queries
|
|
this._queue = new FlatQueue();
|
|
};
|
|
Flatbush.from = function from(data) {
|
|
if (!(data instanceof ArrayBuffer)) {
|
|
throw new Error('Data must be an instance of ArrayBuffer.');
|
|
}
|
|
var ref = new Uint8Array(data, 0, 2);
|
|
var magic = ref[0];
|
|
var versionAndType = ref[1];
|
|
if (magic !== 0xfb) {
|
|
throw new Error('Data does not appear to be in a Flatbush format.');
|
|
}
|
|
if (versionAndType >> 4 !== VERSION) {
|
|
throw new Error(("Got v" + (versionAndType >> 4) + " data when expected v" + VERSION + "."));
|
|
}
|
|
var ref$1 = new Uint16Array(data, 2, 1);
|
|
var nodeSize = ref$1[0];
|
|
var ref$2 = new Uint32Array(data, 4, 1);
|
|
var numItems = ref$2[0];
|
|
return new Flatbush(numItems, nodeSize, ARRAY_TYPES[versionAndType & 0x0f], data);
|
|
};
|
|
Flatbush.prototype.add = function add(minX, minY, maxX, maxY) {
|
|
var index = this._pos >> 2;
|
|
this._indices[index] = index;
|
|
this._boxes[this._pos++] = minX;
|
|
this._boxes[this._pos++] = minY;
|
|
this._boxes[this._pos++] = maxX;
|
|
this._boxes[this._pos++] = maxY;
|
|
if (minX < this.minX) {
|
|
this.minX = minX;
|
|
}
|
|
if (minY < this.minY) {
|
|
this.minY = minY;
|
|
}
|
|
if (maxX > this.maxX) {
|
|
this.maxX = maxX;
|
|
}
|
|
if (maxY > this.maxY) {
|
|
this.maxY = maxY;
|
|
}
|
|
};
|
|
Flatbush.prototype.finish = function finish() {
|
|
if (this._pos >> 2 !== this.numItems) {
|
|
throw new Error(("Added " + (this._pos >> 2) + " items when expected " + (this.numItems) + "."));
|
|
}
|
|
var width = this.maxX - this.minX;
|
|
var height = this.maxY - this.minY;
|
|
var hilbertValues = new Uint32Array(this.numItems);
|
|
var hilbertMax = (1 << 16) - 1;
|
|
// map item centers into Hilbert coordinate space and calculate Hilbert values
|
|
for (var i = 0; i < this.numItems; i++) {
|
|
var pos = 4 * i;
|
|
var minX = this._boxes[pos++];
|
|
var minY = this._boxes[pos++];
|
|
var maxX = this._boxes[pos++];
|
|
var maxY = this._boxes[pos++];
|
|
var x = Math.floor(hilbertMax * ((minX + maxX) / 2 - this.minX) / width);
|
|
var y = Math.floor(hilbertMax * ((minY + maxY) / 2 - this.minY) / height);
|
|
hilbertValues[i] = hilbert(x, y);
|
|
}
|
|
// sort items by their Hilbert value (for packing later)
|
|
sort(hilbertValues, this._boxes, this._indices, 0, this.numItems - 1);
|
|
// generate nodes at each tree level, bottom-up
|
|
for (var i$1 = 0, pos$1 = 0; i$1 < this._levelBounds.length - 1; i$1++) {
|
|
var end = this._levelBounds[i$1];
|
|
// generate a parent node for each block of consecutive <nodeSize> nodes
|
|
while (pos$1 < end) {
|
|
var nodeMinX = Infinity;
|
|
var nodeMinY = Infinity;
|
|
var nodeMaxX = -Infinity;
|
|
var nodeMaxY = -Infinity;
|
|
var nodeIndex = pos$1;
|
|
// calculate bbox for the new node
|
|
for (var i$2 = 0; i$2 < this.nodeSize && pos$1 < end; i$2++) {
|
|
var minX$1 = this._boxes[pos$1++];
|
|
var minY$1 = this._boxes[pos$1++];
|
|
var maxX$1 = this._boxes[pos$1++];
|
|
var maxY$1 = this._boxes[pos$1++];
|
|
if (minX$1 < nodeMinX) {
|
|
nodeMinX = minX$1;
|
|
}
|
|
if (minY$1 < nodeMinY) {
|
|
nodeMinY = minY$1;
|
|
}
|
|
if (maxX$1 > nodeMaxX) {
|
|
nodeMaxX = maxX$1;
|
|
}
|
|
if (maxY$1 > nodeMaxY) {
|
|
nodeMaxY = maxY$1;
|
|
}
|
|
}
|
|
// add the new node to the tree data
|
|
this._indices[this._pos >> 2] = nodeIndex;
|
|
this._boxes[this._pos++] = nodeMinX;
|
|
this._boxes[this._pos++] = nodeMinY;
|
|
this._boxes[this._pos++] = nodeMaxX;
|
|
this._boxes[this._pos++] = nodeMaxY;
|
|
}
|
|
}
|
|
};
|
|
Flatbush.prototype.search = function search(minX, minY, maxX, maxY, filterFn) {
|
|
if (this._pos !== this._boxes.length) {
|
|
throw new Error('Data not yet indexed - call index.finish().');
|
|
}
|
|
var nodeIndex = this._boxes.length - 4;
|
|
var level = this._levelBounds.length - 1;
|
|
var queue = [];
|
|
var results = [];
|
|
while (nodeIndex !== undefined) {
|
|
// find the end index of the node
|
|
var end = Math.min(nodeIndex + this.nodeSize * 4, this._levelBounds[level]);
|
|
// search through child nodes
|
|
for (var pos = nodeIndex; pos < end; pos += 4) {
|
|
var index = this._indices[pos >> 2] | 0;
|
|
// check if node bbox intersects with query bbox
|
|
if (maxX < this._boxes[pos]) {
|
|
continue;
|
|
} // maxX < nodeMinX
|
|
if (maxY < this._boxes[pos + 1]) {
|
|
continue;
|
|
} // maxY < nodeMinY
|
|
if (minX > this._boxes[pos + 2]) {
|
|
continue;
|
|
} // minX > nodeMaxX
|
|
if (minY > this._boxes[pos + 3]) {
|
|
continue;
|
|
} // minY > nodeMaxY
|
|
if (nodeIndex < this.numItems * 4) {
|
|
if (filterFn === undefined || filterFn(index)) {
|
|
results.push(index); // leaf item
|
|
}
|
|
}
|
|
else {
|
|
queue.push(index); // node; add it to the search queue
|
|
queue.push(level - 1);
|
|
}
|
|
}
|
|
level = queue.pop();
|
|
nodeIndex = queue.pop();
|
|
}
|
|
return results;
|
|
};
|
|
Flatbush.prototype.neighbors = function neighbors(x, y, maxResults, maxDistance, filterFn) {
|
|
if (maxResults === void 0)
|
|
maxResults = Infinity;
|
|
if (maxDistance === void 0)
|
|
maxDistance = Infinity;
|
|
if (this._pos !== this._boxes.length) {
|
|
throw new Error('Data not yet indexed - call index.finish().');
|
|
}
|
|
var nodeIndex = this._boxes.length - 4;
|
|
var q = this._queue;
|
|
var results = [];
|
|
var maxDistSquared = maxDistance * maxDistance;
|
|
while (nodeIndex !== undefined) {
|
|
// find the end index of the node
|
|
var end = Math.min(nodeIndex + this.nodeSize * 4, upperBound(nodeIndex, this._levelBounds));
|
|
// add child nodes to the queue
|
|
for (var pos = nodeIndex; pos < end; pos += 4) {
|
|
var index = this._indices[pos >> 2] | 0;
|
|
var dx = axisDist(x, this._boxes[pos], this._boxes[pos + 2]);
|
|
var dy = axisDist(y, this._boxes[pos + 1], this._boxes[pos + 3]);
|
|
var dist = dx * dx + dy * dy;
|
|
if (nodeIndex < this.numItems * 4) { // leaf node
|
|
if (filterFn === undefined || filterFn(index)) {
|
|
// put a negative index if it's an item rather than a node, to recognize later
|
|
q.push(-index - 1, dist);
|
|
}
|
|
}
|
|
else {
|
|
q.push(index, dist);
|
|
}
|
|
}
|
|
// pop items from the queue
|
|
while (q.length && q.peek() < 0) {
|
|
var dist$1 = q.peekValue();
|
|
if (dist$1 > maxDistSquared) {
|
|
q.clear();
|
|
return results;
|
|
}
|
|
results.push(-q.pop() - 1);
|
|
if (results.length === maxResults) {
|
|
q.clear();
|
|
return results;
|
|
}
|
|
}
|
|
nodeIndex = q.pop();
|
|
}
|
|
q.clear();
|
|
return results;
|
|
};
|
|
function axisDist(k, min, max) {
|
|
return k < min ? min - k : k <= max ? 0 : k - max;
|
|
}
|
|
// binary search for the first value in the array bigger than the given
|
|
function upperBound(value, arr) {
|
|
var i = 0;
|
|
var j = arr.length - 1;
|
|
while (i < j) {
|
|
var m = (i + j) >> 1;
|
|
if (arr[m] > value) {
|
|
j = m;
|
|
}
|
|
else {
|
|
i = m + 1;
|
|
}
|
|
}
|
|
return arr[i];
|
|
}
|
|
// custom quicksort that sorts bbox data alongside the hilbert values
|
|
function sort(values, boxes, indices, left, right) {
|
|
if (left >= right) {
|
|
return;
|
|
}
|
|
var pivot = values[(left + right) >> 1];
|
|
var i = left - 1;
|
|
var j = right + 1;
|
|
while (true) {
|
|
do {
|
|
i++;
|
|
} while (values[i] < pivot);
|
|
do {
|
|
j--;
|
|
} while (values[j] > pivot);
|
|
if (i >= j) {
|
|
break;
|
|
}
|
|
swap(values, boxes, indices, i, j);
|
|
}
|
|
sort(values, boxes, indices, left, j);
|
|
sort(values, boxes, indices, j + 1, right);
|
|
}
|
|
// swap two values and two corresponding boxes
|
|
function swap(values, boxes, indices, i, j) {
|
|
var temp = values[i];
|
|
values[i] = values[j];
|
|
values[j] = temp;
|
|
var k = 4 * i;
|
|
var m = 4 * j;
|
|
var a = boxes[k];
|
|
var b = boxes[k + 1];
|
|
var c = boxes[k + 2];
|
|
var d = boxes[k + 3];
|
|
boxes[k] = boxes[m];
|
|
boxes[k + 1] = boxes[m + 1];
|
|
boxes[k + 2] = boxes[m + 2];
|
|
boxes[k + 3] = boxes[m + 3];
|
|
boxes[m] = a;
|
|
boxes[m + 1] = b;
|
|
boxes[m + 2] = c;
|
|
boxes[m + 3] = d;
|
|
var e = indices[i];
|
|
indices[i] = indices[j];
|
|
indices[j] = e;
|
|
}
|
|
// Fast Hilbert curve algorithm by http://threadlocalmutex.com/
|
|
// Ported from C++ https://github.com/rawrunprotected/hilbert_curves (public domain)
|
|
function hilbert(x, y) {
|
|
var a = x ^ y;
|
|
var b = 0xFFFF ^ a;
|
|
var c = 0xFFFF ^ (x | y);
|
|
var d = x & (y ^ 0xFFFF);
|
|
var A = a | (b >> 1);
|
|
var B = (a >> 1) ^ a;
|
|
var C = ((c >> 1) ^ (b & (d >> 1))) ^ c;
|
|
var D = ((a & (c >> 1)) ^ (d >> 1)) ^ d;
|
|
a = A;
|
|
b = B;
|
|
c = C;
|
|
d = D;
|
|
A = ((a & (a >> 2)) ^ (b & (b >> 2)));
|
|
B = ((a & (b >> 2)) ^ (b & ((a ^ b) >> 2)));
|
|
C ^= ((a & (c >> 2)) ^ (b & (d >> 2)));
|
|
D ^= ((b & (c >> 2)) ^ ((a ^ b) & (d >> 2)));
|
|
a = A;
|
|
b = B;
|
|
c = C;
|
|
d = D;
|
|
A = ((a & (a >> 4)) ^ (b & (b >> 4)));
|
|
B = ((a & (b >> 4)) ^ (b & ((a ^ b) >> 4)));
|
|
C ^= ((a & (c >> 4)) ^ (b & (d >> 4)));
|
|
D ^= ((b & (c >> 4)) ^ ((a ^ b) & (d >> 4)));
|
|
a = A;
|
|
b = B;
|
|
c = C;
|
|
d = D;
|
|
C ^= ((a & (c >> 8)) ^ (b & (d >> 8)));
|
|
D ^= ((b & (c >> 8)) ^ ((a ^ b) & (d >> 8)));
|
|
a = C ^ (C >> 1);
|
|
b = D ^ (D >> 1);
|
|
var i0 = x ^ y;
|
|
var i1 = b | (0xFFFF ^ (i0 | a));
|
|
i0 = (i0 | (i0 << 8)) & 0x00FF00FF;
|
|
i0 = (i0 | (i0 << 4)) & 0x0F0F0F0F;
|
|
i0 = (i0 | (i0 << 2)) & 0x33333333;
|
|
i0 = (i0 | (i0 << 1)) & 0x55555555;
|
|
i1 = (i1 | (i1 << 8)) & 0x00FF00FF;
|
|
i1 = (i1 | (i1 << 4)) & 0x0F0F0F0F;
|
|
i1 = (i1 | (i1 << 2)) & 0x33333333;
|
|
i1 = (i1 | (i1 << 1)) & 0x55555555;
|
|
return ((i1 << 1) | i0) >>> 0;
|
|
}
|
|
return Flatbush;
|
|
}));
|
|
}
|
|
,
|
|
/* hammerjs/hammer */ function _(require, module, exports) {
|
|
/*! Hammer.JS - v2.0.7 - 2016-04-22
|
|
* http://hammerjs.github.io/
|
|
*
|
|
* Copyright (c) 2016 Jorik Tangelder;
|
|
* Licensed under the MIT license */
|
|
(function (window, document, exportName, undefined) {
|
|
'use strict';
|
|
var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
|
|
var TEST_ELEMENT = document.createElement('div');
|
|
var TYPE_FUNCTION = 'function';
|
|
var round = Math.round;
|
|
var abs = Math.abs;
|
|
var now = Date.now;
|
|
/**
|
|
* set a timeout with a given scope
|
|
* @param {Function} fn
|
|
* @param {Number} timeout
|
|
* @param {Object} context
|
|
* @returns {number}
|
|
*/
|
|
function setTimeoutContext(fn, timeout, context) {
|
|
return setTimeout(bindFn(fn, context), timeout);
|
|
}
|
|
/**
|
|
* if the argument is an array, we want to execute the fn on each entry
|
|
* if it aint an array we don't want to do a thing.
|
|
* this is used by all the methods that accept a single and array argument.
|
|
* @param {*|Array} arg
|
|
* @param {String} fn
|
|
* @param {Object} [context]
|
|
* @returns {Boolean}
|
|
*/
|
|
function invokeArrayArg(arg, fn, context) {
|
|
if (Array.isArray(arg)) {
|
|
each(arg, context[fn], context);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
/**
|
|
* walk objects and arrays
|
|
* @param {Object} obj
|
|
* @param {Function} iterator
|
|
* @param {Object} context
|
|
*/
|
|
function each(obj, iterator, context) {
|
|
var i;
|
|
if (!obj) {
|
|
return;
|
|
}
|
|
if (obj.forEach) {
|
|
obj.forEach(iterator, context);
|
|
}
|
|
else if (obj.length !== undefined) {
|
|
i = 0;
|
|
while (i < obj.length) {
|
|
iterator.call(context, obj[i], i, obj);
|
|
i++;
|
|
}
|
|
}
|
|
else {
|
|
for (i in obj) {
|
|
obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* wrap a method with a deprecation warning and stack trace
|
|
* @param {Function} method
|
|
* @param {String} name
|
|
* @param {String} message
|
|
* @returns {Function} A new function wrapping the supplied method.
|
|
*/
|
|
function deprecate(method, name, message) {
|
|
var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\n' + message + ' AT \n';
|
|
return function () {
|
|
var e = new Error('get-stack-trace');
|
|
var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '')
|
|
.replace(/^\s+at\s+/gm, '')
|
|
.replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';
|
|
var log = window.console && (window.console.warn || window.console.log);
|
|
if (log) {
|
|
log.call(window.console, deprecationMessage, stack);
|
|
}
|
|
return method.apply(this, arguments);
|
|
};
|
|
}
|
|
/**
|
|
* extend object.
|
|
* means that properties in dest will be overwritten by the ones in src.
|
|
* @param {Object} target
|
|
* @param {...Object} objects_to_assign
|
|
* @returns {Object} target
|
|
*/
|
|
var assign;
|
|
if (typeof Object.assign !== 'function') {
|
|
assign = function assign(target) {
|
|
if (target === undefined || target === null) {
|
|
throw new TypeError('Cannot convert undefined or null to object');
|
|
}
|
|
var output = Object(target);
|
|
for (var index = 1; index < arguments.length; index++) {
|
|
var source = arguments[index];
|
|
if (source !== undefined && source !== null) {
|
|
for (var nextKey in source) {
|
|
if (source.hasOwnProperty(nextKey)) {
|
|
output[nextKey] = source[nextKey];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return output;
|
|
};
|
|
}
|
|
else {
|
|
assign = Object.assign;
|
|
}
|
|
/**
|
|
* extend object.
|
|
* means that properties in dest will be overwritten by the ones in src.
|
|
* @param {Object} dest
|
|
* @param {Object} src
|
|
* @param {Boolean} [merge=false]
|
|
* @returns {Object} dest
|
|
*/
|
|
var extend = deprecate(function extend(dest, src, merge) {
|
|
var keys = Object.keys(src);
|
|
var i = 0;
|
|
while (i < keys.length) {
|
|
if (!merge || (merge && dest[keys[i]] === undefined)) {
|
|
dest[keys[i]] = src[keys[i]];
|
|
}
|
|
i++;
|
|
}
|
|
return dest;
|
|
}, 'extend', 'Use `assign`.');
|
|
/**
|
|
* merge the values from src in the dest.
|
|
* means that properties that exist in dest will not be overwritten by src
|
|
* @param {Object} dest
|
|
* @param {Object} src
|
|
* @returns {Object} dest
|
|
*/
|
|
var merge = deprecate(function merge(dest, src) {
|
|
return extend(dest, src, true);
|
|
}, 'merge', 'Use `assign`.');
|
|
/**
|
|
* simple class inheritance
|
|
* @param {Function} child
|
|
* @param {Function} base
|
|
* @param {Object} [properties]
|
|
*/
|
|
function inherit(child, base, properties) {
|
|
var baseP = base.prototype, childP;
|
|
childP = child.prototype = Object.create(baseP);
|
|
childP.constructor = child;
|
|
childP._super = baseP;
|
|
if (properties) {
|
|
assign(childP, properties);
|
|
}
|
|
}
|
|
/**
|
|
* simple function bind
|
|
* @param {Function} fn
|
|
* @param {Object} context
|
|
* @returns {Function}
|
|
*/
|
|
function bindFn(fn, context) {
|
|
return function boundFn() {
|
|
return fn.apply(context, arguments);
|
|
};
|
|
}
|
|
/**
|
|
* let a boolean value also be a function that must return a boolean
|
|
* this first item in args will be used as the context
|
|
* @param {Boolean|Function} val
|
|
* @param {Array} [args]
|
|
* @returns {Boolean}
|
|
*/
|
|
function boolOrFn(val, args) {
|
|
if (typeof val == TYPE_FUNCTION) {
|
|
return val.apply(args ? args[0] || undefined : undefined, args);
|
|
}
|
|
return val;
|
|
}
|
|
/**
|
|
* use the val2 when val1 is undefined
|
|
* @param {*} val1
|
|
* @param {*} val2
|
|
* @returns {*}
|
|
*/
|
|
function ifUndefined(val1, val2) {
|
|
return (val1 === undefined) ? val2 : val1;
|
|
}
|
|
/**
|
|
* addEventListener with multiple events at once
|
|
* @param {EventTarget} target
|
|
* @param {String} types
|
|
* @param {Function} handler
|
|
*/
|
|
function addEventListeners(target, types, handler) {
|
|
each(splitStr(types), function (type) {
|
|
target.addEventListener(type, handler, false);
|
|
});
|
|
}
|
|
/**
|
|
* removeEventListener with multiple events at once
|
|
* @param {EventTarget} target
|
|
* @param {String} types
|
|
* @param {Function} handler
|
|
*/
|
|
function removeEventListeners(target, types, handler) {
|
|
each(splitStr(types), function (type) {
|
|
target.removeEventListener(type, handler, false);
|
|
});
|
|
}
|
|
/**
|
|
* find if a node is in the given parent
|
|
* @method hasParent
|
|
* @param {HTMLElement} node
|
|
* @param {HTMLElement} parent
|
|
* @return {Boolean} found
|
|
*/
|
|
function hasParent(node, parent) {
|
|
while (node) {
|
|
if (node == parent) {
|
|
return true;
|
|
}
|
|
node = node.parentNode;
|
|
}
|
|
return false;
|
|
}
|
|
/**
|
|
* small indexOf wrapper
|
|
* @param {String} str
|
|
* @param {String} find
|
|
* @returns {Boolean} found
|
|
*/
|
|
function inStr(str, find) {
|
|
return str.indexOf(find) > -1;
|
|
}
|
|
/**
|
|
* split string on whitespace
|
|
* @param {String} str
|
|
* @returns {Array} words
|
|
*/
|
|
function splitStr(str) {
|
|
return str.trim().split(/\s+/g);
|
|
}
|
|
/**
|
|
* find if a array contains the object using indexOf or a simple polyFill
|
|
* @param {Array} src
|
|
* @param {String} find
|
|
* @param {String} [findByKey]
|
|
* @return {Boolean|Number} false when not found, or the index
|
|
*/
|
|
function inArray(src, find, findByKey) {
|
|
if (src.indexOf && !findByKey) {
|
|
return src.indexOf(find);
|
|
}
|
|
else {
|
|
var i = 0;
|
|
while (i < src.length) {
|
|
if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) {
|
|
return i;
|
|
}
|
|
i++;
|
|
}
|
|
return -1;
|
|
}
|
|
}
|
|
/**
|
|
* convert array-like objects to real arrays
|
|
* @param {Object} obj
|
|
* @returns {Array}
|
|
*/
|
|
function toArray(obj) {
|
|
return Array.prototype.slice.call(obj, 0);
|
|
}
|
|
/**
|
|
* unique array with objects based on a key (like 'id') or just by the array's value
|
|
* @param {Array} src [{id:1},{id:2},{id:1}]
|
|
* @param {String} [key]
|
|
* @param {Boolean} [sort=False]
|
|
* @returns {Array} [{id:1},{id:2}]
|
|
*/
|
|
function uniqueArray(src, key, sort) {
|
|
var results = [];
|
|
var values = [];
|
|
var i = 0;
|
|
while (i < src.length) {
|
|
var val = key ? src[i][key] : src[i];
|
|
if (inArray(values, val) < 0) {
|
|
results.push(src[i]);
|
|
}
|
|
values[i] = val;
|
|
i++;
|
|
}
|
|
if (sort) {
|
|
if (!key) {
|
|
results = results.sort();
|
|
}
|
|
else {
|
|
results = results.sort(function sortUniqueArray(a, b) {
|
|
return a[key] > b[key];
|
|
});
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
/**
|
|
* get the prefixed property
|
|
* @param {Object} obj
|
|
* @param {String} property
|
|
* @returns {String|Undefined} prefixed
|
|
*/
|
|
function prefixed(obj, property) {
|
|
var prefix, prop;
|
|
var camelProp = property[0].toUpperCase() + property.slice(1);
|
|
var i = 0;
|
|
while (i < VENDOR_PREFIXES.length) {
|
|
prefix = VENDOR_PREFIXES[i];
|
|
prop = (prefix) ? prefix + camelProp : property;
|
|
if (prop in obj) {
|
|
return prop;
|
|
}
|
|
i++;
|
|
}
|
|
return undefined;
|
|
}
|
|
/**
|
|
* get a unique id
|
|
* @returns {number} uniqueId
|
|
*/
|
|
var _uniqueId = 1;
|
|
function uniqueId() {
|
|
return _uniqueId++;
|
|
}
|
|
/**
|
|
* get the window object of an element
|
|
* @param {HTMLElement} element
|
|
* @returns {DocumentView|Window}
|
|
*/
|
|
function getWindowForElement(element) {
|
|
var doc = element.ownerDocument || element;
|
|
return (doc.defaultView || doc.parentWindow || window);
|
|
}
|
|
var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
|
|
var SUPPORT_TOUCH = ('ontouchstart' in window);
|
|
var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;
|
|
var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
|
|
var INPUT_TYPE_TOUCH = 'touch';
|
|
var INPUT_TYPE_PEN = 'pen';
|
|
var INPUT_TYPE_MOUSE = 'mouse';
|
|
var INPUT_TYPE_KINECT = 'kinect';
|
|
var COMPUTE_INTERVAL = 25;
|
|
var INPUT_START = 1;
|
|
var INPUT_MOVE = 2;
|
|
var INPUT_END = 4;
|
|
var INPUT_CANCEL = 8;
|
|
var DIRECTION_NONE = 1;
|
|
var DIRECTION_LEFT = 2;
|
|
var DIRECTION_RIGHT = 4;
|
|
var DIRECTION_UP = 8;
|
|
var DIRECTION_DOWN = 16;
|
|
var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
|
|
var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
|
|
var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
|
|
var PROPS_XY = ['x', 'y'];
|
|
var PROPS_CLIENT_XY = ['clientX', 'clientY'];
|
|
/**
|
|
* create new input type manager
|
|
* @param {Manager} manager
|
|
* @param {Function} callback
|
|
* @returns {Input}
|
|
* @constructor
|
|
*/
|
|
function Input(manager, callback) {
|
|
var self = this;
|
|
this.manager = manager;
|
|
this.callback = callback;
|
|
this.element = manager.element;
|
|
this.target = manager.options.inputTarget;
|
|
// smaller wrapper around the handler, for the scope and the enabled state of the manager,
|
|
// so when disabled the input events are completely bypassed.
|
|
this.domHandler = function (ev) {
|
|
if (boolOrFn(manager.options.enable, [manager])) {
|
|
self.handler(ev);
|
|
}
|
|
};
|
|
this.init();
|
|
}
|
|
Input.prototype = {
|
|
/**
|
|
* should handle the inputEvent data and trigger the callback
|
|
* @virtual
|
|
*/
|
|
handler: function () { },
|
|
/**
|
|
* bind the events
|
|
*/
|
|
init: function () {
|
|
this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
|
|
this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
|
|
this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
|
|
},
|
|
/**
|
|
* unbind the events
|
|
*/
|
|
destroy: function () {
|
|
this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
|
|
this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
|
|
this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
|
|
}
|
|
};
|
|
/**
|
|
* create new input type manager
|
|
* called by the Manager constructor
|
|
* @param {Hammer} manager
|
|
* @returns {Input}
|
|
*/
|
|
function createInputInstance(manager) {
|
|
var Type;
|
|
var inputClass = manager.options.inputClass;
|
|
if (inputClass) {
|
|
Type = inputClass;
|
|
}
|
|
else if (SUPPORT_POINTER_EVENTS) {
|
|
Type = PointerEventInput;
|
|
}
|
|
else if (SUPPORT_ONLY_TOUCH) {
|
|
Type = TouchInput;
|
|
}
|
|
else if (!SUPPORT_TOUCH) {
|
|
Type = MouseInput;
|
|
}
|
|
else {
|
|
Type = TouchMouseInput;
|
|
}
|
|
return new (Type)(manager, inputHandler);
|
|
}
|
|
/**
|
|
* handle input events
|
|
* @param {Manager} manager
|
|
* @param {String} eventType
|
|
* @param {Object} input
|
|
*/
|
|
function inputHandler(manager, eventType, input) {
|
|
var pointersLen = input.pointers.length;
|
|
var changedPointersLen = input.changedPointers.length;
|
|
var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));
|
|
var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));
|
|
input.isFirst = !!isFirst;
|
|
input.isFinal = !!isFinal;
|
|
if (isFirst) {
|
|
manager.session = {};
|
|
}
|
|
// source event is the normalized value of the domEvents
|
|
// like 'touchstart, mouseup, pointerdown'
|
|
input.eventType = eventType;
|
|
// compute scale, rotation etc
|
|
computeInputData(manager, input);
|
|
// emit secret event
|
|
manager.emit('hammer.input', input);
|
|
manager.recognize(input);
|
|
manager.session.prevInput = input;
|
|
}
|
|
/**
|
|
* extend the data with some usable properties like scale, rotate, velocity etc
|
|
* @param {Object} manager
|
|
* @param {Object} input
|
|
*/
|
|
function computeInputData(manager, input) {
|
|
var session = manager.session;
|
|
var pointers = input.pointers;
|
|
var pointersLength = pointers.length;
|
|
// store the first input to calculate the distance and direction
|
|
if (!session.firstInput) {
|
|
session.firstInput = simpleCloneInputData(input);
|
|
}
|
|
// to compute scale and rotation we need to store the multiple touches
|
|
if (pointersLength > 1 && !session.firstMultiple) {
|
|
session.firstMultiple = simpleCloneInputData(input);
|
|
}
|
|
else if (pointersLength === 1) {
|
|
session.firstMultiple = false;
|
|
}
|
|
var firstInput = session.firstInput;
|
|
var firstMultiple = session.firstMultiple;
|
|
var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
|
|
var center = input.center = getCenter(pointers);
|
|
input.timeStamp = now();
|
|
input.deltaTime = input.timeStamp - firstInput.timeStamp;
|
|
input.angle = getAngle(offsetCenter, center);
|
|
input.distance = getDistance(offsetCenter, center);
|
|
computeDeltaXY(session, input);
|
|
input.offsetDirection = getDirection(input.deltaX, input.deltaY);
|
|
var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
|
|
input.overallVelocityX = overallVelocity.x;
|
|
input.overallVelocityY = overallVelocity.y;
|
|
input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y;
|
|
input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
|
|
input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
|
|
input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length >
|
|
session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers);
|
|
computeIntervalInputData(session, input);
|
|
// find the correct target
|
|
var target = manager.element;
|
|
if (hasParent(input.srcEvent.target, target)) {
|
|
target = input.srcEvent.target;
|
|
}
|
|
input.target = target;
|
|
}
|
|
function computeDeltaXY(session, input) {
|
|
var center = input.center;
|
|
var offset = session.offsetDelta || {};
|
|
var prevDelta = session.prevDelta || {};
|
|
var prevInput = session.prevInput || {};
|
|
if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
|
|
prevDelta = session.prevDelta = {
|
|
x: prevInput.deltaX || 0,
|
|
y: prevInput.deltaY || 0
|
|
};
|
|
offset = session.offsetDelta = {
|
|
x: center.x,
|
|
y: center.y
|
|
};
|
|
}
|
|
input.deltaX = prevDelta.x + (center.x - offset.x);
|
|
input.deltaY = prevDelta.y + (center.y - offset.y);
|
|
}
|
|
/**
|
|
* velocity is calculated every x ms
|
|
* @param {Object} session
|
|
* @param {Object} input
|
|
*/
|
|
function computeIntervalInputData(session, input) {
|
|
var last = session.lastInterval || input, deltaTime = input.timeStamp - last.timeStamp, velocity, velocityX, velocityY, direction;
|
|
if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {
|
|
var deltaX = input.deltaX - last.deltaX;
|
|
var deltaY = input.deltaY - last.deltaY;
|
|
var v = getVelocity(deltaTime, deltaX, deltaY);
|
|
velocityX = v.x;
|
|
velocityY = v.y;
|
|
velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;
|
|
direction = getDirection(deltaX, deltaY);
|
|
session.lastInterval = input;
|
|
}
|
|
else {
|
|
// use latest velocity info if it doesn't overtake a minimum period
|
|
velocity = last.velocity;
|
|
velocityX = last.velocityX;
|
|
velocityY = last.velocityY;
|
|
direction = last.direction;
|
|
}
|
|
input.velocity = velocity;
|
|
input.velocityX = velocityX;
|
|
input.velocityY = velocityY;
|
|
input.direction = direction;
|
|
}
|
|
/**
|
|
* create a simple clone from the input used for storage of firstInput and firstMultiple
|
|
* @param {Object} input
|
|
* @returns {Object} clonedInputData
|
|
*/
|
|
function simpleCloneInputData(input) {
|
|
// make a simple copy of the pointers because we will get a reference if we don't
|
|
// we only need clientXY for the calculations
|
|
var pointers = [];
|
|
var i = 0;
|
|
while (i < input.pointers.length) {
|
|
pointers[i] = {
|
|
clientX: round(input.pointers[i].clientX),
|
|
clientY: round(input.pointers[i].clientY)
|
|
};
|
|
i++;
|
|
}
|
|
return {
|
|
timeStamp: now(),
|
|
pointers: pointers,
|
|
center: getCenter(pointers),
|
|
deltaX: input.deltaX,
|
|
deltaY: input.deltaY
|
|
};
|
|
}
|
|
/**
|
|
* get the center of all the pointers
|
|
* @param {Array} pointers
|
|
* @return {Object} center contains `x` and `y` properties
|
|
*/
|
|
function getCenter(pointers) {
|
|
var pointersLength = pointers.length;
|
|
// no need to loop when only one touch
|
|
if (pointersLength === 1) {
|
|
return {
|
|
x: round(pointers[0].clientX),
|
|
y: round(pointers[0].clientY)
|
|
};
|
|
}
|
|
var x = 0, y = 0, i = 0;
|
|
while (i < pointersLength) {
|
|
x += pointers[i].clientX;
|
|
y += pointers[i].clientY;
|
|
i++;
|
|
}
|
|
return {
|
|
x: round(x / pointersLength),
|
|
y: round(y / pointersLength)
|
|
};
|
|
}
|
|
/**
|
|
* calculate the velocity between two points. unit is in px per ms.
|
|
* @param {Number} deltaTime
|
|
* @param {Number} x
|
|
* @param {Number} y
|
|
* @return {Object} velocity `x` and `y`
|
|
*/
|
|
function getVelocity(deltaTime, x, y) {
|
|
return {
|
|
x: x / deltaTime || 0,
|
|
y: y / deltaTime || 0
|
|
};
|
|
}
|
|
/**
|
|
* get the direction between two points
|
|
* @param {Number} x
|
|
* @param {Number} y
|
|
* @return {Number} direction
|
|
*/
|
|
function getDirection(x, y) {
|
|
if (x === y) {
|
|
return DIRECTION_NONE;
|
|
}
|
|
if (abs(x) >= abs(y)) {
|
|
return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
|
|
}
|
|
return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
|
|
}
|
|
/**
|
|
* calculate the absolute distance between two points
|
|
* @param {Object} p1 {x, y}
|
|
* @param {Object} p2 {x, y}
|
|
* @param {Array} [props] containing x and y keys
|
|
* @return {Number} distance
|
|
*/
|
|
function getDistance(p1, p2, props) {
|
|
if (!props) {
|
|
props = PROPS_XY;
|
|
}
|
|
var x = p2[props[0]] - p1[props[0]], y = p2[props[1]] - p1[props[1]];
|
|
return Math.sqrt((x * x) + (y * y));
|
|
}
|
|
/**
|
|
* calculate the angle between two coordinates
|
|
* @param {Object} p1
|
|
* @param {Object} p2
|
|
* @param {Array} [props] containing x and y keys
|
|
* @return {Number} angle
|
|
*/
|
|
function getAngle(p1, p2, props) {
|
|
if (!props) {
|
|
props = PROPS_XY;
|
|
}
|
|
var x = p2[props[0]] - p1[props[0]], y = p2[props[1]] - p1[props[1]];
|
|
return Math.atan2(y, x) * 180 / Math.PI;
|
|
}
|
|
/**
|
|
* calculate the rotation degrees between two pointersets
|
|
* @param {Array} start array of pointers
|
|
* @param {Array} end array of pointers
|
|
* @return {Number} rotation
|
|
*/
|
|
function getRotation(start, end) {
|
|
return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
|
|
}
|
|
/**
|
|
* calculate the scale factor between two pointersets
|
|
* no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
|
|
* @param {Array} start array of pointers
|
|
* @param {Array} end array of pointers
|
|
* @return {Number} scale
|
|
*/
|
|
function getScale(start, end) {
|
|
return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
|
|
}
|
|
var MOUSE_INPUT_MAP = {
|
|
mousedown: INPUT_START,
|
|
mousemove: INPUT_MOVE,
|
|
mouseup: INPUT_END
|
|
};
|
|
var MOUSE_ELEMENT_EVENTS = 'mousedown';
|
|
var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';
|
|
/**
|
|
* Mouse events input
|
|
* @constructor
|
|
* @extends Input
|
|
*/
|
|
function MouseInput() {
|
|
this.evEl = MOUSE_ELEMENT_EVENTS;
|
|
this.evWin = MOUSE_WINDOW_EVENTS;
|
|
this.pressed = false; // mousedown state
|
|
Input.apply(this, arguments);
|
|
}
|
|
inherit(MouseInput, Input, {
|
|
/**
|
|
* handle mouse events
|
|
* @param {Object} ev
|
|
*/
|
|
handler: function MEhandler(ev) {
|
|
var eventType = MOUSE_INPUT_MAP[ev.type];
|
|
// on start we want to have the left mouse button down
|
|
if (eventType & INPUT_START && ev.button === 0) {
|
|
this.pressed = true;
|
|
}
|
|
if (eventType & INPUT_MOVE && ev.which !== 1) {
|
|
eventType = INPUT_END;
|
|
}
|
|
// mouse must be down
|
|
if (!this.pressed) {
|
|
return;
|
|
}
|
|
if (eventType & INPUT_END) {
|
|
this.pressed = false;
|
|
}
|
|
this.callback(this.manager, eventType, {
|
|
pointers: [ev],
|
|
changedPointers: [ev],
|
|
pointerType: INPUT_TYPE_MOUSE,
|
|
srcEvent: ev
|
|
});
|
|
}
|
|
});
|
|
var POINTER_INPUT_MAP = {
|
|
pointerdown: INPUT_START,
|
|
pointermove: INPUT_MOVE,
|
|
pointerup: INPUT_END,
|
|
pointercancel: INPUT_CANCEL,
|
|
pointerout: INPUT_CANCEL
|
|
};
|
|
// in IE10 the pointer types is defined as an enum
|
|
var IE10_POINTER_TYPE_ENUM = {
|
|
2: INPUT_TYPE_TOUCH,
|
|
3: INPUT_TYPE_PEN,
|
|
4: INPUT_TYPE_MOUSE,
|
|
5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
|
|
};
|
|
var POINTER_ELEMENT_EVENTS = 'pointerdown';
|
|
var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';
|
|
// IE10 has prefixed support, and case-sensitive
|
|
if (window.MSPointerEvent && !window.PointerEvent) {
|
|
POINTER_ELEMENT_EVENTS = 'MSPointerDown';
|
|
POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
|
|
}
|
|
/**
|
|
* Pointer events input
|
|
* @constructor
|
|
* @extends Input
|
|
*/
|
|
function PointerEventInput() {
|
|
this.evEl = POINTER_ELEMENT_EVENTS;
|
|
this.evWin = POINTER_WINDOW_EVENTS;
|
|
Input.apply(this, arguments);
|
|
this.store = (this.manager.session.pointerEvents = []);
|
|
}
|
|
inherit(PointerEventInput, Input, {
|
|
/**
|
|
* handle mouse events
|
|
* @param {Object} ev
|
|
*/
|
|
handler: function PEhandler(ev) {
|
|
var store = this.store;
|
|
var removePointer = false;
|
|
var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
|
|
var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
|
|
var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
|
|
var isTouch = (pointerType == INPUT_TYPE_TOUCH);
|
|
// get index of the event in the store
|
|
var storeIndex = inArray(store, ev.pointerId, 'pointerId');
|
|
// start and mouse must be down
|
|
if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
|
|
if (storeIndex < 0) {
|
|
store.push(ev);
|
|
storeIndex = store.length - 1;
|
|
}
|
|
}
|
|
else if (eventType & (INPUT_END | INPUT_CANCEL)) {
|
|
removePointer = true;
|
|
}
|
|
// it not found, so the pointer hasn't been down (so it's probably a hover)
|
|
if (storeIndex < 0) {
|
|
return;
|
|
}
|
|
// update the event in the store
|
|
store[storeIndex] = ev;
|
|
this.callback(this.manager, eventType, {
|
|
pointers: store,
|
|
changedPointers: [ev],
|
|
pointerType: pointerType,
|
|
srcEvent: ev
|
|
});
|
|
if (removePointer) {
|
|
// remove from the store
|
|
store.splice(storeIndex, 1);
|
|
}
|
|
}
|
|
});
|
|
var SINGLE_TOUCH_INPUT_MAP = {
|
|
touchstart: INPUT_START,
|
|
touchmove: INPUT_MOVE,
|
|
touchend: INPUT_END,
|
|
touchcancel: INPUT_CANCEL
|
|
};
|
|
var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
|
|
var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';
|
|
/**
|
|
* Touch events input
|
|
* @constructor
|
|
* @extends Input
|
|
*/
|
|
function SingleTouchInput() {
|
|
this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
|
|
this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
|
|
this.started = false;
|
|
Input.apply(this, arguments);
|
|
}
|
|
inherit(SingleTouchInput, Input, {
|
|
handler: function TEhandler(ev) {
|
|
var type = SINGLE_TOUCH_INPUT_MAP[ev.type];
|
|
// should we handle the touch events?
|
|
if (type === INPUT_START) {
|
|
this.started = true;
|
|
}
|
|
if (!this.started) {
|
|
return;
|
|
}
|
|
var touches = normalizeSingleTouches.call(this, ev, type);
|
|
// when done, reset the started state
|
|
if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
|
|
this.started = false;
|
|
}
|
|
this.callback(this.manager, type, {
|
|
pointers: touches[0],
|
|
changedPointers: touches[1],
|
|
pointerType: INPUT_TYPE_TOUCH,
|
|
srcEvent: ev
|
|
});
|
|
}
|
|
});
|
|
/**
|
|
* @this {TouchInput}
|
|
* @param {Object} ev
|
|
* @param {Number} type flag
|
|
* @returns {undefined|Array} [all, changed]
|
|
*/
|
|
function normalizeSingleTouches(ev, type) {
|
|
var all = toArray(ev.touches);
|
|
var changed = toArray(ev.changedTouches);
|
|
if (type & (INPUT_END | INPUT_CANCEL)) {
|
|
all = uniqueArray(all.concat(changed), 'identifier', true);
|
|
}
|
|
return [all, changed];
|
|
}
|
|
var TOUCH_INPUT_MAP = {
|
|
touchstart: INPUT_START,
|
|
touchmove: INPUT_MOVE,
|
|
touchend: INPUT_END,
|
|
touchcancel: INPUT_CANCEL
|
|
};
|
|
var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';
|
|
/**
|
|
* Multi-user touch events input
|
|
* @constructor
|
|
* @extends Input
|
|
*/
|
|
function TouchInput() {
|
|
this.evTarget = TOUCH_TARGET_EVENTS;
|
|
this.targetIds = {};
|
|
Input.apply(this, arguments);
|
|
}
|
|
inherit(TouchInput, Input, {
|
|
handler: function MTEhandler(ev) {
|
|
var type = TOUCH_INPUT_MAP[ev.type];
|
|
var touches = getTouches.call(this, ev, type);
|
|
if (!touches) {
|
|
return;
|
|
}
|
|
this.callback(this.manager, type, {
|
|
pointers: touches[0],
|
|
changedPointers: touches[1],
|
|
pointerType: INPUT_TYPE_TOUCH,
|
|
srcEvent: ev
|
|
});
|
|
}
|
|
});
|
|
/**
|
|
* @this {TouchInput}
|
|
* @param {Object} ev
|
|
* @param {Number} type flag
|
|
* @returns {undefined|Array} [all, changed]
|
|
*/
|
|
function getTouches(ev, type) {
|
|
var allTouches = toArray(ev.touches);
|
|
var targetIds = this.targetIds;
|
|
// when there is only one touch, the process can be simplified
|
|
if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
|
|
targetIds[allTouches[0].identifier] = true;
|
|
return [allTouches, allTouches];
|
|
}
|
|
var i, targetTouches, changedTouches = toArray(ev.changedTouches), changedTargetTouches = [], target = this.target;
|
|
// get target touches from touches
|
|
targetTouches = allTouches.filter(function (touch) {
|
|
return hasParent(touch.target, target);
|
|
});
|
|
// collect touches
|
|
if (type === INPUT_START) {
|
|
i = 0;
|
|
while (i < targetTouches.length) {
|
|
targetIds[targetTouches[i].identifier] = true;
|
|
i++;
|
|
}
|
|
}
|
|
// filter changed touches to only contain touches that exist in the collected target ids
|
|
i = 0;
|
|
while (i < changedTouches.length) {
|
|
if (targetIds[changedTouches[i].identifier]) {
|
|
changedTargetTouches.push(changedTouches[i]);
|
|
}
|
|
// cleanup removed touches
|
|
if (type & (INPUT_END | INPUT_CANCEL)) {
|
|
delete targetIds[changedTouches[i].identifier];
|
|
}
|
|
i++;
|
|
}
|
|
if (!changedTargetTouches.length) {
|
|
return;
|
|
}
|
|
return [
|
|
// merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
|
|
uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true),
|
|
changedTargetTouches
|
|
];
|
|
}
|
|
/**
|
|
* Combined touch and mouse input
|
|
*
|
|
* Touch has a higher priority then mouse, and while touching no mouse events are allowed.
|
|
* This because touch devices also emit mouse events while doing a touch.
|
|
*
|
|
* @constructor
|
|
* @extends Input
|
|
*/
|
|
var DEDUP_TIMEOUT = 2500;
|
|
var DEDUP_DISTANCE = 25;
|
|
function TouchMouseInput() {
|
|
Input.apply(this, arguments);
|
|
var handler = bindFn(this.handler, this);
|
|
this.touch = new TouchInput(this.manager, handler);
|
|
this.mouse = new MouseInput(this.manager, handler);
|
|
this.primaryTouch = null;
|
|
this.lastTouches = [];
|
|
}
|
|
inherit(TouchMouseInput, Input, {
|
|
/**
|
|
* handle mouse and touch events
|
|
* @param {Hammer} manager
|
|
* @param {String} inputEvent
|
|
* @param {Object} inputData
|
|
*/
|
|
handler: function TMEhandler(manager, inputEvent, inputData) {
|
|
var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH), isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE);
|
|
if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {
|
|
return;
|
|
}
|
|
// when we're in a touch event, record touches to de-dupe synthetic mouse event
|
|
if (isTouch) {
|
|
recordTouches.call(this, inputEvent, inputData);
|
|
}
|
|
else if (isMouse && isSyntheticEvent.call(this, inputData)) {
|
|
return;
|
|
}
|
|
this.callback(manager, inputEvent, inputData);
|
|
},
|
|
/**
|
|
* remove the event listeners
|
|
*/
|
|
destroy: function destroy() {
|
|
this.touch.destroy();
|
|
this.mouse.destroy();
|
|
}
|
|
});
|
|
function recordTouches(eventType, eventData) {
|
|
if (eventType & INPUT_START) {
|
|
this.primaryTouch = eventData.changedPointers[0].identifier;
|
|
setLastTouch.call(this, eventData);
|
|
}
|
|
else if (eventType & (INPUT_END | INPUT_CANCEL)) {
|
|
setLastTouch.call(this, eventData);
|
|
}
|
|
}
|
|
function setLastTouch(eventData) {
|
|
var touch = eventData.changedPointers[0];
|
|
if (touch.identifier === this.primaryTouch) {
|
|
var lastTouch = { x: touch.clientX, y: touch.clientY };
|
|
this.lastTouches.push(lastTouch);
|
|
var lts = this.lastTouches;
|
|
var removeLastTouch = function () {
|
|
var i = lts.indexOf(lastTouch);
|
|
if (i > -1) {
|
|
lts.splice(i, 1);
|
|
}
|
|
};
|
|
setTimeout(removeLastTouch, DEDUP_TIMEOUT);
|
|
}
|
|
}
|
|
function isSyntheticEvent(eventData) {
|
|
var x = eventData.srcEvent.clientX, y = eventData.srcEvent.clientY;
|
|
for (var i = 0; i < this.lastTouches.length; i++) {
|
|
var t = this.lastTouches[i];
|
|
var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);
|
|
if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
|
|
var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;
|
|
// magical touchAction value
|
|
var TOUCH_ACTION_COMPUTE = 'compute';
|
|
var TOUCH_ACTION_AUTO = 'auto';
|
|
var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
|
|
var TOUCH_ACTION_NONE = 'none';
|
|
var TOUCH_ACTION_PAN_X = 'pan-x';
|
|
var TOUCH_ACTION_PAN_Y = 'pan-y';
|
|
var TOUCH_ACTION_MAP = getTouchActionProps();
|
|
/**
|
|
* Touch Action
|
|
* sets the touchAction property or uses the js alternative
|
|
* @param {Manager} manager
|
|
* @param {String} value
|
|
* @constructor
|
|
*/
|
|
function TouchAction(manager, value) {
|
|
this.manager = manager;
|
|
this.set(value);
|
|
}
|
|
TouchAction.prototype = {
|
|
/**
|
|
* set the touchAction value on the element or enable the polyfill
|
|
* @param {String} value
|
|
*/
|
|
set: function (value) {
|
|
// find out the touch-action by the event handlers
|
|
if (value == TOUCH_ACTION_COMPUTE) {
|
|
value = this.compute();
|
|
}
|
|
if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {
|
|
this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
|
|
}
|
|
this.actions = value.toLowerCase().trim();
|
|
},
|
|
/**
|
|
* just re-set the touchAction value
|
|
*/
|
|
update: function () {
|
|
this.set(this.manager.options.touchAction);
|
|
},
|
|
/**
|
|
* compute the value for the touchAction property based on the recognizer's settings
|
|
* @returns {String} value
|
|
*/
|
|
compute: function () {
|
|
var actions = [];
|
|
each(this.manager.recognizers, function (recognizer) {
|
|
if (boolOrFn(recognizer.options.enable, [recognizer])) {
|
|
actions = actions.concat(recognizer.getTouchAction());
|
|
}
|
|
});
|
|
return cleanTouchActions(actions.join(' '));
|
|
},
|
|
/**
|
|
* this method is called on each input cycle and provides the preventing of the browser behavior
|
|
* @param {Object} input
|
|
*/
|
|
preventDefaults: function (input) {
|
|
var srcEvent = input.srcEvent;
|
|
var direction = input.offsetDirection;
|
|
// if the touch action did prevented once this session
|
|
if (this.manager.session.prevented) {
|
|
srcEvent.preventDefault();
|
|
return;
|
|
}
|
|
var actions = this.actions;
|
|
var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];
|
|
var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];
|
|
var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];
|
|
if (hasNone) {
|
|
//do not prevent defaults if this is a tap gesture
|
|
var isTapPointer = input.pointers.length === 1;
|
|
var isTapMovement = input.distance < 2;
|
|
var isTapTouchTime = input.deltaTime < 250;
|
|
if (isTapPointer && isTapMovement && isTapTouchTime) {
|
|
return;
|
|
}
|
|
}
|
|
if (hasPanX && hasPanY) {
|
|
// `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
|
|
return;
|
|
}
|
|
if (hasNone ||
|
|
(hasPanY && direction & DIRECTION_HORIZONTAL) ||
|
|
(hasPanX && direction & DIRECTION_VERTICAL)) {
|
|
return this.preventSrc(srcEvent);
|
|
}
|
|
},
|
|
/**
|
|
* call preventDefault to prevent the browser's default behavior (scrolling in most cases)
|
|
* @param {Object} srcEvent
|
|
*/
|
|
preventSrc: function (srcEvent) {
|
|
this.manager.session.prevented = true;
|
|
srcEvent.preventDefault();
|
|
}
|
|
};
|
|
/**
|
|
* when the touchActions are collected they are not a valid value, so we need to clean things up. *
|
|
* @param {String} actions
|
|
* @returns {*}
|
|
*/
|
|
function cleanTouchActions(actions) {
|
|
// none
|
|
if (inStr(actions, TOUCH_ACTION_NONE)) {
|
|
return TOUCH_ACTION_NONE;
|
|
}
|
|
var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
|
|
var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);
|
|
// if both pan-x and pan-y are set (different recognizers
|
|
// for different directions, e.g. horizontal pan but vertical swipe?)
|
|
// we need none (as otherwise with pan-x pan-y combined none of these
|
|
// recognizers will work, since the browser would handle all panning
|
|
if (hasPanX && hasPanY) {
|
|
return TOUCH_ACTION_NONE;
|
|
}
|
|
// pan-x OR pan-y
|
|
if (hasPanX || hasPanY) {
|
|
return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
|
|
}
|
|
// manipulation
|
|
if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
|
|
return TOUCH_ACTION_MANIPULATION;
|
|
}
|
|
return TOUCH_ACTION_AUTO;
|
|
}
|
|
function getTouchActionProps() {
|
|
if (!NATIVE_TOUCH_ACTION) {
|
|
return false;
|
|
}
|
|
var touchMap = {};
|
|
var cssSupports = window.CSS && window.CSS.supports;
|
|
['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function (val) {
|
|
// If css.supports is not supported but there is native touch-action assume it supports
|
|
// all values. This is the case for IE 10 and 11.
|
|
touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true;
|
|
});
|
|
return touchMap;
|
|
}
|
|
/**
|
|
* Recognizer flow explained; *
|
|
* All recognizers have the initial state of POSSIBLE when a input session starts.
|
|
* The definition of a input session is from the first input until the last input, with all it's movement in it. *
|
|
* Example session for mouse-input: mousedown -> mousemove -> mouseup
|
|
*
|
|
* On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
|
|
* which determines with state it should be.
|
|
*
|
|
* If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
|
|
* POSSIBLE to give it another change on the next cycle.
|
|
*
|
|
* Possible
|
|
* |
|
|
* +-----+---------------+
|
|
* | |
|
|
* +-----+-----+ |
|
|
* | | |
|
|
* Failed Cancelled |
|
|
* +-------+------+
|
|
* | |
|
|
* Recognized Began
|
|
* |
|
|
* Changed
|
|
* |
|
|
* Ended/Recognized
|
|
*/
|
|
var STATE_POSSIBLE = 1;
|
|
var STATE_BEGAN = 2;
|
|
var STATE_CHANGED = 4;
|
|
var STATE_ENDED = 8;
|
|
var STATE_RECOGNIZED = STATE_ENDED;
|
|
var STATE_CANCELLED = 16;
|
|
var STATE_FAILED = 32;
|
|
/**
|
|
* Recognizer
|
|
* Every recognizer needs to extend from this class.
|
|
* @constructor
|
|
* @param {Object} options
|
|
*/
|
|
function Recognizer(options) {
|
|
this.options = assign({}, this.defaults, options || {});
|
|
this.id = uniqueId();
|
|
this.manager = null;
|
|
// default is enable true
|
|
this.options.enable = ifUndefined(this.options.enable, true);
|
|
this.state = STATE_POSSIBLE;
|
|
this.simultaneous = {};
|
|
this.requireFail = [];
|
|
}
|
|
Recognizer.prototype = {
|
|
/**
|
|
* @virtual
|
|
* @type {Object}
|
|
*/
|
|
defaults: {},
|
|
/**
|
|
* set options
|
|
* @param {Object} options
|
|
* @return {Recognizer}
|
|
*/
|
|
set: function (options) {
|
|
assign(this.options, options);
|
|
// also update the touchAction, in case something changed about the directions/enabled state
|
|
this.manager && this.manager.touchAction.update();
|
|
return this;
|
|
},
|
|
/**
|
|
* recognize simultaneous with an other recognizer.
|
|
* @param {Recognizer} otherRecognizer
|
|
* @returns {Recognizer} this
|
|
*/
|
|
recognizeWith: function (otherRecognizer) {
|
|
if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
|
|
return this;
|
|
}
|
|
var simultaneous = this.simultaneous;
|
|
otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
|
|
if (!simultaneous[otherRecognizer.id]) {
|
|
simultaneous[otherRecognizer.id] = otherRecognizer;
|
|
otherRecognizer.recognizeWith(this);
|
|
}
|
|
return this;
|
|
},
|
|
/**
|
|
* drop the simultaneous link. it doesnt remove the link on the other recognizer.
|
|
* @param {Recognizer} otherRecognizer
|
|
* @returns {Recognizer} this
|
|
*/
|
|
dropRecognizeWith: function (otherRecognizer) {
|
|
if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
|
|
return this;
|
|
}
|
|
otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
|
|
delete this.simultaneous[otherRecognizer.id];
|
|
return this;
|
|
},
|
|
/**
|
|
* recognizer can only run when an other is failing
|
|
* @param {Recognizer} otherRecognizer
|
|
* @returns {Recognizer} this
|
|
*/
|
|
requireFailure: function (otherRecognizer) {
|
|
if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
|
|
return this;
|
|
}
|
|
var requireFail = this.requireFail;
|
|
otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
|
|
if (inArray(requireFail, otherRecognizer) === -1) {
|
|
requireFail.push(otherRecognizer);
|
|
otherRecognizer.requireFailure(this);
|
|
}
|
|
return this;
|
|
},
|
|
/**
|
|
* drop the requireFailure link. it does not remove the link on the other recognizer.
|
|
* @param {Recognizer} otherRecognizer
|
|
* @returns {Recognizer} this
|
|
*/
|
|
dropRequireFailure: function (otherRecognizer) {
|
|
if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
|
|
return this;
|
|
}
|
|
otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
|
|
var index = inArray(this.requireFail, otherRecognizer);
|
|
if (index > -1) {
|
|
this.requireFail.splice(index, 1);
|
|
}
|
|
return this;
|
|
},
|
|
/**
|
|
* has require failures boolean
|
|
* @returns {boolean}
|
|
*/
|
|
hasRequireFailures: function () {
|
|
return this.requireFail.length > 0;
|
|
},
|
|
/**
|
|
* if the recognizer can recognize simultaneous with an other recognizer
|
|
* @param {Recognizer} otherRecognizer
|
|
* @returns {Boolean}
|
|
*/
|
|
canRecognizeWith: function (otherRecognizer) {
|
|
return !!this.simultaneous[otherRecognizer.id];
|
|
},
|
|
/**
|
|
* You should use `tryEmit` instead of `emit` directly to check
|
|
* that all the needed recognizers has failed before emitting.
|
|
* @param {Object} input
|
|
*/
|
|
emit: function (input) {
|
|
var self = this;
|
|
var state = this.state;
|
|
function emit(event) {
|
|
self.manager.emit(event, input);
|
|
}
|
|
// 'panstart' and 'panmove'
|
|
if (state < STATE_ENDED) {
|
|
emit(self.options.event + stateStr(state));
|
|
}
|
|
emit(self.options.event); // simple 'eventName' events
|
|
if (input.additionalEvent) { // additional event(panleft, panright, pinchin, pinchout...)
|
|
emit(input.additionalEvent);
|
|
}
|
|
// panend and pancancel
|
|
if (state >= STATE_ENDED) {
|
|
emit(self.options.event + stateStr(state));
|
|
}
|
|
},
|
|
/**
|
|
* Check that all the require failure recognizers has failed,
|
|
* if true, it emits a gesture event,
|
|
* otherwise, setup the state to FAILED.
|
|
* @param {Object} input
|
|
*/
|
|
tryEmit: function (input) {
|
|
if (this.canEmit()) {
|
|
return this.emit(input);
|
|
}
|
|
// it's failing anyway
|
|
this.state = STATE_FAILED;
|
|
},
|
|
/**
|
|
* can we emit?
|
|
* @returns {boolean}
|
|
*/
|
|
canEmit: function () {
|
|
var i = 0;
|
|
while (i < this.requireFail.length) {
|
|
if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
|
|
return false;
|
|
}
|
|
i++;
|
|
}
|
|
return true;
|
|
},
|
|
/**
|
|
* update the recognizer
|
|
* @param {Object} inputData
|
|
*/
|
|
recognize: function (inputData) {
|
|
// make a new copy of the inputData
|
|
// so we can change the inputData without messing up the other recognizers
|
|
var inputDataClone = assign({}, inputData);
|
|
// is is enabled and allow recognizing?
|
|
if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
|
|
this.reset();
|
|
this.state = STATE_FAILED;
|
|
return;
|
|
}
|
|
// reset when we've reached the end
|
|
if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
|
|
this.state = STATE_POSSIBLE;
|
|
}
|
|
this.state = this.process(inputDataClone);
|
|
// the recognizer has recognized a gesture
|
|
// so trigger an event
|
|
if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
|
|
this.tryEmit(inputDataClone);
|
|
}
|
|
},
|
|
/**
|
|
* return the state of the recognizer
|
|
* the actual recognizing happens in this method
|
|
* @virtual
|
|
* @param {Object} inputData
|
|
* @returns {Const} STATE
|
|
*/
|
|
process: function (inputData) { },
|
|
/**
|
|
* return the preferred touch-action
|
|
* @virtual
|
|
* @returns {Array}
|
|
*/
|
|
getTouchAction: function () { },
|
|
/**
|
|
* called when the gesture isn't allowed to recognize
|
|
* like when another is being recognized or it is disabled
|
|
* @virtual
|
|
*/
|
|
reset: function () { }
|
|
};
|
|
/**
|
|
* get a usable string, used as event postfix
|
|
* @param {Const} state
|
|
* @returns {String} state
|
|
*/
|
|
function stateStr(state) {
|
|
if (state & STATE_CANCELLED) {
|
|
return 'cancel';
|
|
}
|
|
else if (state & STATE_ENDED) {
|
|
return 'end';
|
|
}
|
|
else if (state & STATE_CHANGED) {
|
|
return 'move';
|
|
}
|
|
else if (state & STATE_BEGAN) {
|
|
return 'start';
|
|
}
|
|
return '';
|
|
}
|
|
/**
|
|
* direction cons to string
|
|
* @param {Const} direction
|
|
* @returns {String}
|
|
*/
|
|
function directionStr(direction) {
|
|
if (direction == DIRECTION_DOWN) {
|
|
return 'down';
|
|
}
|
|
else if (direction == DIRECTION_UP) {
|
|
return 'up';
|
|
}
|
|
else if (direction == DIRECTION_LEFT) {
|
|
return 'left';
|
|
}
|
|
else if (direction == DIRECTION_RIGHT) {
|
|
return 'right';
|
|
}
|
|
return '';
|
|
}
|
|
/**
|
|
* get a recognizer by name if it is bound to a manager
|
|
* @param {Recognizer|String} otherRecognizer
|
|
* @param {Recognizer} recognizer
|
|
* @returns {Recognizer}
|
|
*/
|
|
function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
|
|
var manager = recognizer.manager;
|
|
if (manager) {
|
|
return manager.get(otherRecognizer);
|
|
}
|
|
return otherRecognizer;
|
|
}
|
|
/**
|
|
* This recognizer is just used as a base for the simple attribute recognizers.
|
|
* @constructor
|
|
* @extends Recognizer
|
|
*/
|
|
function AttrRecognizer() {
|
|
Recognizer.apply(this, arguments);
|
|
}
|
|
inherit(AttrRecognizer, Recognizer, {
|
|
/**
|
|
* @namespace
|
|
* @memberof AttrRecognizer
|
|
*/
|
|
defaults: {
|
|
/**
|
|
* @type {Number}
|
|
* @default 1
|
|
*/
|
|
pointers: 1
|
|
},
|
|
/**
|
|
* Used to check if it the recognizer receives valid input, like input.distance > 10.
|
|
* @memberof AttrRecognizer
|
|
* @param {Object} input
|
|
* @returns {Boolean} recognized
|
|
*/
|
|
attrTest: function (input) {
|
|
var optionPointers = this.options.pointers;
|
|
return optionPointers === 0 || input.pointers.length === optionPointers;
|
|
},
|
|
/**
|
|
* Process the input and return the state for the recognizer
|
|
* @memberof AttrRecognizer
|
|
* @param {Object} input
|
|
* @returns {*} State
|
|
*/
|
|
process: function (input) {
|
|
var state = this.state;
|
|
var eventType = input.eventType;
|
|
var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
|
|
var isValid = this.attrTest(input);
|
|
// on cancel input and we've recognized before, return STATE_CANCELLED
|
|
if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
|
|
return state | STATE_CANCELLED;
|
|
}
|
|
else if (isRecognized || isValid) {
|
|
if (eventType & INPUT_END) {
|
|
return state | STATE_ENDED;
|
|
}
|
|
else if (!(state & STATE_BEGAN)) {
|
|
return STATE_BEGAN;
|
|
}
|
|
return state | STATE_CHANGED;
|
|
}
|
|
return STATE_FAILED;
|
|
}
|
|
});
|
|
/**
|
|
* Pan
|
|
* Recognized when the pointer is down and moved in the allowed direction.
|
|
* @constructor
|
|
* @extends AttrRecognizer
|
|
*/
|
|
function PanRecognizer() {
|
|
AttrRecognizer.apply(this, arguments);
|
|
this.pX = null;
|
|
this.pY = null;
|
|
}
|
|
inherit(PanRecognizer, AttrRecognizer, {
|
|
/**
|
|
* @namespace
|
|
* @memberof PanRecognizer
|
|
*/
|
|
defaults: {
|
|
event: 'pan',
|
|
threshold: 10,
|
|
pointers: 1,
|
|
direction: DIRECTION_ALL
|
|
},
|
|
getTouchAction: function () {
|
|
var direction = this.options.direction;
|
|
var actions = [];
|
|
if (direction & DIRECTION_HORIZONTAL) {
|
|
actions.push(TOUCH_ACTION_PAN_Y);
|
|
}
|
|
if (direction & DIRECTION_VERTICAL) {
|
|
actions.push(TOUCH_ACTION_PAN_X);
|
|
}
|
|
return actions;
|
|
},
|
|
directionTest: function (input) {
|
|
var options = this.options;
|
|
var hasMoved = true;
|
|
var distance = input.distance;
|
|
var direction = input.direction;
|
|
var x = input.deltaX;
|
|
var y = input.deltaY;
|
|
// lock to axis?
|
|
if (!(direction & options.direction)) {
|
|
if (options.direction & DIRECTION_HORIZONTAL) {
|
|
direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT;
|
|
hasMoved = x != this.pX;
|
|
distance = Math.abs(input.deltaX);
|
|
}
|
|
else {
|
|
direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN;
|
|
hasMoved = y != this.pY;
|
|
distance = Math.abs(input.deltaY);
|
|
}
|
|
}
|
|
input.direction = direction;
|
|
return hasMoved && distance > options.threshold && direction & options.direction;
|
|
},
|
|
attrTest: function (input) {
|
|
return AttrRecognizer.prototype.attrTest.call(this, input) &&
|
|
(this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input)));
|
|
},
|
|
emit: function (input) {
|
|
this.pX = input.deltaX;
|
|
this.pY = input.deltaY;
|
|
var direction = directionStr(input.direction);
|
|
if (direction) {
|
|
input.additionalEvent = this.options.event + direction;
|
|
}
|
|
this._super.emit.call(this, input);
|
|
}
|
|
});
|
|
/**
|
|
* Pinch
|
|
* Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
|
|
* @constructor
|
|
* @extends AttrRecognizer
|
|
*/
|
|
function PinchRecognizer() {
|
|
AttrRecognizer.apply(this, arguments);
|
|
}
|
|
inherit(PinchRecognizer, AttrRecognizer, {
|
|
/**
|
|
* @namespace
|
|
* @memberof PinchRecognizer
|
|
*/
|
|
defaults: {
|
|
event: 'pinch',
|
|
threshold: 0,
|
|
pointers: 2
|
|
},
|
|
getTouchAction: function () {
|
|
return [TOUCH_ACTION_NONE];
|
|
},
|
|
attrTest: function (input) {
|
|
return this._super.attrTest.call(this, input) &&
|
|
(Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
|
|
},
|
|
emit: function (input) {
|
|
if (input.scale !== 1) {
|
|
var inOut = input.scale < 1 ? 'in' : 'out';
|
|
input.additionalEvent = this.options.event + inOut;
|
|
}
|
|
this._super.emit.call(this, input);
|
|
}
|
|
});
|
|
/**
|
|
* Press
|
|
* Recognized when the pointer is down for x ms without any movement.
|
|
* @constructor
|
|
* @extends Recognizer
|
|
*/
|
|
function PressRecognizer() {
|
|
Recognizer.apply(this, arguments);
|
|
this._timer = null;
|
|
this._input = null;
|
|
}
|
|
inherit(PressRecognizer, Recognizer, {
|
|
/**
|
|
* @namespace
|
|
* @memberof PressRecognizer
|
|
*/
|
|
defaults: {
|
|
event: 'press',
|
|
pointers: 1,
|
|
time: 251,
|
|
threshold: 9 // a minimal movement is ok, but keep it low
|
|
},
|
|
getTouchAction: function () {
|
|
return [TOUCH_ACTION_AUTO];
|
|
},
|
|
process: function (input) {
|
|
var options = this.options;
|
|
var validPointers = input.pointers.length === options.pointers;
|
|
var validMovement = input.distance < options.threshold;
|
|
var validTime = input.deltaTime > options.time;
|
|
this._input = input;
|
|
// we only allow little movement
|
|
// and we've reached an end event, so a tap is possible
|
|
if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {
|
|
this.reset();
|
|
}
|
|
else if (input.eventType & INPUT_START) {
|
|
this.reset();
|
|
this._timer = setTimeoutContext(function () {
|
|
this.state = STATE_RECOGNIZED;
|
|
this.tryEmit();
|
|
}, options.time, this);
|
|
}
|
|
else if (input.eventType & INPUT_END) {
|
|
return STATE_RECOGNIZED;
|
|
}
|
|
return STATE_FAILED;
|
|
},
|
|
reset: function () {
|
|
clearTimeout(this._timer);
|
|
},
|
|
emit: function (input) {
|
|
if (this.state !== STATE_RECOGNIZED) {
|
|
return;
|
|
}
|
|
if (input && (input.eventType & INPUT_END)) {
|
|
this.manager.emit(this.options.event + 'up', input);
|
|
}
|
|
else {
|
|
this._input.timeStamp = now();
|
|
this.manager.emit(this.options.event, this._input);
|
|
}
|
|
}
|
|
});
|
|
/**
|
|
* Rotate
|
|
* Recognized when two or more pointer are moving in a circular motion.
|
|
* @constructor
|
|
* @extends AttrRecognizer
|
|
*/
|
|
function RotateRecognizer() {
|
|
AttrRecognizer.apply(this, arguments);
|
|
}
|
|
inherit(RotateRecognizer, AttrRecognizer, {
|
|
/**
|
|
* @namespace
|
|
* @memberof RotateRecognizer
|
|
*/
|
|
defaults: {
|
|
event: 'rotate',
|
|
threshold: 0,
|
|
pointers: 2
|
|
},
|
|
getTouchAction: function () {
|
|
return [TOUCH_ACTION_NONE];
|
|
},
|
|
attrTest: function (input) {
|
|
return this._super.attrTest.call(this, input) &&
|
|
(Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
|
|
}
|
|
});
|
|
/**
|
|
* Swipe
|
|
* Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
|
|
* @constructor
|
|
* @extends AttrRecognizer
|
|
*/
|
|
function SwipeRecognizer() {
|
|
AttrRecognizer.apply(this, arguments);
|
|
}
|
|
inherit(SwipeRecognizer, AttrRecognizer, {
|
|
/**
|
|
* @namespace
|
|
* @memberof SwipeRecognizer
|
|
*/
|
|
defaults: {
|
|
event: 'swipe',
|
|
threshold: 10,
|
|
velocity: 0.3,
|
|
direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
|
|
pointers: 1
|
|
},
|
|
getTouchAction: function () {
|
|
return PanRecognizer.prototype.getTouchAction.call(this);
|
|
},
|
|
attrTest: function (input) {
|
|
var direction = this.options.direction;
|
|
var velocity;
|
|
if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
|
|
velocity = input.overallVelocity;
|
|
}
|
|
else if (direction & DIRECTION_HORIZONTAL) {
|
|
velocity = input.overallVelocityX;
|
|
}
|
|
else if (direction & DIRECTION_VERTICAL) {
|
|
velocity = input.overallVelocityY;
|
|
}
|
|
return this._super.attrTest.call(this, input) &&
|
|
direction & input.offsetDirection &&
|
|
input.distance > this.options.threshold &&
|
|
input.maxPointers == this.options.pointers &&
|
|
abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
|
|
},
|
|
emit: function (input) {
|
|
var direction = directionStr(input.offsetDirection);
|
|
if (direction) {
|
|
this.manager.emit(this.options.event + direction, input);
|
|
}
|
|
this.manager.emit(this.options.event, input);
|
|
}
|
|
});
|
|
/**
|
|
* A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
|
|
* between the given interval and position. The delay option can be used to recognize multi-taps without firing
|
|
* a single tap.
|
|
*
|
|
* The eventData from the emitted event contains the property `tapCount`, which contains the amount of
|
|
* multi-taps being recognized.
|
|
* @constructor
|
|
* @extends Recognizer
|
|
*/
|
|
function TapRecognizer() {
|
|
Recognizer.apply(this, arguments);
|
|
// previous time and center,
|
|
// used for tap counting
|
|
this.pTime = false;
|
|
this.pCenter = false;
|
|
this._timer = null;
|
|
this._input = null;
|
|
this.count = 0;
|
|
}
|
|
inherit(TapRecognizer, Recognizer, {
|
|
/**
|
|
* @namespace
|
|
* @memberof PinchRecognizer
|
|
*/
|
|
defaults: {
|
|
event: 'tap',
|
|
pointers: 1,
|
|
taps: 1,
|
|
interval: 300,
|
|
time: 250,
|
|
threshold: 9,
|
|
posThreshold: 10 // a multi-tap can be a bit off the initial position
|
|
},
|
|
getTouchAction: function () {
|
|
return [TOUCH_ACTION_MANIPULATION];
|
|
},
|
|
process: function (input) {
|
|
var options = this.options;
|
|
var validPointers = input.pointers.length === options.pointers;
|
|
var validMovement = input.distance < options.threshold;
|
|
var validTouchTime = input.deltaTime < options.time;
|
|
this.reset();
|
|
if ((input.eventType & INPUT_START) && (this.count === 0)) {
|
|
return this.failTimeout();
|
|
}
|
|
// we only allow little movement
|
|
// and we've reached an end event, so a tap is possible
|
|
if (validMovement && validTouchTime && validPointers) {
|
|
if (input.eventType != INPUT_END) {
|
|
return this.failTimeout();
|
|
}
|
|
var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;
|
|
var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
|
|
this.pTime = input.timeStamp;
|
|
this.pCenter = input.center;
|
|
if (!validMultiTap || !validInterval) {
|
|
this.count = 1;
|
|
}
|
|
else {
|
|
this.count += 1;
|
|
}
|
|
this._input = input;
|
|
// if tap count matches we have recognized it,
|
|
// else it has began recognizing...
|
|
var tapCount = this.count % options.taps;
|
|
if (tapCount === 0) {
|
|
// no failing requirements, immediately trigger the tap event
|
|
// or wait as long as the multitap interval to trigger
|
|
if (!this.hasRequireFailures()) {
|
|
return STATE_RECOGNIZED;
|
|
}
|
|
else {
|
|
this._timer = setTimeoutContext(function () {
|
|
this.state = STATE_RECOGNIZED;
|
|
this.tryEmit();
|
|
}, options.interval, this);
|
|
return STATE_BEGAN;
|
|
}
|
|
}
|
|
}
|
|
return STATE_FAILED;
|
|
},
|
|
failTimeout: function () {
|
|
this._timer = setTimeoutContext(function () {
|
|
this.state = STATE_FAILED;
|
|
}, this.options.interval, this);
|
|
return STATE_FAILED;
|
|
},
|
|
reset: function () {
|
|
clearTimeout(this._timer);
|
|
},
|
|
emit: function () {
|
|
if (this.state == STATE_RECOGNIZED) {
|
|
this._input.tapCount = this.count;
|
|
this.manager.emit(this.options.event, this._input);
|
|
}
|
|
}
|
|
});
|
|
/**
|
|
* Simple way to create a manager with a default set of recognizers.
|
|
* @param {HTMLElement} element
|
|
* @param {Object} [options]
|
|
* @constructor
|
|
*/
|
|
function Hammer(element, options) {
|
|
options = options || {};
|
|
options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);
|
|
return new Manager(element, options);
|
|
}
|
|
/**
|
|
* @const {string}
|
|
*/
|
|
Hammer.VERSION = '2.0.7';
|
|
/**
|
|
* default settings
|
|
* @namespace
|
|
*/
|
|
Hammer.defaults = {
|
|
/**
|
|
* set if DOM events are being triggered.
|
|
* But this is slower and unused by simple implementations, so disabled by default.
|
|
* @type {Boolean}
|
|
* @default false
|
|
*/
|
|
domEvents: false,
|
|
/**
|
|
* The value for the touchAction property/fallback.
|
|
* When set to `compute` it will magically set the correct value based on the added recognizers.
|
|
* @type {String}
|
|
* @default compute
|
|
*/
|
|
touchAction: TOUCH_ACTION_COMPUTE,
|
|
/**
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
enable: true,
|
|
/**
|
|
* EXPERIMENTAL FEATURE -- can be removed/changed
|
|
* Change the parent input target element.
|
|
* If Null, then it is being set the to main element.
|
|
* @type {Null|EventTarget}
|
|
* @default null
|
|
*/
|
|
inputTarget: null,
|
|
/**
|
|
* force an input class
|
|
* @type {Null|Function}
|
|
* @default null
|
|
*/
|
|
inputClass: null,
|
|
/**
|
|
* Default recognizer setup when calling `Hammer()`
|
|
* When creating a new Manager these will be skipped.
|
|
* @type {Array}
|
|
*/
|
|
preset: [
|
|
// RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
|
|
[RotateRecognizer, { enable: false }],
|
|
[PinchRecognizer, { enable: false }, ['rotate']],
|
|
[SwipeRecognizer, { direction: DIRECTION_HORIZONTAL }],
|
|
[PanRecognizer, { direction: DIRECTION_HORIZONTAL }, ['swipe']],
|
|
[TapRecognizer],
|
|
[TapRecognizer, { event: 'doubletap', taps: 2 }, ['tap']],
|
|
[PressRecognizer]
|
|
],
|
|
/**
|
|
* Some CSS properties can be used to improve the working of Hammer.
|
|
* Add them to this method and they will be set when creating a new Manager.
|
|
* @namespace
|
|
*/
|
|
cssProps: {
|
|
/**
|
|
* Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
|
|
* @type {String}
|
|
* @default 'none'
|
|
*/
|
|
userSelect: 'none',
|
|
/**
|
|
* Disable the Windows Phone grippers when pressing an element.
|
|
* @type {String}
|
|
* @default 'none'
|
|
*/
|
|
touchSelect: 'none',
|
|
/**
|
|
* Disables the default callout shown when you touch and hold a touch target.
|
|
* On iOS, when you touch and hold a touch target such as a link, Safari displays
|
|
* a callout containing information about the link. This property allows you to disable that callout.
|
|
* @type {String}
|
|
* @default 'none'
|
|
*/
|
|
touchCallout: 'none',
|
|
/**
|
|
* Specifies whether zooming is enabled. Used by IE10>
|
|
* @type {String}
|
|
* @default 'none'
|
|
*/
|
|
contentZooming: 'none',
|
|
/**
|
|
* Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
|
|
* @type {String}
|
|
* @default 'none'
|
|
*/
|
|
userDrag: 'none',
|
|
/**
|
|
* Overrides the highlight color shown when the user taps a link or a JavaScript
|
|
* clickable element in iOS. This property obeys the alpha value, if specified.
|
|
* @type {String}
|
|
* @default 'rgba(0,0,0,0)'
|
|
*/
|
|
tapHighlightColor: 'rgba(0,0,0,0)'
|
|
}
|
|
};
|
|
var STOP = 1;
|
|
var FORCED_STOP = 2;
|
|
/**
|
|
* Manager
|
|
* @param {HTMLElement} element
|
|
* @param {Object} [options]
|
|
* @constructor
|
|
*/
|
|
function Manager(element, options) {
|
|
this.options = assign({}, Hammer.defaults, options || {});
|
|
this.options.inputTarget = this.options.inputTarget || element;
|
|
this.handlers = {};
|
|
this.session = {};
|
|
this.recognizers = [];
|
|
this.oldCssProps = {};
|
|
this.element = element;
|
|
this.input = createInputInstance(this);
|
|
this.touchAction = new TouchAction(this, this.options.touchAction);
|
|
toggleCssProps(this, true);
|
|
each(this.options.recognizers, function (item) {
|
|
var recognizer = this.add(new (item[0])(item[1]));
|
|
item[2] && recognizer.recognizeWith(item[2]);
|
|
item[3] && recognizer.requireFailure(item[3]);
|
|
}, this);
|
|
}
|
|
Manager.prototype = {
|
|
/**
|
|
* set options
|
|
* @param {Object} options
|
|
* @returns {Manager}
|
|
*/
|
|
set: function (options) {
|
|
assign(this.options, options);
|
|
// Options that need a little more setup
|
|
if (options.touchAction) {
|
|
this.touchAction.update();
|
|
}
|
|
if (options.inputTarget) {
|
|
// Clean up existing event listeners and reinitialize
|
|
this.input.destroy();
|
|
this.input.target = options.inputTarget;
|
|
this.input.init();
|
|
}
|
|
return this;
|
|
},
|
|
/**
|
|
* stop recognizing for this session.
|
|
* This session will be discarded, when a new [input]start event is fired.
|
|
* When forced, the recognizer cycle is stopped immediately.
|
|
* @param {Boolean} [force]
|
|
*/
|
|
stop: function (force) {
|
|
this.session.stopped = force ? FORCED_STOP : STOP;
|
|
},
|
|
/**
|
|
* run the recognizers!
|
|
* called by the inputHandler function on every movement of the pointers (touches)
|
|
* it walks through all the recognizers and tries to detect the gesture that is being made
|
|
* @param {Object} inputData
|
|
*/
|
|
recognize: function (inputData) {
|
|
var session = this.session;
|
|
if (session.stopped) {
|
|
return;
|
|
}
|
|
// run the touch-action polyfill
|
|
this.touchAction.preventDefaults(inputData);
|
|
var recognizer;
|
|
var recognizers = this.recognizers;
|
|
// this holds the recognizer that is being recognized.
|
|
// so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
|
|
// if no recognizer is detecting a thing, it is set to `null`
|
|
var curRecognizer = session.curRecognizer;
|
|
// reset when the last recognizer is recognized
|
|
// or when we're in a new session
|
|
if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {
|
|
curRecognizer = session.curRecognizer = null;
|
|
}
|
|
var i = 0;
|
|
while (i < recognizers.length) {
|
|
recognizer = recognizers[i];
|
|
// find out if we are allowed try to recognize the input for this one.
|
|
// 1. allow if the session is NOT forced stopped (see the .stop() method)
|
|
// 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
|
|
// that is being recognized.
|
|
// 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
|
|
// this can be setup with the `recognizeWith()` method on the recognizer.
|
|
if (session.stopped !== FORCED_STOP && ( // 1
|
|
!curRecognizer || recognizer == curRecognizer || // 2
|
|
recognizer.canRecognizeWith(curRecognizer))) { // 3
|
|
recognizer.recognize(inputData);
|
|
}
|
|
else {
|
|
recognizer.reset();
|
|
}
|
|
// if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
|
|
// current active recognizer. but only if we don't already have an active recognizer
|
|
if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
|
|
curRecognizer = session.curRecognizer = recognizer;
|
|
}
|
|
i++;
|
|
}
|
|
},
|
|
/**
|
|
* get a recognizer by its event name.
|
|
* @param {Recognizer|String} recognizer
|
|
* @returns {Recognizer|Null}
|
|
*/
|
|
get: function (recognizer) {
|
|
if (recognizer instanceof Recognizer) {
|
|
return recognizer;
|
|
}
|
|
var recognizers = this.recognizers;
|
|
for (var i = 0; i < recognizers.length; i++) {
|
|
if (recognizers[i].options.event == recognizer) {
|
|
return recognizers[i];
|
|
}
|
|
}
|
|
return null;
|
|
},
|
|
/**
|
|
* add a recognizer to the manager
|
|
* existing recognizers with the same event name will be removed
|
|
* @param {Recognizer} recognizer
|
|
* @returns {Recognizer|Manager}
|
|
*/
|
|
add: function (recognizer) {
|
|
if (invokeArrayArg(recognizer, 'add', this)) {
|
|
return this;
|
|
}
|
|
// remove existing
|
|
var existing = this.get(recognizer.options.event);
|
|
if (existing) {
|
|
this.remove(existing);
|
|
}
|
|
this.recognizers.push(recognizer);
|
|
recognizer.manager = this;
|
|
this.touchAction.update();
|
|
return recognizer;
|
|
},
|
|
/**
|
|
* remove a recognizer by name or instance
|
|
* @param {Recognizer|String} recognizer
|
|
* @returns {Manager}
|
|
*/
|
|
remove: function (recognizer) {
|
|
if (invokeArrayArg(recognizer, 'remove', this)) {
|
|
return this;
|
|
}
|
|
recognizer = this.get(recognizer);
|
|
// let's make sure this recognizer exists
|
|
if (recognizer) {
|
|
var recognizers = this.recognizers;
|
|
var index = inArray(recognizers, recognizer);
|
|
if (index !== -1) {
|
|
recognizers.splice(index, 1);
|
|
this.touchAction.update();
|
|
}
|
|
}
|
|
return this;
|
|
},
|
|
/**
|
|
* bind event
|
|
* @param {String} events
|
|
* @param {Function} handler
|
|
* @returns {EventEmitter} this
|
|
*/
|
|
on: function (events, handler) {
|
|
if (events === undefined) {
|
|
return;
|
|
}
|
|
if (handler === undefined) {
|
|
return;
|
|
}
|
|
var handlers = this.handlers;
|
|
each(splitStr(events), function (event) {
|
|
handlers[event] = handlers[event] || [];
|
|
handlers[event].push(handler);
|
|
});
|
|
return this;
|
|
},
|
|
/**
|
|
* unbind event, leave emit blank to remove all handlers
|
|
* @param {String} events
|
|
* @param {Function} [handler]
|
|
* @returns {EventEmitter} this
|
|
*/
|
|
off: function (events, handler) {
|
|
if (events === undefined) {
|
|
return;
|
|
}
|
|
var handlers = this.handlers;
|
|
each(splitStr(events), function (event) {
|
|
if (!handler) {
|
|
delete handlers[event];
|
|
}
|
|
else {
|
|
handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
|
|
}
|
|
});
|
|
return this;
|
|
},
|
|
/**
|
|
* emit event to the listeners
|
|
* @param {String} event
|
|
* @param {Object} data
|
|
*/
|
|
emit: function (event, data) {
|
|
// we also want to trigger dom events
|
|
if (this.options.domEvents) {
|
|
triggerDomEvent(event, data);
|
|
}
|
|
// no handlers, so skip it all
|
|
var handlers = this.handlers[event] && this.handlers[event].slice();
|
|
if (!handlers || !handlers.length) {
|
|
return;
|
|
}
|
|
data.type = event;
|
|
data.preventDefault = function () {
|
|
data.srcEvent.preventDefault();
|
|
};
|
|
var i = 0;
|
|
while (i < handlers.length) {
|
|
handlers[i](data);
|
|
i++;
|
|
}
|
|
},
|
|
/**
|
|
* destroy the manager and unbinds all events
|
|
* it doesn't unbind dom events, that is the user own responsibility
|
|
*/
|
|
destroy: function () {
|
|
this.element && toggleCssProps(this, false);
|
|
this.handlers = {};
|
|
this.session = {};
|
|
this.input.destroy();
|
|
this.element = null;
|
|
}
|
|
};
|
|
/**
|
|
* add/remove the css properties as defined in manager.options.cssProps
|
|
* @param {Manager} manager
|
|
* @param {Boolean} add
|
|
*/
|
|
function toggleCssProps(manager, add) {
|
|
var element = manager.element;
|
|
if (!element.style) {
|
|
return;
|
|
}
|
|
var prop;
|
|
each(manager.options.cssProps, function (value, name) {
|
|
prop = prefixed(element.style, name);
|
|
if (add) {
|
|
manager.oldCssProps[prop] = element.style[prop];
|
|
element.style[prop] = value;
|
|
}
|
|
else {
|
|
element.style[prop] = manager.oldCssProps[prop] || '';
|
|
}
|
|
});
|
|
if (!add) {
|
|
manager.oldCssProps = {};
|
|
}
|
|
}
|
|
/**
|
|
* trigger dom event
|
|
* @param {String} event
|
|
* @param {Object} data
|
|
*/
|
|
function triggerDomEvent(event, data) {
|
|
var gestureEvent = document.createEvent('Event');
|
|
gestureEvent.initEvent(event, true, true);
|
|
gestureEvent.gesture = data;
|
|
data.target.dispatchEvent(gestureEvent);
|
|
}
|
|
assign(Hammer, {
|
|
INPUT_START: INPUT_START,
|
|
INPUT_MOVE: INPUT_MOVE,
|
|
INPUT_END: INPUT_END,
|
|
INPUT_CANCEL: INPUT_CANCEL,
|
|
STATE_POSSIBLE: STATE_POSSIBLE,
|
|
STATE_BEGAN: STATE_BEGAN,
|
|
STATE_CHANGED: STATE_CHANGED,
|
|
STATE_ENDED: STATE_ENDED,
|
|
STATE_RECOGNIZED: STATE_RECOGNIZED,
|
|
STATE_CANCELLED: STATE_CANCELLED,
|
|
STATE_FAILED: STATE_FAILED,
|
|
DIRECTION_NONE: DIRECTION_NONE,
|
|
DIRECTION_LEFT: DIRECTION_LEFT,
|
|
DIRECTION_RIGHT: DIRECTION_RIGHT,
|
|
DIRECTION_UP: DIRECTION_UP,
|
|
DIRECTION_DOWN: DIRECTION_DOWN,
|
|
DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,
|
|
DIRECTION_VERTICAL: DIRECTION_VERTICAL,
|
|
DIRECTION_ALL: DIRECTION_ALL,
|
|
Manager: Manager,
|
|
Input: Input,
|
|
TouchAction: TouchAction,
|
|
TouchInput: TouchInput,
|
|
MouseInput: MouseInput,
|
|
PointerEventInput: PointerEventInput,
|
|
TouchMouseInput: TouchMouseInput,
|
|
SingleTouchInput: SingleTouchInput,
|
|
Recognizer: Recognizer,
|
|
AttrRecognizer: AttrRecognizer,
|
|
Tap: TapRecognizer,
|
|
Pan: PanRecognizer,
|
|
Swipe: SwipeRecognizer,
|
|
Pinch: PinchRecognizer,
|
|
Rotate: RotateRecognizer,
|
|
Press: PressRecognizer,
|
|
on: addEventListeners,
|
|
off: removeEventListeners,
|
|
each: each,
|
|
merge: merge,
|
|
extend: extend,
|
|
assign: assign,
|
|
inherit: inherit,
|
|
bindFn: bindFn,
|
|
prefixed: prefixed
|
|
});
|
|
// this prevents errors when Hammer is loaded in the presence of an AMD
|
|
// style loader but by script tag, not by the loader.
|
|
var freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line
|
|
freeGlobal.Hammer = Hammer;
|
|
if (typeof define === 'function' && define.amd) {
|
|
define(function () {
|
|
return Hammer;
|
|
});
|
|
}
|
|
else if (typeof module != 'undefined' && module.exports) {
|
|
module.exports = Hammer;
|
|
}
|
|
else {
|
|
window[exportName] = Hammer;
|
|
}
|
|
})(window, document, 'Hammer');
|
|
}
|
|
,
|
|
/* numbro/numbro */ function _(require, module, exports) {
|
|
/*!
|
|
* numbro.js
|
|
* version : 1.6.2
|
|
* author : Företagsplatsen AB
|
|
* license : MIT
|
|
* http://www.foretagsplatsen.se
|
|
*/
|
|
/************************************
|
|
Constants
|
|
************************************/
|
|
var numbro, VERSION = '1.6.2',
|
|
// internal storage for culture config files
|
|
cultures = {},
|
|
// Todo: Remove in 2.0.0
|
|
languages = cultures, currentCulture = 'en-US', zeroFormat = null, defaultFormat = '0,0', defaultCurrencyFormat = '0$',
|
|
// check for nodeJS
|
|
hasModule = (typeof module !== 'undefined' && module.exports),
|
|
// default culture
|
|
enUS = {
|
|
delimiters: {
|
|
thousands: ',',
|
|
decimal: '.'
|
|
},
|
|
abbreviations: {
|
|
thousand: 'k',
|
|
million: 'm',
|
|
billion: 'b',
|
|
trillion: 't'
|
|
},
|
|
ordinal: function (number) {
|
|
var b = number % 10;
|
|
return (~~(number % 100 / 10) === 1) ? 'th' :
|
|
(b === 1) ? 'st' :
|
|
(b === 2) ? 'nd' :
|
|
(b === 3) ? 'rd' : 'th';
|
|
},
|
|
currency: {
|
|
symbol: '$',
|
|
position: 'prefix'
|
|
},
|
|
defaults: {
|
|
currencyFormat: ',0000 a'
|
|
},
|
|
formats: {
|
|
fourDigits: '0000 a',
|
|
fullWithTwoDecimals: '$ ,0.00',
|
|
fullWithTwoDecimalsNoCurrency: ',0.00'
|
|
}
|
|
};
|
|
/************************************
|
|
Constructors
|
|
************************************/
|
|
// Numbro prototype object
|
|
function Numbro(number) {
|
|
this._value = number;
|
|
}
|
|
function zeroes(count) {
|
|
var i, ret = '';
|
|
for (i = 0; i < count; i++) {
|
|
ret += '0';
|
|
}
|
|
return ret;
|
|
}
|
|
/**
|
|
* Implementation of toFixed() for numbers with exponent > 21
|
|
*
|
|
*
|
|
*/
|
|
function toFixedLarge(value, precision) {
|
|
var mantissa, beforeDec, afterDec, exponent, str;
|
|
str = value.toString();
|
|
mantissa = str.split('e')[0];
|
|
exponent = str.split('e')[1];
|
|
beforeDec = mantissa.split('.')[0];
|
|
afterDec = mantissa.split('.')[1] || '';
|
|
str = beforeDec + afterDec + zeroes(exponent - afterDec.length);
|
|
if (precision > 0) {
|
|
str += '.' + zeroes(precision);
|
|
}
|
|
return str;
|
|
}
|
|
/**
|
|
* Implementation of toFixed() that treats floats more like decimals
|
|
*
|
|
* Fixes binary rounding issues (eg. (0.615).toFixed(2) === '0.61') that present
|
|
* problems for accounting- and finance-related software.
|
|
*/
|
|
function toFixed(value, precision, roundingFunction, optionals) {
|
|
var power = Math.pow(10, precision), optionalsRegExp, output;
|
|
if (value.toFixed(0).search('e') > -1) {
|
|
// Above 1e21, toFixed returns scientific notation, which
|
|
// is useless and unexpected
|
|
output = toFixedLarge(value, precision);
|
|
}
|
|
else {
|
|
//roundingFunction = (roundingFunction !== undefined ? roundingFunction : Math.round);
|
|
// Multiply up by precision, round accurately, then divide and use native toFixed():
|
|
output = (roundingFunction(value * power) / power).toFixed(precision);
|
|
}
|
|
if (optionals) {
|
|
optionalsRegExp = new RegExp('0{1,' + optionals + '}$');
|
|
output = output.replace(optionalsRegExp, '');
|
|
}
|
|
return output;
|
|
}
|
|
/************************************
|
|
Formatting
|
|
************************************/
|
|
// determine what type of formatting we need to do
|
|
function formatNumbro(value, format, roundingFunction) {
|
|
var output;
|
|
// TODO: do something with `language`
|
|
// figure out what kind of format we are dealing with
|
|
if (format.indexOf('$') > -1) { // currency!!!!!
|
|
output = formatCurrency(value, format, roundingFunction);
|
|
}
|
|
else if (format.indexOf('%') > -1) { // percentage
|
|
output = formatPercentage(value, format, roundingFunction);
|
|
}
|
|
else if (format.indexOf(':') > -1) { // time
|
|
output = formatTime(value);
|
|
}
|
|
else { // plain ol' numbers or bytes
|
|
output = formatNumber(value, format, roundingFunction);
|
|
}
|
|
// return string
|
|
return output;
|
|
}
|
|
function formatCurrency(value, originalFormat, roundingFunction) {
|
|
var format = originalFormat, symbolIndex = format.indexOf('$'), openParenIndex = format.indexOf('('), plusSignIndex = format.indexOf('+'), minusSignIndex = format.indexOf('-'), space = '', decimalSeparator = '', spliceIndex, output;
|
|
if (format.indexOf('$') === -1) {
|
|
// Use defaults instead of the format provided
|
|
if (cultures[currentCulture].currency.position === 'infix') {
|
|
decimalSeparator = cultures[currentCulture].currency.symbol;
|
|
if (cultures[currentCulture].currency.spaceSeparated) {
|
|
decimalSeparator = ' ' + decimalSeparator + ' ';
|
|
}
|
|
}
|
|
else if (cultures[currentCulture].currency.spaceSeparated) {
|
|
space = ' ';
|
|
}
|
|
}
|
|
else {
|
|
// check for space before or after currency
|
|
if (format.indexOf(' $') > -1) {
|
|
space = ' ';
|
|
format = format.replace(' $', '');
|
|
}
|
|
else if (format.indexOf('$ ') > -1) {
|
|
space = ' ';
|
|
format = format.replace('$ ', '');
|
|
}
|
|
else {
|
|
format = format.replace('$', '');
|
|
}
|
|
}
|
|
// Format The Number
|
|
output = formatNumber(value, format, roundingFunction, decimalSeparator);
|
|
if (originalFormat.indexOf('$') === -1) {
|
|
// Use defaults instead of the format provided
|
|
switch (cultures[currentCulture].currency.position) {
|
|
case 'postfix':
|
|
if (output.indexOf(')') > -1) {
|
|
output = output.split('');
|
|
output.splice(-1, 0, space + cultures[currentCulture].currency.symbol);
|
|
output = output.join('');
|
|
}
|
|
else {
|
|
output = output + space + cultures[currentCulture].currency.symbol;
|
|
}
|
|
break;
|
|
case 'infix':
|
|
break;
|
|
case 'prefix':
|
|
if (output.indexOf('(') > -1 || output.indexOf('-') > -1) {
|
|
output = output.split('');
|
|
spliceIndex = Math.max(openParenIndex, minusSignIndex) + 1;
|
|
output.splice(spliceIndex, 0, cultures[currentCulture].currency.symbol + space);
|
|
output = output.join('');
|
|
}
|
|
else {
|
|
output = cultures[currentCulture].currency.symbol + space + output;
|
|
}
|
|
break;
|
|
default:
|
|
throw Error('Currency position should be among ["prefix", "infix", "postfix"]');
|
|
}
|
|
}
|
|
else {
|
|
// position the symbol
|
|
if (symbolIndex <= 1) {
|
|
if (output.indexOf('(') > -1 || output.indexOf('+') > -1 || output.indexOf('-') > -1) {
|
|
output = output.split('');
|
|
spliceIndex = 1;
|
|
if (symbolIndex < openParenIndex || symbolIndex < plusSignIndex || symbolIndex < minusSignIndex) {
|
|
// the symbol appears before the "(", "+" or "-"
|
|
spliceIndex = 0;
|
|
}
|
|
output.splice(spliceIndex, 0, cultures[currentCulture].currency.symbol + space);
|
|
output = output.join('');
|
|
}
|
|
else {
|
|
output = cultures[currentCulture].currency.symbol + space + output;
|
|
}
|
|
}
|
|
else {
|
|
if (output.indexOf(')') > -1) {
|
|
output = output.split('');
|
|
output.splice(-1, 0, space + cultures[currentCulture].currency.symbol);
|
|
output = output.join('');
|
|
}
|
|
else {
|
|
output = output + space + cultures[currentCulture].currency.symbol;
|
|
}
|
|
}
|
|
}
|
|
return output;
|
|
}
|
|
function formatPercentage(value, format, roundingFunction) {
|
|
var space = '', output;
|
|
value = value * 100;
|
|
// check for space before %
|
|
if (format.indexOf(' %') > -1) {
|
|
space = ' ';
|
|
format = format.replace(' %', '');
|
|
}
|
|
else {
|
|
format = format.replace('%', '');
|
|
}
|
|
output = formatNumber(value, format, roundingFunction);
|
|
if (output.indexOf(')') > -1) {
|
|
output = output.split('');
|
|
output.splice(-1, 0, space + '%');
|
|
output = output.join('');
|
|
}
|
|
else {
|
|
output = output + space + '%';
|
|
}
|
|
return output;
|
|
}
|
|
function formatTime(value) {
|
|
var hours = Math.floor(value / 60 / 60), minutes = Math.floor((value - (hours * 60 * 60)) / 60), seconds = Math.round(value - (hours * 60 * 60) - (minutes * 60));
|
|
return hours + ':' +
|
|
((minutes < 10) ? '0' + minutes : minutes) + ':' +
|
|
((seconds < 10) ? '0' + seconds : seconds);
|
|
}
|
|
function formatNumber(value, format, roundingFunction, sep) {
|
|
var negP = false, signed = false, optDec = false, abbr = '', i, abbrK = false, // force abbreviation to thousands
|
|
abbrM = false, // force abbreviation to millions
|
|
abbrB = false, // force abbreviation to billions
|
|
abbrT = false, // force abbreviation to trillions
|
|
abbrForce = false, // force abbreviation
|
|
bytes = '', ord = '', abs = Math.abs(value), binarySuffixes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'], decimalSuffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], min, max, power, totalLength, length, minimumPrecision, pow, w, intPrecision, precision, prefix, postfix, thousands, d = '', forcedNeg = false, neg = false, indexOpenP, size, indexMinus, paren = '', minlen;
|
|
// check if number is zero and a custom zero format has been set
|
|
if (value === 0 && zeroFormat !== null) {
|
|
return zeroFormat;
|
|
}
|
|
if (!isFinite(value)) {
|
|
return '' + value;
|
|
}
|
|
if (format.indexOf('{') === 0) {
|
|
var end = format.indexOf('}');
|
|
if (end === -1) {
|
|
throw Error('Format should also contain a "}"');
|
|
}
|
|
prefix = format.slice(1, end);
|
|
format = format.slice(end + 1);
|
|
}
|
|
else {
|
|
prefix = '';
|
|
}
|
|
if (format.indexOf('}') === format.length - 1) {
|
|
var start = format.indexOf('{');
|
|
if (start === -1) {
|
|
throw Error('Format should also contain a "{"');
|
|
}
|
|
postfix = format.slice(start + 1, -1);
|
|
format = format.slice(0, start + 1);
|
|
}
|
|
else {
|
|
postfix = '';
|
|
}
|
|
// check for min length
|
|
var info;
|
|
if (format.indexOf('.') === -1) {
|
|
info = format.match(/([0-9]+).*/);
|
|
}
|
|
else {
|
|
info = format.match(/([0-9]+)\..*/);
|
|
}
|
|
minlen = info === null ? -1 : info[1].length;
|
|
// see if we should use parentheses for negative number or if we should prefix with a sign
|
|
// if both are present we default to parentheses
|
|
if (format.indexOf('-') !== -1) {
|
|
forcedNeg = true;
|
|
}
|
|
if (format.indexOf('(') > -1) {
|
|
negP = true;
|
|
format = format.slice(1, -1);
|
|
}
|
|
else if (format.indexOf('+') > -1) {
|
|
signed = true;
|
|
format = format.replace(/\+/g, '');
|
|
}
|
|
// see if abbreviation is wanted
|
|
if (format.indexOf('a') > -1) {
|
|
intPrecision = format.split('.')[0].match(/[0-9]+/g) || ['0'];
|
|
intPrecision = parseInt(intPrecision[0], 10);
|
|
// check if abbreviation is specified
|
|
abbrK = format.indexOf('aK') >= 0;
|
|
abbrM = format.indexOf('aM') >= 0;
|
|
abbrB = format.indexOf('aB') >= 0;
|
|
abbrT = format.indexOf('aT') >= 0;
|
|
abbrForce = abbrK || abbrM || abbrB || abbrT;
|
|
// check for space before abbreviation
|
|
if (format.indexOf(' a') > -1) {
|
|
abbr = ' ';
|
|
format = format.replace(' a', '');
|
|
}
|
|
else {
|
|
format = format.replace('a', '');
|
|
}
|
|
totalLength = Math.floor(Math.log(abs) / Math.LN10) + 1;
|
|
minimumPrecision = totalLength % 3;
|
|
minimumPrecision = minimumPrecision === 0 ? 3 : minimumPrecision;
|
|
if (intPrecision && abs !== 0) {
|
|
length = Math.floor(Math.log(abs) / Math.LN10) + 1 - intPrecision;
|
|
pow = 3 * ~~((Math.min(intPrecision, totalLength) - minimumPrecision) / 3);
|
|
abs = abs / Math.pow(10, pow);
|
|
if (format.indexOf('.') === -1 && intPrecision > 3) {
|
|
format += '[.]';
|
|
size = length === 0 ? 0 : 3 * ~~(length / 3) - length;
|
|
size = size < 0 ? size + 3 : size;
|
|
for (i = 0; i < size; i++) {
|
|
format += '0';
|
|
}
|
|
}
|
|
}
|
|
if (Math.floor(Math.log(Math.abs(value)) / Math.LN10) + 1 !== intPrecision) {
|
|
if (abs >= Math.pow(10, 12) && !abbrForce || abbrT) {
|
|
// trillion
|
|
abbr = abbr + cultures[currentCulture].abbreviations.trillion;
|
|
value = value / Math.pow(10, 12);
|
|
}
|
|
else if (abs < Math.pow(10, 12) && abs >= Math.pow(10, 9) && !abbrForce || abbrB) {
|
|
// billion
|
|
abbr = abbr + cultures[currentCulture].abbreviations.billion;
|
|
value = value / Math.pow(10, 9);
|
|
}
|
|
else if (abs < Math.pow(10, 9) && abs >= Math.pow(10, 6) && !abbrForce || abbrM) {
|
|
// million
|
|
abbr = abbr + cultures[currentCulture].abbreviations.million;
|
|
value = value / Math.pow(10, 6);
|
|
}
|
|
else if (abs < Math.pow(10, 6) && abs >= Math.pow(10, 3) && !abbrForce || abbrK) {
|
|
// thousand
|
|
abbr = abbr + cultures[currentCulture].abbreviations.thousand;
|
|
value = value / Math.pow(10, 3);
|
|
}
|
|
}
|
|
}
|
|
// see if we are formatting binary bytes
|
|
if (format.indexOf('b') > -1) {
|
|
// check for space before
|
|
if (format.indexOf(' b') > -1) {
|
|
bytes = ' ';
|
|
format = format.replace(' b', '');
|
|
}
|
|
else {
|
|
format = format.replace('b', '');
|
|
}
|
|
for (power = 0; power <= binarySuffixes.length; power++) {
|
|
min = Math.pow(1024, power);
|
|
max = Math.pow(1024, power + 1);
|
|
if (value >= min && value < max) {
|
|
bytes = bytes + binarySuffixes[power];
|
|
if (min > 0) {
|
|
value = value / min;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// see if we are formatting decimal bytes
|
|
if (format.indexOf('d') > -1) {
|
|
// check for space before
|
|
if (format.indexOf(' d') > -1) {
|
|
bytes = ' ';
|
|
format = format.replace(' d', '');
|
|
}
|
|
else {
|
|
format = format.replace('d', '');
|
|
}
|
|
for (power = 0; power <= decimalSuffixes.length; power++) {
|
|
min = Math.pow(1000, power);
|
|
max = Math.pow(1000, power + 1);
|
|
if (value >= min && value < max) {
|
|
bytes = bytes + decimalSuffixes[power];
|
|
if (min > 0) {
|
|
value = value / min;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// see if ordinal is wanted
|
|
if (format.indexOf('o') > -1) {
|
|
// check for space before
|
|
if (format.indexOf(' o') > -1) {
|
|
ord = ' ';
|
|
format = format.replace(' o', '');
|
|
}
|
|
else {
|
|
format = format.replace('o', '');
|
|
}
|
|
if (cultures[currentCulture].ordinal) {
|
|
ord = ord + cultures[currentCulture].ordinal(value);
|
|
}
|
|
}
|
|
if (format.indexOf('[.]') > -1) {
|
|
optDec = true;
|
|
format = format.replace('[.]', '.');
|
|
}
|
|
w = value.toString().split('.')[0];
|
|
precision = format.split('.')[1];
|
|
thousands = format.indexOf(',');
|
|
if (precision) {
|
|
if (precision.indexOf('*') !== -1) {
|
|
d = toFixed(value, value.toString().split('.')[1].length, roundingFunction);
|
|
}
|
|
else {
|
|
if (precision.indexOf('[') > -1) {
|
|
precision = precision.replace(']', '');
|
|
precision = precision.split('[');
|
|
d = toFixed(value, (precision[0].length + precision[1].length), roundingFunction, precision[1].length);
|
|
}
|
|
else {
|
|
d = toFixed(value, precision.length, roundingFunction);
|
|
}
|
|
}
|
|
w = d.split('.')[0];
|
|
if (d.split('.')[1].length) {
|
|
var p = sep ? abbr + sep : cultures[currentCulture].delimiters.decimal;
|
|
d = p + d.split('.')[1];
|
|
}
|
|
else {
|
|
d = '';
|
|
}
|
|
if (optDec && Number(d.slice(1)) === 0) {
|
|
d = '';
|
|
}
|
|
}
|
|
else {
|
|
w = toFixed(value, null, roundingFunction);
|
|
}
|
|
// format number
|
|
if (w.indexOf('-') > -1) {
|
|
w = w.slice(1);
|
|
neg = true;
|
|
}
|
|
if (w.length < minlen) {
|
|
w = new Array(minlen - w.length + 1).join('0') + w;
|
|
}
|
|
if (thousands > -1) {
|
|
w = w.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' +
|
|
cultures[currentCulture].delimiters.thousands);
|
|
}
|
|
if (format.indexOf('.') === 0) {
|
|
w = '';
|
|
}
|
|
indexOpenP = format.indexOf('(');
|
|
indexMinus = format.indexOf('-');
|
|
if (indexOpenP < indexMinus) {
|
|
paren = ((negP && neg) ? '(' : '') + (((forcedNeg && neg) || (!negP && neg)) ? '-' : '');
|
|
}
|
|
else {
|
|
paren = (((forcedNeg && neg) || (!negP && neg)) ? '-' : '') + ((negP && neg) ? '(' : '');
|
|
}
|
|
return prefix +
|
|
paren + ((!neg && signed && value !== 0) ? '+' : '') +
|
|
w + d +
|
|
((ord) ? ord : '') +
|
|
((abbr && !sep) ? abbr : '') +
|
|
((bytes) ? bytes : '') +
|
|
((negP && neg) ? ')' : '') +
|
|
postfix;
|
|
}
|
|
/************************************
|
|
Top Level Functions
|
|
************************************/
|
|
numbro = function (input) {
|
|
if (numbro.isNumbro(input)) {
|
|
input = input.value();
|
|
}
|
|
else if (input === 0 || typeof input === 'undefined') {
|
|
input = 0;
|
|
}
|
|
else if (!Number(input)) {
|
|
input = numbro.fn.unformat(input);
|
|
}
|
|
return new Numbro(Number(input));
|
|
};
|
|
// version number
|
|
numbro.version = VERSION;
|
|
// compare numbro object
|
|
numbro.isNumbro = function (obj) {
|
|
return obj instanceof Numbro;
|
|
};
|
|
/**
|
|
* This function allow the user to set a new language with a fallback if
|
|
* the language does not exist. If no fallback language is provided,
|
|
* it fallbacks to english.
|
|
*
|
|
* @deprecated Since in version 1.6.0. It will be deleted in version 2.0
|
|
* `setCulture` should be used instead.
|
|
*/
|
|
numbro.setLanguage = function (newLanguage, fallbackLanguage) {
|
|
console.warn('`setLanguage` is deprecated since version 1.6.0. Use `setCulture` instead');
|
|
var key = newLanguage, prefix = newLanguage.split('-')[0], matchingLanguage = null;
|
|
if (!languages[key]) {
|
|
Object.keys(languages).forEach(function (language) {
|
|
if (!matchingLanguage && language.split('-')[0] === prefix) {
|
|
matchingLanguage = language;
|
|
}
|
|
});
|
|
key = matchingLanguage || fallbackLanguage || 'en-US';
|
|
}
|
|
chooseCulture(key);
|
|
};
|
|
/**
|
|
* This function allow the user to set a new culture with a fallback if
|
|
* the culture does not exist. If no fallback culture is provided,
|
|
* it fallbacks to "en-US".
|
|
*/
|
|
numbro.setCulture = function (newCulture, fallbackCulture) {
|
|
var key = newCulture, suffix = newCulture.split('-')[1], matchingCulture = null;
|
|
if (!cultures[key]) {
|
|
if (suffix) {
|
|
Object.keys(cultures).forEach(function (language) {
|
|
if (!matchingCulture && language.split('-')[1] === suffix) {
|
|
matchingCulture = language;
|
|
}
|
|
});
|
|
}
|
|
key = matchingCulture || fallbackCulture || 'en-US';
|
|
}
|
|
chooseCulture(key);
|
|
};
|
|
/**
|
|
* This function will load languages and then set the global language. If
|
|
* no arguments are passed in, it will simply return the current global
|
|
* language key.
|
|
*
|
|
* @deprecated Since in version 1.6.0. It will be deleted in version 2.0
|
|
* `culture` should be used instead.
|
|
*/
|
|
numbro.language = function (key, values) {
|
|
console.warn('`language` is deprecated since version 1.6.0. Use `culture` instead');
|
|
if (!key) {
|
|
return currentCulture;
|
|
}
|
|
if (key && !values) {
|
|
if (!languages[key]) {
|
|
throw new Error('Unknown language : ' + key);
|
|
}
|
|
chooseCulture(key);
|
|
}
|
|
if (values || !languages[key]) {
|
|
setCulture(key, values);
|
|
}
|
|
return numbro;
|
|
};
|
|
/**
|
|
* This function will load cultures and then set the global culture. If
|
|
* no arguments are passed in, it will simply return the current global
|
|
* culture code.
|
|
*/
|
|
numbro.culture = function (code, values) {
|
|
if (!code) {
|
|
return currentCulture;
|
|
}
|
|
if (code && !values) {
|
|
if (!cultures[code]) {
|
|
throw new Error('Unknown culture : ' + code);
|
|
}
|
|
chooseCulture(code);
|
|
}
|
|
if (values || !cultures[code]) {
|
|
setCulture(code, values);
|
|
}
|
|
return numbro;
|
|
};
|
|
/**
|
|
* This function provides access to the loaded language data. If
|
|
* no arguments are passed in, it will simply return the current
|
|
* global language object.
|
|
*
|
|
* @deprecated Since in version 1.6.0. It will be deleted in version 2.0
|
|
* `culture` should be used instead.
|
|
*/
|
|
numbro.languageData = function (key) {
|
|
console.warn('`languageData` is deprecated since version 1.6.0. Use `cultureData` instead');
|
|
if (!key) {
|
|
return languages[currentCulture];
|
|
}
|
|
if (!languages[key]) {
|
|
throw new Error('Unknown language : ' + key);
|
|
}
|
|
return languages[key];
|
|
};
|
|
/**
|
|
* This function provides access to the loaded culture data. If
|
|
* no arguments are passed in, it will simply return the current
|
|
* global culture object.
|
|
*/
|
|
numbro.cultureData = function (code) {
|
|
if (!code) {
|
|
return cultures[currentCulture];
|
|
}
|
|
if (!cultures[code]) {
|
|
throw new Error('Unknown culture : ' + code);
|
|
}
|
|
return cultures[code];
|
|
};
|
|
numbro.culture('en-US', enUS);
|
|
/**
|
|
* @deprecated Since in version 1.6.0. It will be deleted in version 2.0
|
|
* `cultures` should be used instead.
|
|
*/
|
|
numbro.languages = function () {
|
|
console.warn('`languages` is deprecated since version 1.6.0. Use `cultures` instead');
|
|
return languages;
|
|
};
|
|
numbro.cultures = function () {
|
|
return cultures;
|
|
};
|
|
numbro.zeroFormat = function (format) {
|
|
zeroFormat = typeof (format) === 'string' ? format : null;
|
|
};
|
|
numbro.defaultFormat = function (format) {
|
|
defaultFormat = typeof (format) === 'string' ? format : '0.0';
|
|
};
|
|
numbro.defaultCurrencyFormat = function (format) {
|
|
defaultCurrencyFormat = typeof (format) === 'string' ? format : '0$';
|
|
};
|
|
numbro.validate = function (val, culture) {
|
|
var _decimalSep, _thousandSep, _currSymbol, _valArray, _abbrObj, _thousandRegEx, cultureData, temp;
|
|
//coerce val to string
|
|
if (typeof val !== 'string') {
|
|
val += '';
|
|
if (console.warn) {
|
|
console.warn('Numbro.js: Value is not string. It has been co-erced to: ', val);
|
|
}
|
|
}
|
|
//trim whitespaces from either sides
|
|
val = val.trim();
|
|
//if val is just digits return true
|
|
if (!!val.match(/^\d+$/)) {
|
|
return true;
|
|
}
|
|
//if val is empty return false
|
|
if (val === '') {
|
|
return false;
|
|
}
|
|
//get the decimal and thousands separator from numbro.cultureData
|
|
try {
|
|
//check if the culture is understood by numbro. if not, default it to current culture
|
|
cultureData = numbro.cultureData(culture);
|
|
}
|
|
catch (e) {
|
|
cultureData = numbro.cultureData(numbro.culture());
|
|
}
|
|
//setup the delimiters and currency symbol based on culture
|
|
_currSymbol = cultureData.currency.symbol;
|
|
_abbrObj = cultureData.abbreviations;
|
|
_decimalSep = cultureData.delimiters.decimal;
|
|
if (cultureData.delimiters.thousands === '.') {
|
|
_thousandSep = '\\.';
|
|
}
|
|
else {
|
|
_thousandSep = cultureData.delimiters.thousands;
|
|
}
|
|
// validating currency symbol
|
|
temp = val.match(/^[^\d]+/);
|
|
if (temp !== null) {
|
|
val = val.substr(1);
|
|
if (temp[0] !== _currSymbol) {
|
|
return false;
|
|
}
|
|
}
|
|
//validating abbreviation symbol
|
|
temp = val.match(/[^\d]+$/);
|
|
if (temp !== null) {
|
|
val = val.slice(0, -1);
|
|
if (temp[0] !== _abbrObj.thousand && temp[0] !== _abbrObj.million &&
|
|
temp[0] !== _abbrObj.billion && temp[0] !== _abbrObj.trillion) {
|
|
return false;
|
|
}
|
|
}
|
|
_thousandRegEx = new RegExp(_thousandSep + '{2}');
|
|
if (!val.match(/[^\d.,]/g)) {
|
|
_valArray = val.split(_decimalSep);
|
|
if (_valArray.length > 2) {
|
|
return false;
|
|
}
|
|
else {
|
|
if (_valArray.length < 2) {
|
|
return (!!_valArray[0].match(/^\d+.*\d$/) && !_valArray[0].match(_thousandRegEx));
|
|
}
|
|
else {
|
|
if (_valArray[0].length === 1) {
|
|
return (!!_valArray[0].match(/^\d+$/) &&
|
|
!_valArray[0].match(_thousandRegEx) &&
|
|
!!_valArray[1].match(/^\d+$/));
|
|
}
|
|
else {
|
|
return (!!_valArray[0].match(/^\d+.*\d$/) &&
|
|
!_valArray[0].match(_thousandRegEx) &&
|
|
!!_valArray[1].match(/^\d+$/));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
/************************************
|
|
Helpers
|
|
************************************/
|
|
function setCulture(code, values) {
|
|
cultures[code] = values;
|
|
}
|
|
function chooseCulture(code) {
|
|
currentCulture = code;
|
|
var defaults = cultures[code].defaults;
|
|
if (defaults && defaults.format) {
|
|
numbro.defaultFormat(defaults.format);
|
|
}
|
|
if (defaults && defaults.currencyFormat) {
|
|
numbro.defaultCurrencyFormat(defaults.currencyFormat);
|
|
}
|
|
}
|
|
function format(input, formatString, language, roundingFunction) {
|
|
if (language != null && language !== numbro.culture()) {
|
|
numbro.setCulture(language);
|
|
}
|
|
return formatNumbro(Number(input), formatString != null ? formatString : defaultFormat, roundingFunction == null ? Math.round : roundingFunction);
|
|
}
|
|
module.exports = { "format": format };
|
|
}
|
|
,
|
|
/* proj4/lib/Proj */ function _(require, module, exports) {
|
|
var parseCode = require(391) /* ./parseCode */;
|
|
var extend = require(389) /* ./extend */;
|
|
var projections = require(393) /* ./projections */;
|
|
var deriveConstants = require(388) /* ./deriveConstants */;
|
|
var Datum = require(379) /* ./constants/Datum */;
|
|
var datum = require(384) /* ./datum */;
|
|
function Projection(srsCode, callback) {
|
|
if (!(this instanceof Projection)) {
|
|
return new Projection(srsCode);
|
|
}
|
|
callback = callback || function (error) {
|
|
if (error) {
|
|
throw error;
|
|
}
|
|
};
|
|
var json = parseCode(srsCode);
|
|
if (typeof json !== 'object') {
|
|
callback(srsCode);
|
|
return;
|
|
}
|
|
var ourProj = Projection.projections.get(json.projName);
|
|
if (!ourProj) {
|
|
callback(srsCode);
|
|
return;
|
|
}
|
|
if (json.datumCode && json.datumCode !== 'none') {
|
|
var datumDef = Datum[json.datumCode];
|
|
if (datumDef) {
|
|
json.datum_params = datumDef.towgs84 ? datumDef.towgs84.split(',') : null;
|
|
json.ellps = datumDef.ellipse;
|
|
json.datumName = datumDef.datumName ? datumDef.datumName : json.datumCode;
|
|
}
|
|
}
|
|
json.k0 = json.k0 || 1.0;
|
|
json.axis = json.axis || 'enu';
|
|
var sphere = deriveConstants.sphere(json.a, json.b, json.rf, json.ellps, json.sphere);
|
|
var ecc = deriveConstants.eccentricity(sphere.a, sphere.b, sphere.rf, json.R_A);
|
|
var datumObj = json.datum || datum(json.datumCode, json.datum_params, sphere.a, sphere.b, ecc.es, ecc.ep2);
|
|
extend(this, json); // transfer everything over from the projection because we don't know what we'll need
|
|
extend(this, ourProj); // transfer all the methods from the projection
|
|
// copy the 4 things over we calulated in deriveConstants.sphere
|
|
this.a = sphere.a;
|
|
this.b = sphere.b;
|
|
this.rf = sphere.rf;
|
|
this.sphere = sphere.sphere;
|
|
// copy the 3 things we calculated in deriveConstants.eccentricity
|
|
this.es = ecc.es;
|
|
this.e = ecc.e;
|
|
this.ep2 = ecc.ep2;
|
|
// add in the datum object
|
|
this.datum = datumObj;
|
|
// init the projection
|
|
this.init();
|
|
// legecy callback from back in the day when it went to spatialreference.org
|
|
callback(null, this);
|
|
}
|
|
Projection.projections = projections;
|
|
Projection.projections.start();
|
|
module.exports = Projection;
|
|
}
|
|
,
|
|
/* proj4/lib/adjust_axis */ function _(require, module, exports) {
|
|
module.exports = function (crs, denorm, point) {
|
|
var xin = point.x, yin = point.y, zin = point.z || 0.0;
|
|
var v, t, i;
|
|
var out = {};
|
|
for (i = 0; i < 3; i++) {
|
|
if (denorm && i === 2 && point.z === undefined) {
|
|
continue;
|
|
}
|
|
if (i === 0) {
|
|
v = xin;
|
|
t = 'x';
|
|
}
|
|
else if (i === 1) {
|
|
v = yin;
|
|
t = 'y';
|
|
}
|
|
else {
|
|
v = zin;
|
|
t = 'z';
|
|
}
|
|
switch (crs.axis[i]) {
|
|
case 'e':
|
|
out[t] = v;
|
|
break;
|
|
case 'w':
|
|
out[t] = -v;
|
|
break;
|
|
case 'n':
|
|
out[t] = v;
|
|
break;
|
|
case 's':
|
|
out[t] = -v;
|
|
break;
|
|
case 'u':
|
|
if (point[t] !== undefined) {
|
|
out.z = v;
|
|
}
|
|
break;
|
|
case 'd':
|
|
if (point[t] !== undefined) {
|
|
out.z = -v;
|
|
}
|
|
break;
|
|
default:
|
|
//console.log("ERROR: unknow axis ("+crs.axis[i]+") - check definition of "+crs.projName);
|
|
return null;
|
|
}
|
|
}
|
|
return out;
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/common/adjust_lon */ function _(require, module, exports) {
|
|
var TWO_PI = Math.PI * 2;
|
|
// SPI is slightly greater than Math.PI, so values that exceed the -180..180
|
|
// degree range by a tiny amount don't get wrapped. This prevents points that
|
|
// have drifted from their original location along the 180th meridian (due to
|
|
// floating point error) from changing their sign.
|
|
var SPI = 3.14159265359;
|
|
var sign = require(376) /* ./sign */;
|
|
module.exports = function (x) {
|
|
return (Math.abs(x) <= SPI) ? x : (x - (sign(x) * TWO_PI));
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/common/msfnz */ function _(require, module, exports) {
|
|
module.exports = function (eccent, sinphi, cosphi) {
|
|
var con = eccent * sinphi;
|
|
return cosphi / (Math.sqrt(1 - con * con));
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/common/phi2z */ function _(require, module, exports) {
|
|
var HALF_PI = Math.PI / 2;
|
|
module.exports = function (eccent, ts) {
|
|
var eccnth = 0.5 * eccent;
|
|
var con, dphi;
|
|
var phi = HALF_PI - 2 * Math.atan(ts);
|
|
for (var i = 0; i <= 15; i++) {
|
|
con = eccent * Math.sin(phi);
|
|
dphi = HALF_PI - 2 * Math.atan(ts * (Math.pow(((1 - con) / (1 + con)), eccnth))) - phi;
|
|
phi += dphi;
|
|
if (Math.abs(dphi) <= 0.0000000001) {
|
|
return phi;
|
|
}
|
|
}
|
|
//console.log("phi2z has NoConvergence");
|
|
return -9999;
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/common/sign */ function _(require, module, exports) {
|
|
module.exports = function (x) {
|
|
return x < 0 ? -1 : 1;
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/common/toPoint */ function _(require, module, exports) {
|
|
module.exports = function (array) {
|
|
var out = {
|
|
x: array[0],
|
|
y: array[1]
|
|
};
|
|
if (array.length > 2) {
|
|
out.z = array[2];
|
|
}
|
|
if (array.length > 3) {
|
|
out.m = array[3];
|
|
}
|
|
return out;
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/common/tsfnz */ function _(require, module, exports) {
|
|
var HALF_PI = Math.PI / 2;
|
|
module.exports = function (eccent, phi, sinphi) {
|
|
var con = eccent * sinphi;
|
|
var com = 0.5 * eccent;
|
|
con = Math.pow(((1 - con) / (1 + con)), com);
|
|
return (Math.tan(0.5 * (HALF_PI - phi)) / con);
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/constants/Datum */ function _(require, module, exports) {
|
|
exports.wgs84 = {
|
|
towgs84: "0,0,0",
|
|
ellipse: "WGS84",
|
|
datumName: "WGS84"
|
|
};
|
|
exports.ch1903 = {
|
|
towgs84: "674.374,15.056,405.346",
|
|
ellipse: "bessel",
|
|
datumName: "swiss"
|
|
};
|
|
exports.ggrs87 = {
|
|
towgs84: "-199.87,74.79,246.62",
|
|
ellipse: "GRS80",
|
|
datumName: "Greek_Geodetic_Reference_System_1987"
|
|
};
|
|
exports.nad83 = {
|
|
towgs84: "0,0,0",
|
|
ellipse: "GRS80",
|
|
datumName: "North_American_Datum_1983"
|
|
};
|
|
exports.nad27 = {
|
|
nadgrids: "@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat",
|
|
ellipse: "clrk66",
|
|
datumName: "North_American_Datum_1927"
|
|
};
|
|
exports.potsdam = {
|
|
towgs84: "606.0,23.0,413.0",
|
|
ellipse: "bessel",
|
|
datumName: "Potsdam Rauenberg 1950 DHDN"
|
|
};
|
|
exports.carthage = {
|
|
towgs84: "-263.0,6.0,431.0",
|
|
ellipse: "clark80",
|
|
datumName: "Carthage 1934 Tunisia"
|
|
};
|
|
exports.hermannskogel = {
|
|
towgs84: "653.0,-212.0,449.0",
|
|
ellipse: "bessel",
|
|
datumName: "Hermannskogel"
|
|
};
|
|
exports.ire65 = {
|
|
towgs84: "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",
|
|
ellipse: "mod_airy",
|
|
datumName: "Ireland 1965"
|
|
};
|
|
exports.rassadiran = {
|
|
towgs84: "-133.63,-157.5,-158.62",
|
|
ellipse: "intl",
|
|
datumName: "Rassadiran"
|
|
};
|
|
exports.nzgd49 = {
|
|
towgs84: "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993",
|
|
ellipse: "intl",
|
|
datumName: "New Zealand Geodetic Datum 1949"
|
|
};
|
|
exports.osgb36 = {
|
|
towgs84: "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894",
|
|
ellipse: "airy",
|
|
datumName: "Airy 1830"
|
|
};
|
|
exports.s_jtsk = {
|
|
towgs84: "589,76,480",
|
|
ellipse: 'bessel',
|
|
datumName: 'S-JTSK (Ferro)'
|
|
};
|
|
exports.beduaram = {
|
|
towgs84: '-106,-87,188',
|
|
ellipse: 'clrk80',
|
|
datumName: 'Beduaram'
|
|
};
|
|
exports.gunung_segara = {
|
|
towgs84: '-403,684,41',
|
|
ellipse: 'bessel',
|
|
datumName: 'Gunung Segara Jakarta'
|
|
};
|
|
exports.rnb72 = {
|
|
towgs84: "106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1",
|
|
ellipse: "intl",
|
|
datumName: "Reseau National Belge 1972"
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/constants/Ellipsoid */ function _(require, module, exports) {
|
|
exports.MERIT = {
|
|
a: 6378137.0,
|
|
rf: 298.257,
|
|
ellipseName: "MERIT 1983"
|
|
};
|
|
exports.SGS85 = {
|
|
a: 6378136.0,
|
|
rf: 298.257,
|
|
ellipseName: "Soviet Geodetic System 85"
|
|
};
|
|
exports.GRS80 = {
|
|
a: 6378137.0,
|
|
rf: 298.257222101,
|
|
ellipseName: "GRS 1980(IUGG, 1980)"
|
|
};
|
|
exports.IAU76 = {
|
|
a: 6378140.0,
|
|
rf: 298.257,
|
|
ellipseName: "IAU 1976"
|
|
};
|
|
exports.airy = {
|
|
a: 6377563.396,
|
|
b: 6356256.910,
|
|
ellipseName: "Airy 1830"
|
|
};
|
|
exports.APL4 = {
|
|
a: 6378137,
|
|
rf: 298.25,
|
|
ellipseName: "Appl. Physics. 1965"
|
|
};
|
|
exports.NWL9D = {
|
|
a: 6378145.0,
|
|
rf: 298.25,
|
|
ellipseName: "Naval Weapons Lab., 1965"
|
|
};
|
|
exports.mod_airy = {
|
|
a: 6377340.189,
|
|
b: 6356034.446,
|
|
ellipseName: "Modified Airy"
|
|
};
|
|
exports.andrae = {
|
|
a: 6377104.43,
|
|
rf: 300.0,
|
|
ellipseName: "Andrae 1876 (Den., Iclnd.)"
|
|
};
|
|
exports.aust_SA = {
|
|
a: 6378160.0,
|
|
rf: 298.25,
|
|
ellipseName: "Australian Natl & S. Amer. 1969"
|
|
};
|
|
exports.GRS67 = {
|
|
a: 6378160.0,
|
|
rf: 298.2471674270,
|
|
ellipseName: "GRS 67(IUGG 1967)"
|
|
};
|
|
exports.bessel = {
|
|
a: 6377397.155,
|
|
rf: 299.1528128,
|
|
ellipseName: "Bessel 1841"
|
|
};
|
|
exports.bess_nam = {
|
|
a: 6377483.865,
|
|
rf: 299.1528128,
|
|
ellipseName: "Bessel 1841 (Namibia)"
|
|
};
|
|
exports.clrk66 = {
|
|
a: 6378206.4,
|
|
b: 6356583.8,
|
|
ellipseName: "Clarke 1866"
|
|
};
|
|
exports.clrk80 = {
|
|
a: 6378249.145,
|
|
rf: 293.4663,
|
|
ellipseName: "Clarke 1880 mod."
|
|
};
|
|
exports.clrk58 = {
|
|
a: 6378293.645208759,
|
|
rf: 294.2606763692654,
|
|
ellipseName: "Clarke 1858"
|
|
};
|
|
exports.CPM = {
|
|
a: 6375738.7,
|
|
rf: 334.29,
|
|
ellipseName: "Comm. des Poids et Mesures 1799"
|
|
};
|
|
exports.delmbr = {
|
|
a: 6376428.0,
|
|
rf: 311.5,
|
|
ellipseName: "Delambre 1810 (Belgium)"
|
|
};
|
|
exports.engelis = {
|
|
a: 6378136.05,
|
|
rf: 298.2566,
|
|
ellipseName: "Engelis 1985"
|
|
};
|
|
exports.evrst30 = {
|
|
a: 6377276.345,
|
|
rf: 300.8017,
|
|
ellipseName: "Everest 1830"
|
|
};
|
|
exports.evrst48 = {
|
|
a: 6377304.063,
|
|
rf: 300.8017,
|
|
ellipseName: "Everest 1948"
|
|
};
|
|
exports.evrst56 = {
|
|
a: 6377301.243,
|
|
rf: 300.8017,
|
|
ellipseName: "Everest 1956"
|
|
};
|
|
exports.evrst69 = {
|
|
a: 6377295.664,
|
|
rf: 300.8017,
|
|
ellipseName: "Everest 1969"
|
|
};
|
|
exports.evrstSS = {
|
|
a: 6377298.556,
|
|
rf: 300.8017,
|
|
ellipseName: "Everest (Sabah & Sarawak)"
|
|
};
|
|
exports.fschr60 = {
|
|
a: 6378166.0,
|
|
rf: 298.3,
|
|
ellipseName: "Fischer (Mercury Datum) 1960"
|
|
};
|
|
exports.fschr60m = {
|
|
a: 6378155.0,
|
|
rf: 298.3,
|
|
ellipseName: "Fischer 1960"
|
|
};
|
|
exports.fschr68 = {
|
|
a: 6378150.0,
|
|
rf: 298.3,
|
|
ellipseName: "Fischer 1968"
|
|
};
|
|
exports.helmert = {
|
|
a: 6378200.0,
|
|
rf: 298.3,
|
|
ellipseName: "Helmert 1906"
|
|
};
|
|
exports.hough = {
|
|
a: 6378270.0,
|
|
rf: 297.0,
|
|
ellipseName: "Hough"
|
|
};
|
|
exports.intl = {
|
|
a: 6378388.0,
|
|
rf: 297.0,
|
|
ellipseName: "International 1909 (Hayford)"
|
|
};
|
|
exports.kaula = {
|
|
a: 6378163.0,
|
|
rf: 298.24,
|
|
ellipseName: "Kaula 1961"
|
|
};
|
|
exports.lerch = {
|
|
a: 6378139.0,
|
|
rf: 298.257,
|
|
ellipseName: "Lerch 1979"
|
|
};
|
|
exports.mprts = {
|
|
a: 6397300.0,
|
|
rf: 191.0,
|
|
ellipseName: "Maupertius 1738"
|
|
};
|
|
exports.new_intl = {
|
|
a: 6378157.5,
|
|
b: 6356772.2,
|
|
ellipseName: "New International 1967"
|
|
};
|
|
exports.plessis = {
|
|
a: 6376523.0,
|
|
rf: 6355863.0,
|
|
ellipseName: "Plessis 1817 (France)"
|
|
};
|
|
exports.krass = {
|
|
a: 6378245.0,
|
|
rf: 298.3,
|
|
ellipseName: "Krassovsky, 1942"
|
|
};
|
|
exports.SEasia = {
|
|
a: 6378155.0,
|
|
b: 6356773.3205,
|
|
ellipseName: "Southeast Asia"
|
|
};
|
|
exports.walbeck = {
|
|
a: 6376896.0,
|
|
b: 6355834.8467,
|
|
ellipseName: "Walbeck"
|
|
};
|
|
exports.WGS60 = {
|
|
a: 6378165.0,
|
|
rf: 298.3,
|
|
ellipseName: "WGS 60"
|
|
};
|
|
exports.WGS66 = {
|
|
a: 6378145.0,
|
|
rf: 298.25,
|
|
ellipseName: "WGS 66"
|
|
};
|
|
exports.WGS7 = {
|
|
a: 6378135.0,
|
|
rf: 298.26,
|
|
ellipseName: "WGS 72"
|
|
};
|
|
exports.WGS84 = {
|
|
a: 6378137.0,
|
|
rf: 298.257223563,
|
|
ellipseName: "WGS 84"
|
|
};
|
|
exports.sphere = {
|
|
a: 6370997.0,
|
|
b: 6370997.0,
|
|
ellipseName: "Normal Sphere (r=6370997)"
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/constants/PrimeMeridian */ function _(require, module, exports) {
|
|
exports.greenwich = 0.0; //"0dE",
|
|
exports.lisbon = -9.131906111111; //"9d07'54.862\"W",
|
|
exports.paris = 2.337229166667; //"2d20'14.025\"E",
|
|
exports.bogota = -74.080916666667; //"74d04'51.3\"W",
|
|
exports.madrid = -3.687938888889; //"3d41'16.58\"W",
|
|
exports.rome = 12.452333333333; //"12d27'8.4\"E",
|
|
exports.bern = 7.439583333333; //"7d26'22.5\"E",
|
|
exports.jakarta = 106.807719444444; //"106d48'27.79\"E",
|
|
exports.ferro = -17.666666666667; //"17d40'W",
|
|
exports.brussels = 4.367975; //"4d22'4.71\"E",
|
|
exports.stockholm = 18.058277777778; //"18d3'29.8\"E",
|
|
exports.athens = 23.7163375; //"23d42'58.815\"E",
|
|
exports.oslo = 10.722916666667; //"10d43'22.5\"E"
|
|
}
|
|
,
|
|
/* proj4/lib/constants/units */ function _(require, module, exports) {
|
|
exports.ft = { to_meter: 0.3048 };
|
|
exports['us-ft'] = { to_meter: 1200 / 3937 };
|
|
}
|
|
,
|
|
/* proj4/lib/core */ function _(require, module, exports) {
|
|
var proj = require(371) /* ./Proj */;
|
|
var transform = require(396) /* ./transform */;
|
|
var wgs84 = proj('WGS84');
|
|
function transformer(from, to, coords) {
|
|
var transformedArray;
|
|
if (Array.isArray(coords)) {
|
|
transformedArray = transform(from, to, coords);
|
|
if (coords.length === 3) {
|
|
return [transformedArray.x, transformedArray.y, transformedArray.z];
|
|
}
|
|
else {
|
|
return [transformedArray.x, transformedArray.y];
|
|
}
|
|
}
|
|
else {
|
|
return transform(from, to, coords);
|
|
}
|
|
}
|
|
function checkProj(item) {
|
|
if (item instanceof proj) {
|
|
return item;
|
|
}
|
|
if (item.oProj) {
|
|
return item.oProj;
|
|
}
|
|
return proj(item);
|
|
}
|
|
function proj4(fromProj, toProj, coord) {
|
|
fromProj = checkProj(fromProj);
|
|
var single = false;
|
|
var obj;
|
|
if (typeof toProj === 'undefined') {
|
|
toProj = fromProj;
|
|
fromProj = wgs84;
|
|
single = true;
|
|
}
|
|
else if (typeof toProj.x !== 'undefined' || Array.isArray(toProj)) {
|
|
coord = toProj;
|
|
toProj = fromProj;
|
|
fromProj = wgs84;
|
|
single = true;
|
|
}
|
|
toProj = checkProj(toProj);
|
|
if (coord) {
|
|
return transformer(fromProj, toProj, coord);
|
|
}
|
|
else {
|
|
obj = {
|
|
forward: function (coords) {
|
|
return transformer(fromProj, toProj, coords);
|
|
},
|
|
inverse: function (coords) {
|
|
return transformer(toProj, fromProj, coords);
|
|
}
|
|
};
|
|
if (single) {
|
|
obj.oProj = toProj;
|
|
}
|
|
return obj;
|
|
}
|
|
}
|
|
module.exports = proj4;
|
|
}
|
|
,
|
|
/* proj4/lib/datum */ function _(require, module, exports) {
|
|
var PJD_3PARAM = 1;
|
|
var PJD_7PARAM = 2;
|
|
var PJD_WGS84 = 4; // WGS84 or equivalent
|
|
var PJD_NODATUM = 5; // WGS84 or equivalent
|
|
var SEC_TO_RAD = 4.84813681109535993589914102357e-6;
|
|
function datum(datumCode, datum_params, a, b, es, ep2) {
|
|
var out = {};
|
|
out.datum_type = PJD_WGS84; //default setting
|
|
if (datumCode && datumCode === 'none') {
|
|
out.datum_type = PJD_NODATUM;
|
|
}
|
|
if (datum_params) {
|
|
out.datum_params = datum_params.map(parseFloat);
|
|
if (out.datum_params[0] !== 0 || out.datum_params[1] !== 0 || out.datum_params[2] !== 0) {
|
|
out.datum_type = PJD_3PARAM;
|
|
}
|
|
if (out.datum_params.length > 3) {
|
|
if (out.datum_params[3] !== 0 || out.datum_params[4] !== 0 || out.datum_params[5] !== 0 || out.datum_params[6] !== 0) {
|
|
out.datum_type = PJD_7PARAM;
|
|
out.datum_params[3] *= SEC_TO_RAD;
|
|
out.datum_params[4] *= SEC_TO_RAD;
|
|
out.datum_params[5] *= SEC_TO_RAD;
|
|
out.datum_params[6] = (out.datum_params[6] / 1000000.0) + 1.0;
|
|
}
|
|
}
|
|
}
|
|
out.a = a; //datum object also uses these values
|
|
out.b = b;
|
|
out.es = es;
|
|
out.ep2 = ep2;
|
|
return out;
|
|
}
|
|
module.exports = datum;
|
|
}
|
|
,
|
|
/* proj4/lib/datumUtils */ function _(require, module, exports) {
|
|
var PJD_3PARAM = 1;
|
|
var PJD_7PARAM = 2;
|
|
var HALF_PI = Math.PI / 2;
|
|
exports.compareDatums = function (source, dest) {
|
|
if (source.datum_type !== dest.datum_type) {
|
|
return false; // false, datums are not equal
|
|
}
|
|
else if (source.a !== dest.a || Math.abs(this.es - dest.es) > 0.000000000050) {
|
|
// the tolerence for es is to ensure that GRS80 and WGS84
|
|
// are considered identical
|
|
return false;
|
|
}
|
|
else if (source.datum_type === PJD_3PARAM) {
|
|
return (this.datum_params[0] === dest.datum_params[0] && source.datum_params[1] === dest.datum_params[1] && source.datum_params[2] === dest.datum_params[2]);
|
|
}
|
|
else if (source.datum_type === PJD_7PARAM) {
|
|
return (source.datum_params[0] === dest.datum_params[0] && source.datum_params[1] === dest.datum_params[1] && source.datum_params[2] === dest.datum_params[2] && source.datum_params[3] === dest.datum_params[3] && source.datum_params[4] === dest.datum_params[4] && source.datum_params[5] === dest.datum_params[5] && source.datum_params[6] === dest.datum_params[6]);
|
|
}
|
|
else {
|
|
return true; // datums are equal
|
|
}
|
|
}; // cs_compare_datums()
|
|
/*
|
|
* The function Convert_Geodetic_To_Geocentric converts geodetic coordinates
|
|
* (latitude, longitude, and height) to geocentric coordinates (X, Y, Z),
|
|
* according to the current ellipsoid parameters.
|
|
*
|
|
* Latitude : Geodetic latitude in radians (input)
|
|
* Longitude : Geodetic longitude in radians (input)
|
|
* Height : Geodetic height, in meters (input)
|
|
* X : Calculated Geocentric X coordinate, in meters (output)
|
|
* Y : Calculated Geocentric Y coordinate, in meters (output)
|
|
* Z : Calculated Geocentric Z coordinate, in meters (output)
|
|
*
|
|
*/
|
|
exports.geodeticToGeocentric = function (p, es, a) {
|
|
var Longitude = p.x;
|
|
var Latitude = p.y;
|
|
var Height = p.z ? p.z : 0; //Z value not always supplied
|
|
var Rn; /* Earth radius at location */
|
|
var Sin_Lat; /* Math.sin(Latitude) */
|
|
var Sin2_Lat; /* Square of Math.sin(Latitude) */
|
|
var Cos_Lat; /* Math.cos(Latitude) */
|
|
/*
|
|
** Don't blow up if Latitude is just a little out of the value
|
|
** range as it may just be a rounding issue. Also removed longitude
|
|
** test, it should be wrapped by Math.cos() and Math.sin(). NFW for PROJ.4, Sep/2001.
|
|
*/
|
|
if (Latitude < -HALF_PI && Latitude > -1.001 * HALF_PI) {
|
|
Latitude = -HALF_PI;
|
|
}
|
|
else if (Latitude > HALF_PI && Latitude < 1.001 * HALF_PI) {
|
|
Latitude = HALF_PI;
|
|
}
|
|
else if ((Latitude < -HALF_PI) || (Latitude > HALF_PI)) {
|
|
/* Latitude out of range */
|
|
//..reportError('geocent:lat out of range:' + Latitude);
|
|
return null;
|
|
}
|
|
if (Longitude > Math.PI) {
|
|
Longitude -= (2 * Math.PI);
|
|
}
|
|
Sin_Lat = Math.sin(Latitude);
|
|
Cos_Lat = Math.cos(Latitude);
|
|
Sin2_Lat = Sin_Lat * Sin_Lat;
|
|
Rn = a / (Math.sqrt(1.0e0 - es * Sin2_Lat));
|
|
return {
|
|
x: (Rn + Height) * Cos_Lat * Math.cos(Longitude),
|
|
y: (Rn + Height) * Cos_Lat * Math.sin(Longitude),
|
|
z: ((Rn * (1 - es)) + Height) * Sin_Lat
|
|
};
|
|
}; // cs_geodetic_to_geocentric()
|
|
exports.geocentricToGeodetic = function (p, es, a, b) {
|
|
/* local defintions and variables */
|
|
/* end-criterium of loop, accuracy of sin(Latitude) */
|
|
var genau = 1e-12;
|
|
var genau2 = (genau * genau);
|
|
var maxiter = 30;
|
|
var P; /* distance between semi-minor axis and location */
|
|
var RR; /* distance between center and location */
|
|
var CT; /* sin of geocentric latitude */
|
|
var ST; /* cos of geocentric latitude */
|
|
var RX;
|
|
var RK;
|
|
var RN; /* Earth radius at location */
|
|
var CPHI0; /* cos of start or old geodetic latitude in iterations */
|
|
var SPHI0; /* sin of start or old geodetic latitude in iterations */
|
|
var CPHI; /* cos of searched geodetic latitude */
|
|
var SPHI; /* sin of searched geodetic latitude */
|
|
var SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */
|
|
var iter; /* # of continous iteration, max. 30 is always enough (s.a.) */
|
|
var X = p.x;
|
|
var Y = p.y;
|
|
var Z = p.z ? p.z : 0.0; //Z value not always supplied
|
|
var Longitude;
|
|
var Latitude;
|
|
var Height;
|
|
P = Math.sqrt(X * X + Y * Y);
|
|
RR = Math.sqrt(X * X + Y * Y + Z * Z);
|
|
/* special cases for latitude and longitude */
|
|
if (P / a < genau) {
|
|
/* special case, if P=0. (X=0., Y=0.) */
|
|
Longitude = 0.0;
|
|
/* if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis
|
|
* of ellipsoid (=center of mass), Latitude becomes PI/2 */
|
|
if (RR / a < genau) {
|
|
Latitude = HALF_PI;
|
|
Height = -b;
|
|
return {
|
|
x: p.x,
|
|
y: p.y,
|
|
z: p.z
|
|
};
|
|
}
|
|
}
|
|
else {
|
|
/* ellipsoidal (geodetic) longitude
|
|
* interval: -PI < Longitude <= +PI */
|
|
Longitude = Math.atan2(Y, X);
|
|
}
|
|
/* --------------------------------------------------------------
|
|
* Following iterative algorithm was developped by
|
|
* "Institut for Erdmessung", University of Hannover, July 1988.
|
|
* Internet: www.ife.uni-hannover.de
|
|
* Iterative computation of CPHI,SPHI and Height.
|
|
* Iteration of CPHI and SPHI to 10**-12 radian resp.
|
|
* 2*10**-7 arcsec.
|
|
* --------------------------------------------------------------
|
|
*/
|
|
CT = Z / RR;
|
|
ST = P / RR;
|
|
RX = 1.0 / Math.sqrt(1.0 - es * (2.0 - es) * ST * ST);
|
|
CPHI0 = ST * (1.0 - es) * RX;
|
|
SPHI0 = CT * RX;
|
|
iter = 0;
|
|
/* loop to find sin(Latitude) resp. Latitude
|
|
* until |sin(Latitude(iter)-Latitude(iter-1))| < genau */
|
|
do {
|
|
iter++;
|
|
RN = a / Math.sqrt(1.0 - es * SPHI0 * SPHI0);
|
|
/* ellipsoidal (geodetic) height */
|
|
Height = P * CPHI0 + Z * SPHI0 - RN * (1.0 - es * SPHI0 * SPHI0);
|
|
RK = es * RN / (RN + Height);
|
|
RX = 1.0 / Math.sqrt(1.0 - RK * (2.0 - RK) * ST * ST);
|
|
CPHI = ST * (1.0 - RK) * RX;
|
|
SPHI = CT * RX;
|
|
SDPHI = SPHI * CPHI0 - CPHI * SPHI0;
|
|
CPHI0 = CPHI;
|
|
SPHI0 = SPHI;
|
|
} while (SDPHI * SDPHI > genau2 && iter < maxiter);
|
|
/* ellipsoidal (geodetic) latitude */
|
|
Latitude = Math.atan(SPHI / Math.abs(CPHI));
|
|
return {
|
|
x: Longitude,
|
|
y: Latitude,
|
|
z: Height
|
|
};
|
|
}; // cs_geocentric_to_geodetic()
|
|
/****************************************************************/
|
|
// pj_geocentic_to_wgs84( p )
|
|
// p = point to transform in geocentric coordinates (x,y,z)
|
|
/** point object, nothing fancy, just allows values to be
|
|
passed back and forth by reference rather than by value.
|
|
Other point classes may be used as long as they have
|
|
x and y properties, which will get modified in the transform method.
|
|
*/
|
|
exports.geocentricToWgs84 = function (p, datum_type, datum_params) {
|
|
if (datum_type === PJD_3PARAM) {
|
|
// if( x[io] === HUGE_VAL )
|
|
// continue;
|
|
return {
|
|
x: p.x + datum_params[0],
|
|
y: p.y + datum_params[1],
|
|
z: p.z + datum_params[2],
|
|
};
|
|
}
|
|
else if (datum_type === PJD_7PARAM) {
|
|
var Dx_BF = datum_params[0];
|
|
var Dy_BF = datum_params[1];
|
|
var Dz_BF = datum_params[2];
|
|
var Rx_BF = datum_params[3];
|
|
var Ry_BF = datum_params[4];
|
|
var Rz_BF = datum_params[5];
|
|
var M_BF = datum_params[6];
|
|
// if( x[io] === HUGE_VAL )
|
|
// continue;
|
|
return {
|
|
x: M_BF * (p.x - Rz_BF * p.y + Ry_BF * p.z) + Dx_BF,
|
|
y: M_BF * (Rz_BF * p.x + p.y - Rx_BF * p.z) + Dy_BF,
|
|
z: M_BF * (-Ry_BF * p.x + Rx_BF * p.y + p.z) + Dz_BF
|
|
};
|
|
}
|
|
}; // cs_geocentric_to_wgs84
|
|
/****************************************************************/
|
|
// pj_geocentic_from_wgs84()
|
|
// coordinate system definition,
|
|
// point to transform in geocentric coordinates (x,y,z)
|
|
exports.geocentricFromWgs84 = function (p, datum_type, datum_params) {
|
|
if (datum_type === PJD_3PARAM) {
|
|
//if( x[io] === HUGE_VAL )
|
|
// continue;
|
|
return {
|
|
x: p.x - datum_params[0],
|
|
y: p.y - datum_params[1],
|
|
z: p.z - datum_params[2],
|
|
};
|
|
}
|
|
else if (datum_type === PJD_7PARAM) {
|
|
var Dx_BF = datum_params[0];
|
|
var Dy_BF = datum_params[1];
|
|
var Dz_BF = datum_params[2];
|
|
var Rx_BF = datum_params[3];
|
|
var Ry_BF = datum_params[4];
|
|
var Rz_BF = datum_params[5];
|
|
var M_BF = datum_params[6];
|
|
var x_tmp = (p.x - Dx_BF) / M_BF;
|
|
var y_tmp = (p.y - Dy_BF) / M_BF;
|
|
var z_tmp = (p.z - Dz_BF) / M_BF;
|
|
//if( x[io] === HUGE_VAL )
|
|
// continue;
|
|
return {
|
|
x: x_tmp + Rz_BF * y_tmp - Ry_BF * z_tmp,
|
|
y: -Rz_BF * x_tmp + y_tmp + Rx_BF * z_tmp,
|
|
z: Ry_BF * x_tmp - Rx_BF * y_tmp + z_tmp
|
|
};
|
|
} //cs_geocentric_from_wgs84()
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/datum_transform */ function _(require, module, exports) {
|
|
var PJD_3PARAM = 1;
|
|
var PJD_7PARAM = 2;
|
|
var PJD_NODATUM = 5; // WGS84 or equivalent
|
|
var datum = require(385) /* ./datumUtils */;
|
|
function checkParams(type) {
|
|
return (type === PJD_3PARAM || type === PJD_7PARAM);
|
|
}
|
|
module.exports = function (source, dest, point) {
|
|
// Short cut if the datums are identical.
|
|
if (datum.compareDatums(source, dest)) {
|
|
return point; // in this case, zero is sucess,
|
|
// whereas cs_compare_datums returns 1 to indicate TRUE
|
|
// confusing, should fix this
|
|
}
|
|
// Explicitly skip datum transform by setting 'datum=none' as parameter for either source or dest
|
|
if (source.datum_type === PJD_NODATUM || dest.datum_type === PJD_NODATUM) {
|
|
return point;
|
|
}
|
|
// If this datum requires grid shifts, then apply it to geodetic coordinates.
|
|
// Do we need to go through geocentric coordinates?
|
|
if (source.es === dest.es && source.a === dest.a && !checkParams(source.datum_type) && !checkParams(dest.datum_type)) {
|
|
return point;
|
|
}
|
|
// Convert to geocentric coordinates.
|
|
point = datum.geodeticToGeocentric(point, source.es, source.a);
|
|
// Convert between datums
|
|
if (checkParams(source.datum_type)) {
|
|
point = datum.geocentricToWgs84(point, source.datum_type, source.datum_params);
|
|
}
|
|
if (checkParams(dest.datum_type)) {
|
|
point = datum.geocentricFromWgs84(point, dest.datum_type, dest.datum_params);
|
|
}
|
|
return datum.geocentricToGeodetic(point, dest.es, dest.a, dest.b);
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/defs */ function _(require, module, exports) {
|
|
var globals = require(390) /* ./global */;
|
|
var parseProj = require(392) /* ./projString */;
|
|
var wkt = require(397) /* ./wkt */;
|
|
function defs(name) {
|
|
/*global console*/
|
|
var that = this;
|
|
if (arguments.length === 2) {
|
|
var def = arguments[1];
|
|
if (typeof def === 'string') {
|
|
if (def.charAt(0) === '+') {
|
|
defs[name] = parseProj(arguments[1]);
|
|
}
|
|
else {
|
|
defs[name] = wkt(arguments[1]);
|
|
}
|
|
}
|
|
else {
|
|
defs[name] = def;
|
|
}
|
|
}
|
|
else if (arguments.length === 1) {
|
|
if (Array.isArray(name)) {
|
|
return name.map(function (v) {
|
|
if (Array.isArray(v)) {
|
|
defs.apply(that, v);
|
|
}
|
|
else {
|
|
defs(v);
|
|
}
|
|
});
|
|
}
|
|
else if (typeof name === 'string') {
|
|
if (name in defs) {
|
|
return defs[name];
|
|
}
|
|
}
|
|
else if ('EPSG' in name) {
|
|
defs['EPSG:' + name.EPSG] = name;
|
|
}
|
|
else if ('ESRI' in name) {
|
|
defs['ESRI:' + name.ESRI] = name;
|
|
}
|
|
else if ('IAU2000' in name) {
|
|
defs['IAU2000:' + name.IAU2000] = name;
|
|
}
|
|
else {
|
|
console.log(name);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
globals(defs);
|
|
module.exports = defs;
|
|
}
|
|
,
|
|
/* proj4/lib/deriveConstants */ function _(require, module, exports) {
|
|
// ellipoid pj_set_ell.c
|
|
var SIXTH = 0.1666666666666666667;
|
|
/* 1/6 */
|
|
var RA4 = 0.04722222222222222222;
|
|
/* 17/360 */
|
|
var RA6 = 0.02215608465608465608;
|
|
var EPSLN = 1.0e-10;
|
|
var Ellipsoid = require(380) /* ./constants/Ellipsoid */;
|
|
exports.eccentricity = function (a, b, rf, R_A) {
|
|
var a2 = a * a; // used in geocentric
|
|
var b2 = b * b; // used in geocentric
|
|
var es = (a2 - b2) / a2; // e ^ 2
|
|
var e = 0;
|
|
if (R_A) {
|
|
a *= 1 - es * (SIXTH + es * (RA4 + es * RA6));
|
|
a2 = a * a;
|
|
es = 0;
|
|
}
|
|
else {
|
|
e = Math.sqrt(es); // eccentricity
|
|
}
|
|
var ep2 = (a2 - b2) / b2; // used in geocentric
|
|
return {
|
|
es: es,
|
|
e: e,
|
|
ep2: ep2
|
|
};
|
|
};
|
|
exports.sphere = function (a, b, rf, ellps, sphere) {
|
|
if (!a) { // do we have an ellipsoid?
|
|
var ellipse = Ellipsoid[ellps];
|
|
if (!ellipse) {
|
|
ellipse = Ellipsoid.WGS84;
|
|
}
|
|
a = ellipse.a;
|
|
b = ellipse.b;
|
|
rf = ellipse.rf;
|
|
}
|
|
if (rf && !b) {
|
|
b = (1.0 - 1.0 / rf) * a;
|
|
}
|
|
if (rf === 0 || Math.abs(a - b) < EPSLN) {
|
|
sphere = true;
|
|
b = a;
|
|
}
|
|
return {
|
|
a: a,
|
|
b: b,
|
|
rf: rf,
|
|
sphere: sphere
|
|
};
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/extend */ function _(require, module, exports) {
|
|
module.exports = function (destination, source) {
|
|
destination = destination || {};
|
|
var value, property;
|
|
if (!source) {
|
|
return destination;
|
|
}
|
|
for (property in source) {
|
|
value = source[property];
|
|
if (value !== undefined) {
|
|
destination[property] = value;
|
|
}
|
|
}
|
|
return destination;
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/global */ function _(require, module, exports) {
|
|
module.exports = function (defs) {
|
|
defs('EPSG:4326', "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees");
|
|
defs('EPSG:4269', "+title=NAD83 (long/lat) +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees");
|
|
defs('EPSG:3857', "+title=WGS 84 / Pseudo-Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs");
|
|
defs.WGS84 = defs['EPSG:4326'];
|
|
defs['EPSG:3785'] = defs['EPSG:3857']; // maintain backward compat, official code is 3857
|
|
defs.GOOGLE = defs['EPSG:3857'];
|
|
defs['EPSG:900913'] = defs['EPSG:3857'];
|
|
defs['EPSG:102113'] = defs['EPSG:3857'];
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/parseCode */ function _(require, module, exports) {
|
|
var defs = require(387) /* ./defs */;
|
|
var wkt = require(397) /* ./wkt */;
|
|
var projStr = require(392) /* ./projString */;
|
|
function testObj(code) {
|
|
return typeof code === 'string';
|
|
}
|
|
function testDef(code) {
|
|
return code in defs;
|
|
}
|
|
var codeWords = ['GEOGCS', 'GEOCCS', 'PROJCS', 'LOCAL_CS'];
|
|
function testWKT(code) {
|
|
return codeWords.some(function (word) {
|
|
return code.indexOf(word) > -1;
|
|
});
|
|
}
|
|
function testProj(code) {
|
|
return code[0] === '+';
|
|
}
|
|
function parse(code) {
|
|
if (testObj(code)) {
|
|
//check to see if this is a WKT string
|
|
if (testDef(code)) {
|
|
return defs[code];
|
|
}
|
|
if (testWKT(code)) {
|
|
return wkt(code);
|
|
}
|
|
if (testProj(code)) {
|
|
return projStr(code);
|
|
}
|
|
}
|
|
else {
|
|
return code;
|
|
}
|
|
}
|
|
module.exports = parse;
|
|
}
|
|
,
|
|
/* proj4/lib/projString */ function _(require, module, exports) {
|
|
var D2R = 0.01745329251994329577;
|
|
var PrimeMeridian = require(381) /* ./constants/PrimeMeridian */;
|
|
var units = require(382) /* ./constants/units */;
|
|
module.exports = function (defData) {
|
|
var self = {};
|
|
var paramObj = defData.split('+').map(function (v) {
|
|
return v.trim();
|
|
}).filter(function (a) {
|
|
return a;
|
|
}).reduce(function (p, a) {
|
|
var split = a.split('=');
|
|
split.push(true);
|
|
p[split[0].toLowerCase()] = split[1];
|
|
return p;
|
|
}, {});
|
|
var paramName, paramVal, paramOutname;
|
|
var params = {
|
|
proj: 'projName',
|
|
datum: 'datumCode',
|
|
rf: function (v) {
|
|
self.rf = parseFloat(v);
|
|
},
|
|
lat_0: function (v) {
|
|
self.lat0 = v * D2R;
|
|
},
|
|
lat_1: function (v) {
|
|
self.lat1 = v * D2R;
|
|
},
|
|
lat_2: function (v) {
|
|
self.lat2 = v * D2R;
|
|
},
|
|
lat_ts: function (v) {
|
|
self.lat_ts = v * D2R;
|
|
},
|
|
lon_0: function (v) {
|
|
self.long0 = v * D2R;
|
|
},
|
|
lon_1: function (v) {
|
|
self.long1 = v * D2R;
|
|
},
|
|
lon_2: function (v) {
|
|
self.long2 = v * D2R;
|
|
},
|
|
alpha: function (v) {
|
|
self.alpha = parseFloat(v) * D2R;
|
|
},
|
|
lonc: function (v) {
|
|
self.longc = v * D2R;
|
|
},
|
|
x_0: function (v) {
|
|
self.x0 = parseFloat(v);
|
|
},
|
|
y_0: function (v) {
|
|
self.y0 = parseFloat(v);
|
|
},
|
|
k_0: function (v) {
|
|
self.k0 = parseFloat(v);
|
|
},
|
|
k: function (v) {
|
|
self.k0 = parseFloat(v);
|
|
},
|
|
a: function (v) {
|
|
self.a = parseFloat(v);
|
|
},
|
|
b: function (v) {
|
|
self.b = parseFloat(v);
|
|
},
|
|
r_a: function () {
|
|
self.R_A = true;
|
|
},
|
|
zone: function (v) {
|
|
self.zone = parseInt(v, 10);
|
|
},
|
|
south: function () {
|
|
self.utmSouth = true;
|
|
},
|
|
towgs84: function (v) {
|
|
self.datum_params = v.split(",").map(function (a) {
|
|
return parseFloat(a);
|
|
});
|
|
},
|
|
to_meter: function (v) {
|
|
self.to_meter = parseFloat(v);
|
|
},
|
|
units: function (v) {
|
|
self.units = v;
|
|
if (units[v]) {
|
|
self.to_meter = units[v].to_meter;
|
|
}
|
|
},
|
|
from_greenwich: function (v) {
|
|
self.from_greenwich = v * D2R;
|
|
},
|
|
pm: function (v) {
|
|
self.from_greenwich = (PrimeMeridian[v] ? PrimeMeridian[v] : parseFloat(v)) * D2R;
|
|
},
|
|
nadgrids: function (v) {
|
|
if (v === '@null') {
|
|
self.datumCode = 'none';
|
|
}
|
|
else {
|
|
self.nadgrids = v;
|
|
}
|
|
},
|
|
axis: function (v) {
|
|
var legalAxis = "ewnsud";
|
|
if (v.length === 3 && legalAxis.indexOf(v.substr(0, 1)) !== -1 && legalAxis.indexOf(v.substr(1, 1)) !== -1 && legalAxis.indexOf(v.substr(2, 1)) !== -1) {
|
|
self.axis = v;
|
|
}
|
|
}
|
|
};
|
|
for (paramName in paramObj) {
|
|
paramVal = paramObj[paramName];
|
|
if (paramName in params) {
|
|
paramOutname = params[paramName];
|
|
if (typeof paramOutname === 'function') {
|
|
paramOutname(paramVal);
|
|
}
|
|
else {
|
|
self[paramOutname] = paramVal;
|
|
}
|
|
}
|
|
else {
|
|
self[paramName] = paramVal;
|
|
}
|
|
}
|
|
if (typeof self.datumCode === 'string' && self.datumCode !== "WGS84") {
|
|
self.datumCode = self.datumCode.toLowerCase();
|
|
}
|
|
return self;
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/projections */ function _(require, module, exports) {
|
|
var projs = [
|
|
require(395) /* ./projections/merc */,
|
|
require(394) /* ./projections/longlat */
|
|
];
|
|
var names = {};
|
|
var projStore = [];
|
|
function add(proj, i) {
|
|
var len = projStore.length;
|
|
if (!proj.names) {
|
|
console.log(i);
|
|
return true;
|
|
}
|
|
projStore[len] = proj;
|
|
proj.names.forEach(function (n) {
|
|
names[n.toLowerCase()] = len;
|
|
});
|
|
return this;
|
|
}
|
|
exports.add = add;
|
|
exports.get = function (name) {
|
|
if (!name) {
|
|
return false;
|
|
}
|
|
var n = name.toLowerCase();
|
|
if (typeof names[n] !== 'undefined' && projStore[names[n]]) {
|
|
return projStore[names[n]];
|
|
}
|
|
};
|
|
exports.start = function () {
|
|
projs.forEach(add);
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/projections/longlat */ function _(require, module, exports) {
|
|
exports.init = function () {
|
|
//no-op for longlat
|
|
};
|
|
function identity(pt) {
|
|
return pt;
|
|
}
|
|
exports.forward = identity;
|
|
exports.inverse = identity;
|
|
exports.names = ["longlat", "identity"];
|
|
}
|
|
,
|
|
/* proj4/lib/projections/merc */ function _(require, module, exports) {
|
|
var msfnz = require(374) /* ../common/msfnz */;
|
|
var HALF_PI = Math.PI / 2;
|
|
var EPSLN = 1.0e-10;
|
|
var R2D = 57.29577951308232088;
|
|
var adjust_lon = require(373) /* ../common/adjust_lon */;
|
|
var FORTPI = Math.PI / 4;
|
|
var tsfnz = require(378) /* ../common/tsfnz */;
|
|
var phi2z = require(375) /* ../common/phi2z */;
|
|
exports.init = function () {
|
|
var con = this.b / this.a;
|
|
this.es = 1 - con * con;
|
|
if (!('x0' in this)) {
|
|
this.x0 = 0;
|
|
}
|
|
if (!('y0' in this)) {
|
|
this.y0 = 0;
|
|
}
|
|
this.e = Math.sqrt(this.es);
|
|
if (this.lat_ts) {
|
|
if (this.sphere) {
|
|
this.k0 = Math.cos(this.lat_ts);
|
|
}
|
|
else {
|
|
this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts));
|
|
}
|
|
}
|
|
else {
|
|
if (!this.k0) {
|
|
if (this.k) {
|
|
this.k0 = this.k;
|
|
}
|
|
else {
|
|
this.k0 = 1;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
/* Mercator forward equations--mapping lat,long to x,y
|
|
--------------------------------------------------*/
|
|
exports.forward = function (p) {
|
|
var lon = p.x;
|
|
var lat = p.y;
|
|
// convert to radians
|
|
if (lat * R2D > 90 && lat * R2D < -90 && lon * R2D > 180 && lon * R2D < -180) {
|
|
return null;
|
|
}
|
|
var x, y;
|
|
if (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) {
|
|
return null;
|
|
}
|
|
else {
|
|
if (this.sphere) {
|
|
x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0);
|
|
y = this.y0 + this.a * this.k0 * Math.log(Math.tan(FORTPI + 0.5 * lat));
|
|
}
|
|
else {
|
|
var sinphi = Math.sin(lat);
|
|
var ts = tsfnz(this.e, lat, sinphi);
|
|
x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0);
|
|
y = this.y0 - this.a * this.k0 * Math.log(ts);
|
|
}
|
|
p.x = x;
|
|
p.y = y;
|
|
return p;
|
|
}
|
|
};
|
|
/* Mercator inverse equations--mapping x,y to lat/long
|
|
--------------------------------------------------*/
|
|
exports.inverse = function (p) {
|
|
var x = p.x - this.x0;
|
|
var y = p.y - this.y0;
|
|
var lon, lat;
|
|
if (this.sphere) {
|
|
lat = HALF_PI - 2 * Math.atan(Math.exp(-y / (this.a * this.k0)));
|
|
}
|
|
else {
|
|
var ts = Math.exp(-y / (this.a * this.k0));
|
|
lat = phi2z(this.e, ts);
|
|
if (lat === -9999) {
|
|
return null;
|
|
}
|
|
}
|
|
lon = adjust_lon(this.long0 + x / (this.a * this.k0));
|
|
p.x = lon;
|
|
p.y = lat;
|
|
return p;
|
|
};
|
|
exports.names = ["Mercator", "Popular Visualisation Pseudo Mercator", "Mercator_1SP", "Mercator_Auxiliary_Sphere", "merc"];
|
|
}
|
|
,
|
|
/* proj4/lib/transform */ function _(require, module, exports) {
|
|
var D2R = 0.01745329251994329577;
|
|
var R2D = 57.29577951308232088;
|
|
var PJD_3PARAM = 1;
|
|
var PJD_7PARAM = 2;
|
|
var datum_transform = require(386) /* ./datum_transform */;
|
|
var adjust_axis = require(372) /* ./adjust_axis */;
|
|
var proj = require(371) /* ./Proj */;
|
|
var toPoint = require(377) /* ./common/toPoint */;
|
|
function checkNotWGS(source, dest) {
|
|
return ((source.datum.datum_type === PJD_3PARAM || source.datum.datum_type === PJD_7PARAM) && dest.datumCode !== 'WGS84') || ((dest.datum.datum_type === PJD_3PARAM || dest.datum.datum_type === PJD_7PARAM) && source.datumCode !== 'WGS84');
|
|
}
|
|
module.exports = function transform(source, dest, point) {
|
|
var wgs84;
|
|
if (Array.isArray(point)) {
|
|
point = toPoint(point);
|
|
}
|
|
// Workaround for datum shifts towgs84, if either source or destination projection is not wgs84
|
|
if (source.datum && dest.datum && checkNotWGS(source, dest)) {
|
|
wgs84 = new proj('WGS84');
|
|
point = transform(source, wgs84, point);
|
|
source = wgs84;
|
|
}
|
|
// DGR, 2010/11/12
|
|
if (source.axis !== 'enu') {
|
|
point = adjust_axis(source, false, point);
|
|
}
|
|
// Transform source points to long/lat, if they aren't already.
|
|
if (source.projName === 'longlat') {
|
|
point = {
|
|
x: point.x * D2R,
|
|
y: point.y * D2R
|
|
};
|
|
}
|
|
else {
|
|
if (source.to_meter) {
|
|
point = {
|
|
x: point.x * source.to_meter,
|
|
y: point.y * source.to_meter
|
|
};
|
|
}
|
|
point = source.inverse(point); // Convert Cartesian to longlat
|
|
}
|
|
// Adjust for the prime meridian if necessary
|
|
if (source.from_greenwich) {
|
|
point.x += source.from_greenwich;
|
|
}
|
|
// Convert datums if needed, and if possible.
|
|
point = datum_transform(source.datum, dest.datum, point);
|
|
// Adjust for the prime meridian if necessary
|
|
if (dest.from_greenwich) {
|
|
point = {
|
|
x: point.x - dest.grom_greenwich,
|
|
y: point.y
|
|
};
|
|
}
|
|
if (dest.projName === 'longlat') {
|
|
// convert radians to decimal degrees
|
|
point = {
|
|
x: point.x * R2D,
|
|
y: point.y * R2D
|
|
};
|
|
}
|
|
else { // else project
|
|
point = dest.forward(point);
|
|
if (dest.to_meter) {
|
|
point = {
|
|
x: point.x / dest.to_meter,
|
|
y: point.y / dest.to_meter
|
|
};
|
|
}
|
|
}
|
|
// DGR, 2010/11/12
|
|
if (dest.axis !== 'enu') {
|
|
return adjust_axis(dest, true, point);
|
|
}
|
|
return point;
|
|
};
|
|
}
|
|
,
|
|
/* proj4/lib/wkt */ function _(require, module, exports) {
|
|
var D2R = 0.01745329251994329577;
|
|
var extend = require(389) /* ./extend */;
|
|
function mapit(obj, key, v) {
|
|
obj[key] = v.map(function (aa) {
|
|
var o = {};
|
|
sExpr(aa, o);
|
|
return o;
|
|
}).reduce(function (a, b) {
|
|
return extend(a, b);
|
|
}, {});
|
|
}
|
|
function sExpr(v, obj) {
|
|
var key;
|
|
if (!Array.isArray(v)) {
|
|
obj[v] = true;
|
|
return;
|
|
}
|
|
else {
|
|
key = v.shift();
|
|
if (key === 'PARAMETER') {
|
|
key = v.shift();
|
|
}
|
|
if (v.length === 1) {
|
|
if (Array.isArray(v[0])) {
|
|
obj[key] = {};
|
|
sExpr(v[0], obj[key]);
|
|
}
|
|
else {
|
|
obj[key] = v[0];
|
|
}
|
|
}
|
|
else if (!v.length) {
|
|
obj[key] = true;
|
|
}
|
|
else if (key === 'TOWGS84') {
|
|
obj[key] = v;
|
|
}
|
|
else {
|
|
obj[key] = {};
|
|
if (['UNIT', 'PRIMEM', 'VERT_DATUM'].indexOf(key) > -1) {
|
|
obj[key] = {
|
|
name: v[0].toLowerCase(),
|
|
convert: v[1]
|
|
};
|
|
if (v.length === 3) {
|
|
obj[key].auth = v[2];
|
|
}
|
|
}
|
|
else if (key === 'SPHEROID') {
|
|
obj[key] = {
|
|
name: v[0],
|
|
a: v[1],
|
|
rf: v[2]
|
|
};
|
|
if (v.length === 4) {
|
|
obj[key].auth = v[3];
|
|
}
|
|
}
|
|
else if (['GEOGCS', 'GEOCCS', 'DATUM', 'VERT_CS', 'COMPD_CS', 'LOCAL_CS', 'FITTED_CS', 'LOCAL_DATUM'].indexOf(key) > -1) {
|
|
v[0] = ['name', v[0]];
|
|
mapit(obj, key, v);
|
|
}
|
|
else if (v.every(function (aa) {
|
|
return Array.isArray(aa);
|
|
})) {
|
|
mapit(obj, key, v);
|
|
}
|
|
else {
|
|
sExpr(v, obj[key]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function rename(obj, params) {
|
|
var outName = params[0];
|
|
var inName = params[1];
|
|
if (!(outName in obj) && (inName in obj)) {
|
|
obj[outName] = obj[inName];
|
|
if (params.length === 3) {
|
|
obj[outName] = params[2](obj[outName]);
|
|
}
|
|
}
|
|
}
|
|
function d2r(input) {
|
|
return input * D2R;
|
|
}
|
|
function cleanWKT(wkt) {
|
|
if (wkt.type === 'GEOGCS') {
|
|
wkt.projName = 'longlat';
|
|
}
|
|
else if (wkt.type === 'LOCAL_CS') {
|
|
wkt.projName = 'identity';
|
|
wkt.local = true;
|
|
}
|
|
else {
|
|
if (typeof wkt.PROJECTION === "object") {
|
|
wkt.projName = Object.keys(wkt.PROJECTION)[0];
|
|
}
|
|
else {
|
|
wkt.projName = wkt.PROJECTION;
|
|
}
|
|
}
|
|
if (wkt.UNIT) {
|
|
wkt.units = wkt.UNIT.name.toLowerCase();
|
|
if (wkt.units === 'metre') {
|
|
wkt.units = 'meter';
|
|
}
|
|
if (wkt.UNIT.convert) {
|
|
if (wkt.type === 'GEOGCS') {
|
|
if (wkt.DATUM && wkt.DATUM.SPHEROID) {
|
|
wkt.to_meter = parseFloat(wkt.UNIT.convert, 10) * wkt.DATUM.SPHEROID.a;
|
|
}
|
|
}
|
|
else {
|
|
wkt.to_meter = parseFloat(wkt.UNIT.convert, 10);
|
|
}
|
|
}
|
|
}
|
|
if (wkt.GEOGCS) {
|
|
//if(wkt.GEOGCS.PRIMEM&&wkt.GEOGCS.PRIMEM.convert){
|
|
// wkt.from_greenwich=wkt.GEOGCS.PRIMEM.convert*D2R;
|
|
//}
|
|
if (wkt.GEOGCS.DATUM) {
|
|
wkt.datumCode = wkt.GEOGCS.DATUM.name.toLowerCase();
|
|
}
|
|
else {
|
|
wkt.datumCode = wkt.GEOGCS.name.toLowerCase();
|
|
}
|
|
if (wkt.datumCode.slice(0, 2) === 'd_') {
|
|
wkt.datumCode = wkt.datumCode.slice(2);
|
|
}
|
|
if (wkt.datumCode === 'new_zealand_geodetic_datum_1949' || wkt.datumCode === 'new_zealand_1949') {
|
|
wkt.datumCode = 'nzgd49';
|
|
}
|
|
if (wkt.datumCode === "wgs_1984") {
|
|
if (wkt.PROJECTION === 'Mercator_Auxiliary_Sphere') {
|
|
wkt.sphere = true;
|
|
}
|
|
wkt.datumCode = 'wgs84';
|
|
}
|
|
if (wkt.datumCode.slice(-6) === '_ferro') {
|
|
wkt.datumCode = wkt.datumCode.slice(0, -6);
|
|
}
|
|
if (wkt.datumCode.slice(-8) === '_jakarta') {
|
|
wkt.datumCode = wkt.datumCode.slice(0, -8);
|
|
}
|
|
if (~wkt.datumCode.indexOf('belge')) {
|
|
wkt.datumCode = "rnb72";
|
|
}
|
|
if (wkt.GEOGCS.DATUM && wkt.GEOGCS.DATUM.SPHEROID) {
|
|
wkt.ellps = wkt.GEOGCS.DATUM.SPHEROID.name.replace('_19', '').replace(/[Cc]larke\_18/, 'clrk');
|
|
if (wkt.ellps.toLowerCase().slice(0, 13) === "international") {
|
|
wkt.ellps = 'intl';
|
|
}
|
|
wkt.a = wkt.GEOGCS.DATUM.SPHEROID.a;
|
|
wkt.rf = parseFloat(wkt.GEOGCS.DATUM.SPHEROID.rf, 10);
|
|
}
|
|
if (~wkt.datumCode.indexOf('osgb_1936')) {
|
|
wkt.datumCode = "osgb36";
|
|
}
|
|
}
|
|
if (wkt.b && !isFinite(wkt.b)) {
|
|
wkt.b = wkt.a;
|
|
}
|
|
function toMeter(input) {
|
|
var ratio = wkt.to_meter || 1;
|
|
return parseFloat(input, 10) * ratio;
|
|
}
|
|
var renamer = function (a) {
|
|
return rename(wkt, a);
|
|
};
|
|
var list = [
|
|
['standard_parallel_1', 'Standard_Parallel_1'],
|
|
['standard_parallel_2', 'Standard_Parallel_2'],
|
|
['false_easting', 'False_Easting'],
|
|
['false_northing', 'False_Northing'],
|
|
['central_meridian', 'Central_Meridian'],
|
|
['latitude_of_origin', 'Latitude_Of_Origin'],
|
|
['latitude_of_origin', 'Central_Parallel'],
|
|
['scale_factor', 'Scale_Factor'],
|
|
['k0', 'scale_factor'],
|
|
['latitude_of_center', 'Latitude_of_center'],
|
|
['lat0', 'latitude_of_center', d2r],
|
|
['longitude_of_center', 'Longitude_Of_Center'],
|
|
['longc', 'longitude_of_center', d2r],
|
|
['x0', 'false_easting', toMeter],
|
|
['y0', 'false_northing', toMeter],
|
|
['long0', 'central_meridian', d2r],
|
|
['lat0', 'latitude_of_origin', d2r],
|
|
['lat0', 'standard_parallel_1', d2r],
|
|
['lat1', 'standard_parallel_1', d2r],
|
|
['lat2', 'standard_parallel_2', d2r],
|
|
['alpha', 'azimuth', d2r],
|
|
['srsCode', 'name']
|
|
];
|
|
list.forEach(renamer);
|
|
if (!wkt.long0 && wkt.longc && (wkt.projName === 'Albers_Conic_Equal_Area' || wkt.projName === "Lambert_Azimuthal_Equal_Area")) {
|
|
wkt.long0 = wkt.longc;
|
|
}
|
|
if (!wkt.lat_ts && wkt.lat1 && (wkt.projName === 'Stereographic_South_Pole' || wkt.projName === 'Polar Stereographic (variant B)')) {
|
|
wkt.lat0 = d2r(wkt.lat1 > 0 ? 90 : -90);
|
|
wkt.lat_ts = wkt.lat1;
|
|
}
|
|
}
|
|
module.exports = function (wkt, self) {
|
|
var lisp = JSON.parse(("," + wkt).replace(/\s*\,\s*([A-Z_0-9]+?)(\[)/g, ',["$1",').slice(1).replace(/\s*\,\s*([A-Z_0-9]+?)\]/g, ',"$1"]').replace(/,\["VERTCS".+/, ''));
|
|
var type = lisp.shift();
|
|
var name = lisp.shift();
|
|
lisp.unshift(['name', name]);
|
|
lisp.unshift(['type', type]);
|
|
lisp.unshift('output');
|
|
var obj = {};
|
|
sExpr(lisp, obj);
|
|
cleanWKT(obj.output);
|
|
return extend(self, obj.output);
|
|
};
|
|
}
|
|
,
|
|
/* sprintf-js/src/sprintf */ function _(require, module, exports) {
|
|
/* global window, exports, define */
|
|
!function () {
|
|
'use strict';
|
|
var re = {
|
|
not_string: /[^s]/,
|
|
not_bool: /[^t]/,
|
|
not_type: /[^T]/,
|
|
not_primitive: /[^v]/,
|
|
number: /[diefg]/,
|
|
numeric_arg: /[bcdiefguxX]/,
|
|
json: /[j]/,
|
|
not_json: /[^j]/,
|
|
text: /^[^\x25]+/,
|
|
modulo: /^\x25{2}/,
|
|
placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
|
|
key: /^([a-z_][a-z_\d]*)/i,
|
|
key_access: /^\.([a-z_][a-z_\d]*)/i,
|
|
index_access: /^\[(\d+)\]/,
|
|
sign: /^[+-]/
|
|
};
|
|
function sprintf(key) {
|
|
// `arguments` is not an array, but should be fine for this call
|
|
return sprintf_format(sprintf_parse(key), arguments);
|
|
}
|
|
function vsprintf(fmt, argv) {
|
|
return sprintf.apply(null, [fmt].concat(argv || []));
|
|
}
|
|
function sprintf_format(parse_tree, argv) {
|
|
var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign;
|
|
for (i = 0; i < tree_length; i++) {
|
|
if (typeof parse_tree[i] === 'string') {
|
|
output += parse_tree[i];
|
|
}
|
|
else if (typeof parse_tree[i] === 'object') {
|
|
ph = parse_tree[i]; // convenience purposes only
|
|
if (ph.keys) { // keyword argument
|
|
arg = argv[cursor];
|
|
for (k = 0; k < ph.keys.length; k++) {
|
|
if (arg == undefined) {
|
|
throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k - 1]));
|
|
}
|
|
arg = arg[ph.keys[k]];
|
|
}
|
|
}
|
|
else if (ph.param_no) { // positional argument (explicit)
|
|
arg = argv[ph.param_no];
|
|
}
|
|
else { // positional argument (implicit)
|
|
arg = argv[cursor++];
|
|
}
|
|
if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
|
|
arg = arg();
|
|
}
|
|
if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {
|
|
throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg));
|
|
}
|
|
if (re.number.test(ph.type)) {
|
|
is_positive = arg >= 0;
|
|
}
|
|
switch (ph.type) {
|
|
case 'b':
|
|
arg = parseInt(arg, 10).toString(2);
|
|
break;
|
|
case 'c':
|
|
arg = String.fromCharCode(parseInt(arg, 10));
|
|
break;
|
|
case 'd':
|
|
case 'i':
|
|
arg = parseInt(arg, 10);
|
|
break;
|
|
case 'j':
|
|
arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0);
|
|
break;
|
|
case 'e':
|
|
arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential();
|
|
break;
|
|
case 'f':
|
|
arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg);
|
|
break;
|
|
case 'g':
|
|
arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg);
|
|
break;
|
|
case 'o':
|
|
arg = (parseInt(arg, 10) >>> 0).toString(8);
|
|
break;
|
|
case 's':
|
|
arg = String(arg);
|
|
arg = (ph.precision ? arg.substring(0, ph.precision) : arg);
|
|
break;
|
|
case 't':
|
|
arg = String(!!arg);
|
|
arg = (ph.precision ? arg.substring(0, ph.precision) : arg);
|
|
break;
|
|
case 'T':
|
|
arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase();
|
|
arg = (ph.precision ? arg.substring(0, ph.precision) : arg);
|
|
break;
|
|
case 'u':
|
|
arg = parseInt(arg, 10) >>> 0;
|
|
break;
|
|
case 'v':
|
|
arg = arg.valueOf();
|
|
arg = (ph.precision ? arg.substring(0, ph.precision) : arg);
|
|
break;
|
|
case 'x':
|
|
arg = (parseInt(arg, 10) >>> 0).toString(16);
|
|
break;
|
|
case 'X':
|
|
arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase();
|
|
break;
|
|
}
|
|
if (re.json.test(ph.type)) {
|
|
output += arg;
|
|
}
|
|
else {
|
|
if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
|
|
sign = is_positive ? '+' : '-';
|
|
arg = arg.toString().replace(re.sign, '');
|
|
}
|
|
else {
|
|
sign = '';
|
|
}
|
|
pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' ';
|
|
pad_length = ph.width - (sign + arg).length;
|
|
pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : '';
|
|
output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg);
|
|
}
|
|
}
|
|
}
|
|
return output;
|
|
}
|
|
var sprintf_cache = Object.create(null);
|
|
function sprintf_parse(fmt) {
|
|
if (sprintf_cache[fmt]) {
|
|
return sprintf_cache[fmt];
|
|
}
|
|
var _fmt = fmt, match, parse_tree = [], arg_names = 0;
|
|
while (_fmt) {
|
|
if ((match = re.text.exec(_fmt)) !== null) {
|
|
parse_tree.push(match[0]);
|
|
}
|
|
else if ((match = re.modulo.exec(_fmt)) !== null) {
|
|
parse_tree.push('%');
|
|
}
|
|
else if ((match = re.placeholder.exec(_fmt)) !== null) {
|
|
if (match[2]) {
|
|
arg_names |= 1;
|
|
var field_list = [], replacement_field = match[2], field_match = [];
|
|
if ((field_match = re.key.exec(replacement_field)) !== null) {
|
|
field_list.push(field_match[1]);
|
|
while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
|
|
if ((field_match = re.key_access.exec(replacement_field)) !== null) {
|
|
field_list.push(field_match[1]);
|
|
}
|
|
else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
|
|
field_list.push(field_match[1]);
|
|
}
|
|
else {
|
|
throw new SyntaxError('[sprintf] failed to parse named argument key');
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
throw new SyntaxError('[sprintf] failed to parse named argument key');
|
|
}
|
|
match[2] = field_list;
|
|
}
|
|
else {
|
|
arg_names |= 2;
|
|
}
|
|
if (arg_names === 3) {
|
|
throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported');
|
|
}
|
|
parse_tree.push({
|
|
placeholder: match[0],
|
|
param_no: match[1],
|
|
keys: match[2],
|
|
sign: match[3],
|
|
pad_char: match[4],
|
|
align: match[5],
|
|
width: match[6],
|
|
precision: match[7],
|
|
type: match[8]
|
|
});
|
|
}
|
|
else {
|
|
throw new SyntaxError('[sprintf] unexpected placeholder');
|
|
}
|
|
_fmt = _fmt.substring(match[0].length);
|
|
}
|
|
return sprintf_cache[fmt] = parse_tree;
|
|
}
|
|
/**
|
|
* export to either browser or node.js
|
|
*/
|
|
/* eslint-disable quote-props */
|
|
if (typeof exports !== 'undefined') {
|
|
exports['sprintf'] = sprintf;
|
|
exports['vsprintf'] = vsprintf;
|
|
}
|
|
if (typeof window !== 'undefined') {
|
|
window['sprintf'] = sprintf;
|
|
window['vsprintf'] = vsprintf;
|
|
if (typeof define === 'function' && define['amd']) {
|
|
define(function () {
|
|
return {
|
|
'sprintf': sprintf,
|
|
'vsprintf': vsprintf
|
|
};
|
|
});
|
|
}
|
|
}
|
|
/* eslint-enable quote-props */
|
|
}(); // eslint-disable-line
|
|
}
|
|
,
|
|
/* timezone/index */ function _(require, module, exports) {
|
|
!function (definition) {
|
|
if (typeof module == "object" && module.exports)
|
|
module.exports = definition();
|
|
else if (typeof define == "function")
|
|
define(definition);
|
|
else
|
|
this.tz = definition();
|
|
}(function () {
|
|
/*
|
|
function die () {
|
|
console.log.apply(console, __slice.call(arguments, 0));
|
|
return process.exit(1);
|
|
}
|
|
|
|
function say () { return console.log.apply(console, __slice.call(arguments, 0)) }
|
|
*/
|
|
function actualize(entry, rule, year) {
|
|
var actualized, date = rule.day[1];
|
|
do {
|
|
actualized = new Date(Date.UTC(year, rule.month, Math.abs(date++)));
|
|
} while (rule.day[0] < 7 && actualized.getUTCDay() != rule.day[0]);
|
|
actualized = {
|
|
clock: rule.clock,
|
|
sort: actualized.getTime(),
|
|
rule: rule,
|
|
save: rule.save * 6e4,
|
|
offset: entry.offset
|
|
};
|
|
actualized[actualized.clock] = actualized.sort + rule.time * 6e4;
|
|
if (actualized.posix) {
|
|
actualized.wallclock = actualized[actualized.clock] + (entry.offset + rule.saved);
|
|
}
|
|
else {
|
|
actualized.posix = actualized[actualized.clock] - (entry.offset + rule.saved);
|
|
}
|
|
return actualized;
|
|
}
|
|
function find(request, clock, time) {
|
|
var i, I, entry, found, zone = request[request.zone], actualized = [], abbrev, rules, j, year = new Date(time).getUTCFullYear(), off = 1;
|
|
for (i = 1, I = zone.length; i < I; i++)
|
|
if (zone[i][clock] <= time)
|
|
break;
|
|
entry = zone[i];
|
|
if (entry.rules) {
|
|
rules = request[entry.rules];
|
|
for (j = year + 1; j >= year - off; --j)
|
|
for (i = 0, I = rules.length; i < I; i++)
|
|
if (rules[i].from <= j && j <= rules[i].to)
|
|
actualized.push(actualize(entry, rules[i], j));
|
|
else if (rules[i].to < j && off == 1)
|
|
off = j - rules[i].to;
|
|
actualized.sort(function (a, b) { return a.sort - b.sort; });
|
|
for (i = 0, I = actualized.length; i < I; i++) {
|
|
if (time >= actualized[i][clock] && actualized[i][actualized[i].clock] > entry[actualized[i].clock])
|
|
found = actualized[i];
|
|
}
|
|
}
|
|
if (found) {
|
|
if (abbrev = /^(.*)\/(.*)$/.exec(entry.format)) {
|
|
found.abbrev = abbrev[found.save ? 2 : 1];
|
|
}
|
|
else {
|
|
found.abbrev = entry.format.replace(/%s/, found.rule.letter);
|
|
}
|
|
}
|
|
return found || entry;
|
|
}
|
|
function convertToWallclock(request, posix) {
|
|
if (request.zone == "UTC")
|
|
return posix;
|
|
request.entry = find(request, "posix", posix);
|
|
return posix + request.entry.offset + request.entry.save;
|
|
}
|
|
function convertToPOSIX(request, wallclock) {
|
|
if (request.zone == "UTC")
|
|
return wallclock;
|
|
var entry, diff;
|
|
request.entry = entry = find(request, "wallclock", wallclock);
|
|
diff = wallclock - entry.wallclock;
|
|
return 0 < diff && diff < entry.save ? null : wallclock - entry.offset - entry.save;
|
|
}
|
|
function adjust(request, posix, match) {
|
|
var increment = +(match[1] + 1) // conversion necessary for week day addition
|
|
, offset = match[2] * increment, index = UNITS.indexOf(match[3].toLowerCase()), date;
|
|
if (index > 9) {
|
|
posix += offset * TIME[index - 10];
|
|
}
|
|
else {
|
|
date = new Date(convertToWallclock(request, posix));
|
|
if (index < 7) {
|
|
while (offset) {
|
|
date.setUTCDate(date.getUTCDate() + increment);
|
|
if (date.getUTCDay() == index)
|
|
offset -= increment;
|
|
}
|
|
}
|
|
else if (index == 7) {
|
|
date.setUTCFullYear(date.getUTCFullYear() + offset);
|
|
}
|
|
else if (index == 8) {
|
|
date.setUTCMonth(date.getUTCMonth() + offset);
|
|
}
|
|
else {
|
|
date.setUTCDate(date.getUTCDate() + offset);
|
|
}
|
|
if ((posix = convertToPOSIX(request, date.getTime())) == null) {
|
|
posix = convertToPOSIX(request, date.getTime() + 864e5 * increment) - 864e5 * increment;
|
|
}
|
|
}
|
|
return posix;
|
|
}
|
|
function convert(vargs) {
|
|
if (!vargs.length)
|
|
return "1.0.22";
|
|
var request = Object.create(this), adjustments = [], i, I, $, argument, date;
|
|
for (i = 0; i < vargs.length; i++) { // leave the for loop alone, it works.
|
|
argument = vargs[i];
|
|
// https://twitter.com/bigeasy/status/215112186572439552
|
|
if (Array.isArray(argument)) {
|
|
if (!i && !isNaN(argument[1])) {
|
|
date = argument;
|
|
}
|
|
else {
|
|
argument.splice.apply(vargs, [i--, 1].concat(argument));
|
|
}
|
|
}
|
|
else if (isNaN(argument)) {
|
|
$ = typeof argument;
|
|
if ($ == "string") {
|
|
if (~argument.indexOf("%")) {
|
|
request.format = argument;
|
|
}
|
|
else if (!i && argument == "*") {
|
|
date = argument;
|
|
}
|
|
else if (!i && ($ = /^(\d{4})-(\d{2})-(\d{2})(?:[T\s](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d+))?)?(Z|(([+-])(\d{2}(:\d{2}){0,2})))?)?$/.exec(argument))) {
|
|
date = [];
|
|
date.push.apply(date, $.slice(1, 8));
|
|
if ($[9]) {
|
|
date.push($[10] + 1);
|
|
date.push.apply(date, $[11].split(/:/));
|
|
}
|
|
else if ($[8]) {
|
|
date.push(1);
|
|
}
|
|
}
|
|
else if (/^\w{2,3}_\w{2}$/.test(argument)) {
|
|
request.locale = argument;
|
|
}
|
|
else if ($ = UNIT_RE.exec(argument)) {
|
|
adjustments.push($);
|
|
}
|
|
else {
|
|
request.zone = argument;
|
|
}
|
|
}
|
|
else if ($ == "function") {
|
|
if ($ = argument.call(request))
|
|
return $;
|
|
}
|
|
else if (/^\w{2,3}_\w{2}$/.test(argument.name)) {
|
|
request[argument.name] = argument;
|
|
}
|
|
else if (argument.zones) {
|
|
for ($ in argument.zones)
|
|
request[$] = argument.zones[$];
|
|
for ($ in argument.rules)
|
|
request[$] = argument.rules[$];
|
|
}
|
|
}
|
|
else if (!i) {
|
|
date = argument;
|
|
}
|
|
}
|
|
if (!request[request.locale])
|
|
delete request.locale;
|
|
if (!request[request.zone])
|
|
delete request.zone;
|
|
if (date != null) {
|
|
if (date == "*") {
|
|
date = request.clock();
|
|
}
|
|
else if (Array.isArray(date)) {
|
|
$ = [];
|
|
I = !date[7];
|
|
for (i = 0; i < 11; i++)
|
|
$[i] = +(date[i] || 0); // conversion necessary for decrement
|
|
--$[1]; // Grr..
|
|
date = Date.UTC.apply(Date.UTC, $) + -$[7] * ($[8] * 36e5 + $[9] * 6e4 + $[10] * 1e3);
|
|
}
|
|
else {
|
|
date = Math.floor(date);
|
|
}
|
|
if (!isNaN(date)) {
|
|
if (I)
|
|
date = convertToPOSIX(request, date);
|
|
if (date == null)
|
|
return date;
|
|
for (i = 0, I = adjustments.length; i < I; i++) {
|
|
date = adjust(request, date, adjustments[i]);
|
|
}
|
|
if (!request.format)
|
|
return date;
|
|
$ = new Date(convertToWallclock(request, date));
|
|
return request.format.replace(/%([-0_^]?)(:{0,3})(\d*)(.)/g, function (value, flag, colons, padding, specifier) {
|
|
var f, fill = "0", pad;
|
|
if (f = request[specifier]) {
|
|
value = String(f.call(request, $, date, flag, colons.length));
|
|
if ((flag || f.style) == "_")
|
|
fill = " ";
|
|
pad = flag == "-" ? 0 : f.pad || 0;
|
|
while (value.length < pad)
|
|
value = fill + value;
|
|
pad = flag == "-" ? 0 : padding || f.pad;
|
|
while (value.length < pad)
|
|
value = fill + value;
|
|
if (specifier == "N" && pad < value.length)
|
|
value = value.slice(0, pad);
|
|
if (flag == "^")
|
|
value = value.toUpperCase();
|
|
}
|
|
return value;
|
|
});
|
|
}
|
|
}
|
|
return function () { return request.convert(arguments); };
|
|
}
|
|
var context = { clock: function () { return +(new Date()); },
|
|
zone: "UTC",
|
|
entry: { abbrev: "UTC", offset: 0, save: 0 },
|
|
UTC: 1,
|
|
z: function (date, posix, flag, delimiters) {
|
|
var offset = this.entry.offset + this.entry.save, seconds = Math.abs(offset / 1000), parts = [], part = 3600, i, z;
|
|
for (i = 0; i < 3; i++) {
|
|
parts.push(("0" + Math.floor(seconds / part)).slice(-2));
|
|
seconds %= part;
|
|
part /= 60;
|
|
}
|
|
if (flag == "^" && !offset)
|
|
return "Z";
|
|
if (flag == "^")
|
|
delimiters = 3;
|
|
if (delimiters == 3) {
|
|
z = parts.join(":");
|
|
z = z.replace(/:00$/, "");
|
|
if (flag != "^")
|
|
z = z.replace(/:00$/, "");
|
|
}
|
|
else if (delimiters) {
|
|
z = parts.slice(0, delimiters + 1).join(":");
|
|
if (flag == "^")
|
|
z = z.replace(/:00$/, "");
|
|
}
|
|
else {
|
|
z = parts.slice(0, 2).join("");
|
|
}
|
|
z = (offset < 0 ? "-" : "+") + z;
|
|
z = z.replace(/([-+])(0)/, { "_": " $1", "-": "$1" }[flag] || "$1$2");
|
|
return z;
|
|
},
|
|
"%": function (date) { return "%"; },
|
|
n: function (date) { return "\n"; },
|
|
t: function (date) { return "\t"; },
|
|
U: function (date) { return weekOfYear(date, 0); },
|
|
W: function (date) { return weekOfYear(date, 1); },
|
|
V: function (date) { return isoWeek(date)[0]; },
|
|
G: function (date) { return isoWeek(date)[1]; },
|
|
g: function (date) { return isoWeek(date)[1] % 100; },
|
|
j: function (date) { return Math.floor((date.getTime() - Date.UTC(date.getUTCFullYear(), 0)) / 864e5) + 1; },
|
|
s: function (date) { return Math.floor(date.getTime() / 1000); },
|
|
C: function (date) { return Math.floor(date.getUTCFullYear() / 100); },
|
|
N: function (date) { return date.getTime() % 1000 * 1000000; },
|
|
m: function (date) { return date.getUTCMonth() + 1; },
|
|
Y: function (date) { return date.getUTCFullYear(); },
|
|
y: function (date) { return date.getUTCFullYear() % 100; },
|
|
H: function (date) { return date.getUTCHours(); },
|
|
M: function (date) { return date.getUTCMinutes(); },
|
|
S: function (date) { return date.getUTCSeconds(); },
|
|
e: function (date) { return date.getUTCDate(); },
|
|
d: function (date) { return date.getUTCDate(); },
|
|
u: function (date) { return date.getUTCDay() || 7; },
|
|
w: function (date) { return date.getUTCDay(); },
|
|
l: function (date) { return date.getUTCHours() % 12 || 12; },
|
|
I: function (date) { return date.getUTCHours() % 12 || 12; },
|
|
k: function (date) { return date.getUTCHours(); },
|
|
Z: function (date) { return this.entry.abbrev; },
|
|
a: function (date) { return this[this.locale].day.abbrev[date.getUTCDay()]; },
|
|
A: function (date) { return this[this.locale].day.full[date.getUTCDay()]; },
|
|
h: function (date) { return this[this.locale].month.abbrev[date.getUTCMonth()]; },
|
|
b: function (date) { return this[this.locale].month.abbrev[date.getUTCMonth()]; },
|
|
B: function (date) { return this[this.locale].month.full[date.getUTCMonth()]; },
|
|
P: function (date) { return this[this.locale].meridiem[Math.floor(date.getUTCHours() / 12)].toLowerCase(); },
|
|
p: function (date) { return this[this.locale].meridiem[Math.floor(date.getUTCHours() / 12)]; },
|
|
R: function (date, posix) { return this.convert([posix, "%H:%M"]); },
|
|
T: function (date, posix) { return this.convert([posix, "%H:%M:%S"]); },
|
|
D: function (date, posix) { return this.convert([posix, "%m/%d/%y"]); },
|
|
F: function (date, posix) { return this.convert([posix, "%Y-%m-%d"]); },
|
|
x: function (date, posix) { return this.convert([posix, this[this.locale].date]); },
|
|
r: function (date, posix) { return this.convert([posix, this[this.locale].time12 || '%I:%M:%S']); },
|
|
X: function (date, posix) { return this.convert([posix, this[this.locale].time24]); },
|
|
c: function (date, posix) { return this.convert([posix, this[this.locale].dateTime]); },
|
|
convert: convert,
|
|
locale: "en_US",
|
|
en_US: {
|
|
date: "%m/%d/%Y",
|
|
time24: "%I:%M:%S %p",
|
|
time12: "%I:%M:%S %p",
|
|
dateTime: "%a %d %b %Y %I:%M:%S %p %Z",
|
|
meridiem: ["AM", "PM"],
|
|
month: {
|
|
abbrev: "Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec".split("|"),
|
|
full: "January|February|March|April|May|June|July|August|September|October|November|December".split("|")
|
|
},
|
|
day: {
|
|
abbrev: "Sun|Mon|Tue|Wed|Thu|Fri|Sat".split("|"),
|
|
full: "Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday".split("|")
|
|
}
|
|
}
|
|
};
|
|
var UNITS = "Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|year|month|day|hour|minute|second|millisecond", UNIT_RE = new RegExp("^\\s*([+-])(\\d+)\\s+(" + UNITS + ")s?\\s*$", "i"), TIME = [36e5, 6e4, 1e3, 1];
|
|
UNITS = UNITS.toLowerCase().split("|");
|
|
"delmHMSUWVgCIky".replace(/./g, function (e) { context[e].pad = 2; });
|
|
context.N.pad = 9;
|
|
context.j.pad = 3;
|
|
context.k.style = "_";
|
|
context.l.style = "_";
|
|
context.e.style = "_";
|
|
function weekOfYear(date, startOfWeek) {
|
|
var diff, nyd, weekStart;
|
|
nyd = new Date(Date.UTC(date.getUTCFullYear(), 0));
|
|
diff = Math.floor((date.getTime() - nyd.getTime()) / 864e5);
|
|
if (nyd.getUTCDay() == startOfWeek) {
|
|
weekStart = 0;
|
|
}
|
|
else {
|
|
weekStart = 7 - nyd.getUTCDay() + startOfWeek;
|
|
if (weekStart == 8) {
|
|
weekStart = 1;
|
|
}
|
|
}
|
|
return diff >= weekStart ? Math.floor((diff - weekStart) / 7) + 1 : 0;
|
|
}
|
|
function isoWeek(date) {
|
|
var nyd, nyy, week;
|
|
nyy = date.getUTCFullYear();
|
|
nyd = new Date(Date.UTC(nyy, 0)).getUTCDay();
|
|
week = weekOfYear(date, 1) + (nyd > 1 && nyd <= 4 ? 1 : 0);
|
|
if (!week) {
|
|
nyy = date.getUTCFullYear() - 1;
|
|
nyd = new Date(Date.UTC(nyy, 0)).getUTCDay();
|
|
week = nyd == 4 || (nyd == 3 && new Date(nyy, 1, 29).getDate() == 29) ? 53 : 52;
|
|
return [week, date.getUTCFullYear() - 1];
|
|
}
|
|
else if (week == 53 && !(nyd == 4 || (nyd == 3 && new Date(nyy, 1, 29).getDate() == 29))) {
|
|
return [1, date.getUTCFullYear() + 1];
|
|
}
|
|
else {
|
|
return [week, date.getUTCFullYear()];
|
|
}
|
|
}
|
|
return function () { return context.convert(arguments); };
|
|
});
|
|
}
|
|
,
|
|
/* tslib/tslib */ function _(require, module, exports) {
|
|
/*! *****************************************************************************
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
this file except in compliance with the License. You may obtain a copy of the
|
|
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
|
|
See the Apache Version 2.0 License for specific language governing permissions
|
|
and limitations under the License.
|
|
***************************************************************************** */
|
|
/* global global, define, System, Reflect, Promise */
|
|
var __extends;
|
|
var __assign;
|
|
var __rest;
|
|
var __decorate;
|
|
var __param;
|
|
var __metadata;
|
|
var __awaiter;
|
|
var __generator;
|
|
var __exportStar;
|
|
var __values;
|
|
var __read;
|
|
var __spread;
|
|
var __await;
|
|
var __asyncGenerator;
|
|
var __asyncDelegator;
|
|
var __asyncValues;
|
|
var __makeTemplateObject;
|
|
var __importStar;
|
|
var __importDefault;
|
|
(function (factory) {
|
|
var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {};
|
|
if (typeof define === "function" && define.amd) {
|
|
define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); });
|
|
}
|
|
else if (typeof module === "object" && typeof module.exports === "object") {
|
|
factory(createExporter(root, createExporter(module.exports)));
|
|
}
|
|
else {
|
|
factory(createExporter(root));
|
|
}
|
|
function createExporter(exports, previous) {
|
|
if (exports !== root) {
|
|
if (typeof Object.create === "function") {
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
}
|
|
else {
|
|
exports.__esModule = true;
|
|
}
|
|
}
|
|
return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };
|
|
}
|
|
})(function (exporter) {
|
|
var extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b)
|
|
if (b.hasOwnProperty(p))
|
|
d[p] = b[p]; };
|
|
__extends = function (d, b) {
|
|
extendStatics(d, b);
|
|
function __() { this.constructor = d; }
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
};
|
|
__assign = Object.assign || function (t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s)
|
|
if (Object.prototype.hasOwnProperty.call(s, p))
|
|
t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
__rest = function (s, e) {
|
|
var t = {};
|
|
for (var p in s)
|
|
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
t[p] = s[p];
|
|
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
|
|
if (e.indexOf(p[i]) < 0)
|
|
t[p[i]] = s[p[i]];
|
|
return t;
|
|
};
|
|
__decorate = function (decorators, target, key, desc) {
|
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
r = Reflect.decorate(decorators, target, key, desc);
|
|
else
|
|
for (var i = decorators.length - 1; i >= 0; i--)
|
|
if (d = decorators[i])
|
|
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
};
|
|
__param = function (paramIndex, decorator) {
|
|
return function (target, key) { decorator(target, key, paramIndex); };
|
|
};
|
|
__metadata = function (metadataKey, metadataValue) {
|
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
|
|
return Reflect.metadata(metadataKey, metadataValue);
|
|
};
|
|
__awaiter = function (thisArg, _arguments, P, generator) {
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
function fulfilled(value) { try {
|
|
step(generator.next(value));
|
|
}
|
|
catch (e) {
|
|
reject(e);
|
|
} }
|
|
function rejected(value) { try {
|
|
step(generator["throw"](value));
|
|
}
|
|
catch (e) {
|
|
reject(e);
|
|
} }
|
|
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
};
|
|
__generator = function (thisArg, body) {
|
|
var _ = { label: 0, sent: function () { if (t[0] & 1)
|
|
throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g;
|
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
function step(op) {
|
|
if (f)
|
|
throw new TypeError("Generator is already executing.");
|
|
while (_)
|
|
try {
|
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
|
|
return t;
|
|
if (y = 0, t)
|
|
op = [op[0] & 2, t.value];
|
|
switch (op[0]) {
|
|
case 0:
|
|
case 1:
|
|
t = op;
|
|
break;
|
|
case 4:
|
|
_.label++;
|
|
return { value: op[1], done: false };
|
|
case 5:
|
|
_.label++;
|
|
y = op[1];
|
|
op = [0];
|
|
continue;
|
|
case 7:
|
|
op = _.ops.pop();
|
|
_.trys.pop();
|
|
continue;
|
|
default:
|
|
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
_ = 0;
|
|
continue;
|
|
}
|
|
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
|
|
_.label = op[1];
|
|
break;
|
|
}
|
|
if (op[0] === 6 && _.label < t[1]) {
|
|
_.label = t[1];
|
|
t = op;
|
|
break;
|
|
}
|
|
if (t && _.label < t[2]) {
|
|
_.label = t[2];
|
|
_.ops.push(op);
|
|
break;
|
|
}
|
|
if (t[2])
|
|
_.ops.pop();
|
|
_.trys.pop();
|
|
continue;
|
|
}
|
|
op = body.call(thisArg, _);
|
|
}
|
|
catch (e) {
|
|
op = [6, e];
|
|
y = 0;
|
|
}
|
|
finally {
|
|
f = t = 0;
|
|
}
|
|
if (op[0] & 5)
|
|
throw op[1];
|
|
return { value: op[0] ? op[1] : void 0, done: true };
|
|
}
|
|
};
|
|
__exportStar = function (m, exports) {
|
|
for (var p in m)
|
|
if (!exports.hasOwnProperty(p))
|
|
exports[p] = m[p];
|
|
};
|
|
__values = function (o) {
|
|
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
|
if (m)
|
|
return m.call(o);
|
|
return {
|
|
next: function () {
|
|
if (o && i >= o.length)
|
|
o = void 0;
|
|
return { value: o && o[i++], done: !o };
|
|
}
|
|
};
|
|
};
|
|
__read = function (o, n) {
|
|
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
if (!m)
|
|
return o;
|
|
var i = m.call(o), r, ar = [], e;
|
|
try {
|
|
while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
|
|
ar.push(r.value);
|
|
}
|
|
catch (error) {
|
|
e = { error: error };
|
|
}
|
|
finally {
|
|
try {
|
|
if (r && !r.done && (m = i["return"]))
|
|
m.call(i);
|
|
}
|
|
finally {
|
|
if (e)
|
|
throw e.error;
|
|
}
|
|
}
|
|
return ar;
|
|
};
|
|
__spread = function () {
|
|
for (var ar = [], i = 0; i < arguments.length; i++)
|
|
ar = ar.concat(__read(arguments[i]));
|
|
return ar;
|
|
};
|
|
__await = function (v) {
|
|
return this instanceof __await ? (this.v = v, this) : new __await(v);
|
|
};
|
|
__asyncGenerator = function (thisArg, _arguments, generator) {
|
|
if (!Symbol.asyncIterator)
|
|
throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
function verb(n) { if (g[n])
|
|
i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
|
|
function resume(n, v) { try {
|
|
step(g[n](v));
|
|
}
|
|
catch (e) {
|
|
settle(q[0][3], e);
|
|
} }
|
|
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
function fulfill(value) { resume("next", value); }
|
|
function reject(value) { resume("throw", value); }
|
|
function settle(f, v) { if (f(v), q.shift(), q.length)
|
|
resume(q[0][0], q[0][1]); }
|
|
};
|
|
__asyncDelegator = function (o) {
|
|
var i, p;
|
|
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
|
|
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
|
|
};
|
|
__asyncValues = function (o) {
|
|
if (!Symbol.asyncIterator)
|
|
throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
var m = o[Symbol.asyncIterator], i;
|
|
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); }
|
|
};
|
|
__makeTemplateObject = function (cooked, raw) {
|
|
if (Object.defineProperty) {
|
|
Object.defineProperty(cooked, "raw", { value: raw });
|
|
}
|
|
else {
|
|
cooked.raw = raw;
|
|
}
|
|
return cooked;
|
|
};
|
|
__importStar = function (mod) {
|
|
if (mod && mod.__esModule)
|
|
return mod;
|
|
var result = {};
|
|
if (mod != null)
|
|
for (var k in mod)
|
|
if (Object.hasOwnProperty.call(mod, k))
|
|
result[k] = mod[k];
|
|
result["default"] = mod;
|
|
return result;
|
|
};
|
|
__importDefault = function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
exporter("__extends", __extends);
|
|
exporter("__assign", __assign);
|
|
exporter("__rest", __rest);
|
|
exporter("__decorate", __decorate);
|
|
exporter("__param", __param);
|
|
exporter("__metadata", __metadata);
|
|
exporter("__awaiter", __awaiter);
|
|
exporter("__generator", __generator);
|
|
exporter("__exportStar", __exportStar);
|
|
exporter("__values", __values);
|
|
exporter("__read", __read);
|
|
exporter("__spread", __spread);
|
|
exporter("__await", __await);
|
|
exporter("__asyncGenerator", __asyncGenerator);
|
|
exporter("__asyncDelegator", __asyncDelegator);
|
|
exporter("__asyncValues", __asyncValues);
|
|
exporter("__makeTemplateObject", __makeTemplateObject);
|
|
exporter("__importStar", __importStar);
|
|
exporter("__importDefault", __importDefault);
|
|
});
|
|
}
|
|
|
|
], {"base":0,"client/connection":1,"client/session":2,"core/bokeh_events":3,"core/build_views":4,"core/dom":5,"core/dom_view":6,"core/enums":7,"core/has_props":8,"core/hittest":9,"core/layout/alignments":10,"core/layout/grid":11,"core/layout/html":12,"core/layout/index":13,"core/layout/layoutable":14,"core/layout/side_panel":15,"core/layout/types":16,"core/logging":17,"core/properties":18,"core/property_mixins":19,"core/selection_manager":20,"core/settings":21,"core/signaling":22,"core/ui_events":23,"core/util/array":24,"core/util/arrayable":25,"core/util/assert":26,"core/util/bbox":27,"core/util/callback":28,"core/util/canvas":29,"core/util/color":30,"core/util/compat":31,"core/util/data_structures":32,"core/util/eq":33,"core/util/math":34,"core/util/object":35,"core/util/projections":36,"core/util/refs":37,"core/util/serialization":38,"core/util/spatial":39,"core/util/string":40,"core/util/svg_colors":41,"core/util/templating":42,"core/util/text":43,"core/util/throttle":44,"core/util/typed_array":45,"core/util/types":46,"core/util/wheel":47,"core/util/zoom":48,"core/vectorization":49,"core/view":50,"core/visuals":51,"document/document":52,"document/events":53,"document/index":54,"embed/dom":55,"embed/index":56,"embed/notebook":57,"embed/server":58,"embed/standalone":59,"index":60,"main":61,"model":62,"models/annotations/annotation":63,"models/annotations/arrow":64,"models/annotations/arrow_head":65,"models/annotations/band":66,"models/annotations/box_annotation":67,"models/annotations/color_bar":68,"models/annotations/index":69,"models/annotations/label":70,"models/annotations/label_set":71,"models/annotations/legend":72,"models/annotations/legend_item":73,"models/annotations/poly_annotation":74,"models/annotations/slope":75,"models/annotations/span":76,"models/annotations/text_annotation":77,"models/annotations/title":78,"models/annotations/toolbar_panel":79,"models/annotations/tooltip":80,"models/annotations/whisker":81,"models/axes/axis":82,"models/axes/categorical_axis":83,"models/axes/continuous_axis":84,"models/axes/datetime_axis":85,"models/axes/index":86,"models/axes/linear_axis":87,"models/axes/log_axis":88,"models/axes/mercator_axis":89,"models/callbacks/callback":90,"models/callbacks/customjs":91,"models/callbacks/index":92,"models/callbacks/open_url":93,"models/canvas/canvas":94,"models/canvas/cartesian_frame":95,"models/canvas/index":96,"models/expressions/cumsum":97,"models/expressions/expression":98,"models/expressions/index":99,"models/expressions/stack":100,"models/filters/boolean_filter":101,"models/filters/customjs_filter":102,"models/filters/filter":103,"models/filters/group_filter":104,"models/filters/index":105,"models/filters/index_filter":106,"models/formatters/basic_tick_formatter":107,"models/formatters/categorical_tick_formatter":108,"models/formatters/datetime_tick_formatter":109,"models/formatters/func_tick_formatter":110,"models/formatters/index":111,"models/formatters/log_tick_formatter":112,"models/formatters/mercator_tick_formatter":113,"models/formatters/numeral_tick_formatter":114,"models/formatters/printf_tick_formatter":115,"models/formatters/tick_formatter":116,"models/glyphs/annular_wedge":117,"models/glyphs/annulus":118,"models/glyphs/arc":119,"models/glyphs/bezier":120,"models/glyphs/box":121,"models/glyphs/center_rotatable":122,"models/glyphs/circle":123,"models/glyphs/ellipse":124,"models/glyphs/ellipse_oval":125,"models/glyphs/glyph":126,"models/glyphs/hbar":127,"models/glyphs/hex_tile":128,"models/glyphs/image":129,"models/glyphs/image_base":130,"models/glyphs/image_rgba":131,"models/glyphs/image_url":132,"models/glyphs/index":133,"models/glyphs/line":134,"models/glyphs/multi_line":135,"models/glyphs/multi_polygons":136,"models/glyphs/oval":137,"models/glyphs/patch":138,"models/glyphs/patches":139,"models/glyphs/quad":140,"models/glyphs/quadratic":141,"models/glyphs/ray":142,"models/glyphs/rect":143,"models/glyphs/segment":144,"models/glyphs/step":145,"models/glyphs/text":146,"models/glyphs/utils":147,"models/glyphs/vbar":148,"models/glyphs/wedge":149,"models/glyphs/xy_glyph":150,"models/graphs/graph_hit_test_policy":151,"models/graphs/index":152,"models/graphs/layout_provider":153,"models/graphs/static_layout_provider":154,"models/grids/grid":155,"models/grids/index":156,"models/index":157,"models/layouts/box":158,"models/layouts/column":159,"models/layouts/grid_box":160,"models/layouts/html_box":161,"models/layouts/index":162,"models/layouts/layout_dom":163,"models/layouts/row":164,"models/layouts/spacer":165,"models/layouts/tabs":166,"models/layouts/widget_box":167,"models/mappers/categorical_color_mapper":168,"models/mappers/categorical_mapper":169,"models/mappers/categorical_marker_mapper":170,"models/mappers/color_mapper":171,"models/mappers/continuous_color_mapper":172,"models/mappers/index":173,"models/mappers/linear_color_mapper":174,"models/mappers/log_color_mapper":175,"models/mappers/mapper":176,"models/markers/defs":177,"models/markers/index":178,"models/markers/marker":179,"models/markers/scatter":180,"models/plots/gmap_plot":181,"models/plots/gmap_plot_canvas":182,"models/plots/index":183,"models/plots/plot":184,"models/plots/plot_canvas":185,"models/ranges/data_range":186,"models/ranges/data_range1d":187,"models/ranges/factor_range":188,"models/ranges/index":189,"models/ranges/range":190,"models/ranges/range1d":191,"models/renderers/data_renderer":192,"models/renderers/glyph_renderer":193,"models/renderers/graph_renderer":194,"models/renderers/guide_renderer":195,"models/renderers/index":196,"models/renderers/renderer":197,"models/scales/categorical_scale":198,"models/scales/index":199,"models/scales/linear_scale":200,"models/scales/log_scale":201,"models/scales/scale":202,"models/selections/index":203,"models/selections/interaction_policy":204,"models/selections/selection":205,"models/sources/ajax_data_source":206,"models/sources/cds_view":207,"models/sources/column_data_source":208,"models/sources/columnar_data_source":209,"models/sources/data_source":210,"models/sources/geojson_data_source":211,"models/sources/index":212,"models/sources/remote_data_source":213,"models/sources/server_sent_data_source":214,"models/sources/web_data_source":215,"models/tickers/adaptive_ticker":216,"models/tickers/basic_ticker":217,"models/tickers/categorical_ticker":218,"models/tickers/composite_ticker":219,"models/tickers/continuous_ticker":220,"models/tickers/datetime_ticker":221,"models/tickers/days_ticker":222,"models/tickers/fixed_ticker":223,"models/tickers/index":224,"models/tickers/log_ticker":225,"models/tickers/mercator_ticker":226,"models/tickers/months_ticker":227,"models/tickers/single_interval_ticker":228,"models/tickers/ticker":229,"models/tickers/util":230,"models/tickers/years_ticker":231,"models/tiles/bbox_tile_source":232,"models/tiles/image_pool":233,"models/tiles/index":234,"models/tiles/mercator_tile_source":235,"models/tiles/quadkey_tile_source":236,"models/tiles/tile_renderer":237,"models/tiles/tile_source":238,"models/tiles/tile_utils":239,"models/tiles/tms_tile_source":240,"models/tiles/wmts_tile_source":241,"models/tools/actions/action_tool":242,"models/tools/actions/custom_action":243,"models/tools/actions/help_tool":244,"models/tools/actions/redo_tool":245,"models/tools/actions/reset_tool":246,"models/tools/actions/save_tool":247,"models/tools/actions/undo_tool":248,"models/tools/actions/zoom_in_tool":249,"models/tools/actions/zoom_out_tool":250,"models/tools/button_tool":251,"models/tools/edit/box_edit_tool":252,"models/tools/edit/edit_tool":253,"models/tools/edit/freehand_draw_tool":254,"models/tools/edit/point_draw_tool":255,"models/tools/edit/poly_draw_tool":256,"models/tools/edit/poly_edit_tool":257,"models/tools/edit/poly_tool":258,"models/tools/gestures/box_select_tool":259,"models/tools/gestures/box_zoom_tool":260,"models/tools/gestures/gesture_tool":261,"models/tools/gestures/lasso_select_tool":262,"models/tools/gestures/pan_tool":263,"models/tools/gestures/poly_select_tool":264,"models/tools/gestures/range_tool":265,"models/tools/gestures/select_tool":266,"models/tools/gestures/tap_tool":267,"models/tools/gestures/wheel_pan_tool":268,"models/tools/gestures/wheel_zoom_tool":269,"models/tools/index":270,"models/tools/inspectors/crosshair_tool":271,"models/tools/inspectors/customjs_hover":272,"models/tools/inspectors/hover_tool":273,"models/tools/inspectors/inspect_tool":274,"models/tools/on_off_button":275,"models/tools/tool":276,"models/tools/tool_proxy":277,"models/tools/toolbar":278,"models/tools/toolbar_base":279,"models/tools/toolbar_box":280,"models/tools/util":281,"models/transforms/customjs_transform":282,"models/transforms/dodge":283,"models/transforms/index":284,"models/transforms/interpolator":285,"models/transforms/jitter":286,"models/transforms/linear_interpolator":287,"models/transforms/step_interpolator":288,"models/transforms/transform":289,"polyfill":290,"protocol/index":291,"protocol/message":292,"protocol/receiver":293,"safely":294,"testing":295,"version":296}, 61, null);
|
|
})
|
|
|
|
//# sourceMappingURL=bokeh.js.map
|