UNPKG

@quartic/bokehjs

Version:

Interactive, novel data visualization

468 lines (467 loc) 19.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _color_to_hex, extend = function (child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty; var inspect_tool_1 = require("./inspect_tool"); var tooltip_1 = require("../../annotations/tooltip"); var glyph_renderer_1 = require("../../renderers/glyph_renderer"); var hittest = require("core/hittest"); var templating_1 = require("core/util/templating"); var dom_1 = require("core/dom"); var p = require("core/properties"); var object_1 = require("core/util/object"); var types_1 = require("core/util/types"); _color_to_hex = function (color) { var blue, digits, green, red, rgb; if (color.substr(0, 1) === '#') { return color; } digits = /(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec(color); red = parseInt(digits[2]); green = parseInt(digits[3]); blue = parseInt(digits[4]); rgb = blue | (green << 8) | (red << 16); return digits[1] + '#' + rgb.toString(16); }; exports.HoverToolView = (function (superClass) { extend(HoverToolView, superClass); function HoverToolView() { return HoverToolView.__super__.constructor.apply(this, arguments); } HoverToolView.prototype.bind_bokeh_events = function () { var k, len, r, ref; ref = this.model.computed_renderers; for (k = 0, len = ref.length; k < len; k++) { r = ref[k]; this.listenTo(r.data_source, 'inspect', this._update); } return this.plot_view.canvas_view.el.style.cursor = "crosshair"; }; HoverToolView.prototype._clear = function () { var ref, results, rid, tt; this._inspect(2e308, 2e308); ref = this.model.ttmodels; results = []; for (rid in ref) { tt = ref[rid]; results.push(tt.clear()); } return results; }; HoverToolView.prototype._move = function (e) { var canvas, vx, vy; if (!this.model.active) { return; } canvas = this.plot_view.canvas; vx = canvas.sx_to_vx(e.bokeh.sx); vy = canvas.sy_to_vy(e.bokeh.sy); if (!this.plot_view.frame.contains(vx, vy)) { return this._clear(); } else { return this._inspect(vx, vy); } }; HoverToolView.prototype._move_exit = function () { return this._clear(); }; HoverToolView.prototype._inspect = function (vx, vy, e) { var geometry, hovered_indexes, hovered_renderers, k, len, r, ref, sm; geometry = { type: 'point', vx: vx, vy: vy }; if (this.model.mode === 'mouse') { geometry['type'] = 'point'; } else { geometry['type'] = 'span'; if (this.model.mode === 'vline') { geometry.direction = 'h'; } else { geometry.direction = 'v'; } } hovered_indexes = []; hovered_renderers = []; ref = this.model.computed_renderers; for (k = 0, len = ref.length; k < len; k++) { r = ref[k]; sm = r.data_source.selection_manager; sm.inspect(this, this.plot_view.renderer_views[r.id], geometry, { "geometry": geometry }); } if (this.model.callback != null) { this._emit_callback(geometry); } }; HoverToolView.prototype._update = function (indices, tool, renderer, ds, arg) { var canvas, d1x, d1y, d2x, d2y, data_x, data_y, dist1, dist2, frame, geometry, i, j, k, l, len, len1, pt, ref, ref1, ref10, ref11, ref12, ref13, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, rx, ry, sdatax, sdatay, sx, sy, tooltip, vars, vx, vy, x, xmapper, y, ymapper; geometry = arg.geometry; tooltip = (ref = this.model.ttmodels[renderer.model.id]) != null ? ref : null; if (tooltip == null) { return; } tooltip.clear(); if (indices['0d'].glyph === null && indices['1d'].indices.length === 0) { return; } vx = geometry.vx; vy = geometry.vy; canvas = this.plot_model.canvas; frame = this.plot_model.frame; sx = canvas.vx_to_sx(vx); sy = canvas.vy_to_sy(vy); xmapper = frame.x_mappers[renderer.model.x_range_name]; ymapper = frame.y_mappers[renderer.model.y_range_name]; x = xmapper.map_from_target(vx); y = ymapper.map_from_target(vy); ref1 = indices['0d'].indices; for (k = 0, len = ref1.length; k < len; k++) { i = ref1[k]; data_x = renderer.glyph._x[i + 1]; data_y = renderer.glyph._y[i + 1]; switch (this.model.line_policy) { case "interp": ref2 = renderer.glyph.get_interpolation_hit(i, geometry), data_x = ref2[0], data_y = ref2[1]; rx = xmapper.map_to_target(data_x); ry = ymapper.map_to_target(data_y); break; case "prev": rx = canvas.sx_to_vx(renderer.glyph.sx[i]); ry = canvas.sy_to_vy(renderer.glyph.sy[i]); break; case "next": rx = canvas.sx_to_vx(renderer.glyph.sx[i + 1]); ry = canvas.sy_to_vy(renderer.glyph.sy[i + 1]); break; case "nearest": d1x = renderer.glyph.sx[i]; d1y = renderer.glyph.sy[i]; dist1 = hittest.dist_2_pts(d1x, d1y, sx, sy); d2x = renderer.glyph.sx[i + 1]; d2y = renderer.glyph.sy[i + 1]; dist2 = hittest.dist_2_pts(d2x, d2y, sx, sy); if (dist1 < dist2) { ref3 = [d1x, d1y], sdatax = ref3[0], sdatay = ref3[1]; } else { ref4 = [d2x, d2y], sdatax = ref4[0], sdatay = ref4[1]; i = i + 1; } data_x = renderer.glyph._x[i]; data_y = renderer.glyph._y[i]; rx = canvas.sx_to_vx(sdatax); ry = canvas.sy_to_vy(sdatay); break; default: ref5 = [vx, vy], rx = ref5[0], ry = ref5[1]; } vars = { index: i, x: x, y: y, vx: vx, vy: vy, sx: sx, sy: sy, data_x: data_x, data_y: data_y, rx: rx, ry: ry }; tooltip.add(rx, ry, this._render_tooltips(ds, i, vars)); } ref6 = indices['1d'].indices; for (l = 0, len1 = ref6.length; l < len1; l++) { i = ref6[l]; if (!object_1.isEmpty(indices['2d'].indices)) { ref7 = indices['2d'].indices; for (i in ref7) { j = ref7[i][0]; data_x = renderer.glyph._xs[i][j]; data_y = renderer.glyph._ys[i][j]; switch (this.model.line_policy) { case "interp": ref8 = renderer.glyph.get_interpolation_hit(i, j, geometry), data_x = ref8[0], data_y = ref8[1]; rx = xmapper.map_to_target(data_x); ry = ymapper.map_to_target(data_y); break; case "prev": rx = canvas.sx_to_vx(renderer.glyph.sxs[i][j]); ry = canvas.sy_to_vy(renderer.glyph.sys[i][j]); break; case "next": rx = canvas.sx_to_vx(renderer.glyph.sxs[i][j + 1]); ry = canvas.sy_to_vy(renderer.glyph.sys[i][j + 1]); break; case "nearest": d1x = renderer.glyph.sx[i][j]; d1y = renderer.glyph.sy[i][j]; dist1 = hittest.dist_2_pts(d1x, d1y, sx, sy); d2x = renderer.glyph.sx[i][j + 1]; d2y = renderer.glyph.sy[i][j + 1]; dist2 = hittest.dist_2_pts(d2x, d2y, sx, sy); if (dist1 < dist2) { ref9 = [d1x, d1y], sdatax = ref9[0], sdatay = ref9[1]; } else { ref10 = [d2x, d2y], sdatax = ref10[0], sdatay = ref10[1]; j = j + 1; } data_x = renderer.glyph._x[i][j]; data_y = renderer.glyph._y[i][j]; rx = canvas.sx_to_vx(sdatax); ry = canvas.sy_to_vy(sdatay); } vars = { index: i, segment_index: j, x: x, y: y, vx: vx, vy: vy, sx: sx, sy: sy, data_x: data_x, data_y: data_y }; tooltip.add(rx, ry, this._render_tooltips(ds, i, vars)); } } else { data_x = (ref11 = renderer.glyph._x) != null ? ref11[i] : void 0; data_y = (ref12 = renderer.glyph._y) != null ? ref12[i] : void 0; if (this.model.point_policy === 'snap_to_data') { pt = renderer.glyph.get_anchor_point(this.model.anchor, i, [sx, sy]); if (pt == null) { pt = renderer.glyph.get_anchor_point("center", i, [sx, sy]); } rx = canvas.sx_to_vx(pt.x); ry = canvas.sy_to_vy(pt.y); } else { ref13 = [vx, vy], rx = ref13[0], ry = ref13[1]; } vars = { index: i, x: x, y: y, vx: vx, vy: vy, sx: sx, sy: sy, data_x: data_x, data_y: data_y }; tooltip.add(rx, ry, this._render_tooltips(ds, i, vars)); } } return null; }; HoverToolView.prototype._emit_callback = function (geometry) { var callback, canvas, data, frame, indices, obj, r, ref, xmapper, ymapper; r = this.model.computed_renderers[0]; indices = this.plot_view.renderer_views[r.id].hit_test(geometry); canvas = this.plot_model.canvas; frame = this.plot_model.frame; geometry['sx'] = canvas.vx_to_sx(geometry.vx); geometry['sy'] = canvas.vy_to_sy(geometry.vy); xmapper = frame.x_mappers[r.x_range_name]; ymapper = frame.y_mappers[r.y_range_name]; geometry['x'] = xmapper.map_from_target(geometry.vx); geometry['y'] = ymapper.map_from_target(geometry.vy); callback = this.model.callback; ref = [ callback, { index: indices, geometry: geometry } ], obj = ref[0], data = ref[1]; if (types_1.isFunction(callback)) { callback(obj, data); } else { callback.execute(obj, data); } }; HoverToolView.prototype._render_tooltips = function (ds, i, vars) { var cell, colname, color, column, el, hex, k, label, len, match, opts, ref, ref1, row, rows, swatch, tooltips, value; tooltips = this.model.tooltips; if (types_1.isString(tooltips)) { el = dom_1.div(); el.innerHTML = templating_1.replace_placeholders(tooltips, ds, i, vars); return el; } else if (types_1.isFunction(tooltips)) { return tooltips(ds, vars); } else { rows = dom_1.div({ style: { display: "table", borderSpacing: "2px" } }); for (k = 0, len = tooltips.length; k < len; k++) { ref = tooltips[k], label = ref[0], value = ref[1]; row = dom_1.div({ style: { display: "table-row" } }); rows.appendChild(row); cell = dom_1.div({ style: { display: "table-cell" }, "class": 'bk-tooltip-row-label' }, 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) { ref1 = value.match(/\$color(\[.*\])?:(\w*)/), match = ref1[0], opts = ref1[1], colname = ref1[2]; column = ds.get_column(colname); if (column == null) { el = dom_1.span({}, colname + " unknown"); cell.appendChild(el); continue; } hex = (opts != null ? opts.indexOf("hex") : void 0) >= 0; swatch = (opts != null ? opts.indexOf("swatch") : void 0) >= 0; color = column[i]; if (color == null) { el = dom_1.span({}, "(null)"); cell.appendChild(el); continue; } if (hex) { color = _color_to_hex(color); } 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 { value = value.replace("$~", "$data_"); el = dom_1.span(); el.innerHTML = templating_1.replace_placeholders(value, ds, i, vars); cell.appendChild(el); } } return rows; } }; return HoverToolView; })(inspect_tool_1.InspectToolView); exports.HoverTool = (function (superClass) { extend(HoverTool, superClass); function HoverTool() { return HoverTool.__super__.constructor.apply(this, arguments); } HoverTool.prototype.default_view = exports.HoverToolView; HoverTool.prototype.type = "HoverTool"; HoverTool.prototype.tool_name = "Hover"; HoverTool.prototype.icon = "bk-tool-icon-hover"; HoverTool.define({ tooltips: [p.Any, [["index", "$index"], ["data (x, y)", "($x, $y)"], ["canvas (x, y)", "($sx, $sy)"]]], renderers: [p.Array, []], names: [p.Array, []], mode: [p.String, 'mouse'], point_policy: [p.String, 'snap_to_data'], line_policy: [p.String, 'nearest'], show_arrow: [p.Boolean, true], anchor: [p.String, 'center'], attachment: [p.String, 'horizontal'], callback: [p.Any] }); HoverTool.prototype.initialize = function (attrs, options) { HoverTool.__super__.initialize.call(this, attrs, options); this.define_computed_property('computed_renderers', function () { var all_renderers, names, r, renderers; renderers = this.renderers; names = this.names; if (renderers.length === 0) { all_renderers = this.plot.renderers; renderers = (function () { var k, len, results; results = []; for (k = 0, len = all_renderers.length; k < len; k++) { r = all_renderers[k]; if (r instanceof glyph_renderer_1.GlyphRenderer) { results.push(r); } } return results; })(); } if (names.length > 0) { renderers = (function () { var k, len, results; results = []; for (k = 0, len = renderers.length; k < len; k++) { r = renderers[k]; if (names.indexOf(r.name) >= 0) { results.push(r); } } return results; })(); } return renderers; }, true); this.add_dependencies('computed_renderers', this, ['renderers', 'names', 'plot']); this.add_dependencies('computed_renderers', this.plot, ['renderers']); this.define_computed_property('ttmodels', function () { var k, len, r, ref, tooltip, tooltips, ttmodels; ttmodels = {}; tooltips = this.tooltips; if (tooltips != null) { ref = this.computed_renderers; for (k = 0, len = ref.length; k < len; k++) { r = ref[k]; tooltip = new tooltip_1.Tooltip({ custom: types_1.isString(tooltips) || types_1.isFunction(tooltips), attachment: this.attachment, show_arrow: this.show_arrow }); ttmodels[r.id] = tooltip; } } return ttmodels; }); return this.add_dependencies('ttmodels', this, ['computed_renderers', 'tooltips']); }; HoverTool.getters({ computed_renderers: function () { return this._get_computed('computed_renderers'); }, ttmodels: function () { return this._get_computed('ttmodels'); }, synthetic_renderers: function () { return object_1.values(this.ttmodels); } }); return HoverTool; })(inspect_tool_1.InspectTool);