+ bokeh plugin

This commit is contained in:
tix 2017-02-20 16:33:07 +08:00
parent b36c3999dd
commit a0f286d516
258 changed files with 128585 additions and 0 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
public/lib/bokeh/css/bokeh.min.css vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

31
public/lib/bokeh/js/bokeh-api.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

223
public/lib/bokeh/js/bokeh-widgets.min.js vendored Normal file

File diff suppressed because one or more lines are too long

58207
public/lib/bokeh/js/bokeh.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

273
public/lib/bokeh/js/bokeh.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,13 @@
var _;
_ = require("underscore");
module.exports = {
LinAlg: require("./api/linalg"),
Charts: require("./api/charts"),
Plotting: require("./api/plotting"),
Document: require("./document").Document,
sprintf: require("sprintf")
};
_.extend(module.exports, require("./api/models"));

View File

@ -0,0 +1,467 @@
var $, Document, _, bar, cumsum, embed, hexcolor2rgb, is_dark, models, num2hexcolor, palettes, pie, sprintf, sum;
_ = require("underscore");
$ = require("jquery");
sprintf = require("sprintf");
Document = require("../document").Document;
embed = require("../embed");
models = require("./models");
palettes = require("../palettes/palettes");
sum = function(array) {
return array.reduce(((function(_this) {
return function(a, b) {
return a + b;
};
})(this)), 0);
};
cumsum = function(array) {
var result;
result = [];
array.reduce((function(a, b, i) {
return result[i] = a + b;
}), 0);
return result;
};
num2hexcolor = function(num) {
return sprintf("#%06x", num);
};
hexcolor2rgb = function(color) {
var b, g, r;
r = parseInt(color.substr(1, 2), 16);
g = parseInt(color.substr(3, 2), 16);
b = parseInt(color.substr(5, 2), 16);
return [r, g, b];
};
is_dark = function(arg) {
var b, g, l, r;
r = arg[0], g = arg[1], b = arg[2];
l = 1 - (0.299 * r + 0.587 * g + 0.114 * b) / 255;
return l >= 0.6;
};
pie = function(data, opts) {
var angle_span, colors, cumulative_values, cx, cy, end_angle, end_angles, g1, g2, h1, half_angles, half_radius, hover, i, inner_radius, k, labels, normalized_values, outer_radius, palette, plot, r1, r2, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, source, start_angle, start_angles, text_angles, text_colors, text_cx, text_cy, to_cartesian, to_radians, tooltip, total_value, values, xdr, ydr;
if (opts == null) {
opts = {};
}
labels = [];
values = [];
for (i = k = 0, ref = Math.min(data.labels.length, data.values.length); 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
if (data.values[i] > 0) {
labels.push(data.labels[i]);
values.push(data.values[i]);
}
}
start_angle = (ref1 = opts.start_angle) != null ? ref1 : 0;
end_angle = (ref2 = opts.end_angle) != null ? ref2 : start_angle + 2 * Math.PI;
angle_span = Math.abs(end_angle - start_angle);
to_radians = function(x) {
return angle_span * x;
};
total_value = sum(values);
normalized_values = values.map(function(v) {
return v / total_value;
});
cumulative_values = cumsum(normalized_values);
end_angles = cumulative_values.map(function(v) {
return start_angle + to_radians(v);
});
start_angles = [start_angle].concat(end_angles.slice(0, -1));
half_angles = _.zip(start_angles, end_angles).map((function(_this) {
return function(arg) {
var end, start;
start = arg[0], end = arg[1];
return (start + end) / 2;
};
})(this));
if (opts.center == null) {
cx = 0;
cy = 0;
} else if (_.isArray(opts.center)) {
cx = opts.center[0];
cy = opts.center[1];
} else {
cx = opts.center.x;
cy = opts.center.y;
}
inner_radius = (ref3 = opts.inner_radius) != null ? ref3 : 0;
outer_radius = (ref4 = opts.outer_radius) != null ? ref4 : 1;
if (_.isArray(opts.palette)) {
palette = opts.palette;
} else {
palette = palettes[(ref5 = opts.palette) != null ? ref5 : "Spectral11"].map(num2hexcolor);
}
colors = (function() {
var m, ref6, results;
results = [];
for (i = m = 0, ref6 = normalized_values.length; 0 <= ref6 ? m < ref6 : m > ref6; i = 0 <= ref6 ? ++m : --m) {
results.push(palette[i % palette.length]);
}
return results;
})();
text_colors = colors.map(function(c) {
if (is_dark(hexcolor2rgb(c))) {
return "white";
} else {
return "black";
}
});
to_cartesian = function(r, alpha) {
return [r * Math.cos(alpha), r * Math.sin(alpha)];
};
half_radius = (inner_radius + outer_radius) / 2;
ref6 = _.unzip(half_angles.map((function(_this) {
return function(half_angle) {
return to_cartesian(half_radius, half_angle);
};
})(this))), text_cx = ref6[0], text_cy = ref6[1];
text_cx = text_cx.map(function(x) {
return x + cx;
});
text_cy = text_cy.map(function(y) {
return y + cy;
});
text_angles = half_angles.map(function(a) {
if (a >= Math.PI / 2 && a <= 3 * Math.PI / 2) {
return a + Math.PI;
} else {
return a;
}
});
source = new Bokeh.ColumnDataSource({
data: {
labels: labels,
values: values,
percentages: normalized_values.map((function(_this) {
return function(v) {
return sprintf("%.2f%%", v * 100);
};
})(this)),
start_angles: start_angles,
end_angles: end_angles,
text_angles: text_angles,
colors: colors,
text_colors: text_colors,
text_cx: text_cx,
text_cy: text_cy
}
});
g1 = new models.AnnularWedge({
x: cx,
y: cy,
inner_radius: inner_radius,
outer_radius: outer_radius,
start_angle: {
field: "start_angles"
},
end_angle: {
field: "end_angles"
},
line_color: null,
line_width: 1,
fill_color: {
field: "colors"
}
});
h1 = new models.AnnularWedge({
x: cx,
y: cy,
inner_radius: inner_radius,
outer_radius: outer_radius,
start_angle: {
field: "start_angles"
},
end_angle: {
field: "end_angles"
},
line_color: null,
line_width: 1,
fill_color: {
field: "colors"
},
fill_alpha: 0.8
});
r1 = new models.GlyphRenderer({
data_source: source,
glyph: g1,
hover_glyph: h1
});
g2 = new models.Text({
x: {
field: "text_cx"
},
y: {
field: "text_cy"
},
text: {
field: (ref7 = opts.slice_labels) != null ? ref7 : "labels"
},
angle: {
field: "text_angles"
},
text_align: "center",
text_baseline: "middle",
text_color: {
field: "text_colors"
},
text_font_size: "9pt"
});
r2 = new models.GlyphRenderer({
data_source: source,
glyph: g2
});
xdr = new models.DataRange1d({
renderers: [r1],
range_padding: 0.2
});
ydr = new models.DataRange1d({
renderers: [r1],
range_padding: 0.2
});
plot = new models.Plot({
x_range: xdr,
y_range: ydr
});
if (opts.width != null) {
plot.plot_width = opts.width;
}
if (opts.height != null) {
plot.plot_height = opts.height;
}
plot.add_renderers(r1, r2);
tooltip = "<div>@labels</div><div><b>@values</b> (@percentages)</div>";
hover = new models.HoverTool({
renderers: [r1],
tooltips: tooltip
});
plot.add_tools(hover);
return plot;
};
bar = function(data, opts) {
var anchor, attachment, bottom, column_names, columns, dy, g1, hover, i, j, k, label, labels, left, len, len1, len2, len3, len4, m, n, name, o, orientation, p, palette, plot, q, r, r1, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, renderers, right, row, rows, s, source, stacked, tooltip, top, v, xaxis, xdr, xformatter, yaxis, ydr;
if (opts == null) {
opts = {};
}
column_names = data[0];
rows = data.slice(1);
columns = (function() {
var k, len, results;
results = [];
for (k = 0, len = column_names.length; k < len; k++) {
name = column_names[k];
results.push([]);
}
return results;
})();
for (k = 0, len = rows.length; k < len; k++) {
row = rows[k];
for (i = m = 0, len1 = row.length; m < len1; i = ++m) {
v = row[i];
columns[i].push(v);
}
}
labels = _.map(columns[0], function(v) {
return v.toString();
});
columns = columns.slice(1);
yaxis = new models.CategoricalAxis();
ydr = new models.FactorRange({
factors: labels
});
if (opts.axis_number_format != null) {
xformatter = new models.NumeralTickFormatter({
format: opts.axis_number_format
});
} else {
xformatter = new models.BasicTickFormatter();
}
xaxis = new models.LinearAxis({
formatter: xformatter
});
xdr = new models.DataRange1d({
start: 0
});
if (_.isArray(opts.palette)) {
palette = opts.palette;
} else {
palette = palettes[(ref = opts.palette) != null ? ref : "Spectral11"].map(num2hexcolor);
}
stacked = (ref1 = opts.stacked) != null ? ref1 : false;
orientation = (ref2 = opts.orientation) != null ? ref2 : "horizontal";
renderers = [];
if (stacked) {
left = [];
right = [];
for (i = n = 0, ref3 = columns.length; 0 <= ref3 ? n < ref3 : n > ref3; i = 0 <= ref3 ? ++n : --n) {
bottom = [];
top = [];
for (j = o = 0, len2 = labels.length; o < len2; j = ++o) {
label = labels[j];
if (i === 0) {
left.push(0);
right.push(columns[i][j]);
} else {
left[j] += columns[i - 1][j];
right[j] += columns[i][j];
}
bottom.push(label + ":0");
top.push(label + ":1");
}
source = new Bokeh.ColumnDataSource({
data: {
left: _.clone(left),
right: _.clone(right),
top: top,
bottom: bottom,
labels: labels,
values: columns[i],
columns: (function() {
var len3, p, ref4, results;
ref4 = columns[i];
results = [];
for (p = 0, len3 = ref4.length; p < len3; p++) {
v = ref4[p];
results.push(column_names[i + 1]);
}
return results;
})()
}
});
g1 = new models.Quad({
left: {
field: "left"
},
bottom: {
field: "bottom"
},
right: {
field: "right"
},
top: {
field: "top"
},
line_color: null,
fill_color: palette[i % palette.length]
});
r1 = new models.GlyphRenderer({
data_source: source,
glyph: g1
});
renderers.push(r1);
}
} else {
dy = 1 / columns.length;
for (i = p = 0, ref4 = columns.length; 0 <= ref4 ? p < ref4 : p > ref4; i = 0 <= ref4 ? ++p : --p) {
left = [];
right = [];
bottom = [];
top = [];
for (j = q = 0, len3 = labels.length; q < len3; j = ++q) {
label = labels[j];
left.push(0);
right.push(columns[i][j]);
bottom.push(label + ":" + (i * dy));
top.push(label + ":" + ((i + 1) * dy));
}
source = new Bokeh.ColumnDataSource({
data: {
left: left,
right: right,
top: top,
bottom: bottom,
labels: labels,
values: columns[i],
columns: (function() {
var len4, ref5, results, s;
ref5 = columns[i];
results = [];
for (s = 0, len4 = ref5.length; s < len4; s++) {
v = ref5[s];
results.push(column_names[i + 1]);
}
return results;
})()
}
});
g1 = new models.Quad({
left: {
field: "left"
},
bottom: {
field: "bottom"
},
right: {
field: "right"
},
top: {
field: "top"
},
line_color: null,
fill_color: palette[i % palette.length]
});
r1 = new models.GlyphRenderer({
data_source: source,
glyph: g1
});
renderers.push(r1);
}
}
if (orientation === "vertical") {
ref5 = [ydr, xdr], xdr = ref5[0], ydr = ref5[1];
ref6 = [yaxis, xaxis], xaxis = ref6[0], yaxis = ref6[1];
for (s = 0, len4 = renderers.length; s < len4; s++) {
r = renderers[s];
data = r.data_source.data;
ref7 = [data.bottom, data.left], data.left = ref7[0], data.bottom = ref7[1];
ref8 = [data.top, data.right], data.right = ref8[0], data.top = ref8[1];
}
}
plot = new models.Plot({
x_range: xdr,
y_range: ydr
});
if (opts.width != null) {
plot.plot_width = opts.width;
}
if (opts.height != null) {
plot.plot_height = opts.height;
}
plot.add_renderers.apply(plot, renderers);
plot.add_layout(yaxis, "left");
plot.add_layout(xaxis, "below");
tooltip = "<div>@labels</div><div>@columns:&nbsp<b>@values</b></div>";
if (orientation === "horizontal") {
anchor = "right_center";
attachment = "horizontal";
} else {
anchor = "top_center";
attachment = "vertical";
}
hover = new models.HoverTool({
renderers: renderers,
tooltips: tooltip,
point_policy: "snap_to_data",
anchor: anchor,
attachment: attachment,
show_arrow: opts.show_arrow
});
plot.add_tools(hover);
return plot;
};
module.exports = {
pie: pie,
bar: bar
};

View File

@ -0,0 +1,34 @@
"use strict";
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 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 arange(start, stop, step) {
if (step === void 0) { step = 1; }
var num = Math.ceil((stop - start) / step);
var array = new Array(num);
for (var i = 0; i < num; i++) {
array[i] = start + step * i;
}
return array;
}
exports.arange = arange;

View File

@ -0,0 +1,118 @@
module.exports = {
Arrow: require("../models/annotations/arrow").Model,
OpenHead: require("../models/annotations/arrow_head").OpenHead,
NormalHead: require("../models/annotations/arrow_head").NormalHead,
VeeHead: require("../models/annotations/arrow_head").VeeHead,
BoxAnnotation: require("../models/annotations/box_annotation").Model,
ColorBar: require("../models/annotations/color_bar").Model,
Label: require("../models/annotations/label").Model,
LabelSet: require("../models/annotations/label_set").Model,
Legend: require("../models/annotations/legend").Model,
PolyAnnotation: require("../models/annotations/poly_annotation").Model,
Span: require("../models/annotations/span").Model,
Title: require("../models/annotations/title").Model,
Tooltip: require("../models/annotations/tooltip").Model,
Axis: require("../models/axes/axis").Model,
ContinuousAxis: require("../models/axes/continuous_axis").Model,
LinearAxis: require("../models/axes/linear_axis").Model,
LogAxis: require("../models/axes/log_axis").Model,
CategoricalAxis: require("../models/axes/categorical_axis").Model,
DatetimeAxis: require("../models/axes/datetime_axis").Model,
OpenURL: require("../models/callbacks/open_url").Model,
CustomJS: require("../models/callbacks/customjs").Model,
TickFormatter: require("../models/formatters/tick_formatter").Model,
BasicTickFormatter: require("../models/formatters/basic_tick_formatter").Model,
LogTickFormatter: require("../models/formatters/basic_tick_formatter").Model,
CategoricalTickFormatter: require("../models/formatters/categorical_tick_formatter").Model,
DatetimeTickFormatter: require("../models/formatters/datetime_tick_formatter").Model,
FuncTickFormatter: require("../models/formatters/func_tick_formatter").Model,
NumeralTickFormatter: require("../models/formatters/numeral_tick_formatter").Model,
PrintfTickFormatter: require("../models/formatters/printf_tick_formatter").Model,
Glyph: require("../models/glyphs/glyph").Model,
AnnularWedge: require("../models/glyphs/annular_wedge").Model,
Annulus: require("../models/glyphs/annulus").Model,
Arc: require("../models/glyphs/arc").Model,
Bezier: require("../models/glyphs/bezier").Model,
Circle: require("../models/glyphs/circle").Model,
Ellipse: require("../models/glyphs/ellipse").Model,
ImageRGBA: require("../models/glyphs/image_rgba").Model,
Image: require("../models/glyphs/image").Model,
ImageURL: require("../models/glyphs/image_url").Model,
Line: require("../models/glyphs/line").Model,
MultiLine: require("../models/glyphs/multi_line").Model,
Oval: require("../models/glyphs/oval").Model,
Patch: require("../models/glyphs/patch").Model,
Patches: require("../models/glyphs/patches").Model,
Quad: require("../models/glyphs/quad").Model,
Quadratic: require("../models/glyphs/quadratic").Model,
Ray: require("../models/glyphs/ray").Model,
Rect: require("../models/glyphs/rect").Model,
Segment: require("../models/glyphs/segment").Model,
Text: require("../models/glyphs/text").Model,
Wedge: require("../models/glyphs/wedge").Model,
Gear: require("../models/glyphs/gear").Model,
Grid: require("../models/grids/grid").Model,
ImageSource: require("../models/tiles/image_source").Model,
LayoutDOM: require("../models/layouts/layout_dom").Model,
Row: require("../models/layouts/row").Model,
Column: require("../models/layouts/column").Model,
Spacer: require("../models/layouts/spacer").Model,
WidgetBox: require("../models/layouts/widget_box").Model,
GMapPlot: require("../models/plots/gmap_plot").Model,
LinearColorMapper: require("../models/mappers/linear_color_mapper").Model,
markers: [require('../models/markers/index')],
Model: require("../model").Model,
Plot: require("../models/plots/plot").Model,
Range: require("../models/ranges/range").Model,
Range1d: require("../models/ranges/range1d").Model,
DataRange: require("../models/ranges/data_range").Model,
DataRange1d: require("../models/ranges/data_range1d").Model,
FactorRange: require("../models/ranges/factor_range").Model,
Renderer: require("../models/renderers/renderer").Model,
TileRenderer: require("../models/tiles/tile_renderer").Model,
DynamicImageRenderer: require("../models/tiles/dynamic_image_renderer").Model,
GlyphRenderer: require("../models/renderers/glyph_renderer").Model,
GuideRenderer: require("../models/renderers/guide_renderer").Model,
DataSource: require("../models/sources/data_source").Model,
ColumnDataSource: require("../models/sources/column_data_source").Model,
AjaxDataSource: require("../models/sources/ajax_data_source").Model,
Ticker: require("../models/tickers/ticker").Model,
ContinuousTicker: require("../models/tickers/continuous_ticker").Model,
FixedTicker: require("../models/tickers/fixed_ticker").Model,
AdaptiveTicker: require("../models/tickers/adaptive_ticker").Model,
CompositeTicker: require("../models/tickers/composite_ticker").Model,
SingleIntervalTicker: require("../models/tickers/single_interval_ticker").Model,
DaysTicker: require("../models/tickers/days_ticker").Model,
MonthsTicker: require("../models/tickers/months_ticker").Model,
YearsTicker: require("../models/tickers/years_ticker").Model,
BasicTicker: require("../models/tickers/basic_ticker").Model,
LogTicker: require("../models/tickers/log_ticker").Model,
CategoricalTicker: require("../models/tickers/categorical_ticker").Model,
DatetimeTicker: require("../models/tickers/datetime_ticker").Model,
TileSource: require("../models/tiles/tile_source").Model,
MercatorTileSource: require("../models/tiles/mercator_tile_source").Model,
TMSTileSource: require("../models/tiles/tms_tile_source").Model,
WMTSTileSource: require("../models/tiles/wmts_tile_source").Model,
QUADKEYTileSource: require("../models/tiles/quadkey_tile_source").Model,
BBoxTileSource: require("../models/tiles/bbox_tile_source").Model,
ToolbarBase: require("../models/tools/toolbar_base").Model,
Toolbar: require("../models/tools/toolbar").Model,
ToolbarBox: require("../models/tools/toolbar_box").Model,
ToolEvents: require("../common/tool_events").Model,
Tool: require("../models/tools/tool").Model,
PanTool: require("../models/tools/gestures/pan_tool").Model,
WheelZoomTool: require("../models/tools/gestures/wheel_zoom_tool").Model,
SaveTool: require("../models/tools/actions/save_tool").Model,
UndoTool: require("../models/tools/actions/undo_tool").Model,
RedoTool: require("../models/tools/actions/redo_tool").Model,
ResetTool: require("../models/tools/actions/reset_tool").Model,
ResizeTool: require("../models/tools/gestures/resize_tool").Model,
CrosshairTool: require("../models/tools/inspectors/crosshair_tool").Model,
BoxZoomTool: require("../models/tools/gestures/box_zoom_tool").Model,
BoxSelectTool: require("../models/tools/gestures/box_select_tool").Model,
LassoSelectTool: require("../models/tools/gestures/lasso_select_tool").Model,
PolySelectTool: require("../models/tools/gestures/poly_select_tool").Model,
TapTool: require("../models/tools/gestures/tap_tool").Model,
HoverTool: require("../models/tools/inspectors/hover_tool").Model,
HelpTool: require("../models/tools/actions/help_tool").Model
};

View File

@ -0,0 +1,889 @@
var $, BOKEH_ROOT, Document, Figure, _, _default_tools, _default_tooltips, _known_tools, _with_default, color, embed, figure, gridplot, models, show, sprintf,
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,
slice = [].slice;
_ = require("underscore");
$ = require("jquery");
sprintf = require("sprintf");
Document = require("../document").Document;
embed = require("../embed");
BOKEH_ROOT = require("../embed").BOKEH_ROOT;
models = require("./models");
_default_tooltips = [["index", "$index"], ["data (x, y)", "($x, $y)"], ["canvas (x, y)", "($sx, $sy)"]];
_default_tools = "pan,wheel_zoom,box_zoom,save,reset,help";
_known_tools = {
pan: function(plot) {
return new models.PanTool({
plot: plot,
dimensions: ["width", "height"]
});
},
xpan: function(plot) {
return new models.PanTool({
plot: plot,
dimensions: ["width"]
});
},
ypan: function(plot) {
return new models.PanTool({
plot: plot,
dimensions: ["height"]
});
},
wheel_zoom: function(plot) {
return new models.WheelZoomTool({
plot: plot,
dimensions: ["width", "height"]
});
},
xwheel_zoom: function(plot) {
return new models.WheelZoomTool({
plot: plot,
dimensions: ["width"]
});
},
ywheel_zoom: function(plot) {
return new models.WheelZoomTool({
plot: plot,
dimensions: ["height"]
});
},
resize: function(plot) {
return new models.ResizeTool({
plot: plot
});
},
click: function(plot) {
return new models.TapTool({
plot: plot,
behavior: "inspect"
});
},
tap: function(plot) {
return new models.TapTool({
plot: plot
});
},
crosshair: function(plot) {
return new models.CrosshairTool({
plot: plot
});
},
box_select: function(plot) {
return new models.BoxSelectTool({
plot: plot
});
},
xbox_select: function(plot) {
return new models.BoxSelectTool({
plot: plot,
dimensions: ['width']
});
},
ybox_select: function(plot) {
return new models.BoxSelectTool({
plot: plot,
dimensions: ['height']
});
},
poly_select: function(plot) {
return new models.PolySelectTool({
plot: plot
});
},
lasso_select: function(plot) {
return new models.LassoSelectTool({
plot: plot
});
},
box_zoom: function(plot) {
return new models.BoxZoomTool({
plot: plot,
dimensions: ['width', 'height']
});
},
xbox_zoom: function(plot) {
return new models.BoxZoomTool({
plot: plot,
dimensions: ['width']
});
},
ybox_zoom: function(plot) {
return new models.BoxZoomTool({
plot: plot,
dimensions: ['height']
});
},
hover: function(plot) {
return new models.HoverTool({
plot: plot,
tooltips: _default_tooltips
});
},
save: function(plot) {
return new models.SaveTool({
plot: plot
});
},
previewsave: function(plot) {
return new models.SaveTool({
plot: plot
});
},
undo: function(plot) {
return new models.UndoTool({
plot: plot
});
},
redo: function(plot) {
return new models.RedoTool({
plot: plot
});
},
reset: function(plot) {
return new models.ResetTool({
plot: plot
});
},
help: function(plot) {
return new models.HelpTool({
plot: plot
});
}
};
_with_default = function(value, default_value) {
if (value === void 0) {
return default_value;
} else {
return value;
}
};
Figure = (function(superClass) {
extend(Figure, superClass);
function Figure(attributes, options) {
var attrs, ref, ref1, ref2, ref3, ref4, ref5, tools, x_axis_label, x_axis_location, x_axis_type, x_minor_ticks, y_axis_label, y_axis_location, y_axis_type, y_minor_ticks;
if (attributes == null) {
attributes = {};
}
if (options == null) {
options = {};
}
attrs = _.clone(attributes);
tools = _with_default(attrs.tools, _default_tools);
delete attrs.tools;
attrs.x_range = this._get_range(attrs.x_range);
attrs.y_range = this._get_range(attrs.y_range);
x_axis_type = _.isUndefined(attrs.x_axis_type) ? "auto" : attrs.x_axis_type;
y_axis_type = _.isUndefined(attrs.y_axis_type) ? "auto" : attrs.y_axis_type;
delete attrs.x_axis_type;
delete attrs.y_axis_type;
x_minor_ticks = (ref = attrs.x_minor_ticks) != null ? ref : "auto";
y_minor_ticks = (ref1 = attrs.y_minor_ticks) != null ? ref1 : "auto";
delete attrs.x_minor_ticks;
delete attrs.y_minor_ticks;
x_axis_location = (ref2 = attrs.x_axis_location) != null ? ref2 : "below";
y_axis_location = (ref3 = attrs.y_axis_location) != null ? ref3 : "left";
delete attrs.x_axis_location;
delete attrs.y_axis_location;
x_axis_label = (ref4 = attrs.x_axis_label) != null ? ref4 : "";
y_axis_label = (ref5 = attrs.y_axis_label) != null ? ref5 : "";
delete attrs.x_axis_label;
delete attrs.y_axis_label;
if (!_.isUndefined(attrs.width)) {
if (_.isUndefined(attrs.plot_width)) {
attrs.plot_width = attrs.width;
} else {
throw new Error("both 'width' and 'plot_width' can't be given at the same time");
}
delete attrs.width;
}
if (!_.isUndefined(attrs.height)) {
if (_.isUndefined(attrs.plot_height)) {
attrs.plot_height = attrs.height;
} else {
throw new Error("both 'height' and 'plot_height' can't be given at the same time");
}
delete attrs.height;
}
Figure.__super__.constructor.call(this, attrs, options);
this._process_guides(0, x_axis_type, x_axis_location, x_minor_ticks, x_axis_label);
this._process_guides(1, y_axis_type, y_axis_location, y_minor_ticks, y_axis_label);
this.add_tools.apply(this, this._process_tools(tools));
this._legend = new models.Legend({
plot: this
});
this.add_renderers(this._legend);
}
Object.defineProperty(Figure.prototype, "xgrid", {
get: function() {
return this.renderers.filter(function(r) {
return r instanceof models.Grid && r.dimension === 0;
})[0];
}
});
Object.defineProperty(Figure.prototype, "ygrid", {
get: function() {
return this.renderers.filter(function(r) {
return r instanceof models.Grid && r.dimension === 1;
})[0];
}
});
Object.defineProperty(Figure.prototype, "xaxis", {
get: function() {
return this.below.concat(this.above).filter(function(r) {
return r instanceof models.Axis;
})[0];
}
});
Object.defineProperty(Figure.prototype, "yaxis", {
get: function() {
return this.left.concat(this.right).filter(function(r) {
return r instanceof models.Axis;
})[0];
}
});
Figure.prototype.annular_wedge = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.AnnularWedge, "x,y,inner_radius,outer_radius,start_angle,end_angle", args);
};
Figure.prototype.annulus = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Annulus, "x,y,inner_radius,outer_radius", args);
};
Figure.prototype.arc = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Arc, "x,y,radius,start_angle,end_angle", args);
};
Figure.prototype.bezier = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Bezier, "x0,y0,x1,y1,cx0,cy0,cx1,cy1", args);
};
Figure.prototype.ellipse = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Ellipse, "x,y,width,height", args);
};
Figure.prototype.gear = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Gear, "x,y,module,teeth", args);
};
Figure.prototype.image = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Image, "color_mapper,image,rows,cols,x,y,dw,dh", args);
};
Figure.prototype.image_rgba = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.ImageRGBA, "image,rows,cols,x,y,dw,dh", args);
};
Figure.prototype.image_url = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.ImageURL, "url,x,y,w,h", args);
};
Figure.prototype.line = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Line, "x,y", args);
};
Figure.prototype.multi_line = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.MultiLine, "xs,ys", args);
};
Figure.prototype.oval = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Oval, "x,y,width,height", args);
};
Figure.prototype.patch = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Patch, "x,y", args);
};
Figure.prototype.patches = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Patches, "xs,ys", args);
};
Figure.prototype.quad = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Quad, "left,right,bottom,top", args);
};
Figure.prototype.quadratic = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Quadratic, "x0,y0,x1,y1,cx,cy", args);
};
Figure.prototype.ray = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Ray, "x,y,length", args);
};
Figure.prototype.rect = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Rect, "x,y,width,height", args);
};
Figure.prototype.segment = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Segment, "x0,y0,x1,y1", args);
};
Figure.prototype.text = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Text, "x,y,text", args);
};
Figure.prototype.wedge = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._glyph(models.Wedge, "x,y,radius,start_angle,end_angle", args);
};
Figure.prototype.asterisk = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._marker(models.Asterisk, args);
};
Figure.prototype.circle = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._marker(models.Circle, args);
};
Figure.prototype.circle_cross = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._marker(models.CircleCross, args);
};
Figure.prototype.circle_x = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._marker(models.CircleX, args);
};
Figure.prototype.cross = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._marker(models.Cross, args);
};
Figure.prototype.diamond = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._marker(models.Diamond, args);
};
Figure.prototype.diamond_cross = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._marker(models.DiamondCross, args);
};
Figure.prototype.inverted_triangle = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._marker(models.InvertedTriangle, args);
};
Figure.prototype.square = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._marker(models.Square, args);
};
Figure.prototype.square_cross = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._marker(models.SquareCross, args);
};
Figure.prototype.square_x = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._marker(models.SquareX, args);
};
Figure.prototype.triangle = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._marker(models.Triangle, args);
};
Figure.prototype.x = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return this._marker(models.X, args);
};
Figure.prototype._vectorable = ["fill_color", "fill_alpha", "line_color", "line_alpha", "line_width", "text_color", "text_alpha", "text_font_size"];
Figure.prototype._default_color = "#1f77b4";
Figure.prototype._default_alpha = 1.0;
Figure.prototype._pop_colors_and_alpha = function(cls, attrs, prefix, default_color, default_alpha) {
var _update_with, alpha, color, result;
if (prefix == null) {
prefix = "";
}
if (default_color == null) {
default_color = this._default_color;
}
if (default_alpha == null) {
default_alpha = this._default_alpha;
}
result = {};
color = _with_default(attrs[prefix + "color"], default_color);
alpha = _with_default(attrs[prefix + "alpha"], default_alpha);
delete attrs[prefix + "color"];
delete attrs[prefix + "alpha"];
_update_with = function(name, default_value) {
if (cls.prototype.props[name] != null) {
result[name] = _with_default(attrs[prefix + name], default_value);
return delete attrs[prefix + name];
}
};
_update_with("fill_color", color);
_update_with("line_color", color);
_update_with("text_color", "black");
_update_with("fill_alpha", alpha);
_update_with("line_alpha", alpha);
_update_with("text_alpha", alpha);
return result;
};
Figure.prototype._find_uniq_name = function(data, name) {
var i, new_name;
i = 1;
while (true) {
new_name = name + "__" + i;
if (data[new_name] != null) {
i += 1;
} else {
return new_name;
}
}
};
Figure.prototype._fixup_values = function(cls, data, attrs) {
var name, results, value;
results = [];
for (name in attrs) {
value = attrs[name];
results.push((function(_this) {
return function(name, value) {
var field, prop;
prop = cls.prototype.props[name];
if (prop != null) {
if (prop.type.prototype.dataspec) {
if (value != null) {
if (_.isArray(value)) {
if (data[name] != null) {
if (data[name] !== value) {
field = _this._find_uniq_name(data, name);
data[field] = value;
} else {
field = name;
}
} else {
field = name;
data[field] = value;
}
return attrs[name] = {
field: field
};
} else if (_.isNumber(value) || _.isString(value)) {
return attrs[name] = {
value: value
};
}
}
}
}
};
})(this)(name, value));
}
return results;
};
Figure.prototype._glyph = function(cls, params, args) {
var _make_glyph, attrs, data, fn, glyph, glyph_ca, glyph_renderer, has_hglyph, has_sglyph, hglyph, hglyph_ca, i, j, k, legend, len, nsglyph, nsglyph_ca, opts, param, ref, ref1, sglyph, sglyph_ca, source;
params = params.split(",");
if (args.length === 1) {
attrs = args[0];
attrs = _.clone(attrs);
} else {
ref = args, args = 2 <= ref.length ? slice.call(ref, 0, j = ref.length - 1) : (j = 0, []), opts = ref[j++];
attrs = _.clone(opts);
fn = function(param, i) {
return attrs[param] = args[i];
};
for (i = k = 0, len = params.length; k < len; i = ++k) {
param = params[i];
fn(param, i);
}
}
legend = attrs.legend;
delete attrs.legend;
has_sglyph = _.any(_.keys(attrs), function(key) {
return key.startsWith("selection_");
});
has_hglyph = _.any(_.keys(attrs), function(key) {
return key.startsWith("hover_");
});
glyph_ca = this._pop_colors_and_alpha(cls, attrs);
nsglyph_ca = this._pop_colors_and_alpha(cls, attrs, "nonselection_", void 0, 0.1);
sglyph_ca = has_sglyph ? this._pop_colors_and_alpha(cls, attrs, "selection_") : {};
hglyph_ca = has_hglyph ? this._pop_colors_and_alpha(cls, attrs, "hover_") : {};
source = (ref1 = attrs.source) != null ? ref1 : new models.ColumnDataSource();
data = _.clone(source.data);
delete attrs.source;
this._fixup_values(cls, data, glyph_ca);
this._fixup_values(cls, data, nsglyph_ca);
this._fixup_values(cls, data, sglyph_ca);
this._fixup_values(cls, data, hglyph_ca);
this._fixup_values(cls, data, attrs);
source.data = data;
_make_glyph = (function(_this) {
return function(cls, attrs, extra_attrs) {
return new cls(_.extend({}, attrs, extra_attrs));
};
})(this);
glyph = _make_glyph(cls, attrs, glyph_ca);
nsglyph = _make_glyph(cls, attrs, nsglyph_ca);
sglyph = has_sglyph ? _make_glyph(cls, attrs, sglyph_ca) : null;
hglyph = has_hglyph ? _make_glyph(cls, attrs, hglyph_ca) : null;
glyph_renderer = new models.GlyphRenderer({
data_source: source,
glyph: glyph,
nonselection_glyph: nsglyph,
selection_glyph: sglyph,
hover_glyph: hglyph
});
if (legend != null) {
this._update_legend(legend, glyph_renderer);
}
this.add_renderers(glyph_renderer);
return glyph_renderer;
};
Figure.prototype._marker = function(cls, args) {
return this._glyph(cls, "x,y", args);
};
Figure.prototype._get_range = function(range) {
if (range == null) {
return new models.DataRange1d();
}
if (range instanceof models.Range) {
return range;
}
if (_.isArray(range)) {
if (_.all(function(x) {
var j, len, results;
results = [];
for (j = 0, len = range.length; j < len; j++) {
x = range[j];
results.push(_.isString(x));
}
return results;
})) {
return new models.FactorRange({
factors: range
});
}
if (range.length === 2) {
return new models.Range1d({
start: range[0],
end: range[1]
});
}
}
};
Figure.prototype._process_guides = function(dim, axis_type, axis_location, minor_ticks, axis_label) {
var axis, axiscls, grid, range;
range = dim === 0 ? this.x_range : this.y_range;
axiscls = this._get_axis_class(axis_type, range);
if (axiscls != null) {
if (axiscls === models.LogAxis) {
if (dim === 0) {
this.x_mapper_type = 'log';
} else {
this.y_mapper_type = 'log';
}
}
axis = new axiscls();
if (axis.ticker instanceof models.ContinuousTicker) {
axis.ticker.num_minor_ticks = this._get_num_minor_ticks(axiscls, minor_ticks);
}
if (axis_label.length !== 0) {
axis.axis_label = axis_label;
}
grid = new models.Grid({
dimension: dim,
ticker: axis.ticker
});
this.add_layout(axis, axis_location);
return this.add_layout(grid);
}
};
Figure.prototype._get_axis_class = function(axis_type, range) {
if (axis_type == null) {
return null;
}
if (axis_type === "linear") {
return models.LinearAxis;
}
if (axis_type === "log") {
return models.LogAxis;
}
if (axis_type === "datetime") {
return models.DatetimeAxis;
}
if (axis_type === "auto") {
if (range instanceof models.FactorRange) {
return models.CategoricalAxis;
} else {
return models.LinearAxis;
}
}
};
Figure.prototype._get_num_minor_ticks = function(axis_class, num_minor_ticks) {
if (_.isNumber(num_minor_ticks)) {
if (num_minor_ticks <= 1) {
throw new Error("num_minor_ticks must be > 1");
}
return num_minor_ticks;
}
if (num_minor_ticks == null) {
return 0;
}
if (num_minor_ticks === 'auto') {
if (axis_class === models.LogAxis) {
return 10;
}
return 5;
}
};
Figure.prototype._process_tools = function(tools) {
var objs, tool;
if (_.isString(tools)) {
tools = tools.split(/\s*,\s*/);
}
objs = (function() {
var j, len, results;
results = [];
for (j = 0, len = tools.length; j < len; j++) {
tool = tools[j];
if (_.isString(tool)) {
results.push(_known_tools[tool](this));
} else {
results.push(tool);
}
}
return results;
}).call(this);
return objs;
};
Figure.prototype._update_legend = function(legend_name, glyph_renderer) {
var j, legends, len, name, ref, renderers;
legends = _.clone(this._legend.legends);
for (j = 0, len = legends.length; j < len; j++) {
ref = legends[j], name = ref[0], renderers = ref[1];
if (name === legend_name) {
renderers.push(glyph_renderer);
this._legend.legends = legends;
return;
}
}
legends.push([legend_name, [glyph_renderer]]);
return this._legend.legends = legends;
};
return Figure;
})(models.Plot);
figure = function(attributes, options) {
if (attributes == null) {
attributes = {};
}
if (options == null) {
options = {};
}
return new Figure(attributes, options);
};
show = function(obj, target) {
var _obj, div, doc, j, len, multiple, views;
multiple = _.isArray(obj);
doc = new Document();
if (!multiple) {
doc.add_root(obj);
} else {
for (j = 0, len = obj.length; j < len; j++) {
_obj = obj[j];
doc.add_root(_obj);
}
}
div = $("<div class=" + BOKEH_ROOT + ">");
$(target != null ? target : "body").append(div);
views = embed.add_document_standalone(doc, div);
if (!multiple) {
return views[obj.id];
} else {
return views;
}
};
color = function(r, g, b) {
return sprintf("#%02x%02x%02x", r, g, b);
};
gridplot = function(children, options) {
var grid, item, j, k, l, layout, len, len1, len2, neighbor, row, row_children, row_tools, rows, sizing_mode, toolbar, toolbar_location, toolbar_sizing_mode, tools;
if (options == null) {
options = {};
}
toolbar_location = _.isUndefined(options.toolbar_location) ? 'above' : options.toolbar_location;
sizing_mode = _.isUndefined(options.sizing_mode) ? 'fixed' : options.sizing_mode;
toolbar_sizing_mode = options.sizing_mode === 'fixed' ? 'scale_width' : sizing_mode;
tools = [];
rows = [];
for (j = 0, len = children.length; j < len; j++) {
row = children[j];
row_tools = [];
row_children = [];
for (k = 0, len1 = row.length; k < len1; k++) {
item = row[k];
if (item instanceof models.Plot) {
row_tools = row_tools.concat(item.toolbar.tools);
item.toolbar_location = null;
}
if (item === null) {
for (l = 0, len2 = row.length; l < len2; l++) {
neighbor = row[l];
if (neighbor instanceof models.Plot) {
break;
}
}
item = new models.Spacer({
width: neighbor.plot_width,
height: neighbor.plot_height
});
}
if (item instanceof models.LayoutDOM) {
item.sizing_mode = sizing_mode;
row_children.push(item);
} else {
throw new Error("only LayoutDOM items can be inserted into Grid");
}
}
tools = tools.concat(row_tools);
row = new models.Row({
children: row_children,
sizing_mode: sizing_mode
});
rows.push(row);
}
grid = new models.Column({
children: rows,
sizing_mode: sizing_mode
});
layout = (function() {
if (toolbar_location) {
toolbar = new models.ToolbarBox({
tools: tools,
sizing_mode: toolbar_sizing_mode,
toolbar_location: toolbar_location
});
switch (toolbar_location) {
case 'above':
return new models.Column({
children: [toolbar, grid],
sizing_mode: sizing_mode
});
case 'below':
return new models.Column({
children: [grid, toolbar],
sizing_mode: sizing_mode
});
case 'left':
return new models.Row({
children: [toolbar, grid],
sizing_mode: sizing_mode
});
case 'right':
return new models.Row({
children: [grid, toolbar],
sizing_mode: sizing_mode
});
}
} else {
return grid;
}
})();
return layout;
};
module.exports = {
Figure: Figure,
figure: figure,
show: show,
color: color,
gridplot: gridplot
};

View File

@ -0,0 +1,97 @@
var Models, _, _get_mod_cache, _mod_cache, index, locations, logger, make_cache, overrides,
hasProp = {}.hasOwnProperty;
_ = require("underscore");
logger = require("./core/logging").logger;
require("./core/util/underscore").patch();
locations = require("./common/models");
overrides = {};
make_cache = function(locations) {
var mod, modname, name, ref, result, spec, subname, subspec, suffix;
result = {};
for (name in locations) {
spec = locations[name];
if (_.isArray(spec)) {
subspec = spec[0];
suffix = (ref = spec[1]) != null ? ref : "";
for (subname in subspec) {
mod = subspec[subname];
modname = subname + suffix;
result[modname] = mod;
}
} else {
result[name] = spec;
}
}
return result;
};
_mod_cache = null;
_get_mod_cache = function() {
if (_mod_cache == null) {
_mod_cache = make_cache(locations);
}
return _mod_cache;
};
Models = function(typename) {
var mod, mod_cache;
mod_cache = _get_mod_cache();
if (overrides[typename]) {
return overrides[typename];
}
mod = mod_cache[typename];
if (mod == null) {
throw new Error("Module `" + typename + "' does not exists. The problem may be two fold. Either a model was requested that's available in an extra bundle, e.g. a widget, or a custom model was requested, but it wasn't registered before first usage.");
}
return mod.Model;
};
Models.register = function(name, model) {
return overrides[name] = model;
};
Models.unregister = function(name) {
return delete overrides[name];
};
Models.register_locations = function(locations, force, errorFn) {
var cache, mod_cache, module, name, results;
if (force == null) {
force = false;
}
if (errorFn == null) {
errorFn = null;
}
mod_cache = _get_mod_cache();
cache = make_cache(locations);
results = [];
for (name in cache) {
if (!hasProp.call(cache, name)) continue;
module = cache[name];
if (force || !mod_cache.hasOwnProperty(name)) {
results.push(mod_cache[name] = module);
} else {
results.push(typeof errorFn === "function" ? errorFn(name) : void 0);
}
}
return results;
};
Models.registered_names = function() {
return Object.keys(_get_mod_cache());
};
index = {};
module.exports = {
overrides: overrides,
index: index,
Models: Models
};

View File

@ -0,0 +1,605 @@
var ClientConnection, ClientSession, DEFAULT_SERVER_WEBSOCKET_URL, DEFAULT_SESSION_ID, Document, HasProps, Message, ModelChangedEvent, Promise, RootAddedEvent, RootRemovedEvent, _, logger, message_handlers, pull_session, ref;
_ = require("underscore");
Promise = require("es6-promise").Promise;
HasProps = require("./core/has_props");
logger = require("./core/logging").logger;
ref = require("./document"), Document = ref.Document, ModelChangedEvent = ref.ModelChangedEvent, RootAddedEvent = ref.RootAddedEvent, RootRemovedEvent = ref.RootRemovedEvent;
DEFAULT_SERVER_WEBSOCKET_URL = "ws://localhost:5006/ws";
DEFAULT_SESSION_ID = "default";
Message = (function() {
function Message(header1, metadata1, content1) {
this.header = header1;
this.metadata = metadata1;
this.content = content1;
this.buffers = [];
}
Message.assemble = function(header_json, metadata_json, content_json) {
var content, e, error1, header, metadata;
try {
header = JSON.parse(header_json);
metadata = JSON.parse(metadata_json);
content = JSON.parse(content_json);
return new Message(header, metadata, content);
} catch (error1) {
e = error1;
logger.error("Failure parsing json " + e + " " + header_json + " " + metadata_json + " " + content_json, e);
throw e;
}
};
Message.create_header = function(msgtype, options) {
var header;
header = {
'msgid': _.uniqueId(),
'msgtype': msgtype
};
return _.extend(header, options);
};
Message.create = function(msgtype, header_options, content) {
var header;
if (content == null) {
content = {};
}
header = Message.create_header(msgtype, header_options);
return new Message(header, {}, content);
};
Message.prototype.send = function(socket) {
var content_json, e, error1, header_json, metadata_json;
try {
header_json = JSON.stringify(this.header);
metadata_json = JSON.stringify(this.metadata);
content_json = JSON.stringify(this.content);
socket.send(header_json);
socket.send(metadata_json);
return socket.send(content_json);
} catch (error1) {
e = error1;
logger.error("Error sending ", this, e);
throw e;
}
};
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.add_buffer = function(buffer) {
return this.buffers.push(buffer);
};
Message.prototype._header_field = function(field) {
if (field in this.header) {
return this.header[field];
} else {
return null;
}
};
Message.prototype.msgid = function() {
return this._header_field('msgid');
};
Message.prototype.msgtype = function() {
return this._header_field('msgtype');
};
Message.prototype.sessid = function() {
return this._header_field('sessid');
};
Message.prototype.reqid = function() {
return this._header_field('reqid');
};
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;
})();
message_handlers = {
'PATCH-DOC': function(connection, message) {
return connection._for_session(function(session) {
return session._handle_patch(message);
});
},
'OK': function(connection, message) {
return logger.debug("Unhandled OK reply to " + (message.reqid()));
},
'ERROR': function(connection, message) {
return logger.error("Unhandled ERROR reply to " + (message.reqid()) + ": " + message.content['text']);
}
};
ClientConnection = (function() {
ClientConnection._connection_count = 0;
function ClientConnection(url1, id, _on_have_session_hook, _on_closed_permanently_hook) {
this.url = url1;
this.id = id;
this._on_have_session_hook = _on_have_session_hook;
this._on_closed_permanently_hook = _on_closed_permanently_hook;
this._number = ClientConnection._connection_count;
ClientConnection._connection_count = this._number + 1;
if (this.url == null) {
this.url = DEFAULT_SERVER_WEBSOCKET_URL;
}
if (this.id == null) {
this.id = DEFAULT_SESSION_ID;
}
logger.debug("Creating websocket " + this._number + " to '" + this.url + "' session '" + this.id + "'");
this.socket = null;
this.closed_permanently = false;
this._fragments = [];
this._partial = null;
this._current_handler = null;
this._pending_ack = null;
this._pending_replies = {};
this.session = null;
}
ClientConnection.prototype._for_session = function(f) {
if (this.session !== null) {
return f(this.session);
}
};
ClientConnection.prototype.connect = function() {
var error, error1, versioned_url;
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._fragments = [];
this._partial = null;
this._pending_replies = {};
this._current_handler = null;
try {
versioned_url = this.url + "?bokeh-protocol-version=1.0&bokeh-session-id=" + this.id;
if (window.MozWebSocket != null) {
this.socket = new MozWebSocket(versioned_url);
} else {
this.socket = new WebSocket(versioned_url);
}
return new Promise((function(_this) {
return function(resolve, reject) {
_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);
};
return _this.socket.onerror = function() {
return _this._on_error(reject);
};
};
})(this));
} catch (error1) {
error = error1;
logger.error("websocket creation failed to url: " + this.url);
logger.error(" - " + error);
return Promise.reject(error);
}
};
ClientConnection.prototype.close = function() {
if (!this.closed_permanently) {
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._for_session(function(session) {
return session._connection_closed();
});
if (this._on_closed_permanently_hook != null) {
this._on_closed_permanently_hook();
return this._on_closed_permanently_hook = null;
}
}
};
ClientConnection.prototype._schedule_reconnect = function(milliseconds) {
var retry;
retry = (function(_this) {
return function() {
if (true || _this.closed_permanently) {
if (!_this.closed_permanently) {
logger.info("Websocket connection " + _this._number + " disconnected, will not attempt to reconnect");
}
} else {
logger.debug("Attempting to reconnect websocket " + _this._number);
return _this.connect();
}
};
})(this);
return setTimeout(retry, milliseconds);
};
ClientConnection.prototype.send = function(message) {
var e, error1;
try {
if (this.socket === null) {
throw new Error("not connected so cannot send " + message);
}
return message.send(this.socket);
} catch (error1) {
e = error1;
return logger.error("Error sending message ", e, message);
}
};
ClientConnection.prototype.send_with_reply = function(message) {
var promise;
promise = new Promise((function(_this) {
return function(resolve, reject) {
_this._pending_replies[message.msgid()] = [resolve, reject];
return _this.send(message);
};
})(this));
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, promise;
message = Message.create('PULL-DOC-REQ', {});
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() {
if (this.session === null) {
logger.debug("Pulling session for first time");
} else {
logger.debug("Repulling session");
}
return this._pull_doc_json().then((function(_this) {
return function(doc_json) {
var document, patch, patch_message;
if (_this.session === null) {
if (_this.closed_permanently) {
return logger.debug("Got new document after connection was already closed");
} else {
document = Document.from_json(doc_json);
patch = Document._compute_patch_since_json(doc_json, document);
if (patch.events.length > 0) {
logger.debug("Sending " + patch.events.length + " changes from model construction back to server");
patch_message = Message.create('PATCH-DOC', {}, patch);
_this.send(patch_message);
}
_this.session = new ClientSession(_this, document, _this.id);
logger.debug("Created a new session from new pulled doc");
if (_this._on_have_session_hook != null) {
_this._on_have_session_hook(_this.session);
return _this._on_have_session_hook = null;
}
}
} else {
_this.session.document.replace_with_json(doc_json);
return logger.debug("Updated existing session with new pulled doc");
}
};
})(this), function(error) {
throw error;
})["catch"](function(error) {
if (console.trace != null) {
console.trace(error);
}
return logger.error("Failed to repull session " + error);
});
};
ClientConnection.prototype._on_open = function(resolve, reject) {
logger.info("Websocket connection " + this._number + " is now open");
this._pending_ack = [resolve, reject];
return this._current_handler = (function(_this) {
return function(message) {
return _this._awaiting_ack_handler(message);
};
})(this);
};
ClientConnection.prototype._on_message = function(event) {
var e, error1;
try {
return this._on_message_unchecked(event);
} catch (error1) {
e = error1;
return logger.error("Error handling message: " + e + ", " + event);
}
};
ClientConnection.prototype._on_message_unchecked = function(event) {
var msg, problem;
if (this._current_handler == null) {
logger.error("got a message but haven't set _current_handler");
}
if (event.data instanceof ArrayBuffer) {
if ((this._partial != null) && !this._partial.complete()) {
this._partial.add_buffer(event.data);
} else {
this._close_bad_protocol("Got binary from websocket but we were expecting text");
}
} else if (this._partial != null) {
this._close_bad_protocol("Got text from websocket but we were expecting binary");
} else {
this._fragments.push(event.data);
if (this._fragments.length === 3) {
this._partial = Message.assemble(this._fragments[0], this._fragments[1], this._fragments[2]);
this._fragments = [];
problem = this._partial.problem();
if (problem !== null) {
this._close_bad_protocol(problem);
}
}
}
if ((this._partial != null) && this._partial.complete()) {
msg = this._partial;
this._partial = null;
return this._current_handler(msg);
}
};
ClientConnection.prototype._on_close = function(event) {
var pop_pending, promise_funcs;
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;
}
pop_pending = function() {
var promise_funcs, ref1, reqid;
ref1 = this._pending_replies;
for (reqid in ref1) {
promise_funcs = ref1[reqid];
delete this._pending_replies[reqid];
return promise_funcs;
}
return null;
};
promise_funcs = pop_pending();
while (promise_funcs !== null) {
promise_funcs[1]("Disconnected");
promise_funcs = pop_pending();
}
if (!this.closed_permanently) {
return this._schedule_reconnect(2000);
}
};
ClientConnection.prototype._on_error = function(reject) {
logger.debug("Websocket error on socket " + this._number);
return reject(new Error("Could not open websocket"));
};
ClientConnection.prototype._close_bad_protocol = function(detail) {
logger.error("Closing connection: " + detail);
if (this.socket != null) {
return this.socket.close(1002, detail);
}
};
ClientConnection.prototype._awaiting_ack_handler = function(message) {
if (message.msgtype() === "ACK") {
this._current_handler = (function(_this) {
return function(message) {
return _this._steady_state_handler(message);
};
})(this);
this._repull_session_doc();
if (this._pending_ack != null) {
this._pending_ack[0](this);
return this._pending_ack = null;
}
} else {
return this._close_bad_protocol("First message was not an ACK");
}
};
ClientConnection.prototype._steady_state_handler = function(message) {
var promise_funcs;
if (message.reqid() in this._pending_replies) {
promise_funcs = this._pending_replies[message.reqid()];
delete this._pending_replies[message.reqid()];
return promise_funcs[0](message);
} else if (message.msgtype() in message_handlers) {
return message_handlers[message.msgtype()](this, message);
} else {
return logger.debug("Doing nothing with message " + (message.msgtype()));
}
};
return ClientConnection;
})();
ClientSession = (function() {
function ClientSession(_connection, document1, id) {
this._connection = _connection;
this.document = document1;
this.id = id;
this._current_patch = null;
this.document_listener = (function(_this) {
return function(event) {
return _this._document_changed(event);
};
})(this);
this.document.on_change(this.document_listener);
}
ClientSession.prototype.close = function() {
return this._connection.close();
};
ClientSession.prototype._connection_closed = function() {
return this.document.remove_on_change(this.document_listener);
};
ClientSession.prototype.request_server_info = function() {
var message, promise;
message = Message.create('SERVER-INFO-REQ', {});
promise = this._connection.send_with_reply(message);
return promise.then(function(reply) {
return reply.content;
});
};
ClientSession.prototype.force_roundtrip = function() {
return this.request_server_info().then(function(ignored) {
return void 0;
});
};
ClientSession.prototype._should_suppress_on_change = function(patch, event) {
var event_json, i, j, k, l, len, len1, len2, len3, patch_new, ref1, ref2, ref3, ref4;
if (event instanceof ModelChangedEvent) {
ref1 = patch.content['events'];
for (i = 0, len = ref1.length; i < len; i++) {
event_json = ref1[i];
if (event_json['kind'] === 'ModelChanged' && event_json['model']['id'] === event.model.id && event_json['attr'] === event.attr) {
patch_new = event_json['new'];
if (event.new_ instanceof HasProps) {
if (typeof patch_new === 'object' && 'id' in patch_new && patch_new['id'] === event.new_.id) {
return true;
}
} else if (_.isEqual(patch_new, event.new_)) {
return true;
}
}
}
} else if (event instanceof RootAddedEvent) {
ref2 = patch.content['events'];
for (j = 0, len1 = ref2.length; j < len1; j++) {
event_json = ref2[j];
if (event_json['kind'] === 'RootAdded' && event_json['model']['id'] === event.model.id) {
return true;
}
}
} else if (event instanceof RootRemovedEvent) {
ref3 = patch.content['events'];
for (k = 0, len2 = ref3.length; k < len2; k++) {
event_json = ref3[k];
if (event_json['kind'] === 'RootRemoved' && event_json['model']['id'] === event.model.id) {
return true;
}
}
} else if (event instanceof TitleChangedEvent) {
ref4 = patch.content['events'];
for (l = 0, len3 = ref4.length; l < len3; l++) {
event_json = ref4[l];
if (event_json['kind'] === 'TitleChanged' && event_json['title'] === event.title) {
return true;
}
}
}
return false;
};
ClientSession.prototype._document_changed = function(event) {
var patch;
if ((this._current_patch != null) && this._should_suppress_on_change(this._current_patch, event)) {
return;
}
if (event instanceof ModelChangedEvent && !(event.attr in event.model.serializable_attributes())) {
return;
}
patch = Message.create('PATCH-DOC', {}, this.document.create_json_patch([event]));
return this._connection.send(patch);
};
ClientSession.prototype._handle_patch = function(message) {
this._current_patch = message;
try {
return this.document.apply_json_patch(message.content);
} finally {
this._current_patch = null;
}
};
return ClientSession;
})();
pull_session = function(url, session_id) {
var connection, promise, rejecter;
rejecter = null;
connection = null;
promise = new Promise(function(resolve, reject) {
connection = new ClientConnection(url, session_id, function(session) {
var e, error1;
try {
return resolve(session);
} catch (error1) {
e = error1;
logger.error("Promise handler threw an error, closing session " + error);
session.close();
throw e;
}
}, function() {
return reject(new Error("Connection was closed before we successfully pulled a session"));
});
return connection.connect().then(function(whatever) {}, function(error) {
logger.error("Failed to connect to Bokeh server " + error);
throw error;
});
});
promise.close = function() {
return connection.close();
};
return promise;
};
module.exports = {
pull_session: pull_session,
DEFAULT_SERVER_WEBSOCKET_URL: DEFAULT_SERVER_WEBSOCKET_URL,
DEFAULT_SESSION_ID: DEFAULT_SESSION_ID
};

View File

@ -0,0 +1,57 @@
var _, build_views, jQueryUIPrefixer;
_ = require("underscore");
build_views = function(view_storage, view_models, options, view_types) {
var created_views, i, i_model, j, key, len, len1, model, newmodels, to_remove, view_specific_option;
if (view_types == null) {
view_types = [];
}
created_views = [];
newmodels = _.filter(view_models, function(x) {
return !_.has(view_storage, x.id);
});
for (i_model = i = 0, len = newmodels.length; i < len; i_model = ++i) {
model = newmodels[i_model];
view_specific_option = _.extend({}, options, {
'model': model
});
if (i_model < view_types.length) {
view_storage[model.id] = new view_types[i_model](view_specific_option);
} else {
view_storage[model.id] = new model.default_view(view_specific_option);
}
view_storage[model.id].$el.find("*[class*='ui-']").each(function(idx, el) {
return el.className = jQueryUIPrefixer(el);
});
created_views.push(view_storage[model.id]);
}
to_remove = _.difference(_.keys(view_storage), _.pluck(view_models, 'id'));
for (j = 0, len1 = to_remove.length; j < len1; j++) {
key = to_remove[j];
view_storage[key].remove();
delete view_storage[key];
}
return created_views;
};
jQueryUIPrefixer = function(el) {
var classList, prefixedClassList;
if (el.className == null) {
return;
}
classList = el.className.split(" ");
prefixedClassList = _.map(classList, function(a) {
a = a.trim();
if (a.indexOf("ui-") === 0) {
return "bk-" + a;
} else {
return a;
}
});
return prefixedClassList.join(" ");
};
build_views.jQueryUIPrefixer = jQueryUIPrefixer;
module.exports = build_views = build_views;

View File

@ -0,0 +1,156 @@
var HitTestResult, check_2_segments_intersect, create_hit_test_result, dist_2_pts, dist_to_segment, dist_to_segment_squared, nullreturner, point_in_poly, sqr, validate_bbox_coords;
point_in_poly = function(x, y, px, py) {
var i, inside, j, ref, x1, x2, y1, y2;
inside = false;
x1 = px[px.length - 1];
y1 = py[py.length - 1];
for (i = j = 0, ref = px.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
x2 = px[i];
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;
};
nullreturner = function() {
return null;
};
HitTestResult = (function() {
function HitTestResult() {
this['0d'] = {
glyph: null,
get_view: nullreturner,
indices: []
};
this['1d'] = {
indices: []
};
this['2d'] = {};
}
Object.defineProperty(HitTestResult.prototype, '_0d', {
get: function() {
return this['0d'];
}
});
Object.defineProperty(HitTestResult.prototype, '_1d', {
get: function() {
return this['1d'];
}
});
Object.defineProperty(HitTestResult.prototype, '_2d', {
get: function() {
return this['2d'];
}
});
HitTestResult.prototype.is_empty = function() {
return this._0d.indices.length === 0 && this._1d.indices.length === 0;
};
return HitTestResult;
})();
create_hit_test_result = function() {
return new HitTestResult();
};
validate_bbox_coords = function(arg, arg1) {
var ref, ref1, x0, x1, y0, y1;
x0 = arg[0], x1 = arg[1];
y0 = arg1[0], y1 = arg1[1];
if (x0 > x1) {
ref = [x1, x0], x0 = ref[0], x1 = ref[1];
}
if (y0 > y1) {
ref1 = [y1, y0], y0 = ref1[0], y1 = ref1[1];
}
return {
minX: x0,
minY: y0,
maxX: x1,
maxY: y1
};
};
sqr = function(x) {
return x * x;
};
dist_2_pts = function(vx, vy, wx, wy) {
return sqr(vx - wx) + sqr(vy - wy);
};
dist_to_segment_squared = function(p, v, w) {
var l2, t;
l2 = dist_2_pts(v.x, v.y, w.x, w.y);
if (l2 === 0) {
return dist_2_pts(p.x, p.y, v.x, v.y);
}
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.x, p.y, v.x, v.y);
}
if (t > 1) {
return dist_2_pts(p.x, p.y, w.x, w.y);
}
return dist_2_pts(p.x, p.y, v.x + t * (w.x - v.x), v.y + t * (w.y - v.y));
};
dist_to_segment = function(p, v, w) {
return Math.sqrt(dist_to_segment_squared(p, v, w));
};
check_2_segments_intersect = function(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 a, b, den, num1, num2, x, y;
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 {
a = l0_y0 - l1_y0;
b = l0_x0 - l1_x0;
num1 = ((l1_x1 - l1_x0) * a) - ((l1_y1 - l1_y0) * b);
num2 = ((l0_x1 - l0_x0) * a) - ((l0_y1 - l0_y0) * b);
a = num1 / den;
b = num2 / den;
x = l0_x0 + (a * (l0_x1 - l0_x0));
y = l0_y0 + (a * (l0_y1 - l0_y0));
return {
hit: (a > 0 && a < 1) && (b > 0 && b < 1),
x: x,
y: y
};
}
};
module.exports = {
point_in_poly: point_in_poly,
HitTestResult: HitTestResult,
create_hit_test_result: create_hit_test_result,
dist_2_pts: dist_2_pts,
dist_to_segment: dist_to_segment,
check_2_segments_intersect: check_2_segments_intersect,
validate_bbox_coords: validate_bbox_coords
};

View File

@ -0,0 +1,136 @@
module.exports = {
SelectionManager: require('./selection_manager'),
Selector: require('./selector'),
ToolEvents: require('./tool_events'),
Arrow: require('../models/annotations/arrow'),
BoxAnnotation: require('../models/annotations/box_annotation'),
ColorBar: require('../models/annotations/color_bar'),
Label: require('../models/annotations/label'),
LabelSet: require('../models/annotations/label_set'),
Legend: require('../models/annotations/legend'),
PolyAnnotation: require('../models/annotations/poly_annotation'),
Span: require('../models/annotations/span'),
Title: require('../models/annotations/title'),
Tooltip: require('../models/annotations/tooltip'),
OpenHead: require('../models/annotations/arrow_head').OpenHead,
NormalHead: require('../models/annotations/arrow_head').NormalHead,
VeeHead: require('../models/annotations/arrow_head').VeeHead,
CategoricalAxis: require('../models/axes/categorical_axis'),
DatetimeAxis: require('../models/axes/datetime_axis'),
LinearAxis: require('../models/axes/linear_axis'),
LogAxis: require('../models/axes/log_axis'),
CustomJS: require('../models/callbacks/customjs'),
OpenURL: require('../models/callbacks/open_url'),
Canvas: require('../models/canvas/canvas'),
CartesianFrame: require('../models/canvas/cartesian_frame'),
BasicTickFormatter: require('../models/formatters/basic_tick_formatter'),
CategoricalTickFormatter: require('../models/formatters/categorical_tick_formatter'),
DatetimeTickFormatter: require('../models/formatters/datetime_tick_formatter'),
LogTickFormatter: require('../models/formatters/log_tick_formatter'),
FuncTickFormatter: require('../models/formatters/func_tick_formatter'),
NumeralTickFormatter: require('../models/formatters/numeral_tick_formatter'),
PrintfTickFormatter: require('../models/formatters/printf_tick_formatter'),
AnnularWedge: require('../models/glyphs/annular_wedge'),
Annulus: require('../models/glyphs/annulus'),
Arc: require('../models/glyphs/arc'),
Bezier: require('../models/glyphs/bezier'),
Circle: require('../models/glyphs/circle'),
Ellipse: require('../models/glyphs/ellipse'),
Gear: require('../models/glyphs/gear'),
HBar: require('../models/glyphs/hbar'),
Image: require('../models/glyphs/image'),
ImageRGBA: require('../models/glyphs/image_rgba'),
ImageURL: require('../models/glyphs/image_url'),
Line: require('../models/glyphs/line'),
MultiLine: require('../models/glyphs/multi_line'),
Oval: require('../models/glyphs/oval'),
Patch: require('../models/glyphs/patch'),
Patches: require('../models/glyphs/patches'),
Quad: require('../models/glyphs/quad'),
Quadratic: require('../models/glyphs/quadratic'),
Ray: require('../models/glyphs/ray'),
Rect: require('../models/glyphs/rect'),
Segment: require('../models/glyphs/segment'),
Text: require('../models/glyphs/text'),
VBar: require('../models/glyphs/vbar'),
Wedge: require('../models/glyphs/wedge'),
Grid: require('../models/grids/grid'),
Column: require('../models/layouts/column'),
Row: require('../models/layouts/row'),
Spacer: require('../models/layouts/spacer'),
WidgetBox: require('../models/layouts/widget_box'),
CategoricalMapper: require('../models/mappers/categorical_mapper'),
GridMapper: require('../models/mappers/grid_mapper'),
LinearColorMapper: require('../models/mappers/linear_color_mapper'),
LinearMapper: require('../models/mappers/linear_mapper'),
LogColorMapper: require('../models/mappers/log_color_mapper'),
LogMapper: require('../models/mappers/log_mapper'),
Transform: require('../models/transforms/transform'),
Jitter: require('../models/transforms/jitter'),
Interpolator: require('../models/transforms/interpolator'),
LinearInterpolator: require('../models/transforms/linear_interpolator'),
StepInterpolator: require('../models/transforms/step_interpolator'),
Asterisk: require('../models/markers/index').Asterisk,
CircleCross: require('../models/markers/index').CircleCross,
CircleX: require('../models/markers/index').CircleX,
Cross: require('../models/markers/index').Cross,
Diamond: require('../models/markers/index').Diamond,
DiamondCross: require('../models/markers/index').DiamondCross,
InvertedTriangle: require('../models/markers/index').InvertedTriangle,
Square: require('../models/markers/index').Square,
SquareCross: require('../models/markers/index').SquareCross,
SquareX: require('../models/markers/index').SquareX,
Triangle: require('../models/markers/index').Triangle,
X: require('../models/markers/index').X,
Plot: require('../models/plots/plot'),
GMapPlot: require('../models/plots/gmap_plot'),
DataRange1d: require('../models/ranges/data_range1d'),
FactorRange: require('../models/ranges/factor_range'),
Range1d: require('../models/ranges/range1d'),
GlyphRenderer: require('../models/renderers/glyph_renderer'),
AjaxDataSource: require('../models/sources/ajax_data_source'),
ColumnDataSource: require('../models/sources/column_data_source'),
GeoJSONDataSource: require('../models/sources/geojson_data_source'),
AdaptiveTicker: require('../models/tickers/adaptive_ticker'),
BasicTicker: require('../models/tickers/basic_ticker'),
CategoricalTicker: require('../models/tickers/categorical_ticker'),
CompositeTicker: require('../models/tickers/composite_ticker'),
ContinuousTicker: require('../models/tickers/continuous_ticker'),
DatetimeTicker: require('../models/tickers/datetime_ticker'),
DaysTicker: require('../models/tickers/days_ticker'),
FixedTicker: require('../models/tickers/fixed_ticker'),
LogTicker: require('../models/tickers/log_ticker'),
MonthsTicker: require('../models/tickers/months_ticker'),
SingleIntervalTicker: require('../models/tickers/single_interval_ticker'),
YearsTicker: require('../models/tickers/years_ticker'),
TileRenderer: require('../models/tiles/tile_renderer'),
TileSource: require('../models/tiles/tile_source'),
TMSTileSource: require('../models/tiles/tms_tile_source'),
WMTSTileSource: require('../models/tiles/wmts_tile_source'),
QUADKEYTileSource: require('../models/tiles/quadkey_tile_source'),
BBoxTileSource: require('../models/tiles/bbox_tile_source'),
DynamicImageRenderer: require('../models/tiles/dynamic_image_renderer'),
ImageSource: require('../models/tiles/image_source'),
Toolbar: require('../models/tools/toolbar'),
ToolbarBox: require('../models/tools/toolbar_box'),
ButtonTool: require('../models/tools/button_tool'),
ActionTool: require('../models/tools/actions/action_tool'),
SaveTool: require('../models/tools/actions/save_tool'),
UndoTool: require('../models/tools/actions/undo_tool'),
RedoTool: require('../models/tools/actions/redo_tool'),
ResetTool: require('../models/tools/actions/reset_tool'),
HelpTool: require('../models/tools/actions/help_tool'),
BoxSelectTool: require('../models/tools/gestures/box_select_tool'),
BoxZoomTool: require('../models/tools/gestures/box_zoom_tool'),
GestureTool: require('../models/tools/gestures/gesture_tool'),
LassoSelectTool: require('../models/tools/gestures/lasso_select_tool'),
PanTool: require('../models/tools/gestures/pan_tool'),
PolySelectTool: require('../models/tools/gestures/poly_select_tool'),
SelectTool: require('../models/tools/gestures/select_tool'),
ResizeTool: require('../models/tools/gestures/resize_tool'),
TapTool: require('../models/tools/gestures/tap_tool'),
WheelZoomTool: require('../models/tools/gestures/wheel_zoom_tool'),
CrosshairTool: require('../models/tools/inspectors/crosshair_tool'),
HoverTool: require('../models/tools/inspectors/hover_tool'),
InspectTool: require('../models/tools/inspectors/inspect_tool')
};

View File

@ -0,0 +1,128 @@
var HasProps, SelectionManager, Selector, _, hittest, logger, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
HasProps = require("../core/has_props");
logger = require("../core/logging").logger;
Selector = require("./selector");
hittest = require("./hittest");
p = require("../core/properties");
SelectionManager = (function(superClass) {
extend(SelectionManager, superClass);
function SelectionManager() {
return SelectionManager.__super__.constructor.apply(this, arguments);
}
SelectionManager.prototype.type = 'SelectionManager';
SelectionManager.internal({
source: [p.Any]
});
SelectionManager.prototype.initialize = function(attrs, options) {
SelectionManager.__super__.initialize.call(this, attrs, options);
this.selectors = {};
this.inspectors = {};
return this.last_inspection_was_empty = {};
};
SelectionManager.prototype.select = function(tool, renderer_view, geometry, final, append) {
var indices, selector, source;
if (append == null) {
append = false;
}
source = this.get('source');
if (source !== renderer_view.mget('data_source')) {
logger.warn('select called with mis-matched data sources');
}
indices = renderer_view.hit_test(geometry);
if (indices != null) {
selector = this._get_selector(renderer_view);
selector.update(indices, final, append);
this.get('source').set({
"selected": selector.get('indices')
});
source.trigger('select');
source.trigger('select-' + renderer_view.mget('id'));
return !indices.is_empty();
} else {
return false;
}
};
SelectionManager.prototype.inspect = function(tool, renderer_view, geometry, data) {
var indices, inspector, r_id, source;
source = this.get('source');
if (source !== renderer_view.mget('data_source')) {
logger.warn('inspect called with mis-matched data sources');
}
indices = renderer_view.hit_test(geometry);
if (indices != null) {
r_id = renderer_view.model.id;
if (indices.is_empty()) {
if (this.last_inspection_was_empty[r_id] == null) {
this.last_inspection_was_empty[r_id] = false;
}
if (this.last_inspection_was_empty[r_id]) {
return;
} else {
this.last_inspection_was_empty[r_id] = true;
}
} else {
this.last_inspection_was_empty[r_id] = false;
}
inspector = this._get_inspector(renderer_view);
inspector.update(indices, true, false, true);
this.get('source').set({
"inspected": inspector.get('indices')
}, {
"silent": true
});
source.trigger('inspect', indices, tool, renderer_view, source, data);
source.trigger("inspect" + (renderer_view.mget('id')), indices, tool, renderer_view, source, data);
return !indices.is_empty();
} else {
return false;
}
};
SelectionManager.prototype.clear = function(rview) {
var k, ref, s, selector;
if (rview != null) {
selector = this._get_selector(rview);
selector.clear();
} else {
ref = this.selectors;
for (k in ref) {
s = ref[k];
s.clear();
}
}
return this.get('source').set({
"selected": hittest.create_hit_test_result()
});
};
SelectionManager.prototype._get_selector = function(rview) {
_.setdefault(this.selectors, rview.model.id, new Selector());
return this.selectors[rview.model.id];
};
SelectionManager.prototype._get_inspector = function(rview) {
_.setdefault(this.inspectors, rview.model.id, new Selector());
return this.inspectors[rview.model.id];
};
return SelectionManager;
})(HasProps);
module.exports = SelectionManager;

View File

@ -0,0 +1,65 @@
var HasProps, Selector, _, hittest, logger, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
HasProps = require("../core/has_props");
hittest = require("./hittest");
logger = require("../core/logging").logger;
p = require("../core/properties");
Selector = (function(superClass) {
extend(Selector, superClass);
function Selector() {
return Selector.__super__.constructor.apply(this, arguments);
}
Selector.prototype.type = 'Selector';
Selector.prototype.update = function(indices, final, append, silent) {
if (silent == null) {
silent = false;
}
this.set('timestamp', new Date(), {
silent: silent
});
this.set('final', final, {
silent: silent
});
if (append) {
indices['0d'].indices = _.union(this.get('indices')['0d'].indices, indices['0d'].indices);
indices['0d'].glyph = this.get('indices')['0d'].glyph || indices['0d'].glyph;
indices['1d'].indices = _.union(this.get('indices')['1d'].indices, indices['1d'].indices);
indices['2d'].indices = _.union(this.get('indices')['2d'].indices, indices['2d'].indices);
}
return this.set('indices', indices, {
silent: silent
});
};
Selector.prototype.clear = function() {
this.set('timestamp', new Date());
this.set('final', true);
return this.set('indices', hittest.create_hit_test_result());
};
Selector.internal({
indices: [
p.Any, function() {
return hittest.create_hit_test_result();
}
],
final: [p.Boolean],
timestamp: [p.Any]
});
return Selector;
})(HasProps);
module.exports = Selector;

View File

@ -0,0 +1,32 @@
var Model, ToolEvents, _, logger, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Model = require("../model");
logger = require("../core/logging").logger;
p = require("../core/properties");
ToolEvents = (function(superClass) {
extend(ToolEvents, superClass);
function ToolEvents() {
return ToolEvents.__super__.constructor.apply(this, arguments);
}
ToolEvents.prototype.type = 'ToolEvents';
ToolEvents.define({
geometries: [p.Array, []]
});
return ToolEvents;
})(Model);
module.exports = {
Model: ToolEvents
};

View File

@ -0,0 +1,338 @@
var $, Backbone, Hammer, UIEvents, logger, mousewheel,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
$ = require("jquery");
Backbone = require("backbone");
Hammer = require("hammerjs");
mousewheel = require("jquery-mousewheel")($);
logger = require("../core/logging").logger;
UIEvents = (function(superClass) {
extend(UIEvents, superClass);
function UIEvents() {
return UIEvents.__super__.constructor.apply(this, arguments);
}
UIEvents.prototype.initialize = function(attrs, options) {
UIEvents.__super__.initialize.call(this, attrs, options);
return this._hammer_element();
};
UIEvents.prototype._hammer_element = function() {
var hit_area;
hit_area = this.get('hit_area');
this.hammer = new Hammer(hit_area[0]);
this.hammer.get('doubletap').recognizeWith('tap');
this.hammer.get('tap').requireFailure('doubletap');
this.hammer.get('doubletap').dropRequireFailure('tap');
this.hammer.on('doubletap', (function(_this) {
return function(e) {
return _this._doubletap(e);
};
})(this));
this.hammer.on('tap', (function(_this) {
return function(e) {
return _this._tap(e);
};
})(this));
this.hammer.on('press', (function(_this) {
return function(e) {
return _this._press(e);
};
})(this));
this.hammer.get('pan').set({
direction: Hammer.DIRECTION_ALL
});
this.hammer.on('panstart', (function(_this) {
return function(e) {
return _this._pan_start(e);
};
})(this));
this.hammer.on('pan', (function(_this) {
return function(e) {
return _this._pan(e);
};
})(this));
this.hammer.on('panend', (function(_this) {
return function(e) {
return _this._pan_end(e);
};
})(this));
this.hammer.get('pinch').set({
enable: true
});
this.hammer.on('pinchstart', (function(_this) {
return function(e) {
return _this._pinch_start(e);
};
})(this));
this.hammer.on('pinch', (function(_this) {
return function(e) {
return _this._pinch(e);
};
})(this));
this.hammer.on('pinchend', (function(_this) {
return function(e) {
return _this._pinch_end(e);
};
})(this));
this.hammer.get('rotate').set({
enable: true
});
this.hammer.on('rotatestart', (function(_this) {
return function(e) {
return _this._rotate_start(e);
};
})(this));
this.hammer.on('rotate', (function(_this) {
return function(e) {
return _this._rotate(e);
};
})(this));
this.hammer.on('rotateend', (function(_this) {
return function(e) {
return _this._rotate_end(e);
};
})(this));
hit_area.mousemove((function(_this) {
return function(e) {
return _this._mouse_move(e);
};
})(this));
hit_area.mouseenter((function(_this) {
return function(e) {
return _this._mouse_enter(e);
};
})(this));
hit_area.mouseleave((function(_this) {
return function(e) {
return _this._mouse_exit(e);
};
})(this));
hit_area.mousewheel((function(_this) {
return function(e, delta) {
return _this._mouse_wheel(e, delta);
};
})(this));
$(document).keydown((function(_this) {
return function(e) {
return _this._key_down(e);
};
})(this));
return $(document).keyup((function(_this) {
return function(e) {
return _this._key_up(e);
};
})(this));
};
UIEvents.prototype.register_tool = function(tool_view) {
var et, id, type;
et = tool_view.model.event_type;
id = tool_view.model.id;
type = tool_view.model.type;
if (et == null) {
logger.debug("Button tool: " + type);
return;
}
if (et === 'pan' || et === 'pinch' || et === 'rotate') {
logger.debug("Registering tool: " + type + " for event '" + et + "'");
if (tool_view["_" + et + "_start"] != null) {
tool_view.listenTo(this, et + ":start:" + id, tool_view["_" + et + "_start"]);
}
if (tool_view["_" + et]) {
tool_view.listenTo(this, et + ":" + id, tool_view["_" + et]);
}
if (tool_view["_" + et + "_end"]) {
tool_view.listenTo(this, et + ":end:" + id, tool_view["_" + et + "_end"]);
}
} else if (et === "move") {
logger.debug("Registering tool: " + type + " for event '" + et + "'");
if (tool_view._move_enter != null) {
tool_view.listenTo(this, "move:enter", tool_view._move_enter);
}
tool_view.listenTo(this, "move", tool_view["_move"]);
if (tool_view._move_exit != null) {
tool_view.listenTo(this, "move:exit", tool_view._move_exit);
}
} else {
logger.debug("Registering tool: " + type + " for event '" + et + "'");
tool_view.listenTo(this, et + ":" + id, tool_view["_" + et]);
}
if (tool_view._keydown != null) {
logger.debug("Registering tool: " + type + " for event 'keydown'");
tool_view.listenTo(this, "keydown", tool_view._keydown);
}
if (tool_view._keyup != null) {
logger.debug("Registering tool: " + type + " for event 'keyup'");
tool_view.listenTo(this, "keyup", tool_view._keyup);
}
if (tool_view._doubletap != null) {
logger.debug("Registering tool: " + type + " for event 'doubletap'");
tool_view.listenTo(this, "doubletap", tool_view._doubletap);
}
if ('ontouchstart' in window || navigator.maxTouchPoints > 0) {
if (et === 'pinch') {
logger.debug("Registering scroll on touch screen");
return tool_view.listenTo(this, "scroll:" + id, tool_view["_scroll"]);
}
}
};
UIEvents.prototype._trigger = function(event_type, e) {
var active_tool, base_event_type, gestures, toolbar;
toolbar = this.get('toolbar');
base_event_type = event_type.split(":")[0];
if ('ontouchstart' in window || navigator.maxTouchPoints > 0) {
if (event_type === 'scroll') {
base_event_type = 'pinch';
}
}
gestures = toolbar.get('gestures');
active_tool = gestures[base_event_type].active;
if (active_tool != null) {
return this._trigger_event(event_type, active_tool, e);
}
};
UIEvents.prototype._trigger_event = function(event_type, active_tool, e) {
if (active_tool.get('active') === true) {
if (event_type === 'scroll') {
e.preventDefault();
e.stopPropagation();
}
return this.trigger(event_type + ":" + active_tool.id, e);
}
};
UIEvents.prototype._bokify_hammer = function(e) {
var left, offset, ref, ref1, top, x, y;
if (e.pointerType === 'mouse') {
x = e.srcEvent.pageX;
y = e.srcEvent.pageY;
} else {
x = e.pointers[0].pageX;
y = e.pointers[0].pageY;
}
offset = $(e.target).offset();
left = (ref = offset.left) != null ? ref : 0;
top = (ref1 = offset.top) != null ? ref1 : 0;
return e.bokeh = {
sx: x - left,
sy: y - top
};
};
UIEvents.prototype._bokify_jq = function(e) {
var left, offset, ref, ref1, top;
offset = $(e.currentTarget).offset();
left = (ref = offset.left) != null ? ref : 0;
top = (ref1 = offset.top) != null ? ref1 : 0;
return e.bokeh = {
sx: e.pageX - left,
sy: e.pageY - top
};
};
UIEvents.prototype._tap = function(e) {
this._bokify_hammer(e);
return this._trigger('tap', e);
};
UIEvents.prototype._doubletap = function(e) {
this._bokify_hammer(e);
return this.trigger('doubletap', e);
};
UIEvents.prototype._press = function(e) {
this._bokify_hammer(e);
return this._trigger('press', e);
};
UIEvents.prototype._pan_start = function(e) {
this._bokify_hammer(e);
e.bokeh.sx -= e.deltaX;
e.bokeh.sy -= e.deltaY;
return this._trigger('pan:start', e);
};
UIEvents.prototype._pan = function(e) {
this._bokify_hammer(e);
return this._trigger('pan', e);
};
UIEvents.prototype._pan_end = function(e) {
this._bokify_hammer(e);
return this._trigger('pan:end', e);
};
UIEvents.prototype._pinch_start = function(e) {
this._bokify_hammer(e);
return this._trigger('pinch:start', e);
};
UIEvents.prototype._pinch = function(e) {
this._bokify_hammer(e);
return this._trigger('pinch', e);
};
UIEvents.prototype._pinch_end = function(e) {
this._bokify_hammer(e);
return this._trigger('pinch:end', e);
};
UIEvents.prototype._rotate_start = function(e) {
this._bokify_hammer(e);
return this._trigger('rotate:start', e);
};
UIEvents.prototype._rotate = function(e) {
this._bokify_hammer(e);
return this._trigger('rotate', e);
};
UIEvents.prototype._rotate_end = function(e) {
this._bokify_hammer(e);
return this._trigger('rotate:end', e);
};
UIEvents.prototype._mouse_enter = function(e) {
this._bokify_jq(e);
return this.trigger('move:enter', e);
};
UIEvents.prototype._mouse_move = function(e) {
this._bokify_jq(e);
return this.trigger('move', e);
};
UIEvents.prototype._mouse_exit = function(e) {
this._bokify_jq(e);
return this.trigger('move:exit', e);
};
UIEvents.prototype._mouse_wheel = function(e, delta) {
this._bokify_jq(e);
e.bokeh.delta = delta;
return this._trigger('scroll', e);
};
UIEvents.prototype._key_down = function(e) {
return this.trigger('keydown', e);
};
UIEvents.prototype._key_up = function(e) {
return this.trigger('keyup', e);
};
return UIEvents;
})(Backbone.Model);
module.exports = UIEvents;

View File

@ -0,0 +1,5 @@
var coffee, eco;
coffee = require("coffee-script");
eco = require("eco");

View File

@ -0,0 +1,50 @@
var Backbone, BokehView, _,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Backbone = require("backbone");
BokehView = (function(superClass) {
extend(BokehView, superClass);
function BokehView() {
return BokehView.__super__.constructor.apply(this, arguments);
}
BokehView.prototype.initialize = function(options) {
if (!_.has(options, 'id')) {
return this.id = _.uniqueId('BokehView');
}
};
BokehView.prototype.bind_bokeh_events = function() {};
BokehView.prototype.remove = function() {
var ref, target, val;
if (_.has(this, 'eventers')) {
ref = this.eventers;
for (target in ref) {
if (!hasProp.call(ref, target)) continue;
val = ref[target];
val.off(null, null, this);
}
}
this.trigger('remove', this);
return BokehView.__super__.remove.call(this);
};
BokehView.prototype.mget = function() {
return this.model.get.apply(this.model, arguments);
};
BokehView.prototype.mset = function() {
return this.model.set.apply(this.model, arguments);
};
return BokehView;
})(Backbone.View);
module.exports = BokehView;

View File

@ -0,0 +1,21 @@
module.exports = {
AngleUnits: ["deg", "rad"],
Dimension: ["width", "height"],
Direction: ["clock", "anticlock"],
FontStyle: ["normal", "italic", "bold"],
LineCap: ["butt", "round", "square"],
LineJoin: ["miter", "round", "bevel"],
Location: ["above", "below", "left", "right"],
LegendLocation: ["top_left", "top_center", "top_right", "left_center", "center", "right_center", "bottom_left", "bottom_center", "bottom_right"],
Orientation: ["vertical", "horizontal"],
RenderLevel: ["image", "underlay", "glyph", "annotation", "overlay", "tool"],
RenderMode: ["canvas", "css"],
Side: ["left", "right"],
SpatialUnits: ["screen", "data"],
StartEnd: ["start", "end"],
TextAlign: ["left", "right", "center"],
TextBaseline: ["top", "middle", "bottom", "alphabetic", "hanging", "ideographic"],
DistributionTypes: ["uniform", "normal"],
TransformStepModes: ["after", "before", "center"],
SizingMode: ["stretch_both", "scale_width", "scale_height", "scale_both", "fixed"]
};

View File

@ -0,0 +1,553 @@
var $, Backbone, HasProps, _, logger, property_mixins, refs,
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,
slice = [].slice;
$ = require("jquery");
_ = require("underscore");
Backbone = require("backbone");
logger = require("./logging").logger;
property_mixins = require("./property_mixins");
refs = require("./util/refs");
HasProps = (function(superClass) {
extend(HasProps, superClass);
HasProps.prototype.props = {};
HasProps.prototype.mixins = [];
HasProps.define = function(object) {
var name, prop, results;
results = [];
for (name in object) {
prop = object[name];
results.push((function(_this) {
return function(name, prop) {
var default_value, internal, props, refined_prop, type;
if (_this.prototype.props[name] != null) {
throw new Error("attempted to redefine property '" + _this.name + "." + name + "'");
}
if ((_this.prototype[name] != null) && name !== "url") {
throw new Error("attempted to redefine attribute '" + _this.name + "." + name + "'");
}
Object.defineProperty(_this.prototype, name, {
get: function() {
return this.get(name);
},
set: function(value) {
return this.set(name, value);
}
}, {
configurable: false,
enumerable: true
});
type = prop[0], default_value = prop[1], internal = prop[2];
refined_prop = {
type: type,
default_value: default_value,
internal: internal != null ? internal : false
};
props = _.clone(_this.prototype.props);
props[name] = refined_prop;
return _this.prototype.props = props;
};
})(this)(name, prop));
}
return results;
};
HasProps.internal = function(object) {
var _object, fn, name, prop;
_object = {};
fn = (function(_this) {
return function(name, prop) {
var default_value, type;
type = prop[0], default_value = prop[1];
return _object[name] = [type, default_value, true];
};
})(this);
for (name in object) {
prop = object[name];
fn(name, prop);
}
return this.define(_object);
};
HasProps.mixin = function() {
var mixins, names;
names = 1 <= arguments.length ? slice.call(arguments, 0) : [];
this.define(property_mixins.create(names));
mixins = this.prototype.mixins.concat(names);
return this.prototype.mixins = mixins;
};
HasProps.mixins = function(names) {
return this.mixin.apply(this, names);
};
HasProps.override = function(name_or_object, default_value) {
var name, object, results;
if (_.isString(name_or_object)) {
object = {};
object[name] = default_value;
} else {
object = name_or_object;
}
results = [];
for (name in object) {
default_value = object[name];
results.push((function(_this) {
return function(name, default_value) {
var props, value;
value = _this.prototype.props[name];
if (value == null) {
throw new Error("attempted to override nonexistent '" + _this.name + "." + name + "'");
}
props = _.clone(_this.prototype.props);
props[name] = _.extend({}, value, {
default_value: default_value
});
return _this.prototype.props = props;
};
})(this)(name, default_value));
}
return results;
};
HasProps.prototype.toString = function() {
return this.type + "(" + this.id + ")";
};
HasProps.prototype.destroy = function(options) {
HasProps.__super__.destroy.call(this, options);
return this.stopListening();
};
function HasProps(attributes, options) {
var attrs, default_value, name, ref, ref1, type;
this.document = null;
attrs = attributes || {};
if (!options) {
options = {};
}
this.cid = _.uniqueId('c');
this.attributes = {};
this.properties = {};
ref = this.props;
for (name in ref) {
ref1 = ref[name], type = ref1.type, default_value = ref1.default_value;
if (type == null) {
throw new Error("undefined property type for " + this.type + "." + name);
}
this.properties[name] = new type({
obj: this,
attr: name,
default_value: default_value
});
}
if (options.parse) {
attrs = this.parse(attrs, options) || {};
}
this._set_after_defaults = {};
this.set(attrs, options);
this.changed = {};
this._computed = {};
if (!_.has(attrs, this.idAttribute)) {
this.id = _.uniqueId(this.type);
this.attributes[this.idAttribute] = this.id;
}
if (!options.defer_initialization) {
this.initialize.apply(this, arguments);
}
}
HasProps.prototype.set = function(key, value, options) {
var attrs, old, prop_name, results, val;
if (_.isObject(key) || key === null) {
attrs = key;
options = value;
} else {
attrs = {};
attrs[key] = value;
}
for (key in attrs) {
if (!hasProp.call(attrs, key)) continue;
val = attrs[key];
prop_name = key;
if (!(prop_name === "id" || this.props[prop_name])) {
throw new Error(this.type + ".set('" + prop_name + "'): " + prop_name + " wasn't declared");
}
if (!((options != null) && options.defaults)) {
this._set_after_defaults[key] = true;
}
}
if (!_.isEmpty(attrs)) {
old = {};
for (key in attrs) {
value = attrs[key];
old[key] = this.get(key);
}
HasProps.__super__.set.call(this, attrs, options);
if ((options != null ? options.silent : void 0) == null) {
results = [];
for (key in attrs) {
value = attrs[key];
results.push(this._tell_document_about_change(key, old[key], this.get(key)));
}
return results;
}
}
};
HasProps.prototype.add_dependencies = function(prop_name, object, fields) {
var fld, j, len, prop_spec, results;
if (!_.isArray(fields)) {
fields = [fields];
}
prop_spec = this._computed[prop_name];
prop_spec.dependencies = prop_spec.dependencies.concat({
obj: object,
fields: fields
});
results = [];
for (j = 0, len = fields.length; j < len; j++) {
fld = fields[j];
results.push(this.listenTo(object, "change:" + fld, prop_spec['callbacks']['changedep']));
}
return results;
};
HasProps.prototype.define_computed_property = function(prop_name, getter, use_cache) {
var changedep, prop_spec, propchange;
if (use_cache == null) {
use_cache = true;
}
if (this.props[prop_name] != null) {
console.log("attempted to redefine existing property " + this.type + "." + prop_name);
}
if (_.has(this._computed, prop_name)) {
throw new Error("attempted to redefine existing computed property " + this.type + "." + prop_name);
}
changedep = (function(_this) {
return function() {
return _this.trigger('changedep:' + prop_name);
};
})(this);
propchange = (function(_this) {
return function() {
var firechange, new_val, old_val;
firechange = true;
if (prop_spec['use_cache']) {
old_val = prop_spec.cache;
prop_spec.cache = void 0;
new_val = _this.get(prop_name);
firechange = new_val !== old_val;
}
if (firechange) {
_this.trigger('change:' + prop_name, _this, _this.get(prop_name));
return _this.trigger('change', _this);
}
};
})(this);
prop_spec = {
'getter': getter,
'dependencies': [],
'use_cache': use_cache,
'callbacks': {
changedep: changedep,
propchange: propchange
}
};
this._computed[prop_name] = prop_spec;
this.listenTo(this, "changedep:" + prop_name, prop_spec['callbacks']['propchange']);
return prop_spec;
};
HasProps.prototype.override_computed_property = function(prop_name, getter, use_cache) {
if (use_cache == null) {
use_cache = true;
}
if (_.has(this._computed, prop_name)) {
this._remove_computed_property(prop_name);
}
return this.define_computed_property(prop_name, getter, use_cache);
};
HasProps.prototype._remove_computed_property = function(prop_name) {
var dep, dependencies, fld, j, l, len, len1, obj, prop_spec, ref;
prop_spec = this._computed[prop_name];
dependencies = prop_spec.dependencies;
for (j = 0, len = dependencies.length; j < len; j++) {
dep = dependencies[j];
obj = dep.obj;
ref = dep['fields'];
for (l = 0, len1 = ref.length; l < len1; l++) {
fld = ref[l];
obj.off('change:' + fld, prop_spec['callbacks']['changedep'], this);
}
}
this.off("changedep:" + dep);
return delete this._computed[prop_name];
};
HasProps.prototype.get = function(prop_name) {
if (_.has(this._computed, prop_name)) {
return this._get_prop(prop_name);
} else {
if (!(prop_name === "id" || this.props[prop_name])) {
throw new Error(this.type + ".get('" + prop_name + "'): " + prop_name + " wasn't declared");
}
return HasProps.__super__.get.call(this, prop_name);
}
};
HasProps.prototype._get_prop = function(prop_name) {
var computed, getter, prop_spec;
prop_spec = this._computed[prop_name];
if (prop_spec.use_cache && prop_spec.cache) {
return prop_spec.cache;
} else {
getter = prop_spec.getter;
computed = getter.apply(this, [prop_name]);
if (prop_spec.use_cache) {
prop_spec.cache = computed;
}
return computed;
}
};
HasProps.prototype.ref = function() {
return refs.create_ref(this);
};
HasProps.prototype.set_subtype = function(subtype) {
return this._subtype = subtype;
};
HasProps.prototype.sync = function(method, model, options) {
return options.success(model.attributes, null, {});
};
HasProps.prototype.defaults = function() {
throw new Error("don't use HasProps.defaults anymore");
};
HasProps.prototype.attribute_is_serializable = function(attr) {
var prop;
if (attr === "id") {
return true;
}
prop = this.props[attr];
if (prop == null) {
throw new Error(this.type + ".attribute_is_serializable('" + attr + "'): " + attr + " wasn't declared");
}
return !prop.internal;
};
HasProps.prototype.serializable_attributes = function() {
var attrs, name, ref, value;
attrs = {};
ref = this.attributes;
for (name in ref) {
value = ref[name];
if (this.attribute_is_serializable(name)) {
attrs[name] = value;
}
}
return attrs;
};
HasProps.prototype.toJSON = function(options) {
throw new Error("bug: toJSON should not be called on " + this + ", models require special serialization measures");
};
HasProps._value_to_json = function(key, value, optional_parent_object) {
var i, j, len, ref_array, ref_obj, subkey, v;
if (value instanceof HasProps) {
return value.ref();
} else if (_.isArray(value)) {
ref_array = [];
for (i = j = 0, len = value.length; j < len; i = ++j) {
v = value[i];
ref_array.push(HasProps._value_to_json(i, v, value));
}
return ref_array;
} else if (_.isObject(value)) {
ref_obj = {};
for (subkey in value) {
if (!hasProp.call(value, subkey)) continue;
ref_obj[subkey] = HasProps._value_to_json(subkey, value[subkey], value);
}
return ref_obj;
} else {
return value;
}
};
HasProps.prototype.attributes_as_json = function(include_defaults, value_to_json) {
var attrs, key, ref, value;
if (include_defaults == null) {
include_defaults = true;
}
if (value_to_json == null) {
value_to_json = HasProps._value_to_json;
}
attrs = {};
ref = this.serializable_attributes();
for (key in ref) {
if (!hasProp.call(ref, key)) continue;
value = ref[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);
};
HasProps._json_record_references = function(doc, v, result, recurse) {
var elem, j, k, len, model, results, results1;
if (v === null) {
} else if (refs.is_ref(v)) {
if (!(v.id in result)) {
model = doc.get_model_by_id(v.id);
return HasProps._value_record_references(model, result, recurse);
}
} else if (_.isArray(v)) {
results = [];
for (j = 0, len = v.length; j < len; j++) {
elem = v[j];
results.push(HasProps._json_record_references(doc, elem, result, recurse));
}
return results;
} else if (_.isObject(v)) {
results1 = [];
for (k in v) {
if (!hasProp.call(v, k)) continue;
elem = v[k];
results1.push(HasProps._json_record_references(doc, elem, result, recurse));
}
return results1;
}
};
HasProps._value_record_references = function(v, result, recurse) {
var elem, immediate, j, k, l, len, len1, obj, results, results1, results2;
if (v === null) {
} else if (v instanceof HasProps) {
if (!(v.id in result)) {
result[v.id] = v;
if (recurse) {
immediate = v._immediate_references();
results = [];
for (j = 0, len = immediate.length; j < len; j++) {
obj = immediate[j];
results.push(HasProps._value_record_references(obj, result, true));
}
return results;
}
}
} else if (_.isArray(v)) {
results1 = [];
for (l = 0, len1 = v.length; l < len1; l++) {
elem = v[l];
results1.push(HasProps._value_record_references(elem, result, recurse));
}
return results1;
} else if (_.isObject(v)) {
results2 = [];
for (k in v) {
if (!hasProp.call(v, k)) continue;
elem = v[k];
results2.push(HasProps._value_record_references(elem, result, recurse));
}
return results2;
}
};
HasProps.prototype._immediate_references = function() {
var attrs, key, result, value;
result = {};
attrs = this.serializable_attributes();
for (key in attrs) {
value = attrs[key];
HasProps._value_record_references(value, result, false);
}
return _.values(result);
};
HasProps.prototype.references = function() {
var references;
references = {};
HasProps._value_record_references(this, references, true);
return _.values(references);
};
HasProps.prototype.attach_document = function(doc) {
var name, prop, ref;
if (this.document !== null && this.document !== doc) {
throw new Error("models must be owned by only a single document");
}
this.document = doc;
ref = this.properties;
for (name in ref) {
prop = ref[name];
prop.update();
}
if (this._doc_attached != null) {
return this._doc_attached();
}
};
HasProps.prototype.detach_document = function() {
return this.document = null;
};
HasProps.prototype._tell_document_about_change = function(attr, old, new_) {
var need_invalidate, new_id, new_ref, new_refs, old_id, old_ref, old_refs;
if (!this.attribute_is_serializable(attr)) {
return;
}
if (this.document !== null) {
new_refs = {};
HasProps._value_record_references(new_, new_refs, false);
old_refs = {};
HasProps._value_record_references(old, old_refs, false);
need_invalidate = false;
for (new_id in new_refs) {
new_ref = new_refs[new_id];
if (!(new_id in old_refs)) {
need_invalidate = true;
break;
}
}
if (!need_invalidate) {
for (old_id in old_refs) {
old_ref = old_refs[old_id];
if (!(old_id in new_refs)) {
need_invalidate = true;
break;
}
}
}
if (need_invalidate) {
this.document._invalidate_all_models();
}
return this.document._notify_change(this, attr, old, new_);
}
};
return HasProps;
})(Backbone.Model);
module.exports = HasProps;

View File

@ -0,0 +1,78 @@
var EQ, GE, LayoutCanvas, Model, Strength, Variable, _, p, ref,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
ref = require("./solver"), Variable = ref.Variable, EQ = ref.EQ, GE = ref.GE, Strength = ref.Strength;
Model = require("../../model");
p = require("../properties");
LayoutCanvas = (function(superClass) {
extend(LayoutCanvas, superClass);
function LayoutCanvas() {
return LayoutCanvas.__super__.constructor.apply(this, arguments);
}
LayoutCanvas.prototype.type = 'LayoutCanvas';
LayoutCanvas.prototype.initialize = function(attrs, options) {
LayoutCanvas.__super__.initialize.call(this, attrs, options);
this._top = new Variable("top " + this.id);
this._left = new Variable("left " + this.id);
this._width = new Variable("width " + this.id);
this._height = new Variable("height " + this.id);
this._right = new Variable("right " + this.id);
this._bottom = new Variable("bottom " + this.id);
this.define_computed_property('height', this._get_var, false);
this.define_computed_property('width', this._get_var, false);
this.define_computed_property('right', this._get_var, false);
this.define_computed_property('left', this._get_var, false);
this.define_computed_property('top', this._get_var, false);
return this.define_computed_property('bottom', this._get_var, false);
};
LayoutCanvas.internal({
layout_location: [p.Any]
});
LayoutCanvas.prototype.get_edit_variables = function() {
var editables;
editables = [];
editables.push({
edit_variable: this._top,
strength: Strength.strong
});
editables.push({
edit_variable: this._left,
strength: Strength.strong
});
editables.push({
edit_variable: this._width,
strength: Strength.strong
});
editables.push({
edit_variable: this._height,
strength: Strength.strong
});
return editables;
};
LayoutCanvas.prototype.get_constraints = function() {
return [];
};
LayoutCanvas.prototype._get_var = function(prop_name) {
return this['_' + prop_name].value();
};
return LayoutCanvas;
})(Model);
module.exports = {
Model: LayoutCanvas
};

View File

@ -0,0 +1,262 @@
var ALPHABETIC, BOTTOM, CENTER, EQ, GE, HANGING, LEFT, LayoutCanvas, MIDDLE, RIGHT, SidePanel, TOP, _, _align_lookup, _align_lookup_negative, _align_lookup_positive, _angle_lookup, _baseline_lookup, logger, p, pi2, ref, update_constraints,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
ref = require("./solver"), EQ = ref.EQ, GE = ref.GE;
LayoutCanvas = require("./layout_canvas");
p = require("../../core/properties");
logger = require("../../core/logging").logger;
pi2 = Math.PI / 2;
ALPHABETIC = 'alphabetic';
TOP = 'top';
BOTTOM = 'bottom';
MIDDLE = 'middle';
HANGING = 'hanging';
LEFT = 'left';
RIGHT = 'right';
CENTER = 'center';
_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
}
};
_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
}
};
_align_lookup = {
above: {
justified: CENTER,
parallel: CENTER,
normal: LEFT,
horizontal: CENTER,
vertical: LEFT
},
below: {
justified: CENTER,
parallel: CENTER,
normal: LEFT,
horizontal: CENTER,
vertical: RIGHT
},
left: {
justified: CENTER,
parallel: CENTER,
normal: RIGHT,
horizontal: RIGHT,
vertical: CENTER
},
right: {
justified: CENTER,
parallel: CENTER,
normal: LEFT,
horizontal: LEFT,
vertical: CENTER
}
};
_align_lookup_negative = {
above: RIGHT,
below: LEFT,
left: RIGHT,
right: LEFT
};
_align_lookup_positive = {
above: LEFT,
below: RIGHT,
left: RIGHT,
right: LEFT
};
update_constraints = function(view) {
var s, side, size, v;
v = view;
if (v.model.props.visible != null) {
if (v.mget('visible') === false) {
return;
}
}
size = v._get_size();
if (v._last_size == null) {
v._last_size = -1;
}
if (size === v._last_size) {
return;
}
s = v.model.document.solver();
v._last_size = size;
if (v._size_constraint != null) {
s.remove_constraint(v._size_constraint);
}
v._size_constraint = GE(v.model.panel._size, -size);
s.add_constraint(v._size_constraint);
if (v._full_set == null) {
v._full_set = false;
}
if (!v._full_set) {
side = v.model.panel.get('side');
if (side === 'above' || side === 'below') {
s.add_constraint(EQ(v.model.panel._width, [-1, v.plot_model.canvas._width]));
}
if (side === 'left' || side === 'right') {
s.add_constraint(EQ(v.model.panel._height, [-1, v.plot_model.canvas._height]));
}
return v._full_set = true;
}
};
SidePanel = (function(superClass) {
extend(SidePanel, superClass);
function SidePanel() {
return SidePanel.__super__.constructor.apply(this, arguments);
}
SidePanel.internal({
side: [p.String],
plot: [p.Instance]
});
SidePanel.prototype.initialize = function(attrs, options) {
var side;
SidePanel.__super__.initialize.call(this, attrs, options);
side = this.get('side');
if (side === "above") {
this._dim = 0;
this._normals = [0, -1];
this._size = this._height;
return this._anchor = this._bottom;
} else if (side === "below") {
this._dim = 0;
this._normals = [0, 1];
this._size = this._height;
return this._anchor = this._top;
} else if (side === "left") {
this._dim = 1;
this._normals = [-1, 0];
this._size = this._width;
return this._anchor = this._right;
} else if (side === "right") {
this._dim = 1;
this._normals = [1, 0];
this._size = this._width;
return this._anchor = this._left;
} else {
return logger.error("unrecognized side: '" + side + "'");
}
};
SidePanel.prototype.get_constraints = function() {
var constraints;
constraints = [];
constraints.push(GE(this._top));
constraints.push(GE(this._bottom));
constraints.push(GE(this._left));
constraints.push(GE(this._right));
constraints.push(GE(this._width));
constraints.push(GE(this._height));
constraints.push(EQ(this._left, this._width, [-1, this._right]));
constraints.push(EQ(this._bottom, this._height, [-1, this._top]));
return constraints;
};
SidePanel.prototype.apply_label_text_heuristics = function(ctx, orient) {
var align, baseline, side;
side = this.get('side');
if (_.isString(orient)) {
baseline = _baseline_lookup[side][orient];
align = _align_lookup[side][orient];
} else if (orient === 0) {
baseline = _baseline_lookup[side][orient];
align = _align_lookup[side][orient];
} else if (orient < 0) {
baseline = 'middle';
align = _align_lookup_negative[side];
} else if (orient > 0) {
baseline = 'middle';
align = _align_lookup_positive[side];
}
ctx.textBaseline = baseline;
ctx.textAlign = align;
return ctx;
};
SidePanel.prototype.get_label_angle_heuristic = function(orient) {
var side;
side = this.get('side');
return _angle_lookup[side][orient];
};
return SidePanel;
})(LayoutCanvas.Model);
module.exports = {
Model: SidePanel,
update_constraints: update_constraints
};

View File

@ -0,0 +1,104 @@
var Backbone, Constraint, Expression, Operator, Solver, Strength, Variable, _, _constrainer, _weak_constrainer, kiwi;
_ = require("underscore");
Backbone = require("backbone");
kiwi = require("kiwi");
Variable = kiwi.Variable, Expression = kiwi.Expression, Constraint = kiwi.Constraint, Operator = kiwi.Operator, Strength = kiwi.Strength;
_constrainer = function(op) {
return (function(_this) {
return function() {
var expr;
expr = Object.create(Expression.prototype);
Expression.apply(expr, arguments);
return new Constraint(expr, op);
};
})(this);
};
_weak_constrainer = function(op) {
return function() {
var arg, args, i, len;
args = [null];
for (i = 0, len = arguments.length; i < len; i++) {
arg = arguments[i];
args.push(arg);
}
return new Constraint(new (Function.prototype.bind.apply(Expression, args)), op, kiwi.Strength.weak);
};
};
Solver = (function() {
function Solver() {
this.solver = new kiwi.Solver();
}
Solver.prototype.clear = function() {
return this.solver = new kiwi.Solver();
};
Solver.prototype.toString = function() {
return "Solver[num_constraints=" + (this.num_constraints()) + ", num_edit_variables=" + (this.num_edit_variables()) + "]";
};
Solver.prototype.num_constraints = function() {
return this.solver._cnMap._array.length;
};
Solver.prototype.num_edit_variables = function() {
return this.solver._editMap._array.length;
};
Solver.prototype.update_variables = function(trigger) {
if (trigger == null) {
trigger = true;
}
this.solver.updateVariables();
if (trigger) {
return this.trigger('layout_update');
}
};
Solver.prototype.add_constraint = function(constraint) {
return this.solver.addConstraint(constraint);
};
Solver.prototype.remove_constraint = function(constraint) {
return this.solver.removeConstraint(constraint);
};
Solver.prototype.add_edit_variable = function(variable, strength) {
return this.solver.addEditVariable(variable, strength);
};
Solver.prototype.remove_edit_variable = function(variable) {
return this.solver.removeEditVariable(variable, strength);
};
Solver.prototype.suggest_value = function(variable, value) {
return this.solver.suggestValue(variable, value);
};
return Solver;
})();
_.extend(Solver.prototype, Backbone.Events);
module.exports = {
Variable: Variable,
Expression: Expression,
Constraint: Constraint,
Operator: Operator,
Strength: Strength,
EQ: _constrainer(Operator.Eq),
LE: _constrainer(Operator.Le),
GE: _constrainer(Operator.Ge),
WEAK_EQ: _weak_constrainer(Operator.Eq),
WEAK_LE: _weak_constrainer(Operator.Le),
WEAK_GE: _weak_constrainer(Operator.Ge),
Solver: Solver
};

View File

@ -0,0 +1,38 @@
var JL, levels, logger, set_log_level;
JL = require("jsnlog").JL;
logger = JL("Bokeh");
logger.setOptions({
"appenders": [JL.createConsoleAppender('consoleAppender')],
"level": JL.getInfoLevel()
});
levels = {
"trace": JL.getTraceLevel(),
"debug": JL.getDebugLevel(),
"info": JL.getInfoLevel(),
"warn": JL.getWarnLevel(),
"error": JL.getErrorLevel(),
"fatal": JL.getFatalLevel()
};
set_log_level = function(level) {
if (!(level in levels)) {
console.log("Bokeh: Unrecognized logging level '" + level + "' passed to Bokeh.set_log_level, ignoring.");
console.log("Bokeh: Valid log levels are: " + (Object.keys(levels)));
return;
}
console.log("Bokeh: setting log level to: '" + level + "'");
logger.setOptions({
"level": levels[level]
});
return null;
};
module.exports = {
levels: levels,
logger: logger,
set_log_level: set_log_level
};

View File

@ -0,0 +1,735 @@
var Anchor, Angle, AngleSpec, AngleUnits, Any, Array, Backbone, Bool, Color, ColorSpec, Dimension, Direction, DirectionSpec, Distance, DistanceSpec, Distribution, Font, FontSizeSpec, FontStyle, Instance, LegendLocation, LineCap, LineJoin, Location, Number, NumberSpec, Orientation, Property, RenderLevel, RenderMode, SizingMode, SpatialUnits, String, StringSpec, TextAlign, TextBaseline, TransformStepMode, _, enum_prop, enums, simple_prop, svg_colors, units_prop, valid_rgb,
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,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
_ = require("underscore");
Backbone = require("backbone");
enums = require("./enums");
svg_colors = require("./util/svg_colors");
valid_rgb = require("./util/color").valid_rgb;
Property = (function(superClass) {
extend(Property, superClass);
function Property() {
return Property.__super__.constructor.apply(this, arguments);
}
Property.prototype.dataspec = false;
Property.prototype.specifiers = ['field', 'value'];
Property.prototype.initialize = function(attrs, options) {
var attr, obj;
Property.__super__.initialize.call(this, attrs, options);
this._init(false);
obj = this.get('obj');
attr = this.get('attr');
this.listenTo(obj, "change:" + attr, function() {
this._init();
return obj.trigger("propchange");
});
this.listenTo(this, "change:obj", function() {
throw new Error("attempted to reset 'obj' on Property");
});
return this.listenTo(this, "change:attr", function() {
throw new Error("attempted to reset 'attr' on Property");
});
};
Property.prototype.update = function() {
return this._init();
};
Property.prototype.init = function() {};
Property.prototype.transform = function(values) {
return values;
};
Property.prototype.validate = function(value) {};
Property.prototype.value = function(do_spec_transform) {
var ret;
if (do_spec_transform == null) {
do_spec_transform = true;
}
if (_.isUndefined(this.spec.value)) {
throw new Error("attempted to retrieve property value for property without value specification");
}
ret = this.transform([this.spec.value])[0];
if ((this.spec.transform != null) && do_spec_transform) {
ret = this.spec.transform.compute(ret);
}
return ret;
};
Property.prototype.array = function(source) {
var data, i, length, ret, value;
if (!this.dataspec) {
throw new Error("attempted to retrieve property array for non-dataspec property");
}
data = source.get('data');
if (this.spec.field != null) {
if (this.spec.field in data) {
ret = this.transform(source.get_column(this.spec.field));
} else {
throw new Error("attempted to retrieve property array for nonexistent field '" + this.spec.field + "'");
}
} else {
length = source.get_length();
if (length == null) {
length = 1;
}
value = this.value(false);
ret = (function() {
var j, ref, results;
results = [];
for (i = j = 0, ref = length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
results.push(value);
}
return results;
})();
}
if (this.spec.transform != null) {
ret = this.spec.transform.v_compute(ret);
}
return ret;
};
Property.prototype._init = function(trigger) {
var attr, attr_value, default_value, obj;
if (trigger == null) {
trigger = true;
}
obj = this.get('obj');
if (obj == null) {
throw new Error("missing property object");
}
if (obj.properties == null) {
throw new Error("property object must be a HasProps");
}
attr = this.get('attr');
if (attr == null) {
throw new Error("missing property attr");
}
attr_value = obj.get(attr);
if (_.isUndefined(attr_value)) {
default_value = this.get('default_value');
attr_value = (function() {
switch (false) {
case !_.isUndefined(default_value):
return null;
case !_.isArray(default_value):
return _.clone(default_value);
case !_.isFunction(default_value):
return default_value(obj);
default:
return default_value;
}
})();
obj.set(attr, attr_value, {
silent: true,
defaults: true
});
}
if (_.isArray(attr_value)) {
this.spec = {
value: attr_value
};
} else if (_.isObject(attr_value) && _.size(_.pick.apply(null, [attr_value].concat(this.specifiers))) === 1) {
this.spec = attr_value;
} else {
this.spec = {
value: attr_value
};
}
if ((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();
if (trigger) {
return this.trigger("change");
}
};
return Property;
})(Backbone.Model);
simple_prop = function(name, pred) {
var Prop;
return Prop = (function(superClass) {
extend(Prop, superClass);
function Prop() {
return Prop.__super__.constructor.apply(this, arguments);
}
Prop.prototype.toString = function() {
return name + "(obj: " + (this.get(obj).id) + ", spec: " + (JSON.stringify(this.spec)) + ")";
};
Prop.prototype.validate = function(value) {
var attr;
if (!pred(value)) {
attr = this.get('attr');
throw new Error(name + " property '" + attr + "' given invalid value: " + value);
}
};
return Prop;
})(Property);
};
Any = (function(superClass) {
extend(Any, superClass);
function Any() {
return Any.__super__.constructor.apply(this, arguments);
}
return Any;
})(simple_prop("Any", function(x) {
return true;
}));
Array = (function(superClass) {
extend(Array, superClass);
function Array() {
return Array.__super__.constructor.apply(this, arguments);
}
return Array;
})(simple_prop("Array", function(x) {
return _.isArray(x) || x instanceof Float64Array;
}));
Bool = (function(superClass) {
extend(Bool, superClass);
function Bool() {
return Bool.__super__.constructor.apply(this, arguments);
}
return Bool;
})(simple_prop("Bool", _.isBoolean));
Color = (function(superClass) {
extend(Color, superClass);
function Color() {
return Color.__super__.constructor.apply(this, arguments);
}
return Color;
})(simple_prop("Color", function(x) {
return (svg_colors[x.toLowerCase()] != null) || x.substring(0, 1) === "#" || valid_rgb(x);
}));
Instance = (function(superClass) {
extend(Instance, superClass);
function Instance() {
return Instance.__super__.constructor.apply(this, arguments);
}
return Instance;
})(simple_prop("Instance", function(x) {
return x.properties != null;
}));
Number = (function(superClass) {
extend(Number, superClass);
function Number() {
return Number.__super__.constructor.apply(this, arguments);
}
return Number;
})(simple_prop("Number", function(x) {
return _.isNumber(x) || _.isBoolean(x);
}));
String = (function(superClass) {
extend(String, superClass);
function String() {
return String.__super__.constructor.apply(this, arguments);
}
return String;
})(simple_prop("String", _.isString));
Font = (function(superClass) {
extend(Font, superClass);
function Font() {
return Font.__super__.constructor.apply(this, arguments);
}
return Font;
})(String);
enum_prop = function(name, enum_values) {
var Enum;
return Enum = (function(superClass) {
extend(Enum, superClass);
function Enum() {
return Enum.__super__.constructor.apply(this, arguments);
}
Enum.prototype.toString = function() {
return name + "(obj: " + (this.get(obj).id) + ", spec: " + (JSON.stringify(this.spec)) + ")";
};
return Enum;
})(simple_prop(name, function(x) {
return indexOf.call(enum_values, x) >= 0;
}));
};
Anchor = (function(superClass) {
extend(Anchor, superClass);
function Anchor() {
return Anchor.__super__.constructor.apply(this, arguments);
}
return Anchor;
})(enum_prop("Anchor", enums.LegendLocation));
AngleUnits = (function(superClass) {
extend(AngleUnits, superClass);
function AngleUnits() {
return AngleUnits.__super__.constructor.apply(this, arguments);
}
return AngleUnits;
})(enum_prop("AngleUnits", enums.AngleUnits));
Direction = (function(superClass) {
extend(Direction, superClass);
function Direction() {
return Direction.__super__.constructor.apply(this, arguments);
}
Direction.prototype.transform = function(values) {
var i, j, ref, result;
result = new Uint8Array(values.length);
for (i = j = 0, ref = values.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
switch (values[i]) {
case 'clock':
result[i] = false;
break;
case 'anticlock':
result[i] = true;
}
}
return result;
};
return Direction;
})(enum_prop("Direction", enums.Direction));
Dimension = (function(superClass) {
extend(Dimension, superClass);
function Dimension() {
return Dimension.__super__.constructor.apply(this, arguments);
}
return Dimension;
})(enum_prop("Dimension", enums.Dimension));
FontStyle = (function(superClass) {
extend(FontStyle, superClass);
function FontStyle() {
return FontStyle.__super__.constructor.apply(this, arguments);
}
return FontStyle;
})(enum_prop("FontStyle", enums.FontStyle));
LineCap = (function(superClass) {
extend(LineCap, superClass);
function LineCap() {
return LineCap.__super__.constructor.apply(this, arguments);
}
return LineCap;
})(enum_prop("LineCap", enums.LineCap));
LineJoin = (function(superClass) {
extend(LineJoin, superClass);
function LineJoin() {
return LineJoin.__super__.constructor.apply(this, arguments);
}
return LineJoin;
})(enum_prop("LineJoin", enums.LineJoin));
LegendLocation = (function(superClass) {
extend(LegendLocation, superClass);
function LegendLocation() {
return LegendLocation.__super__.constructor.apply(this, arguments);
}
return LegendLocation;
})(enum_prop("LegendLocation", enums.LegendLocation));
Location = (function(superClass) {
extend(Location, superClass);
function Location() {
return Location.__super__.constructor.apply(this, arguments);
}
return Location;
})(enum_prop("Location", enums.Location));
Orientation = (function(superClass) {
extend(Orientation, superClass);
function Orientation() {
return Orientation.__super__.constructor.apply(this, arguments);
}
return Orientation;
})(enum_prop("Orientation", enums.Orientation));
TextAlign = (function(superClass) {
extend(TextAlign, superClass);
function TextAlign() {
return TextAlign.__super__.constructor.apply(this, arguments);
}
return TextAlign;
})(enum_prop("TextAlign", enums.TextAlign));
TextBaseline = (function(superClass) {
extend(TextBaseline, superClass);
function TextBaseline() {
return TextBaseline.__super__.constructor.apply(this, arguments);
}
return TextBaseline;
})(enum_prop("TextBaseline", enums.TextBaseline));
RenderLevel = (function(superClass) {
extend(RenderLevel, superClass);
function RenderLevel() {
return RenderLevel.__super__.constructor.apply(this, arguments);
}
return RenderLevel;
})(enum_prop("RenderLevel", enums.RenderLevel));
RenderMode = (function(superClass) {
extend(RenderMode, superClass);
function RenderMode() {
return RenderMode.__super__.constructor.apply(this, arguments);
}
return RenderMode;
})(enum_prop("RenderMode", enums.RenderMode));
SizingMode = (function(superClass) {
extend(SizingMode, superClass);
function SizingMode() {
return SizingMode.__super__.constructor.apply(this, arguments);
}
return SizingMode;
})(enum_prop("SizingMode", enums.SizingMode));
SpatialUnits = (function(superClass) {
extend(SpatialUnits, superClass);
function SpatialUnits() {
return SpatialUnits.__super__.constructor.apply(this, arguments);
}
return SpatialUnits;
})(enum_prop("SpatialUnits", enums.SpatialUnits));
Distribution = (function(superClass) {
extend(Distribution, superClass);
function Distribution() {
return Distribution.__super__.constructor.apply(this, arguments);
}
return Distribution;
})(enum_prop("Distribution", enums.DistributionTypes));
TransformStepMode = (function(superClass) {
extend(TransformStepMode, superClass);
function TransformStepMode() {
return TransformStepMode.__super__.constructor.apply(this, arguments);
}
return TransformStepMode;
})(enum_prop("TransformStepMode", enums.TransformStepModes));
units_prop = function(name, valid_units, default_units) {
var UnitsProp;
return UnitsProp = (function(superClass) {
extend(UnitsProp, superClass);
function UnitsProp() {
return UnitsProp.__super__.constructor.apply(this, arguments);
}
UnitsProp.prototype.toString = function() {
return name + "(obj: " + (this.get(obj).id) + ", spec: " + (JSON.stringify(this.spec)) + ")";
};
UnitsProp.prototype.init = function() {
var units;
if (this.spec.units == null) {
this.spec.units = default_units;
}
this.units = this.spec.units;
units = this.spec.units;
if (indexOf.call(valid_units, units) < 0) {
throw new Error(name + " units must be one of " + valid_units + ", given invalid value: " + units);
}
};
return UnitsProp;
})(Number);
};
Angle = (function(superClass) {
extend(Angle, superClass);
function Angle() {
return Angle.__super__.constructor.apply(this, arguments);
}
Angle.prototype.transform = function(values) {
var x;
if (this.spec.units === "deg") {
values = (function() {
var j, len, results;
results = [];
for (j = 0, len = values.length; j < len; j++) {
x = values[j];
results.push(x * Math.PI / 180.0);
}
return results;
})();
}
values = (function() {
var j, len, results;
results = [];
for (j = 0, len = values.length; j < len; j++) {
x = values[j];
results.push(-x);
}
return results;
})();
return Angle.__super__.transform.call(this, values);
};
return Angle;
})(units_prop("Angle", enums.AngleUnits, "rad"));
Distance = (function(superClass) {
extend(Distance, superClass);
function Distance() {
return Distance.__super__.constructor.apply(this, arguments);
}
return Distance;
})(units_prop("Distance", enums.SpatialUnits, "data"));
AngleSpec = (function(superClass) {
extend(AngleSpec, superClass);
function AngleSpec() {
return AngleSpec.__super__.constructor.apply(this, arguments);
}
AngleSpec.prototype.dataspec = true;
return AngleSpec;
})(Angle);
ColorSpec = (function(superClass) {
extend(ColorSpec, superClass);
function ColorSpec() {
return ColorSpec.__super__.constructor.apply(this, arguments);
}
ColorSpec.prototype.dataspec = true;
return ColorSpec;
})(Color);
DirectionSpec = (function(superClass) {
extend(DirectionSpec, superClass);
function DirectionSpec() {
return DirectionSpec.__super__.constructor.apply(this, arguments);
}
DirectionSpec.prototype.dataspec = true;
return DirectionSpec;
})(Distance);
DistanceSpec = (function(superClass) {
extend(DistanceSpec, superClass);
function DistanceSpec() {
return DistanceSpec.__super__.constructor.apply(this, arguments);
}
DistanceSpec.prototype.dataspec = true;
return DistanceSpec;
})(Distance);
FontSizeSpec = (function(superClass) {
extend(FontSizeSpec, superClass);
function FontSizeSpec() {
return FontSizeSpec.__super__.constructor.apply(this, arguments);
}
FontSizeSpec.prototype.dataspec = true;
return FontSizeSpec;
})(String);
NumberSpec = (function(superClass) {
extend(NumberSpec, superClass);
function NumberSpec() {
return NumberSpec.__super__.constructor.apply(this, arguments);
}
NumberSpec.prototype.dataspec = true;
return NumberSpec;
})(Number);
StringSpec = (function(superClass) {
extend(StringSpec, superClass);
function StringSpec() {
return StringSpec.__super__.constructor.apply(this, arguments);
}
StringSpec.prototype.dataspec = true;
return StringSpec;
})(String);
module.exports = {
Property: Property,
simple_prop: simple_prop,
enum_prop: enum_prop,
units_prop: units_prop,
Anchor: Anchor,
Any: Any,
Angle: Angle,
AngleUnits: AngleUnits,
Array: Array,
Bool: Bool,
Boolean: Bool,
Color: Color,
Dimension: Dimension,
Direction: Direction,
Distance: Distance,
Font: Font,
FontStyle: FontStyle,
Instance: Instance,
LegendLocation: LegendLocation,
LineCap: LineCap,
LineJoin: LineJoin,
Location: Location,
Number: Number,
Int: Number,
Orientation: Orientation,
RenderLevel: RenderLevel,
RenderMode: RenderMode,
SizingMode: SizingMode,
SpatialUnits: SpatialUnits,
String: String,
TextAlign: TextAlign,
TextBaseline: TextBaseline,
Distribution: Distribution,
TransformStepMode: TransformStepMode,
AngleSpec: AngleSpec,
ColorSpec: ColorSpec,
DirectionSpec: DirectionSpec,
DistanceSpec: DistanceSpec,
FontSizeSpec: FontSizeSpec,
NumberSpec: NumberSpec,
StringSpec: StringSpec
};

View File

@ -0,0 +1,76 @@
var _, _fill_mixin, _gen_mixin, _line_mixin, _text_mixin, create, fill, line, p, text;
_ = require("underscore");
p = require("./properties");
_gen_mixin = function(mixin, prefix) {
var name, result, type;
result = {};
if (prefix == null) {
prefix = "";
}
for (name in mixin) {
type = mixin[name];
result[prefix + name] = type;
}
return result;
};
_line_mixin = {
line_color: [p.ColorSpec, 'black'],
line_width: [p.NumberSpec, 1],
line_alpha: [p.NumberSpec, 1.0],
line_join: [p.LineJoin, 'miter'],
line_cap: [p.LineCap, 'butt'],
line_dash: [p.Array, []],
line_dash_offset: [p.Number, 0]
};
line = function(prefix) {
return _gen_mixin(_line_mixin, prefix);
};
_fill_mixin = {
fill_color: [p.ColorSpec, 'gray'],
fill_alpha: [p.NumberSpec, 1.0]
};
fill = function(prefix) {
return _gen_mixin(_fill_mixin, prefix);
};
_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 = function(prefix) {
return _gen_mixin(_text_mixin, prefix);
};
create = function(configs) {
var config, i, kind, len, prefix, ref, result;
result = {};
for (i = 0, len = configs.length; i < len; i++) {
config = configs[i];
ref = config.split(":"), kind = ref[0], prefix = ref[1];
if (this[kind] == null) {
throw Error("Unknown property mixin kind '" + kind + "'");
}
result = _.extend(result, this[kind](prefix));
}
return result;
};
module.exports = {
line: line,
fill: fill,
text: text,
create: create
};

View File

@ -0,0 +1,25 @@
var empty, union;
empty = function() {
return {
minX: Infinity,
minY: Infinity,
maxX: -Infinity,
maxY: -Infinity
};
};
union = function(a, b) {
var r;
r = {};
r.minX = Math.min(a.minX, b.minX);
r.maxX = Math.max(a.maxX, b.maxX);
r.minY = Math.min(a.minY, b.minY);
r.maxY = Math.max(a.maxY, b.maxY);
return r;
};
module.exports = {
empty: empty,
union: union
};

View File

@ -0,0 +1,100 @@
var fixup_ellipse, fixup_image_smoothing, fixup_line_dash, fixup_line_dash_offset, fixup_measure_text, get_scale_ratio;
fixup_line_dash = function(ctx) {
if (!ctx.setLineDash) {
ctx.setLineDash = function(dash) {
ctx.mozDash = dash;
return ctx.webkitLineDash = dash;
};
}
if (!ctx.getLineDash) {
return ctx.getLineDash = function() {
return ctx.mozDash;
};
}
};
fixup_line_dash_offset = function(ctx) {
ctx.setLineDashOffset = function(dash_offset) {
ctx.lineDashOffset = dash_offset;
ctx.mozDashOffset = dash_offset;
return ctx.webkitLineDashOffset = dash_offset;
};
return ctx.getLineDashOffset = function() {
return ctx.mozDashOffset;
};
};
fixup_image_smoothing = function(ctx) {
ctx.setImageSmoothingEnabled = function(value) {
ctx.imageSmoothingEnabled = value;
ctx.mozImageSmoothingEnabled = value;
ctx.oImageSmoothingEnabled = value;
return ctx.webkitImageSmoothingEnabled = value;
};
return ctx.getImageSmoothingEnabled = function() {
var ref;
return (ref = ctx.imageSmoothingEnabled) != null ? ref : true;
};
};
fixup_measure_text = function(ctx) {
if (ctx.measureText && (ctx.html5MeasureText == null)) {
ctx.html5MeasureText = ctx.measureText;
return ctx.measureText = function(text) {
var textMetrics;
textMetrics = ctx.html5MeasureText(text);
textMetrics.ascent = ctx.html5MeasureText("m").width * 1.6;
return textMetrics;
};
}
};
get_scale_ratio = function(ctx, hidpi) {
var backingStoreRatio, devicePixelRatio;
if (hidpi) {
devicePixelRatio = window.devicePixelRatio || 1;
backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
return devicePixelRatio / backingStoreRatio;
} else {
return 1;
}
};
fixup_ellipse = function(ctx) {
var ellipse_bezier;
ellipse_bezier = function(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise) {
var c, rx, ry;
if (anticlockwise == null) {
anticlockwise = false;
}
c = 0.551784;
ctx.translate(x, y);
ctx.rotate(rotation);
rx = radiusX;
ry = radiusY;
if (anticlockwise) {
rx = -radiusX;
ry = -radiusY;
}
ctx.moveTo(-rx, 0);
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) {
return ctx.ellipse = ellipse_bezier;
}
};
module.exports = {
fixup_image_smoothing: fixup_image_smoothing,
fixup_line_dash: fixup_line_dash,
fixup_line_dash_offset: fixup_line_dash_offset,
fixup_measure_text: fixup_measure_text,
get_scale_ratio: get_scale_ratio,
fixup_ellipse: fixup_ellipse
};

View File

@ -0,0 +1,117 @@
var _component2hex, color2hex, color2rgba, svg_colors, valid_rgb,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
svg_colors = require("./svg_colors");
_component2hex = function(v) {
var h;
h = Number(v).toString(16);
return h = h.length === 1 ? '0' + h : h;
};
color2hex = function(color) {
var hex, rgb, v;
color = color + '';
if (color.indexOf('#') === 0) {
return color;
} else if (svg_colors[color] != null) {
return svg_colors[color];
} else if (color.indexOf('rgb') === 0) {
rgb = color.match(/\d+/g);
hex = ((function() {
var j, len, results;
results = [];
for (j = 0, len = rgb.length; j < len; j++) {
v = rgb[j];
results.push(_component2hex(v));
}
return results;
})()).join('');
return '#' + hex.slice(0, 8);
} else {
return color;
}
};
color2rgba = function(color, alpha) {
var hex, i, rgba;
if (alpha == null) {
alpha = 1;
}
if (!color) {
return [0, 0, 0, 0];
}
hex = color2hex(color);
hex = hex.replace(/ |#/g, '');
if (hex.length <= 4) {
hex = hex.replace(/(.)/g, '$1$1');
}
hex = hex.match(/../g);
rgba = (function() {
var j, len, results;
results = [];
for (j = 0, len = hex.length; j < len; j++) {
i = hex[j];
results.push(parseInt(i, 16) / 255);
}
return results;
})();
while (rgba.length < 3) {
rgba.push(0);
}
if (rgba.length < 4) {
rgba.push(alpha);
}
return rgba.slice(0, 4);
};
valid_rgb = function(value) {
var contents, params, ref, rgb;
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 (new RegExp(".*?(\\.).*(,)").test(value)) {
throw new Error("color expects integers for rgb in rgb/rgba tuple, received " + value);
}
contents = value.replace(params.start, "").replace(")", "").split(',').map(parseFloat);
if (contents.length !== params.len) {
throw new Error("color expects rgba " + expect_len + "-tuple, received " + value);
}
if (params.alpha && !((0 <= (ref = contents[3]) && ref <= 1))) {
throw new Error("color expects rgba 4-tuple to have alpha value between 0 and 1");
}
if (indexOf.call((function() {
var j, len, ref1, results;
ref1 = contents.slice(0, 3);
results = [];
for (j = 0, len = ref1.length; j < len; j++) {
rgb = ref1[j];
results.push((0 <= rgb && rgb <= 255));
}
return results;
})(), false) >= 0) {
throw new Error("color expects rgb to have value between 0 and 255");
}
return true;
};
module.exports = {
color2hex: color2hex,
color2rgba: color2rgba,
valid_rgb: valid_rgb
};

View File

@ -0,0 +1,177 @@
var MultiDict, Set, _;
_ = require("underscore");
MultiDict = (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) {
var existing;
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");
}
existing = this._existing(key);
if (existing === null) {
return this._dict[key] = value;
} else if (_.isArray(existing)) {
return existing.push(value);
} else {
return this._dict[key] = [existing, value];
}
};
MultiDict.prototype.remove_value = function(key, value) {
var existing, new_array;
existing = this._existing(key);
if (_.isArray(existing)) {
new_array = _.without(existing, value);
if (new_array.length > 0) {
return this._dict[key] = new_array;
} else {
return delete this._dict[key];
}
} else if (_.isEqual(existing, value)) {
return delete this._dict[key];
}
};
MultiDict.prototype.get_one = function(key, duplicate_error) {
var existing;
existing = this._existing(key);
if (_.isArray(existing)) {
if (existing.length === 1) {
return existing[0];
} else {
throw new Error(duplicate_error);
}
} else {
return existing;
}
};
return MultiDict;
})();
Set = (function() {
function Set(array) {
if (!array) {
this.values = [];
} else {
if (array.constructor === Set) {
return new Set(array.values);
}
if (array.constructor === Array) {
this.values = Set.compact(array);
} else {
this.values = [array];
}
}
}
Set.compact = function(array) {
var item, j, len, newArray;
newArray = [];
for (j = 0, len = array.length; j < len; j++) {
item = array[j];
if (newArray.indexOf(item) === -1) {
newArray.push(item);
}
}
return newArray;
};
Set.prototype.push = function(item) {
if (this.missing(item)) {
return this.values.push(item);
}
};
Set.prototype.remove = function(item) {
var i;
i = this.values.indexOf(item);
return this.values = this.values.slice(0, i).concat(this.values.slice(i + 1));
};
Set.prototype.length = function() {
return this.values.length;
};
Set.prototype.includes = function(item) {
return this.values.indexOf(item) !== -1;
};
Set.prototype.missing = function(item) {
return !this.includes(item);
};
Set.prototype.slice = function(from, to) {
return this.values.slice(from, to);
};
Set.prototype.join = function(str) {
return this.values.join(str);
};
Set.prototype.toString = function() {
return this.join(', ');
};
Set.prototype.includes = function(item) {
return this.values.indexOf(item) !== -1;
};
Set.prototype.union = function(set) {
set = new Set(set);
return new Set(this.values.concat(set.values));
};
Set.prototype.intersect = function(set) {
var item, j, len, newSet, ref;
set = new Set(set);
newSet = new Set;
ref = set.values;
for (j = 0, len = ref.length; j < len; j++) {
item = ref[j];
if (this.includes(item) && set.includes(item)) {
newSet.push(item);
}
}
return newSet;
};
Set.prototype.diff = function(set) {
var item, j, len, newSet, ref;
set = new Set(set);
newSet = new Set;
ref = this.values;
for (j = 0, len = ref.length; j < len; j++) {
item = ref[j];
if (set.missing(item)) {
newSet.push(item);
}
}
return newSet;
};
return Set;
})();
module.exports = {
MultiDict: MultiDict,
Set: Set
};

View File

@ -0,0 +1,89 @@
var angle_between, angle_dist, angle_norm, array_max, array_min, atan2, random, rnorm;
array_min = function(arr) {
var len, min, val;
len = arr.length;
min = Infinity;
while (len--) {
val = arr[len];
if (val < min) {
min = val;
}
}
return min;
};
array_max = function(arr) {
var len, max, val;
len = arr.length;
max = -Infinity;
while (len--) {
val = arr[len];
if (val > max) {
max = val;
}
}
return max;
};
angle_norm = function(angle) {
while (angle < 0) {
angle += 2 * Math.PI;
}
while (angle > 2 * Math.PI) {
angle -= 2 * Math.PI;
}
return angle;
};
angle_dist = function(lhs, rhs) {
return Math.abs(angle_norm(lhs - rhs));
};
angle_between = function(mid, lhs, rhs, direction) {
var d;
mid = angle_norm(mid);
d = angle_dist(lhs, rhs);
if (direction === "anticlock") {
return angle_dist(lhs, mid) <= d && angle_dist(mid, rhs) <= d;
} else {
return !(angle_dist(lhs, mid) <= d && angle_dist(mid, rhs) <= d);
}
};
random = function() {
return Math.random();
};
atan2 = function(start, end) {
"Calculate the angle between a line containing start and end points (composed\nof [x, y] arrays) and the positive x-axis.";
return Math.atan2(end[1] - start[1], end[0] - start[0]);
};
rnorm = function(mu, sigma) {
var r1, r2, rn;
r1 = null;
r2 = null;
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;
}
}
rn = r2 / r1;
rn = mu + sigma * rn;
return rn;
};
module.exports = {
array_min: array_min,
array_max: array_max,
angle_norm: angle_norm,
angle_dist: angle_dist,
angle_between: angle_between,
atan2: atan2,
rnorm: rnorm,
random: random
};

View File

@ -0,0 +1,50 @@
var HasProps, _, convert_to_ref, create_ref, is_ref;
_ = require("underscore");
HasProps = require("../has_props");
create_ref = function(obj) {
var ref;
if (!(obj instanceof HasProps.constructor)) {
throw new Error("can only create refs for HasProps subclasses");
}
ref = {
'type': obj.type,
'id': obj.id
};
if (obj._subtype != null) {
ref['subtype'] = obj._subtype;
}
return ref;
};
is_ref = function(arg) {
var keys;
if (_.isObject(arg)) {
keys = _.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;
};
convert_to_ref = function(value) {
if (_.isArray(value)) {
return _.map(value, convert_to_ref);
} else {
if (value instanceof HasProps.constructor) {
return value.ref();
}
}
};
module.exports = {
convert_to_ref: convert_to_ref,
create_ref: create_ref,
is_ref: is_ref
};

View File

@ -0,0 +1,149 @@
module.exports = {
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"
};

View File

@ -0,0 +1,40 @@
var $, cache, get_text_height;
$ = require("jquery");
cache = {};
get_text_height = function(font) {
var block, body, div, result, text;
if (cache[font] != null) {
return cache[font];
}
text = $('<span>Hg</span>').css({
font: font
});
block = $('<div style="display: inline-block; width: 1px; height: 0px;"> </div>');
div = $('<div></div>');
div.append(text, block);
body = $('body');
body.append(div);
try {
result = {};
block.css({
verticalAlign: 'baseline'
});
result.ascent = block.offset().top - text.offset().top;
block.css({
verticalAlign: 'bottom'
});
result.height = block.offset().top - text.offset().top;
result.descent = result.height - result.ascent;
} finally {
div.remove();
}
cache[font] = result;
return result;
};
module.exports = {
get_text_height: get_text_height
};

View File

@ -0,0 +1,41 @@
var _delay_animation, delay_animation, throttle;
_delay_animation = function(f) {
return f();
};
delay_animation = (typeof window !== "undefined" && window !== null ? window.requestAnimationFrame : void 0) || (typeof window !== "undefined" && window !== null ? window.mozRequestAnimationFrame : void 0) || (typeof window !== "undefined" && window !== null ? window.webkitRequestAnimationFrame : void 0) || (typeof window !== "undefined" && window !== null ? window.msRequestAnimationFrame : void 0) || _delay_animation;
throttle = function(func, wait) {
var args, context, later, pending, previous, ref, result, timeout;
ref = [null, null, null, null], context = ref[0], args = ref[1], timeout = ref[2], result = ref[3];
previous = 0;
pending = false;
later = function() {
previous = new Date;
timeout = null;
pending = false;
return result = func.apply(context, args);
};
return function() {
var now, remaining;
now = new Date;
remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 && !pending) {
clearTimeout(timeout);
pending = true;
delay_animation(later);
} else if (!timeout && !pending) {
timeout = setTimeout((function() {
return delay_animation(later);
}), remaining);
}
return result;
};
};
module.exports = {
throttle: throttle
};

View File

@ -0,0 +1,39 @@
var _, patch;
_ = require("underscore");
patch = function() {
return _.uniqueId = function(prefix) {
var hexDigits, i, j, s, uuid;
s = [];
hexDigits = "0123456789ABCDEF";
for (i = j = 0; j <= 31; i = ++j) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[12] = "4";
s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1);
uuid = s.join("");
if (prefix) {
return prefix + "-" + uuid;
} else {
return uuid;
}
};
};
_.isNullOrUndefined = function(x) {
return _.isNull(x) || _.isUndefined(x);
};
_.setdefault = function(obj, key, value) {
if (_.has(obj, key)) {
return obj[key];
} else {
obj[key] = value;
return value;
}
};
module.exports = {
patch: patch
};

View File

@ -0,0 +1,890 @@
var $, ColumnDataSource, DEFAULT_TITLE, Document, DocumentChangedEvent, EQ, HasProps, ModelChangedEvent, Models, MultiDict, RootAddedEvent, RootRemovedEvent, Set, Solver, TitleChangedEvent, Variable, _, is_ref, js_version, logger, ref1, ref2,
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,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
_ = require("underscore");
$ = require("jquery");
Models = require("./base").Models;
js_version = require("./version");
ref1 = require("./core/layout/solver"), EQ = ref1.EQ, Solver = ref1.Solver, Variable = ref1.Variable;
logger = require("./core/logging").logger;
HasProps = require("./core/has_props");
is_ref = require("./core/util/refs").is_ref;
ref2 = require("./core/util/data_structures"), MultiDict = ref2.MultiDict, Set = ref2.Set;
ColumnDataSource = require("./models/sources/column_data_source");
DocumentChangedEvent = (function() {
function DocumentChangedEvent(document) {
this.document = document;
}
return DocumentChangedEvent;
})();
ModelChangedEvent = (function(superClass) {
extend(ModelChangedEvent, superClass);
function ModelChangedEvent(document, model1, attr1, old1, new_1) {
this.document = document;
this.model = model1;
this.attr = attr1;
this.old = old1;
this.new_ = new_1;
ModelChangedEvent.__super__.constructor.call(this, this.document);
}
ModelChangedEvent.prototype.json = function(references) {
var id, value, value_json, value_refs;
if (this.attr === 'id') {
console.log("'id' field is immutable and should never be in a ModelChangedEvent ", this);
throw new Error("'id' field should never change, whatever code just set it is wrong");
}
value = this.new_;
value_json = HasProps._value_to_json('new_', value, this.model);
value_refs = {};
HasProps._value_record_references(value, value_refs, true);
if (this.model.id in value_refs && this.model !== value) {
delete value_refs[this.model.id];
}
for (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);
TitleChangedEvent = (function(superClass) {
extend(TitleChangedEvent, superClass);
function TitleChangedEvent(document, title1) {
this.document = document;
this.title = title1;
TitleChangedEvent.__super__.constructor.call(this, this.document);
}
TitleChangedEvent.prototype.json = function(references) {
return {
'kind': 'TitleChanged',
'title': this.title
};
};
return TitleChangedEvent;
})(DocumentChangedEvent);
RootAddedEvent = (function(superClass) {
extend(RootAddedEvent, superClass);
function RootAddedEvent(document, model1) {
this.document = document;
this.model = model1;
RootAddedEvent.__super__.constructor.call(this, this.document);
}
RootAddedEvent.prototype.json = function(references) {
HasProps._value_record_references(this.model, references, true);
return {
'kind': 'RootAdded',
'model': this.model.ref()
};
};
return RootAddedEvent;
})(DocumentChangedEvent);
RootRemovedEvent = (function(superClass) {
extend(RootRemovedEvent, superClass);
function RootRemovedEvent(document, model1) {
this.document = document;
this.model = model1;
RootRemovedEvent.__super__.constructor.call(this, this.document);
}
RootRemovedEvent.prototype.json = function(references) {
return {
'kind': 'RootRemoved',
'model': this.model.ref()
};
};
return RootRemovedEvent;
})(DocumentChangedEvent);
DEFAULT_TITLE = "Bokeh Application";
Document = (function() {
function Document() {
this._title = DEFAULT_TITLE;
this._roots = [];
this._all_models = {};
this._all_models_by_name = new MultiDict();
this._all_models_freeze_count = 0;
this._callbacks = [];
this._doc_width = new Variable("document_width");
this._doc_height = new Variable("document_height");
this._solver = new Solver();
this._init_solver();
$(window).on("resize", $.proxy(this.resize, this));
}
Document.prototype._init_solver = function() {
var j, len, model, ref3, results;
this._solver.clear();
this._solver.add_edit_variable(this._doc_width);
this._solver.add_edit_variable(this._doc_height);
ref3 = this._roots;
results = [];
for (j = 0, len = ref3.length; j < len; j++) {
model = ref3[j];
if (model.layoutable) {
results.push(this._add_layoutable(model));
} else {
results.push(void 0);
}
}
return results;
};
Document.prototype.solver = function() {
return this._solver;
};
Document.prototype.resize = function() {
this._resize();
return this._resize();
};
Document.prototype._resize = function() {
var height, j, len, measuring, ref3, root, root_div, target_height, vars, width;
ref3 = this._roots;
for (j = 0, len = ref3.length; j < len; j++) {
root = ref3[j];
if (root.layoutable !== true) {
continue;
}
vars = root.get_constrained_variables();
if ((vars.width == null) && (vars.height == null)) {
continue;
}
root_div = $("#modelid_" + root.id);
target_height = 0;
measuring = root_div;
while (target_height === 0) {
measuring = measuring.parent();
target_height = measuring.height();
}
width = measuring.width();
height = target_height;
if (vars.width != null) {
logger.debug("Suggest width on Document -- " + width);
this._solver.suggest_value(this._doc_width, width);
}
if (vars.height != null) {
logger.debug("Suggest height on Document -- " + height);
this._solver.suggest_value(this._doc_height, height);
}
}
this._solver.update_variables(false);
return this._solver.trigger('resize');
};
Document.prototype.clear = function() {
var results;
this._push_all_models_freeze();
try {
results = [];
while (this._roots.length > 0) {
results.push(this.remove_root(this._roots[0]));
}
return results;
} finally {
this._pop_all_models_freeze();
}
};
Document.prototype._destructively_move = function(dest_doc) {
var j, l, len, len1, r, roots;
if (dest_doc === this) {
throw new Error("Attempted to overwrite a document with itself");
}
dest_doc.clear();
roots = [];
this._push_all_models_freeze();
try {
while (this._roots.length > 0) {
this.remove_root(this._roots[0]);
roots.push(r);
}
} finally {
this._pop_all_models_freeze();
}
for (j = 0, len = roots.length; j < len; j++) {
r = roots[j];
if (r.document !== null) {
throw new Error("Somehow we didn't detach " + r);
}
}
if (_all_models.length !== 0) {
throw new Error("_all_models still had stuff in it: " + this._all_models);
}
for (l = 0, len1 = roots.length; l < len1; l++) {
r = roots[l];
dest_doc.add_root(r);
}
return dest_doc.set_title(this._title);
};
Document.prototype._push_all_models_freeze = function() {
return 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) {
return this._recompute_all_models();
}
};
Document.prototype._invalidate_all_models = function() {
logger.debug("invalidating document models");
if (this._all_models_freeze_count === 0) {
return this._recompute_all_models();
}
};
Document.prototype._recompute_all_models = function() {
var a, d, j, l, len, len1, len2, len3, m, n, name, new_all_models_set, o, old_all_models_set, r, recomputed, ref3, ref4, ref5, ref6, to_attach, to_detach;
new_all_models_set = new Set();
ref3 = this._roots;
for (j = 0, len = ref3.length; j < len; j++) {
r = ref3[j];
new_all_models_set = new_all_models_set.union(r.references());
}
old_all_models_set = new Set(_.values(this._all_models));
to_detach = old_all_models_set.diff(new_all_models_set);
to_attach = new_all_models_set.diff(old_all_models_set);
recomputed = {};
ref4 = new_all_models_set.values;
for (l = 0, len1 = ref4.length; l < len1; l++) {
m = ref4[l];
recomputed[m.id] = m;
}
ref5 = to_detach.values;
for (n = 0, len2 = ref5.length; n < len2; n++) {
d = ref5[n];
d.detach_document();
name = d.get('name');
if (name !== null) {
this._all_models_by_name.remove_value(name, d);
}
}
ref6 = to_attach.values;
for (o = 0, len3 = ref6.length; o < len3; o++) {
a = ref6[o];
a.attach_document(this);
name = a.get('name');
if (name !== null) {
this._all_models_by_name.add_value(name, a);
}
}
return this._all_models = recomputed;
};
Document.prototype.roots = function() {
return this._roots;
};
Document.prototype._add_layoutable = function(model) {
var constraint, constraints, edit_variable, editables, j, l, len, len1, ref3, strength, vars;
if (model.layoutable !== true) {
throw new Error("Cannot add non-layoutable - " + model);
}
editables = model.get_edit_variables();
constraints = model.get_constraints();
vars = model.get_constrained_variables();
for (j = 0, len = editables.length; j < len; j++) {
ref3 = editables[j], edit_variable = ref3.edit_variable, strength = ref3.strength;
this._solver.add_edit_variable(edit_variable, strength);
}
for (l = 0, len1 = constraints.length; l < len1; l++) {
constraint = constraints[l];
this._solver.add_constraint(constraint);
}
if (vars.width != null) {
this._solver.add_constraint(EQ(vars.width, this._doc_width));
}
if (vars.height != null) {
this._solver.add_constraint(EQ(vars.height, this._doc_height));
}
return this._solver.update_variables();
};
Document.prototype.add_root = function(model) {
logger.debug("Adding root: " + model);
if (indexOf.call(this._roots, model) >= 0) {
return;
}
this._push_all_models_freeze();
try {
this._roots.push(model);
model._is_root = true;
} finally {
this._pop_all_models_freeze();
}
this._init_solver();
return this._trigger_on_change(new RootAddedEvent(this, model));
};
Document.prototype.remove_root = function(model) {
var i;
i = this._roots.indexOf(model);
if (i < 0) {
return;
}
this._push_all_models_freeze();
try {
this._roots.splice(i, 1);
model._is_root = false;
} finally {
this._pop_all_models_freeze();
}
this._init_solver();
return this._trigger_on_change(new RootRemovedEvent(this, model));
};
Document.prototype.title = function() {
return this._title;
};
Document.prototype.set_title = function(title) {
if (title !== this._title) {
this._title = title;
return this._trigger_on_change(new TitleChangedEvent(this, title));
}
};
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 (indexOf.call(this._callbacks, callback) >= 0) {
return;
}
return this._callbacks.push(callback);
};
Document.prototype.remove_on_change = function(callback) {
var i;
i = this._callbacks.indexOf(callback);
if (i >= 0) {
return this._callbacks.splice(i, 1);
}
};
Document.prototype._trigger_on_change = function(event) {
var cb, j, len, ref3, results;
ref3 = this._callbacks;
results = [];
for (j = 0, len = ref3.length; j < len; j++) {
cb = ref3[j];
results.push(cb(event));
}
return results;
};
Document.prototype._notify_change = function(model, attr, old, new_) {
if (attr === 'name') {
this._all_models_by_name.remove_value(old, model);
if (new_ !== null) {
this._all_models_by_name.add_value(new_, model);
}
}
return this._trigger_on_change(new ModelChangedEvent(this, model, attr, old, new_));
};
Document._references_json = function(references, include_defaults) {
var j, len, r, ref, references_json;
if (include_defaults == null) {
include_defaults = true;
}
references_json = [];
for (j = 0, len = references.length; j < len; j++) {
r = references[j];
ref = r.ref();
ref['attributes'] = r.attributes_as_json(include_defaults);
delete ref['attributes']['id'];
references_json.push(ref);
}
return references_json;
};
Document._instantiate_object = function(obj_id, obj_type, obj_attrs) {
var full_attrs, model;
full_attrs = _.extend({}, obj_attrs, {
id: obj_id
});
model = Models(obj_type);
return new model(full_attrs, {
silent: true,
defer_initialization: true
});
};
Document._instantiate_references_json = function(references_json, existing_models) {
var instance, j, len, obj, obj_attrs, obj_id, obj_type, references;
references = {};
for (j = 0, len = references_json.length; j < len; j++) {
obj = references_json[j];
obj_id = obj['id'];
obj_type = obj['type'];
obj_attrs = obj['attributes'];
if (obj_id in existing_models) {
instance = existing_models[obj_id];
} else {
instance = Document._instantiate_object(obj_id, obj_type, obj_attrs);
if ('subtype' in obj) {
instance.set_subtype(obj['subtype']);
}
}
references[instance.id] = instance;
}
return references;
};
Document._resolve_refs = function(value, old_references, new_references) {
var resolve_array, resolve_dict, resolve_ref;
resolve_ref = function(v) {
if (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 (_.isArray(v)) {
return resolve_array(v);
} else if (_.isObject(v)) {
return resolve_dict(v);
} else {
return v;
}
};
resolve_dict = function(dict) {
var k, resolved, v;
resolved = {};
for (k in dict) {
v = dict[k];
resolved[k] = resolve_ref(v);
}
return resolved;
};
resolve_array = function(array) {
var j, len, results, v;
results = [];
for (j = 0, len = array.length; j < len; j++) {
v = array[j];
results.push(resolve_ref(v));
}
return results;
};
return resolve_ref(value);
};
Document._initialize_references_json = function(references_json, old_references, new_references) {
var foreach_depth_first, instance, j, len, obj, obj_attrs, obj_id, to_update, was_new;
to_update = {};
for (j = 0, len = references_json.length; j < len; j++) {
obj = references_json[j];
obj_id = obj['id'];
obj_attrs = obj['attributes'];
was_new = false;
instance = obj_id in old_references ? old_references[obj_id] : (was_new = true, new_references[obj_id]);
obj_attrs = Document._resolve_refs(obj_attrs, old_references, new_references);
to_update[instance.id] = [instance, obj_attrs, was_new];
}
foreach_depth_first = function(items, f) {
var already_started, foreach_value, k, results, v;
already_started = {};
foreach_value = function(v, f) {
var a, attrs, e, k, l, len1, ref3, results, results1, same_as_v;
if (v instanceof HasProps) {
if (!(v.id in already_started) && v.id in items) {
already_started[v.id] = true;
ref3 = items[v.id], same_as_v = ref3[0], attrs = ref3[1], was_new = ref3[2];
for (a in attrs) {
e = attrs[a];
foreach_value(e, f);
}
return f(v, attrs, was_new);
}
} else if (_.isArray(v)) {
results = [];
for (l = 0, len1 = v.length; l < len1; l++) {
e = v[l];
results.push(foreach_value(e, f));
}
return results;
} else if (_.isObject(v)) {
results1 = [];
for (k in v) {
e = v[k];
results1.push(foreach_value(e, f));
}
return results1;
}
};
results = [];
for (k in items) {
v = items[k];
results.push(foreach_value(v[0], f));
}
return results;
};
foreach_depth_first(to_update, function(instance, attrs, was_new) {
if (was_new) {
return instance.set(attrs);
}
});
return foreach_depth_first(to_update, function(instance, attrs, was_new) {
if (was_new) {
return instance.initialize(attrs);
}
});
};
Document._event_for_attribute_change = function(changed_obj, key, new_value, doc, value_refs) {
var changed_model, event;
changed_model = doc.get_model_by_id(changed_obj.id);
if (!changed_model.attribute_is_serializable(key)) {
return null;
}
event = {
'kind': 'ModelChanged',
'model': {
id: changed_obj.id,
type: changed_obj.type
},
'attr': key,
'new': new_value
};
HasProps._json_record_references(doc, new_value, value_refs, true);
return event;
};
Document._events_to_sync_objects = function(from_obj, to_obj, to_doc, value_refs) {
var added, events, from_keys, j, key, l, len, len1, len2, n, new_value, old_value, removed, shared, to_keys;
from_keys = Object.keys(from_obj.attributes);
to_keys = Object.keys(to_obj.attributes);
removed = _.difference(from_keys, to_keys);
added = _.difference(to_keys, from_keys);
shared = _.intersection(from_keys, to_keys);
events = [];
for (j = 0, len = removed.length; j < len; j++) {
key = removed[j];
logger.warn("Server sent key " + key + " but we don't seem to have it in our JSON");
}
for (l = 0, len1 = added.length; l < len1; l++) {
key = added[l];
new_value = to_obj.attributes[key];
events.push(Document._event_for_attribute_change(from_obj, key, new_value, to_doc, value_refs));
}
for (n = 0, len2 = shared.length; n < len2; n++) {
key = shared[n];
old_value = from_obj.attributes[key];
new_value = to_obj.attributes[key];
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 (!_.isEqual(old_value, new_value)) {
events.push(Document._event_for_attribute_change(from_obj, key, new_value, to_doc, value_refs));
}
}
}
return _.filter(events, function(e) {
return e !== null;
});
};
Document._compute_patch_since_json = function(from_json, to_doc) {
var events, from_references, from_root_ids, from_roots, id, include_defaults, j, l, len, len1, model, r, ref3, ref4, ref5, refs, to_json, to_references, to_root_ids, to_roots, update_model_events, value_refs;
to_json = to_doc.to_json(include_defaults = false);
refs = function(json) {
var j, len, obj, ref3, result;
result = {};
ref3 = json['roots']['references'];
for (j = 0, len = ref3.length; j < len; j++) {
obj = ref3[j];
result[obj.id] = obj;
}
return result;
};
from_references = refs(from_json);
from_roots = {};
from_root_ids = [];
ref3 = from_json['roots']['root_ids'];
for (j = 0, len = ref3.length; j < len; j++) {
r = ref3[j];
from_roots[r] = from_references[r];
from_root_ids.push(r);
}
to_references = refs(to_json);
to_roots = {};
to_root_ids = [];
ref4 = to_json['roots']['root_ids'];
for (l = 0, len1 = ref4.length; l < len1; l++) {
r = ref4[l];
to_roots[r] = to_references[r];
to_root_ids.push(r);
}
from_root_ids.sort();
to_root_ids.sort();
if (_.difference(from_root_ids, to_root_ids).length > 0 || _.difference(to_root_ids, from_root_ids).length > 0) {
throw new Error("Not implemented: computing add/remove of document roots");
}
value_refs = {};
events = [];
ref5 = to_doc._all_models;
for (id in ref5) {
model = ref5[id];
if (id in from_references) {
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 {
'events': events,
'references': Document._references_json(_.values(value_refs), include_defaults = false)
};
};
Document.prototype.to_json_string = function(include_defaults) {
if (include_defaults == null) {
include_defaults = true;
}
return JSON.stringify(this.to_json(include_defaults));
};
Document.prototype.to_json = function(include_defaults) {
var j, len, r, ref3, root_ids, root_references;
if (include_defaults == null) {
include_defaults = true;
}
root_ids = [];
ref3 = this._roots;
for (j = 0, len = ref3.length; j < len; j++) {
r = ref3[j];
root_ids.push(r.id);
}
root_references = _.values(this._all_models);
return {
'title': this._title,
'roots': {
'root_ids': root_ids,
'references': Document._references_json(root_references, include_defaults)
}
};
};
Document.from_json_string = function(s) {
var json;
if (s === null || (s == null)) {
throw new Error("JSON string is " + (typeof s));
}
json = JSON.parse(s);
return Document.from_json(json);
};
Document.from_json = function(json) {
var doc, j, len, py_version, r, references, references_json, root_ids, roots_json, versions_string;
logger.debug("Creating Document from JSON");
if (typeof json !== 'object') {
throw new Error("JSON object has wrong type " + (typeof json));
}
py_version = json['version'];
versions_string = "Library versions: JS (" + js_version + ") / Python (" + py_version + ")";
if (py_version.indexOf('-') < 0 && js_version !== py_version) {
logger.warn("JS/Python version mismatch");
logger.warn(versions_string);
} else {
logger.debug(versions_string);
}
roots_json = json['roots'];
root_ids = roots_json['root_ids'];
references_json = roots_json['references'];
references = Document._instantiate_references_json(references_json, {});
Document._initialize_references_json(references_json, {}, references);
doc = new Document();
for (j = 0, len = root_ids.length; j < len; j++) {
r = root_ids[j];
doc.add_root(references[r]);
}
doc.set_title(json['title']);
return doc;
};
Document.prototype.replace_with_json = function(json) {
var replacement;
replacement = Document.from_json(json);
return 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 event, j, json_events, len, references, result;
references = {};
json_events = [];
for (j = 0, len = events.length; j < len; j++) {
event = events[j];
if (event.document !== this) {
console.log("Cannot create a patch using events from a different document, event had ", event.document, " we are ", this);
throw new Error("Cannot create a patch using events from a different document");
}
json_events.push(event.json(references));
}
return result = {
events: json_events,
references: Document._references_json(_.values(references))
};
};
Document.prototype.apply_json_patch_string = function(patch) {
return this.apply_json_patch(JSON.parse(patch));
};
Document.prototype.apply_json_patch = function(patch) {
var attr, column_source, column_source_id, data, event_json, events_json, id, j, l, len, len1, model_id, new_references, obj1, old_references, patched_id, patched_obj, patches, references, references_json, results, rollover, root_id, root_obj, value;
references_json = patch['references'];
events_json = patch['events'];
references = Document._instantiate_references_json(references_json, this._all_models);
for (j = 0, len = events_json.length; j < len; j++) {
event_json = events_json[j];
if ('model' in event_json) {
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)) {
console.log("Got an event for unknown model ", event_json['model']);
throw new Error("event model wasn't known");
}
}
}
}
old_references = {};
new_references = {};
for (id in references) {
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);
results = [];
for (l = 0, len1 = events_json.length; l < len1; l++) {
event_json = events_json[l];
if (event_json['kind'] === 'ModelChanged') {
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");
}
patched_obj = this._all_models[patched_id];
attr = event_json['attr'];
value = Document._resolve_refs(event_json['new'], old_references, new_references);
results.push(patched_obj.set((
obj1 = {},
obj1["" + attr] = value,
obj1
)));
} else if (event_json['kind'] === 'ColumnsStreamed') {
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");
}
column_source = this._all_models[column_source_id];
if (!(column_source instanceof ColumnDataSource.Model)) {
throw new Error("Cannot stream to non-ColumnDataSource");
}
data = event_json['data'];
rollover = event_json['rollover'];
results.push(column_source.stream(data, rollover));
} else if (event_json['kind'] === 'ColumnsPatched') {
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");
}
column_source = this._all_models[column_source_id];
if (!(column_source instanceof ColumnDataSource.Model)) {
throw new Error("Cannot patch non-ColumnDataSource");
}
patches = event_json['patches'];
results.push(column_source.patch(patches));
} else if (event_json['kind'] === 'RootAdded') {
root_id = event_json['model']['id'];
root_obj = references[root_id];
results.push(this.add_root(root_obj));
} else if (event_json['kind'] === 'RootRemoved') {
root_id = event_json['model']['id'];
root_obj = references[root_id];
results.push(this.remove_root(root_obj));
} else if (event_json['kind'] === 'TitleChanged') {
results.push(this.set_title(event_json['title']));
} else {
throw new Error("Unknown patch event " + JSON.stringify(event_json));
}
}
return results;
};
return Document;
})();
module.exports = {
Document: Document,
DocumentChangedEvent: DocumentChangedEvent,
ModelChangedEvent: ModelChangedEvent,
TitleChangedEvent: TitleChangedEvent,
RootAddedEvent: RootAddedEvent,
RootRemovedEvent: RootRemovedEvent,
DEFAULT_TITLE: DEFAULT_TITLE
};

View File

@ -0,0 +1,285 @@
var $, BOKEH_ROOT, Backbone, Document, Promise, RootAddedEvent, RootRemovedEvent, TitleChangedEvent, _, _create_view, _get_session, _handle_notebook_comms, _init_comms, _render_document_to_element, _sessions, _update_comms_callback, add_document_from_session, add_document_standalone, add_document_static, add_model_from_session, add_model_static, base, embed_items, fill_render_item_from_script_tag, inject_css, inject_raw_css, logger, pull_session, ref, ref1, set_log_level;
$ = require("jquery");
_ = require("underscore");
Backbone = require("backbone");
Promise = require("es6-promise").Promise;
base = require("./base");
pull_session = require("./client").pull_session;
ref = require("./core/logging"), logger = ref.logger, set_log_level = ref.set_log_level;
ref1 = require("./document"), Document = ref1.Document, RootAddedEvent = ref1.RootAddedEvent, RootRemovedEvent = ref1.RootRemovedEvent, TitleChangedEvent = ref1.TitleChangedEvent;
BOKEH_ROOT = "bk-root";
_handle_notebook_comms = function(msg) {
var data;
logger.debug("handling notebook comms");
data = JSON.parse(msg.content.data);
if ('events' in data && 'references' in data) {
return this.apply_json_patch(data);
} else if ('doc' in data) {
return this.replace_with_json(data['doc']);
} else {
throw new Error("handling notebook comms message: ", msg);
}
};
_update_comms_callback = function(target, doc, comm) {
if (target === comm.target_name) {
return comm.on_msg(_.bind(_handle_notebook_comms, doc));
}
};
_init_comms = function(target, doc) {
var comm_manager, e, error1, id, promise, ref2, update_comms;
if ((typeof Jupyter !== "undefined" && Jupyter !== null) && (Jupyter.notebook.kernel != null)) {
logger.info("Registering Jupyter comms for target " + target);
comm_manager = Jupyter.notebook.kernel.comm_manager;
update_comms = _.partial(_update_comms_callback, target, doc);
ref2 = comm_manager.comms;
for (id in ref2) {
promise = ref2[id];
promise.then(update_comms);
}
try {
return comm_manager.register_target(target, function(comm, msg) {
logger.info("Registering Jupyter comms for target " + target);
return comm.on_msg(_.bind(_handle_notebook_comms, doc));
});
} catch (error1) {
e = error1;
return logger.warn("Jupyter comms failed to register. push_notebook() will not function. (exception reported: " + e + ")");
}
} else {
return console.warn('Jupyter notebooks comms not available. push_notebook() will not function');
}
};
_create_view = function(model) {
var view;
view = new model.default_view({
model: model
});
base.index[model.id] = view;
return view;
};
_render_document_to_element = function(element, document, use_for_title) {
var i, len, model, ref2, render_model, unrender_model, views;
views = {};
render_model = function(model) {
var view;
view = _create_view(model);
views[model.id] = view;
return $(element).append(view.$el);
};
unrender_model = function(model) {
var view;
if (model.id in views) {
view = views[model.id];
$(element).remove(view.$el);
delete views[model.id];
return delete base.index[model.id];
}
};
ref2 = document.roots();
for (i = 0, len = ref2.length; i < len; i++) {
model = ref2[i];
render_model(model);
}
if (use_for_title) {
window.document.title = document.title();
}
document.on_change(function(event) {
if (event instanceof RootAddedEvent) {
return render_model(event.model);
} else if (event instanceof RootRemovedEvent) {
return unrender_model(event.model);
} else if (use_for_title && event instanceof TitleChangedEvent) {
return window.document.title = event.title;
}
});
return views;
};
add_model_static = function(element, model_id, doc) {
var model, view;
model = doc.get_model_by_id(model_id);
if (model == null) {
throw new Error("Model " + model_id + " was not in document " + doc);
}
view = _create_view(model);
return _.delay(function() {
return $(element).replaceWith(view.$el);
});
};
add_document_static = function(element, doc, use_for_title) {
return _.delay(function() {
return _render_document_to_element($(element), doc, use_for_title);
});
};
add_document_standalone = function(document, element, use_for_title) {
if (use_for_title == null) {
use_for_title = false;
}
return _render_document_to_element($(element), document, use_for_title);
};
_sessions = {};
_get_session = function(websocket_url, session_id) {
var subsessions;
if ((websocket_url == null) || websocket_url === null) {
throw new Error("Missing websocket_url");
}
if (!(websocket_url in _sessions)) {
_sessions[websocket_url] = {};
}
subsessions = _sessions[websocket_url];
if (!(session_id in subsessions)) {
subsessions[session_id] = pull_session(websocket_url, session_id);
}
return subsessions[session_id];
};
add_document_from_session = function(element, websocket_url, session_id, use_for_title) {
var promise;
promise = _get_session(websocket_url, session_id);
return promise.then(function(session) {
return _render_document_to_element(element, session.document, use_for_title);
}, function(error) {
logger.error("Failed to load Bokeh session " + session_id + ": " + error);
throw error;
});
};
add_model_from_session = function(element, websocket_url, model_id, session_id) {
var promise;
promise = _get_session(websocket_url, session_id);
return promise.then(function(session) {
var model, view;
model = session.document.get_model_by_id(model_id);
if (model == null) {
throw new Error("Did not find model " + model_id + " in session");
}
view = _create_view(model);
return $(element).replaceWith(view.$el);
}, function(error) {
logger.error("Failed to load Bokeh session " + session_id + ": " + error);
throw error;
});
};
inject_css = function(url) {
var link;
link = $("<link href='" + url + "' rel='stylesheet' type='text/css'>");
return $('body').append(link);
};
inject_raw_css = function(css) {
var style;
style = $("<style>").html(css);
return $('body').append(style);
};
fill_render_item_from_script_tag = function(script, item) {
var info;
info = script.data();
if ((info.bokehLogLevel != null) && info.bokehLogLevel.length > 0) {
set_log_level(info.bokehLogLevel);
}
if ((info.bokehDocId != null) && info.bokehDocId.length > 0) {
item['docid'] = info.bokehDocId;
}
if ((info.bokehModelId != null) && info.bokehModelId.length > 0) {
item['modelid'] = info.bokehModelId;
}
if ((info.bokehSessionId != null) && info.bokehSessionId.length > 0) {
item['sessionid'] = info.bokehSessionId;
}
return logger.info("Will inject Bokeh script tag with params " + (JSON.stringify(item)));
};
embed_items = function(docs_json, render_items, websocket_url) {
var container, docid, docs, elem, element_id, i, item, len, promise, results, use_for_title;
if (websocket_url == null) {
websocket_url = null;
}
docs = {};
for (docid in docs_json) {
docs[docid] = Document.from_json(docs_json[docid]);
}
results = [];
for (i = 0, len = render_items.length; i < len; i++) {
item = render_items[i];
if (item.notebook_comms_target != null) {
_init_comms(item.notebook_comms_target, docs[docid]);
}
element_id = item['elementid'];
elem = $('#' + element_id);
if (elem.length === 0) {
throw new Error("Error rendering Bokeh model: could not find tag with id: " + element_id);
}
if (elem.length > 1) {
throw new Error("Error rendering Bokeh model: found too many tags with id: " + element_id);
}
if (!document.body.contains(elem[0])) {
throw new Error("Error rendering Bokeh model: element with id '" + element_id + "' must be under <body>");
}
if (elem.prop("tagName") === "SCRIPT") {
fill_render_item_from_script_tag(elem, item);
container = $('<div>', {
"class": BOKEH_ROOT
});
elem.replaceWith(container);
elem = container;
}
use_for_title = (item.use_for_title != null) && item.use_for_title;
promise = null;
if (item.modelid != null) {
if (item.docid != null) {
add_model_static(elem, item.modelid, docs[item.docid]);
} else if (item.sessionid != null) {
promise = add_model_from_session(elem, websocket_url, item.modelid, item.sessionid);
} else {
throw new Error("Error rendering Bokeh model " + item['modelid'] + " to element " + element_id + ": no document ID or session ID specified");
}
} else {
if (item.docid != null) {
add_document_static(elem, docs[item.docid], use_for_title);
} else if (item.sessionid != null) {
promise = add_document_from_session(elem, websocket_url, item.sessionid, use_for_title);
} else {
throw new Error("Error rendering Bokeh document to element " + element_id + ": no document ID or session ID specified");
}
}
if (promise !== null) {
results.push(promise.then(function(value) {
return console.log("Bokeh items were rendered successfully");
}, function(error) {
return console.log("Error rendering Bokeh items ", error);
}));
} else {
results.push(void 0);
}
}
return results;
};
module.exports = {
embed_items: embed_items,
add_document_static: add_document_static,
add_document_standalone: add_document_standalone,
inject_css: inject_css,
inject_raw_css: inject_raw_css,
BOKEH_ROOT: BOKEH_ROOT
};

View File

@ -0,0 +1,35 @@
var Bokeh, _, logging;
_ = require("underscore");
Bokeh = {};
Bokeh.require = require;
Bokeh.version = require("./version");
Bokeh._ = require("underscore");
Bokeh.$ = require("jquery");
Bokeh.Backbone = require("backbone");
Bokeh.Backbone.$ = Bokeh.$;
logging = require("./core/logging");
Bokeh.logger = logging.logger;
Bokeh.set_log_level = logging.set_log_level;
Bokeh.index = require("./base").index;
Bokeh.embed = require("./embed");
Bokeh.safely = require("./safely");
Bokeh.Models = require("./base").Models;
Bokeh.Bokeh = Bokeh;
module.exports = Bokeh;

View File

@ -0,0 +1,71 @@
var HasProps, Model, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
HasProps = require("./core/has_props");
p = require("./core/properties");
Model = (function(superClass) {
extend(Model, superClass);
function Model() {
return Model.__super__.constructor.apply(this, arguments);
}
Model.prototype.type = "Model";
Model.prototype._coords = [];
Model.coords = function(coords) {
var _coords, i, len, ref1, result, x, y;
_coords = this.prototype._coords.concat(coords);
this.prototype._coords = _coords;
result = {};
for (i = 0, len = coords.length; i < len; i++) {
ref1 = coords[i], x = ref1[0], y = ref1[1];
result[x] = [p.NumberSpec];
result[y] = [p.NumberSpec];
}
return this.define(result);
};
Model.define({
tags: [p.Array, []],
name: [p.String]
});
Model.prototype.select = function(selector) {
if (selector.prototype instanceof Model) {
return this.references().filter(function(ref) {
return ref instanceof selector;
});
} else if (_.isString(selector)) {
return this.references().filter(function(ref) {
return ref.name === selector;
});
} else {
throw new Error("invalid selector");
}
};
Model.prototype.select_one = function(selector) {
var result;
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;
})(HasProps);
module.exports = Model;

View File

@ -0,0 +1,72 @@
var Annotation, AnnotationView, Renderer, SidePanel, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
SidePanel = require("../../core/layout/side_panel");
p = require("../../core/properties");
Renderer = require("../renderers/renderer");
AnnotationView = (function(superClass) {
extend(AnnotationView, superClass);
function AnnotationView() {
return AnnotationView.__super__.constructor.apply(this, arguments);
}
AnnotationView.prototype._get_panel_offset = function() {
var x, y;
x = this.model.panel._left._value;
y = this.model.panel._bottom._value;
return {
x: x,
y: -y
};
};
AnnotationView.prototype._get_size = function() {
return -1;
};
return AnnotationView;
})(Renderer.View);
Annotation = (function(superClass) {
extend(Annotation, superClass);
function Annotation() {
return Annotation.__super__.constructor.apply(this, arguments);
}
Annotation.prototype.type = 'Annotation';
Annotation.prototype.default_view = AnnotationView;
Annotation.define({
plot: [p.Instance]
});
Annotation.override({
level: 'annotation'
});
Annotation.prototype.add_panel = function(side) {
this.panel = new SidePanel.Model({
side: side
});
this.panel.attach_document(this.document);
return this.level = 'overlay';
};
return Annotation;
})(Renderer.Model);
module.exports = {
Model: Annotation,
View: AnnotationView
};

View File

@ -0,0 +1,144 @@
var Annotation, Arrow, ArrowView, ColumnDataSource, OpenHead, _, atan2, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Annotation = require("./annotation");
OpenHead = require("./arrow_head").OpenHead;
ColumnDataSource = require("../sources/column_data_source");
p = require("../../core/properties");
atan2 = require("../../core/util/math").atan2;
ArrowView = (function(superClass) {
extend(ArrowView, superClass);
function ArrowView() {
return ArrowView.__super__.constructor.apply(this, arguments);
}
ArrowView.prototype.initialize = function(options) {
ArrowView.__super__.initialize.call(this, options);
if (this.mget('source') == null) {
this.mset('source', new ColumnDataSource.Model());
}
this.canvas = this.plot_model.get('canvas');
this.xmapper = this.plot_view.frame.get('x_mappers')[this.mget("x_range_name")];
this.ymapper = this.plot_view.frame.get('y_mappers')[this.mget("y_range_name")];
return this.set_data();
};
ArrowView.prototype.bind_bokeh_events = function() {
this.listenTo(this.model, 'change', this.plot_view.request_render);
return this.listenTo(this.mget('source'), 'change', function() {
this.set_data();
return this.plot_view.request_render();
});
};
ArrowView.prototype.set_data = function() {
ArrowView.__super__.set_data.call(this, this.mget('source'));
return this.set_visuals(this.mget('source'));
};
ArrowView.prototype._map_data = function() {
var end, start, x_name, y_name;
if (this.mget('start_units') === 'data') {
start = this.plot_view.map_to_screen(this._x_start, this._y_start, x_name = this.mget('x_range_name'), y_name = this.mget('y_range_name'));
} else {
start = [this.canvas.v_vx_to_sx(this._x_start), this.canvas.v_vy_to_sy(this._y_start)];
}
if (this.mget('end_units') === 'data') {
end = this.plot_view.map_to_screen(this._x_end, this._y_end, x_name = this.mget('x_range_name'), y_name = this.mget('y_range_name'));
} else {
end = [this.canvas.v_vx_to_sx(this._x_end), this.canvas.v_vy_to_sy(this._y_end)];
}
return [start, end];
};
ArrowView.prototype.render = function() {
var ref;
ref = this._map_data(), this.start = ref[0], this.end = ref[1];
this._draw_arrow_body();
if (this.mget('end') != null) {
this._draw_arrow_head(this.mget('end'), this.start, this.end);
}
if (this.mget('start') != null) {
return this._draw_arrow_head(this.mget('start'), this.end, this.start);
}
};
ArrowView.prototype._draw_arrow_body = function() {
var ctx, i, j, ref;
ctx = this.plot_view.canvas_view.ctx;
ctx.save();
for (i = j = 0, ref = this._x_start.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
this.visuals.line.set_vectorize(ctx, i);
ctx.beginPath();
ctx.moveTo(this.start[0][i], this.start[1][i]);
ctx.lineTo(this.end[0][i], this.end[1][i]);
if (this.visuals.line.doit) {
ctx.stroke();
}
}
return ctx.restore();
};
ArrowView.prototype._draw_arrow_head = function(head, start, end) {
var angle, ctx, i, j, ref, results;
ctx = this.plot_view.canvas_view.ctx;
results = [];
for (i = j = 0, ref = this._x_start.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
angle = Math.PI / 2 + 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);
head.render(ctx, i);
results.push(ctx.restore());
}
return results;
};
return ArrowView;
})(Annotation.View);
Arrow = (function(superClass) {
extend(Arrow, superClass);
function Arrow() {
return Arrow.__super__.constructor.apply(this, arguments);
}
Arrow.prototype.default_view = ArrowView;
Arrow.prototype.type = 'Arrow';
Arrow.mixins(['line']);
Arrow.define({
x_start: [p.NumberSpec],
y_start: [p.NumberSpec],
start_units: [p.String, 'data'],
start: [p.Instance, null],
x_end: [p.NumberSpec],
y_end: [p.NumberSpec],
end_units: [p.String, 'data'],
end: [p.Instance, new OpenHead.Model({})],
source: [p.Instance],
x_range_name: [p.String, 'default'],
y_range_name: [p.String, 'default']
});
return Arrow;
})(Annotation.Model);
module.exports = {
Model: Arrow,
View: ArrowView
};

View File

@ -0,0 +1,178 @@
var Annotation, ArrowHead, NormalHead, OpenHead, Renderer, VeeHead, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
Annotation = require("./annotation");
Renderer = require("../renderers/renderer");
p = require("../../core/properties");
ArrowHead = (function(superClass) {
extend(ArrowHead, superClass);
function ArrowHead() {
return ArrowHead.__super__.constructor.apply(this, arguments);
}
ArrowHead.prototype.type = 'ArrowHead';
ArrowHead.prototype.initialize = function(options) {
var j, len, name, prefix, ref, ref1, results, spec;
ArrowHead.__super__.initialize.call(this, options);
this.visuals = {};
ref = this.mixins;
results = [];
for (j = 0, len = ref.length; j < len; j++) {
spec = ref[j];
ref1 = spec.split(":"), name = ref1[0], prefix = ref1[1];
if (prefix == null) {
prefix = "";
}
results.push(this.visuals[prefix + name] = new Renderer.Visuals[name]({
obj: this,
prefix: prefix
}));
}
return results;
};
ArrowHead.prototype.render = function(ctx, i) {
return null;
};
return ArrowHead;
})(Annotation.Model);
OpenHead = (function(superClass) {
extend(OpenHead, superClass);
function OpenHead() {
return OpenHead.__super__.constructor.apply(this, arguments);
}
OpenHead.prototype.type = 'OpenHead';
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.get("size"), this.get("size"));
ctx.lineTo(0, 0);
ctx.lineTo(-0.5 * this.get("size"), this.get("size"));
return ctx.stroke();
}
};
OpenHead.mixins(['line']);
OpenHead.define({
size: [p.Number, 25]
});
return OpenHead;
})(ArrowHead);
NormalHead = (function(superClass) {
extend(NormalHead, superClass);
function NormalHead() {
return NormalHead.__super__.constructor.apply(this, arguments);
}
NormalHead.prototype.type = 'NormalHead';
NormalHead.prototype.render = function(ctx, i) {
if (this.visuals["fill"].doit) {
this.visuals["fill"].set_vectorize(ctx, i);
ctx.beginPath();
ctx.moveTo(0.5 * this.get("size"), this.get("size"));
ctx.lineTo(0, 0);
ctx.lineTo(-0.5 * this.get("size"), this.get("size"));
ctx.closePath();
ctx.fill();
}
if (this.visuals["line"].doit) {
this.visuals["line"].set_vectorize(ctx, i);
ctx.beginPath();
ctx.moveTo(0.5 * this.get("size"), this.get("size"));
ctx.lineTo(0, 0);
ctx.lineTo(-0.5 * this.get("size"), this.get("size"));
ctx.closePath();
return ctx.stroke();
}
};
NormalHead.mixins(['line', 'fill']);
NormalHead.define({
size: [p.Number, 25]
});
NormalHead.override({
fill_color: 'black'
});
return NormalHead;
})(ArrowHead);
VeeHead = (function(superClass) {
extend(VeeHead, superClass);
function VeeHead() {
return VeeHead.__super__.constructor.apply(this, arguments);
}
VeeHead.prototype.type = 'VeeHead';
VeeHead.prototype.render = function(ctx, i) {
if (this.visuals["fill"].doit) {
this.visuals["fill"].set_vectorize(ctx, i);
ctx.beginPath();
ctx.moveTo(0.5 * this.get("size"), this.get("size"));
ctx.lineTo(0, 0);
ctx.lineTo(-0.5 * this.get("size"), this.get("size"));
ctx.lineTo(0, 0.5 * this.get("size"));
ctx.closePath();
ctx.fill();
}
if (this.visuals["line"].doit) {
this.visuals["line"].set_vectorize(ctx, i);
ctx.beginPath();
ctx.moveTo(0.5 * this.get("size"), this.get("size"));
ctx.lineTo(0, 0);
ctx.lineTo(-0.5 * this.get("size"), this.get("size"));
ctx.lineTo(0, 0.5 * this.get("size"));
ctx.closePath();
return ctx.stroke();
}
};
VeeHead.mixins(['line', 'fill']);
VeeHead.define({
size: [p.Number, 25]
});
VeeHead.override({
fill_color: 'black'
});
return VeeHead;
})(ArrowHead);
module.exports = {
OpenHead: {
Model: OpenHead
},
NormalHead: {
Model: NormalHead
},
VeeHead: {
Model: VeeHead
}
};

View File

@ -0,0 +1,166 @@
var Annotation, BoxAnnotation, BoxAnnotationView, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Annotation = require("./annotation");
p = require("../../core/properties");
BoxAnnotationView = (function(superClass) {
extend(BoxAnnotationView, superClass);
function BoxAnnotationView() {
return BoxAnnotationView.__super__.constructor.apply(this, arguments);
}
BoxAnnotationView.prototype.initialize = function(options) {
BoxAnnotationView.__super__.initialize.call(this, options);
this.$el.appendTo(this.plot_view.$el.find('div.bk-canvas-overlays'));
this.$el.addClass('bk-shading');
return this.$el.hide();
};
BoxAnnotationView.prototype.bind_bokeh_events = function() {
if (this.mget('render_mode') === 'css') {
this.listenTo(this.model, 'change', this.render);
return this.listenTo(this.model, 'data_update', this.render);
} else {
this.listenTo(this.model, 'change', this.plot_view.request_render);
return this.listenTo(this.model, 'data_update', this.plot_view.request_render);
}
};
BoxAnnotationView.prototype.render = function() {
var sbottom, sleft, sright, stop;
if ((this.mget('left') == null) && (this.mget('right') == null) && (this.mget('top') == null) && (this.mget('bottom') == null)) {
this.$el.hide();
return null;
}
this.frame = this.plot_model.get('frame');
this.canvas = this.plot_model.get('canvas');
this.xmapper = this.plot_view.frame.get('x_mappers')[this.mget("x_range_name")];
this.ymapper = this.plot_view.frame.get('y_mappers')[this.mget("y_range_name")];
sleft = this.canvas.vx_to_sx(this._calc_dim('left', this.xmapper, this.frame.get('h_range').get('start')));
sright = this.canvas.vx_to_sx(this._calc_dim('right', this.xmapper, this.frame.get('h_range').get('end')));
sbottom = this.canvas.vy_to_sy(this._calc_dim('bottom', this.ymapper, this.frame.get('v_range').get('start')));
stop = this.canvas.vy_to_sy(this._calc_dim('top', this.ymapper, this.frame.get('v_range').get('end')));
if (this.mget('render_mode') === 'css') {
return this._css_box(sleft, sright, sbottom, stop);
} else {
return this._canvas_box(sleft, sright, sbottom, stop);
}
};
BoxAnnotationView.prototype._css_box = function(sleft, sright, sbottom, stop) {
var ba, bc, lc, ld, lw, sh, style, sw;
sw = Math.abs(sright - sleft);
sh = Math.abs(sbottom - stop);
lw = this.mget("line_width").value;
lc = this.mget("line_color").value;
bc = this.mget("fill_color").value;
ba = this.mget("fill_alpha").value;
style = "left:" + sleft + "px; width:" + sw + "px; top:" + stop + "px; height:" + sh + "px; border-width:" + lw + "px; border-color:" + lc + "; background-color:" + bc + "; opacity:" + ba + ";";
ld = this.mget("line_dash");
if (_.isArray(ld)) {
if (ld.length < 2) {
ld = "solid";
} else {
ld = "dashed";
}
}
if (_.isString(ld)) {
style += " border-style:" + ld + ";";
}
this.$el.attr('style', style);
return this.$el.show();
};
BoxAnnotationView.prototype._canvas_box = function(sleft, sright, sbottom, stop) {
var ctx;
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();
return ctx.restore();
};
BoxAnnotationView.prototype._calc_dim = function(dim, mapper, frame_extrema) {
var vdim;
if (this.mget(dim) != null) {
if (this.mget(dim + '_units') === 'data') {
vdim = mapper.map_to_target(this.mget(dim));
} else {
vdim = this.mget(dim);
}
} else {
vdim = frame_extrema;
}
return vdim;
};
return BoxAnnotationView;
})(Annotation.View);
BoxAnnotation = (function(superClass) {
extend(BoxAnnotation, superClass);
function BoxAnnotation() {
return BoxAnnotation.__super__.constructor.apply(this, arguments);
}
BoxAnnotation.prototype.default_view = BoxAnnotationView;
BoxAnnotation.prototype.type = 'BoxAnnotation';
BoxAnnotation.mixins(['line', 'fill']);
BoxAnnotation.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']
});
BoxAnnotation.override({
fill_color: '#fff9ba',
fill_alpha: 0.4,
line_color: '#cccccc',
line_alpha: 0.3
});
BoxAnnotation.prototype.update = function(arg) {
var bottom, left, right, top;
left = arg.left, right = arg.right, top = arg.top, bottom = arg.bottom;
this.set({
left: left,
right: right,
top: top,
bottom: bottom
}, {
silent: true
});
return this.trigger('data_update');
};
return BoxAnnotation;
})(Annotation.Model);
module.exports = {
Model: BoxAnnotation,
View: BoxAnnotationView
};

View File

@ -0,0 +1,638 @@
var Annotation, BasicTickFormatter, BasicTicker, ColorBar, ColorBarView, LONG_DIM_MAX_SCALAR, LONG_DIM_MIN_SCALAR, LinearColorMapper, LinearMapper, LogMapper, Range1d, SHORT_DIM, _, p, text_util,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Annotation = require("./annotation");
BasicTicker = require("../tickers/basic_ticker");
BasicTickFormatter = require("../formatters/basic_tick_formatter");
LinearColorMapper = require("../mappers/linear_color_mapper");
LinearMapper = require("../mappers/linear_mapper");
LogMapper = require("../mappers/log_mapper");
Range1d = require("../ranges/range1d");
p = require("../../core/properties");
text_util = require("../../core/util/text");
SHORT_DIM = 25;
LONG_DIM_MIN_SCALAR = 0.3;
LONG_DIM_MAX_SCALAR = 0.8;
ColorBarView = (function(superClass) {
extend(ColorBarView, superClass);
function ColorBarView() {
return ColorBarView.__super__.constructor.apply(this, arguments);
}
ColorBarView.prototype.initialize = function(options) {
ColorBarView.__super__.initialize.call(this, options);
return this._set_canvas_image();
};
ColorBarView.prototype.bind_bokeh_events = function() {
this.listenTo(this.model, 'change:visible', this.plot_view.request_render);
this.listenTo(this.model.ticker, 'change', this.plot_view.request_render);
this.listenTo(this.model.formatter, 'change', this.plot_view.request_render);
return this.listenTo(this.model.color_mapper, 'change', function() {
this._set_canvas_image();
return this.plot_view.request_render();
});
};
ColorBarView.prototype._get_panel_offset = function() {
var x, y;
x = this.model.panel._left._value;
y = this.model.panel._top._value;
return {
x: x,
y: -y
};
};
ColorBarView.prototype._get_size = function() {
var bbox, side;
bbox = this.compute_legend_dimensions();
side = this.model.panel.side;
if (side === 'above' || side === 'below') {
return bbox.height;
}
if (side === 'left' || side === 'right') {
return bbox.width;
}
};
ColorBarView.prototype._set_canvas_image = function() {
var buf, buf8, canvas, cmap, h, image_ctx, image_data, k, palette, ref, ref1, ref2, ref3, results, w;
palette = this.model.color_mapper.palette;
if (this.model.orientation === 'vertical') {
palette = palette.slice(0).reverse();
}
switch (this.model.orientation) {
case "vertical":
ref = [1, palette.length], w = ref[0], h = ref[1];
break;
case "horizontal":
ref1 = [palette.length, 1], w = ref1[0], h = ref1[1];
}
canvas = document.createElement('canvas');
ref2 = [w, h], canvas.width = ref2[0], canvas.height = ref2[1];
image_ctx = canvas.getContext('2d');
image_data = image_ctx.getImageData(0, 0, w, h);
cmap = new LinearColorMapper.Model({
palette: palette
});
buf = cmap.v_map_screen((function() {
results = [];
for (var k = 0, ref3 = palette.length; 0 <= ref3 ? k < ref3 : k > ref3; 0 <= ref3 ? k++ : k--){ results.push(k); }
return results;
}).apply(this));
buf8 = new Uint8ClampedArray(buf);
image_data.data.set(buf8);
image_ctx.putImageData(image_data, 0, 0);
return this.image = canvas;
};
ColorBarView.prototype.compute_legend_dimensions = function() {
var image_dimensions, image_height, image_width, label_extent, legend_height, legend_width, padding, ref, tick_extent, title_extent;
image_dimensions = this.model._computed_image_dimensions();
ref = [image_dimensions.height, image_dimensions.width], image_height = ref[0], image_width = ref[1];
label_extent = this._get_label_extent();
title_extent = this.model._title_extent();
tick_extent = this.model._tick_extent();
padding = this.model.padding;
switch (this.model.orientation) {
case "vertical":
legend_height = image_height + title_extent + padding * 2;
legend_width = image_width + tick_extent + label_extent + padding * 2;
break;
case "horizontal":
legend_height = image_height + title_extent + tick_extent + label_extent + padding * 2;
legend_width = image_width + padding * 2;
}
return {
height: legend_height,
width: legend_width
};
};
ColorBarView.prototype.compute_legend_location = function() {
var h_range, legend_dimensions, legend_height, legend_margin, legend_width, location, ref, sx, sy, v_range, x, y;
legend_dimensions = this.compute_legend_dimensions();
ref = [legend_dimensions.height, legend_dimensions.width], legend_height = ref[0], legend_width = ref[1];
legend_margin = this.model.margin;
location = this.model.location;
h_range = this.plot_view.frame.get('h_range');
v_range = this.plot_view.frame.get('v_range');
if (_.isString(location)) {
switch (location) {
case 'top_left':
x = h_range.get('start') + legend_margin;
y = v_range.get('end') - legend_margin;
break;
case 'top_center':
x = (h_range.get('end') + h_range.get('start')) / 2 - legend_width / 2;
y = v_range.get('end') - legend_margin;
break;
case 'top_right':
x = h_range.get('end') - legend_margin - legend_width;
y = v_range.get('end') - legend_margin;
break;
case 'right_center':
x = h_range.get('end') - legend_margin - legend_width;
y = (v_range.get('end') + v_range.get('start')) / 2 + legend_height / 2;
break;
case 'bottom_right':
x = h_range.get('end') - legend_margin - legend_width;
y = v_range.get('start') + legend_margin + legend_height;
break;
case 'bottom_center':
x = (h_range.get('end') + h_range.get('start')) / 2 - legend_width / 2;
y = v_range.get('start') + legend_margin + legend_height;
break;
case 'bottom_left':
x = h_range.get('start') + legend_margin;
y = v_range.get('start') + legend_margin + legend_height;
break;
case 'left_center':
x = h_range.get('start') + legend_margin;
y = (v_range.get('end') + v_range.get('start')) / 2 + legend_height / 2;
break;
case 'center':
x = (h_range.get('end') + h_range.get('start')) / 2 - legend_width / 2;
y = (v_range.get('end') + v_range.get('start')) / 2 + legend_height / 2;
}
} else if (_.isArray(location) && location.length === 2) {
x = location[0], y = location[1];
}
sx = this.plot_view.canvas.vx_to_sx(x);
sy = this.plot_view.canvas.vy_to_sy(y);
return {
sx: sx,
sy: sy
};
};
ColorBarView.prototype.render = function() {
var ctx, frame_offset, image_offset, location, panel_offset;
if (this.model.visible === false) {
return;
}
ctx = this.plot_view.canvas_view.ctx;
ctx.save();
if (this.model.panel != null) {
panel_offset = this._get_panel_offset();
ctx.translate(panel_offset.x, panel_offset.y);
frame_offset = this._get_frame_offset();
ctx.translate(frame_offset.x, frame_offset.y);
}
location = this.compute_legend_location();
ctx.translate(location.sx, location.sy);
this._draw_bbox(ctx);
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)) {
this._draw_major_ticks(ctx);
this._draw_minor_ticks(ctx);
this._draw_major_labels(ctx);
}
if (this.model.title) {
this._draw_title(ctx);
}
return ctx.restore();
};
ColorBarView.prototype._draw_bbox = function(ctx) {
var bbox;
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);
}
return ctx.restore();
};
ColorBarView.prototype._draw_image = function(ctx) {
var image;
image = this.model._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);
}
return ctx.restore();
};
ColorBarView.prototype._draw_major_ticks = function(ctx) {
var i, image, k, nx, ny, ref, ref1, ref2, ref3, sx, sy, tin, tout, x_offset, y_offset;
if (!this.visuals.major_tick_line.doit) {
return;
}
ref = this.model._normals(), nx = ref[0], ny = ref[1];
image = this.model._computed_image_dimensions();
ref1 = [image.width * nx, image.height * ny], x_offset = ref1[0], y_offset = ref1[1];
ref2 = this.model._tick_coordinates().major, sx = ref2[0], sy = ref2[1];
tin = this.model.major_tick_in;
tout = this.model.major_tick_out;
ctx.save();
ctx.translate(x_offset, y_offset);
this.visuals.major_tick_line.set_value(ctx);
for (i = k = 0, ref3 = sx.length; 0 <= ref3 ? k < ref3 : k > ref3; i = 0 <= ref3 ? ++k : --k) {
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();
}
return ctx.restore();
};
ColorBarView.prototype._draw_minor_ticks = function(ctx) {
var i, image, k, nx, ny, ref, ref1, ref2, ref3, sx, sy, tin, tout, x_offset, y_offset;
if (!this.visuals.minor_tick_line.doit) {
return;
}
ref = this.model._normals(), nx = ref[0], ny = ref[1];
image = this.model._computed_image_dimensions();
ref1 = [image.width * nx, image.height * ny], x_offset = ref1[0], y_offset = ref1[1];
ref2 = this.model._tick_coordinates().minor, sx = ref2[0], sy = ref2[1];
tin = this.model.minor_tick_in;
tout = this.model.minor_tick_out;
ctx.save();
ctx.translate(x_offset, y_offset);
this.visuals.minor_tick_line.set_value(ctx);
for (i = k = 0, ref3 = sx.length; 0 <= ref3 ? k < ref3 : k > ref3; i = 0 <= ref3 ? ++k : --k) {
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();
}
return ctx.restore();
};
ColorBarView.prototype._draw_major_labels = function(ctx) {
var formatted_labels, i, image, k, labels, nx, ny, ref, ref1, ref2, ref3, ref4, standoff, sx, sy, x_offset, x_standoff, y_offset, y_standoff;
if (!this.visuals.major_label_text.doit) {
return;
}
ref = this.model._normals(), nx = ref[0], ny = ref[1];
image = this.model._computed_image_dimensions();
ref1 = [image.width * nx, image.height * ny], x_offset = ref1[0], y_offset = ref1[1];
standoff = this.model.label_standoff + this.model._tick_extent();
ref2 = [standoff * nx, standoff * ny], x_standoff = ref2[0], y_standoff = ref2[1];
ref3 = this.model._tick_coordinates().major, sx = ref3[0], sy = ref3[1];
labels = this.model._tick_coordinates().major_labels;
formatted_labels = this.mget('formatter').doFormat(labels);
this.visuals.major_label_text.set_value(ctx);
ctx.save();
ctx.translate(x_offset + x_standoff, y_offset + y_standoff);
for (i = k = 0, ref4 = sx.length; 0 <= ref4 ? k < ref4 : k > ref4; i = 0 <= ref4 ? ++k : --k) {
ctx.fillText(formatted_labels[i], Math.round(sx[i] + nx * this.model.label_standoff), Math.round(sy[i] + ny * this.model.label_standoff));
}
return 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);
return ctx.restore();
};
ColorBarView.prototype._get_label_extent = function() {
var ctx, formatted_labels, label, label_extent;
if ((this.model.color_mapper.low != null) && (this.model.color_mapper.high != null)) {
ctx = this.plot_view.canvas_view.ctx;
ctx.save();
this.visuals.major_label_text.set_value(ctx);
switch (this.model.orientation) {
case "vertical":
formatted_labels = this.model.formatter.doFormat(this.model._tick_coordinates().major_labels);
label_extent = _.max((function() {
var k, len, results;
results = [];
for (k = 0, len = formatted_labels.length; k < len; k++) {
label = formatted_labels[k];
results.push(ctx.measureText(label.toString()).width);
}
return results;
})());
break;
case "horizontal":
label_extent = text_util.get_text_height(this.visuals.major_label_text.font_value()).height;
}
label_extent += this.model.label_standoff;
ctx.restore();
} else {
label_extent = 0;
}
return label_extent;
};
ColorBarView.prototype._get_frame_offset = function() {
var frame, panel, ref, xoff, yoff;
ref = [0, 0], xoff = ref[0], yoff = ref[1];
panel = this.model.panel;
frame = this.plot_view.frame;
switch (panel.side) {
case "left":
case "right":
yoff = Math.abs(panel.get("top") - frame.get("top"));
break;
case "above":
case "below":
xoff = Math.abs(frame.get("left"));
}
return {
x: xoff,
y: yoff
};
};
ColorBarView.prototype._get_image_offset = function() {
var x, y;
x = this.model.padding;
y = this.model.padding + this.model._title_extent();
return {
x: x,
y: y
};
};
return ColorBarView;
})(Annotation.View);
ColorBar = (function(superClass) {
extend(ColorBar, superClass);
function ColorBar() {
return ColorBar.__super__.constructor.apply(this, arguments);
}
ColorBar.prototype.default_view = ColorBarView;
ColorBar.prototype.type = 'ColorBar';
ColorBar.mixins(['text:major_label_', 'text:title_', 'line:major_tick_', 'line:minor_tick_', 'line:border_', 'line:bar_', 'fill:background_']);
ColorBar.define({
location: [p.Any, 'top_right'],
orientation: [p.Orientation, 'vertical'],
title: [p.String],
title_standoff: [p.Number, 2],
height: [p.Any, 'auto'],
width: [p.Any, 'auto'],
scale_alpha: [p.Number, 1.0],
ticker: [
p.Instance, function() {
return new BasicTicker.Model();
}
],
formatter: [
p.Instance, function() {
return new BasicTickFormatter.Model();
}
],
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]
});
ColorBar.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"
});
ColorBar.prototype.initialize = function(attrs, options) {
return ColorBar.__super__.initialize.call(this, attrs, options);
};
ColorBar.prototype._normals = function() {
var i, j, ref, ref1;
if (this.orientation === 'vertical') {
ref = [1, 0], i = ref[0], j = ref[1];
} else {
ref1 = [0, 1], i = ref1[0], j = ref1[1];
}
return [i, j];
};
ColorBar.prototype._title_extent = function() {
var font_value, title_extent;
font_value = this.title_text_font + " " + this.title_text_font_size + " " + this.title_text_font_style;
title_extent = this.title ? text_util.get_text_height(font_value).height + this.title_standoff : 0;
return title_extent;
};
ColorBar.prototype._tick_extent = function() {
var tick_extent;
if ((this.color_mapper.low != null) && (this.color_mapper.high != null)) {
tick_extent = _.max([this.major_tick_out, this.minor_tick_out]);
} else {
tick_extent = 0;
}
return tick_extent;
};
ColorBar.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, frame_width, height, title_extent, width;
frame_height = this.plot.plot_canvas.frame.get('height');
frame_width = this.plot.plot_canvas.frame.get('width');
title_extent = this._title_extent();
switch (this.orientation) {
case "vertical":
if (this.height === 'auto') {
if (this.panel != null) {
height = frame_height - 2 * this.padding - title_extent;
} else {
height = _.max([this.color_mapper.palette.length * SHORT_DIM, frame_height * LONG_DIM_MIN_SCALAR]);
height = _.min([height, frame_height * LONG_DIM_MAX_SCALAR - 2 * this.padding - title_extent]);
}
} else {
height = this.height;
}
width = this.width === 'auto' ? SHORT_DIM : this.width;
break;
case "horizontal":
height = this.height === 'auto' ? SHORT_DIM : this.height;
if (this.width === 'auto') {
if (this.panel != null) {
width = frame_width - 2 * this.padding;
} else {
width = _.max([this.color_mapper.palette.length * SHORT_DIM, frame_width * LONG_DIM_MIN_SCALAR]);
width = _.min([width, frame_width * LONG_DIM_MAX_SCALAR - 2 * this.padding]);
}
} else {
width = this.width;
}
}
return {
"height": height,
"width": width
};
};
ColorBar.prototype._tick_coordinate_mapper = function(scale_length) {
/*
Creates and returns a mapper 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 mapper 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 mapper (i.e.
a LinearColorMapper will require a corresponding LinearMapper instance).
*/
var mapper, mapping;
mapping = {
'source_range': new Range1d.Model({
start: this.color_mapper.low,
end: this.color_mapper.high
}),
'target_range': new Range1d.Model({
start: 0,
end: scale_length
})
};
switch (this.color_mapper.type) {
case "LinearColorMapper":
mapper = new LinearMapper.Model(mapping);
break;
case "LogColorMapper":
mapper = new LogMapper.Model(mapping);
}
return mapper;
};
ColorBar.prototype._tick_coordinates = function() {
var coord, end, i, ii, image_dimensions, j, k, l, major_coords, major_labels, majors, mapper, minor_coords, minors, ref, ref1, ref2, ref3, scale_length, start, ticks;
image_dimensions = this._computed_image_dimensions();
switch (this.orientation) {
case "vertical":
scale_length = image_dimensions.height;
break;
case "horizontal":
scale_length = image_dimensions.width;
}
mapper = this._tick_coordinate_mapper(scale_length);
ref = this._normals(), i = ref[0], j = ref[1];
ref1 = [this.color_mapper.low, this.color_mapper.high], start = ref1[0], end = ref1[1];
ticks = this.ticker.get_ticks(start, end, null, this.ticker.desired_num_ticks);
majors = ticks.major;
minors = ticks.minor;
major_coords = [[], []];
minor_coords = [[], []];
for (ii = k = 0, ref2 = majors.length; 0 <= ref2 ? k < ref2 : k > ref2; ii = 0 <= ref2 ? ++k : --k) {
if (majors[ii] < start || majors[ii] > end) {
continue;
}
major_coords[i].push(majors[ii]);
major_coords[j].push(0);
}
for (ii = l = 0, ref3 = minors.length; 0 <= ref3 ? l < ref3 : l > ref3; ii = 0 <= ref3 ? ++l : --l) {
if (minors[ii] < start || minors[ii] > end) {
continue;
}
minor_coords[i].push(minors[ii]);
minor_coords[j].push(0);
}
major_labels = major_coords[i].slice(0);
major_coords[i] = mapper.v_map_to_target(major_coords[i]);
minor_coords[i] = mapper.v_map_to_target(minor_coords[i]);
if (this.orientation === 'vertical') {
major_coords[i] = new Float64Array((function() {
var len, m, ref4, results;
ref4 = major_coords[i];
results = [];
for (m = 0, len = ref4.length; m < len; m++) {
coord = ref4[m];
results.push(scale_length - coord);
}
return results;
})());
minor_coords[i] = new Float64Array((function() {
var len, m, ref4, results;
ref4 = minor_coords[i];
results = [];
for (m = 0, len = ref4.length; m < len; m++) {
coord = ref4[m];
results.push(scale_length - coord);
}
return results;
})());
}
return {
"major": major_coords,
"minor": minor_coords,
"major_labels": major_labels
};
};
return ColorBar;
})(Annotation.Model);
module.exports = {
Model: ColorBar,
View: ColorBarView
};

View File

@ -0,0 +1,124 @@
var Label, LabelView, TextAnnotation, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
TextAnnotation = require("./text_annotation");
p = require("../../core/properties");
LabelView = (function(superClass) {
extend(LabelView, superClass);
function LabelView() {
return LabelView.__super__.constructor.apply(this, arguments);
}
LabelView.prototype.initialize = function(options) {
var name, prop, ref, results;
LabelView.__super__.initialize.call(this, options);
this.canvas = this.plot_model.get('canvas');
this.xmapper = this.plot_view.frame.get('x_mappers')[this.mget("x_range_name")];
this.ymapper = this.plot_view.frame.get('y_mappers')[this.mget("y_range_name")];
ref = this.visuals;
results = [];
for (name in ref) {
prop = ref[name];
results.push(prop.warm_cache(null));
}
return results;
};
LabelView.prototype._get_size = function() {
var ctx, height, side, width;
ctx = this.plot_view.canvas_view.ctx;
this.visuals.text.set_value(ctx);
side = this.model.panel.side;
if (side === "above" || side === "below") {
height = ctx.measureText(this.mget('text')).ascent;
return height;
}
if (side === 'left' || side === 'right') {
width = ctx.measureText(this.mget('text')).width;
return width;
}
};
LabelView.prototype.render = function() {
var angle, ctx, panel_offset, sx, sy, vx, vy;
ctx = this.plot_view.canvas_view.ctx;
switch (this.mget('angle_units')) {
case "rad":
angle = -1 * this.mget('angle');
break;
case "deg":
angle = -1 * this.mget('angle') * Math.PI / 180.0;
}
if (this.mget('x_units') === "data") {
vx = this.xmapper.map_to_target(this.mget('x'));
} else {
vx = this.mget('x');
}
sx = this.canvas.vx_to_sx(vx);
if (this.mget('y_units') === "data") {
vy = this.ymapper.map_to_target(this.mget('y'));
} else {
vy = this.mget('y');
}
sy = this.canvas.vy_to_sy(vy);
if (this.model.panel != null) {
panel_offset = this._get_panel_offset();
sx += panel_offset.x;
sy += panel_offset.y;
}
if (this.mget('render_mode') === 'canvas') {
return this._canvas_text(ctx, this.mget('text'), sx + this.mget('x_offset'), sy - this.mget('y_offset'), angle);
} else {
return this._css_text(ctx, this.mget('text'), sx + this.mget('x_offset'), sy - this.mget('y_offset'), angle);
}
};
return LabelView;
})(TextAnnotation.View);
Label = (function(superClass) {
extend(Label, superClass);
function Label() {
return Label.__super__.constructor.apply(this, arguments);
}
Label.prototype.default_view = LabelView;
Label.prototype.type = 'Label';
Label.mixins(['text', 'line:border_', 'fill:background_']);
Label.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'],
render_mode: [p.RenderMode, 'canvas']
});
Label.override({
background_fill_color: null,
border_line_color: null
});
return Label;
})(TextAnnotation.Model);
module.exports = {
Model: Label,
View: LabelView
};

View File

@ -0,0 +1,246 @@
var $, ColumnDataSource, LabelSet, LabelSetView, TextAnnotation, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
$ = require("jquery");
TextAnnotation = require("./text_annotation");
ColumnDataSource = require("../sources/column_data_source");
p = require("../../core/properties");
LabelSetView = (function(superClass) {
extend(LabelSetView, superClass);
function LabelSetView() {
return LabelSetView.__super__.constructor.apply(this, arguments);
}
LabelSetView.prototype.initialize = function(options) {
var i, j, ref, results;
LabelSetView.__super__.initialize.call(this, options);
this.xmapper = this.plot_view.frame.get('x_mappers')[this.model.x_range_name];
this.ymapper = this.plot_view.frame.get('y_mappers')[this.model.y_range_name];
this.set_data();
if (this.model.render_mode === 'css') {
results = [];
for (i = j = 0, ref = this._text.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
this.title_div = $("<div>").addClass('bk-annotation-child').hide();
results.push(this.title_div.appendTo(this.$el));
}
return results;
}
};
LabelSetView.prototype.bind_bokeh_events = function() {
if (this.model.render_mode === 'css') {
this.listenTo(this.model, 'change', function() {
this.set_data();
return this.render();
});
return this.listenTo(this.model.source, 'change', function() {
this.set_data();
return this.render();
});
} else {
this.listenTo(this.model, 'change', function() {
this.set_data();
return this.plot_view.request_render();
});
return this.listenTo(this.model.source, 'change', function() {
this.set_data();
return this.plot_view.request_render();
});
}
};
LabelSetView.prototype.set_data = function() {
LabelSetView.__super__.set_data.call(this, this.model.source);
return this.set_visuals(this.model.source);
};
LabelSetView.prototype._map_data = function() {
var sx, sy, vx, vy;
if (this.model.x_units === "data") {
vx = this.xmapper.v_map_to_target(this._x);
} else {
vx = this._x.slice(0);
}
sx = this.canvas.v_vx_to_sx(vx);
if (this.model.y_units === "data") {
vy = this.ymapper.v_map_to_target(this._y);
} else {
vy = this._y.slice(0);
}
sy = this.canvas.v_vy_to_sy(vy);
return [sx, sy];
};
LabelSetView.prototype.render = function() {
var ctx, i, j, k, ref, ref1, ref2, results, results1, sx, sy;
ctx = this.plot_view.canvas_view.ctx;
ref = this._map_data(), sx = ref[0], sy = ref[1];
if (this.model.render_mode === 'canvas') {
results = [];
for (i = j = 0, ref1 = this._text.length; 0 <= ref1 ? j < ref1 : j > ref1; i = 0 <= ref1 ? ++j : --j) {
results.push(this._v_canvas_text(ctx, i, this._text[i], sx[i] + this._x_offset[i], sy[i] - this._y_offset[i], this._angle[i]));
}
return results;
} else {
results1 = [];
for (i = k = 0, ref2 = this._text.length; 0 <= ref2 ? k < ref2 : k > ref2; i = 0 <= ref2 ? ++k : --k) {
results1.push(this._v_css_text(ctx, i, this._text[i], sx[i] + this._x_offset[i], sy[i] - this._y_offset[i], this._angle[i]));
}
return results1;
}
};
LabelSetView.prototype._get_size = function() {
var ctx, height, side, width;
ctx = this.plot_view.canvas_view.ctx;
this.visuals.text.set_value(ctx);
side = this.model.panel.side;
if (side === "above" || side === "below") {
height = ctx.measureText(this._text[0]).ascent;
return height;
}
if (side === 'left' || side === 'right') {
width = ctx.measureText(this._text[0]).width;
return width;
}
};
LabelSetView.prototype._v_canvas_text = function(ctx, i, text, sx, sy, angle) {
var bbox_dims;
this.visuals.text.set_vectorize(ctx, i);
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);
}
return ctx.restore();
};
LabelSetView.prototype._v_css_text = function(ctx, i, text, sx, sy, angle) {
var bbox_dims, div_style, ld, line_dash;
this.visuals.text.set_vectorize(ctx, i);
bbox_dims = this._calculate_bounding_box_dimensions(ctx, text);
ld = this.visuals.border_line.line_dash.value();
if (_.isArray(ld)) {
if (ld.length < 2) {
line_dash = "solid";
} else {
line_dash = "dashed";
}
}
if (_.isString(ld)) {
line_dash = ld;
}
this.visuals.border_line.set_vectorize(ctx, i);
this.visuals.background_fill.set_vectorize(ctx, i);
div_style = {
'position': 'absolute',
'left': (sx + bbox_dims[0]) + "px",
'top': (sy + bbox_dims[1]) + "px",
'color': "" + (this.visuals.text.text_color.value()),
'opacity': "" + (this.visuals.text.text_alpha.value()),
'font': "" + (this.visuals.text.font_value()),
'line-height': "normal"
};
if (angle) {
_.extend(div_style, {
'transform': "rotate(" + angle + "rad)"
});
}
if (this.visuals.background_fill.doit) {
_.extend(div_style, {
'background-color': "" + (this.visuals.background_fill.color_value())
});
}
if (this.visuals.border_line.doit) {
_.extend(div_style, {
'border-style': "" + line_dash,
'border-width': "" + (this.visuals.border_line.line_width.value()),
'border-color': "" + (this.visuals.border_line.color_value())
});
}
return this.$el.children().eq(i).html(text).css(div_style).show();
};
return LabelSetView;
})(TextAnnotation.View);
LabelSet = (function(superClass) {
extend(LabelSet, superClass);
function LabelSet() {
return LabelSet.__super__.constructor.apply(this, arguments);
}
LabelSet.prototype.default_view = LabelSetView;
LabelSet.prototype.type = 'Label';
LabelSet.mixins(['text', 'line:border_', 'fill:background_']);
LabelSet.coords([['x', 'y']]);
LabelSet.define({
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 ColumnDataSource.Model();
}
],
x_range_name: [p.String, 'default'],
y_range_name: [p.String, 'default'],
render_mode: [p.RenderMode, 'canvas']
});
LabelSet.override({
background_fill_color: null,
border_line_color: null
});
return LabelSet;
})(TextAnnotation.Model);
module.exports = {
Model: LabelSet,
View: LabelSetView
};

View File

@ -0,0 +1,241 @@
var Annotation, Legend, LegendView, _, get_text_height, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Annotation = require("./annotation");
p = require("../../core/properties");
get_text_height = require("../../core/util/text").get_text_height;
LegendView = (function(superClass) {
extend(LegendView, superClass);
function LegendView() {
return LegendView.__super__.constructor.apply(this, arguments);
}
LegendView.prototype.initialize = function(options) {
return LegendView.__super__.initialize.call(this, options);
};
LegendView.prototype.compute_legend_bbox = function() {
var ctx, glyph_height, glyph_width, glyphs, h_range, i, label_height, label_standoff, label_width, legend_height, legend_margin, legend_name, legend_names, legend_padding, legend_spacing, legend_width, len, location, max_label_width, name, ref, v_range, width, x, y;
legend_names = (function() {
var i, len, ref, ref1, results;
ref = this.mget("legends");
results = [];
for (i = 0, len = ref.length; i < len; i++) {
ref1 = ref[i], legend_name = ref1[0], glyphs = ref1[1];
results.push(legend_name);
}
return results;
}).call(this);
glyph_height = this.mget('glyph_height');
glyph_width = this.mget('glyph_width');
label_height = this.mget('label_height');
label_width = this.mget('label_width');
this.max_label_height = _.max([get_text_height(this.visuals.label_text.font_value()).height, label_height, glyph_height]);
ctx = this.plot_view.canvas_view.ctx;
ctx.save();
this.visuals.label_text.set_value(ctx);
this.text_widths = {};
for (i = 0, len = legend_names.length; i < len; i++) {
name = legend_names[i];
this.text_widths[name] = _.max([ctx.measureText(name).width, label_width]);
}
ctx.restore();
max_label_width = _.max(_.values(this.text_widths));
legend_margin = this.mget('legend_margin');
legend_padding = this.mget('legend_padding');
legend_spacing = this.mget('legend_spacing');
label_standoff = this.mget('label_standoff');
if (this.mget("orientation") === "vertical") {
legend_height = legend_names.length * this.max_label_height + (legend_names.length - 1) * legend_spacing + 2 * legend_padding;
legend_width = max_label_width + glyph_width + label_standoff + 2 * legend_padding;
} else {
legend_width = 2 * legend_padding + (legend_names.length - 1) * legend_spacing;
ref = this.text_widths;
for (name in ref) {
width = ref[name];
legend_width += _.max([width, label_width]) + glyph_width + label_standoff;
}
legend_height = this.max_label_height + 2 * legend_padding;
}
location = this.mget('location');
h_range = this.plot_view.frame.get('h_range');
v_range = this.plot_view.frame.get('v_range');
if (_.isString(location)) {
switch (location) {
case 'top_left':
x = h_range.get('start') + legend_margin;
y = v_range.get('end') - legend_margin;
break;
case 'top_center':
x = (h_range.get('end') + h_range.get('start')) / 2 - legend_width / 2;
y = v_range.get('end') - legend_margin;
break;
case 'top_right':
x = h_range.get('end') - legend_margin - legend_width;
y = v_range.get('end') - legend_margin;
break;
case 'right_center':
x = h_range.get('end') - legend_margin - legend_width;
y = (v_range.get('end') + v_range.get('start')) / 2 + legend_height / 2;
break;
case 'bottom_right':
x = h_range.get('end') - legend_margin - legend_width;
y = v_range.get('start') + legend_margin + legend_height;
break;
case 'bottom_center':
x = (h_range.get('end') + h_range.get('start')) / 2 - legend_width / 2;
y = v_range.get('start') + legend_margin + legend_height;
break;
case 'bottom_left':
x = h_range.get('start') + legend_margin;
y = v_range.get('start') + legend_margin + legend_height;
break;
case 'left_center':
x = h_range.get('start') + legend_margin;
y = (v_range.get('end') + v_range.get('start')) / 2 + legend_height / 2;
break;
case 'center':
x = (h_range.get('end') + h_range.get('start')) / 2 - legend_width / 2;
y = (v_range.get('end') + v_range.get('start')) / 2 + legend_height / 2;
}
} else if (_.isArray(location) && location.length === 2) {
x = location[0], y = location[1];
}
x = this.plot_view.canvas.vx_to_sx(x);
y = this.plot_view.canvas.vy_to_sy(y);
return {
x: x,
y: y,
width: legend_width,
height: legend_height
};
};
LegendView.prototype.render = function() {
var N, bbox, ctx, glyph_height, glyph_width, glyphs, i, idx, j, label_standoff, legend_name, legend_spacing, len, len1, orientation, panel_offset, ref, ref1, renderer, view, x1, x2, xoffset, y1, y2, yoffset;
if (this.model.legends.length === 0) {
return;
}
bbox = this.compute_legend_bbox();
glyph_height = this.mget('glyph_height');
glyph_width = this.mget('glyph_width');
orientation = this.mget('orientation');
ctx = this.plot_view.canvas_view.ctx;
ctx.save();
if (this.model.panel != null) {
panel_offset = this._get_panel_offset();
ctx.translate(panel_offset.x, panel_offset.y);
}
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();
}
N = this.mget("legends").length;
legend_spacing = this.mget('legend_spacing');
label_standoff = this.mget('label_standoff');
xoffset = yoffset = this.mget('legend_padding');
ref = this.mget("legends");
for (idx = i = 0, len = ref.length; i < len; idx = ++i) {
ref1 = ref[idx], legend_name = ref1[0], glyphs = ref1[1];
x1 = bbox.x + xoffset;
y1 = bbox.y + yoffset;
x2 = x1 + glyph_width;
y2 = y1 + glyph_height;
if (orientation === "vertical") {
yoffset += this.max_label_height + legend_spacing;
} else {
xoffset += this.text_widths[legend_name] + glyph_width + label_standoff + legend_spacing;
}
this.visuals.label_text.set_value(ctx);
ctx.fillText(legend_name, x2 + label_standoff, y1 + this.max_label_height / 2.0);
for (j = 0, len1 = glyphs.length; j < len1; j++) {
renderer = glyphs[j];
view = this.plot_view.renderer_views[renderer.id];
view.draw_legend(ctx, x1, x2, y1, y2);
}
}
return ctx.restore();
};
LegendView.prototype._get_size = function() {
var bbox, side;
bbox = this.compute_legend_bbox();
side = this.model.panel.side;
if (side === 'above' || side === 'below') {
return bbox.height;
}
if (side === 'left' || side === 'right') {
return bbox.width;
}
};
LegendView.prototype._get_panel_offset = function() {
var x, y;
x = this.model.panel._left._value;
y = this.model.panel._top._value;
return {
x: x,
y: -y
};
};
return LegendView;
})(Annotation.View);
Legend = (function(superClass) {
extend(Legend, superClass);
function Legend() {
return Legend.__super__.constructor.apply(this, arguments);
}
Legend.prototype.default_view = LegendView;
Legend.prototype.type = 'Legend';
Legend.mixins(['text:label_', 'line:border_', 'fill:background_']);
Legend.define({
legends: [p.Array, []],
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],
legend_margin: [p.Number, 10],
legend_padding: [p.Number, 10],
legend_spacing: [p.Number, 3]
});
Legend.override({
border_line_color: "#e5e5e5",
border_line_alpha: 0.5,
border_line_width: 1,
background_fill_color: "#ffffff",
background_fill_alpha: 0.95,
label_text_font_size: "10pt",
label_text_baseline: "middle"
});
return Legend;
})(Annotation.Model);
module.exports = {
Model: Legend,
View: LegendView
};

View File

@ -0,0 +1,114 @@
var Annotation, PolyAnnotation, PolyAnnotationView, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Annotation = require("./annotation");
p = require("../../core/properties");
PolyAnnotationView = (function(superClass) {
extend(PolyAnnotationView, superClass);
function PolyAnnotationView() {
return PolyAnnotationView.__super__.constructor.apply(this, arguments);
}
PolyAnnotationView.prototype.bind_bokeh_events = function() {
this.listenTo(this.model, 'change', this.plot_view.request_render);
return this.listenTo(this.model, 'data_update', this.plot_view.request_render);
};
PolyAnnotationView.prototype.render = function(ctx) {
var canvas, i, j, ref, sx, sy, vx, vy, xs, ys;
xs = this.mget('xs');
ys = this.mget('ys');
if (xs.length !== ys.length) {
return null;
}
if (xs.length < 3 || ys.length < 3) {
return null;
}
canvas = this.plot_view.canvas;
ctx = this.plot_view.canvas_view.ctx;
for (i = j = 0, ref = xs.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
if (this.mget('xs_units') === 'screen') {
vx = xs[i];
}
if (this.mget('ys_units') === 'screen') {
vy = ys[i];
}
sx = canvas.vx_to_sx(vx);
sy = canvas.vy_to_sy(vy);
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);
return ctx.fill();
}
};
return PolyAnnotationView;
})(Annotation.View);
PolyAnnotation = (function(superClass) {
extend(PolyAnnotation, superClass);
function PolyAnnotation() {
return PolyAnnotation.__super__.constructor.apply(this, arguments);
}
PolyAnnotation.prototype.default_view = PolyAnnotationView;
PolyAnnotation.prototype.type = "PolyAnnotation";
PolyAnnotation.mixins(['line', 'fill']);
PolyAnnotation.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']
});
PolyAnnotation.override({
fill_color: "#fff9ba",
fill_alpha: 0.4,
line_color: "#cccccc",
line_alpha: 0.3
});
PolyAnnotation.prototype.update = function(arg) {
var xs, ys;
xs = arg.xs, ys = arg.ys;
this.set({
xs: xs,
ys: ys
}, {
silent: true
});
return this.trigger('data_update');
};
return PolyAnnotation;
})(Annotation.Model);
module.exports = {
Model: PolyAnnotation,
View: PolyAnnotationView
};

View File

@ -0,0 +1,148 @@
var Annotation, Span, SpanView, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Annotation = require("./annotation");
p = require("../../core/properties");
SpanView = (function(superClass) {
extend(SpanView, superClass);
function SpanView() {
return SpanView.__super__.constructor.apply(this, arguments);
}
SpanView.prototype.initialize = function(options) {
SpanView.__super__.initialize.call(this, options);
this.$el.appendTo(this.plot_view.$el.find('div.bk-canvas-overlays'));
this.$el.css({
position: 'absolute'
});
return this.$el.hide();
};
SpanView.prototype.bind_bokeh_events = function() {
if (this.mget('for_hover')) {
return this.listenTo(this.model, 'change:computed_location', this._draw_span);
} else {
if (this.mget('render_mode') === 'canvas') {
return this.listenTo(this.model, 'change:location', this.plot_view.request_render);
} else {
return this.listenTo(this.model, 'change:location', this._draw_span);
}
}
};
SpanView.prototype.render = function() {
return this._draw_span();
};
SpanView.prototype._draw_span = function() {
var canvas, ctx, frame, height, loc, sleft, stop, width, xmapper, ymapper;
if (this.mget('for_hover')) {
loc = this.mget('computed_location');
} else {
loc = this.mget('location');
}
if (loc == null) {
this.$el.hide();
return;
}
frame = this.plot_model.get('frame');
canvas = this.plot_model.get('canvas');
xmapper = this.plot_view.frame.get('x_mappers')[this.mget("x_range_name")];
ymapper = this.plot_view.frame.get('y_mappers')[this.mget("y_range_name")];
if (this.mget('dimension') === 'width') {
stop = canvas.vy_to_sy(this._calc_dim(loc, ymapper));
sleft = canvas.vx_to_sx(frame.get('left'));
width = frame.get('width');
height = this.model.properties.line_width.value();
} else {
stop = canvas.vy_to_sy(frame.get('top'));
sleft = canvas.vx_to_sx(this._calc_dim(loc, xmapper));
width = this.model.properties.line_width.value();
height = frame.get('height');
}
if (this.mget("render_mode") === "css") {
this.$el.css({
'top': stop,
'left': sleft,
'width': width + "px",
'height': height + "px",
'z-index': 1000,
'background-color': this.model.properties.line_color.value(),
'opacity': this.model.properties.line_alpha.value()
});
return this.$el.show();
} else if (this.mget("render_mode") === "canvas") {
ctx = this.plot_view.canvas_view.ctx;
ctx.save();
ctx.beginPath();
this.visuals.line.set_value(ctx);
ctx.moveTo(sleft, stop);
if (this.mget('dimension') === "width") {
ctx.lineTo(sleft + width, stop);
} else {
ctx.lineTo(sleft, stop + height);
}
ctx.stroke();
return ctx.restore();
}
};
SpanView.prototype._calc_dim = function(location, mapper) {
var vdim;
if (this.mget('location_units') === 'data') {
vdim = mapper.map_to_target(location);
} else {
vdim = location;
}
return vdim;
};
return SpanView;
})(Annotation.View);
Span = (function(superClass) {
extend(Span, superClass);
function Span() {
return Span.__super__.constructor.apply(this, arguments);
}
Span.prototype.default_view = SpanView;
Span.prototype.type = 'Span';
Span.mixins(['line']);
Span.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']
});
Span.override({
line_color: 'black'
});
Span.internal({
for_hover: [p.Boolean, false],
computed_location: [p.Number, null]
});
return Span;
})(Annotation.Model);
module.exports = {
Model: Span,
View: SpanView
};

View File

@ -0,0 +1,186 @@
var Annotation, TextAnnotation, TextAnnotationView, _, get_text_height, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Annotation = require("./annotation");
p = require("../../core/properties");
get_text_height = require("../../core/util/text").get_text_height;
TextAnnotationView = (function(superClass) {
extend(TextAnnotationView, superClass);
function TextAnnotationView() {
return TextAnnotationView.__super__.constructor.apply(this, arguments);
}
TextAnnotationView.prototype.initialize = function(options) {
TextAnnotationView.__super__.initialize.call(this, options);
this.canvas = this.plot_model.get('canvas');
this.frame = this.plot_model.get('frame');
if (this.mget('render_mode') === 'css') {
this.$el.addClass('bk-annotation');
return this.$el.appendTo(this.plot_view.$el.find('div.bk-canvas-overlays'));
}
};
TextAnnotationView.prototype.bind_bokeh_events = function() {
if (this.mget('render_mode') === 'css') {
return this.listenTo(this.model, 'change', this.render);
} else {
return this.listenTo(this.model, 'change', this.plot_view.request_render);
}
};
TextAnnotationView.prototype._calculate_text_dimensions = function(ctx, text) {
var height, width;
width = ctx.measureText(text).width;
height = get_text_height(this.visuals.text.font_value()).height;
return [width, height];
};
TextAnnotationView.prototype._calculate_bounding_box_dimensions = function(ctx, text) {
var height, ref, width, x_offset, y_offset;
ref = this._calculate_text_dimensions(ctx, text), width = ref[0], height = ref[1];
switch (ctx.textAlign) {
case 'left':
x_offset = 0;
break;
case 'center':
x_offset = -width / 2;
break;
case 'right':
x_offset = -width;
}
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;
}
return [x_offset, y_offset, width, height];
};
TextAnnotationView.prototype._get_size = function() {
var ctx;
ctx = this.plot_view.canvas_view.ctx;
this.visuals.text.set_value(ctx);
return ctx.measureText(this.mget('text')).ascent;
};
TextAnnotationView.prototype.render = function() {
return null;
};
TextAnnotationView.prototype._canvas_text = function(ctx, text, sx, sy, angle) {
var bbox_dims;
this.visuals.text.set_value(ctx);
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);
}
return ctx.restore();
};
TextAnnotationView.prototype._css_text = function(ctx, text, sx, sy, angle) {
var bbox_dims, div_style, ld, line_dash;
this.$el.hide();
this.visuals.text.set_value(ctx);
bbox_dims = this._calculate_bounding_box_dimensions(ctx, text);
ld = this.visuals.border_line.line_dash.value();
if (_.isArray(ld)) {
if (ld.length < 2) {
line_dash = "solid";
} else {
line_dash = "dashed";
}
}
if (_.isString(ld)) {
line_dash = ld;
}
this.visuals.border_line.set_value(ctx);
this.visuals.background_fill.set_value(ctx);
div_style = {
'position': 'absolute',
'left': (sx + bbox_dims[0]) + "px",
'top': (sy + bbox_dims[1]) + "px",
'color': "" + (this.visuals.text.text_color.value()),
'opacity': "" + (this.visuals.text.text_alpha.value()),
'font': "" + (this.visuals.text.font_value()),
'line-height': "normal"
};
if (angle) {
_.extend(div_style, {
'transform': "rotate(" + angle + "rad)"
});
}
if (this.visuals.background_fill.doit) {
_.extend(div_style, {
'background-color': "" + (this.visuals.background_fill.color_value())
});
}
if (this.visuals.border_line.doit) {
_.extend(div_style, {
'border-style': "" + line_dash,
'border-width': "" + (this.visuals.border_line.line_width.value()),
'border-color': "" + (this.visuals.border_line.color_value())
});
}
return this.$el.html(text).css(div_style).show();
};
return TextAnnotationView;
})(Annotation.View);
TextAnnotation = (function(superClass) {
extend(TextAnnotation, superClass);
function TextAnnotation() {
return TextAnnotation.__super__.constructor.apply(this, arguments);
}
TextAnnotation.prototype.type = 'TextAnnotation';
TextAnnotation.prototype.default_view = TextAnnotationView;
return TextAnnotation;
})(Annotation.Model);
module.exports = {
Model: TextAnnotation,
View: TextAnnotationView
};

View File

@ -0,0 +1,146 @@
var TextAnnotation, Title, TitleView, Visuals, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
TextAnnotation = require("./text_annotation");
p = require("../../core/properties");
Visuals = require("../renderers/renderer").Visuals;
TitleView = (function(superClass) {
extend(TitleView, superClass);
function TitleView() {
return TitleView.__super__.constructor.apply(this, arguments);
}
TitleView.prototype.initialize = function(options) {
var ctx;
TitleView.__super__.initialize.call(this, options);
this.visuals.text = new Visuals.text({
obj: this.model,
prefix: ""
});
ctx = this.plot_view.canvas_view.ctx;
ctx.save();
this.model.panel.apply_label_text_heuristics(ctx, 'justified');
this.model.text_baseline = ctx.textBaseline;
this.model.text_align = this.model.align;
return ctx.restore();
};
TitleView.prototype._get_computed_location = function() {
var height, ref, sx, sy, vx, vy, width;
ref = this._calculate_text_dimensions(this.plot_view.canvas_view.ctx, this.text), width = ref[0], height = ref[1];
switch (this.model.panel.side) {
case 'left':
vx = 0;
vy = this._get_text_location(this.mget('align'), this.frame.get('v_range')) + this.mget('offset');
break;
case 'right':
vx = this.canvas.get('right') - 1;
vy = this.canvas.get('height') - this._get_text_location(this.mget('align'), this.frame.get('v_range')) - this.mget('offset');
break;
case 'above':
vx = this._get_text_location(this.mget('align'), this.frame.get('h_range')) + this.mget('offset');
vy = this.canvas.get('top') - 10;
break;
case 'below':
vx = this._get_text_location(this.mget('align'), this.frame.get('h_range')) + this.mget('offset');
vy = 0;
}
sx = this.canvas.vx_to_sx(vx);
sy = this.canvas.vy_to_sy(vy);
return [sx, sy];
};
TitleView.prototype._get_text_location = function(alignment, range) {
var text_location;
switch (alignment) {
case 'left':
text_location = range.get('start');
break;
case 'center':
text_location = (range.get('end') + range.get('start')) / 2;
break;
case 'right':
text_location = range.get('end');
}
return text_location;
};
TitleView.prototype.render = function() {
var angle, ctx, ref, sx, sy;
angle = this.model.panel.get_label_angle_heuristic('parallel');
ref = this._get_computed_location(), sx = ref[0], sy = ref[1];
ctx = this.plot_view.canvas_view.ctx;
if (this.model.text === "" || this.model.text === null) {
return;
}
if (this.model.render_mode === 'canvas') {
return this._canvas_text(ctx, this.model.text, sx, sy, angle);
} else {
return this._css_text(ctx, this.model.text, sx, sy, angle);
}
};
TitleView.prototype._get_size = function() {
var ctx, text;
text = this.model.text;
if (text === "" || text === null) {
return 0;
} else {
ctx = this.plot_view.canvas_view.ctx;
this.visuals.text.set_value(ctx);
return ctx.measureText(text).ascent + 10;
}
};
return TitleView;
})(TextAnnotation.View);
Title = (function(superClass) {
extend(Title, superClass);
function Title() {
return Title.__super__.constructor.apply(this, arguments);
}
Title.prototype.default_view = TitleView;
Title.prototype.type = 'Title';
Title.mixins(['line:border_', 'fill:background_']);
Title.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],
align: [p.TextAlign, 'left'],
offset: [p.Number, 0],
render_mode: [p.RenderMode, 'canvas']
});
Title.override({
background_fill_color: null,
border_line_color: null
});
Title.internal({
text_align: [p.TextAlign, 'left'],
text_baseline: [p.TextBaseline, 'bottom']
});
return Title;
})(TextAnnotation.Model);
module.exports = {
Model: Title,
View: TitleView
};

View File

@ -0,0 +1,168 @@
var $, Annotation, Tooltip, TooltipView, _, logger, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
$ = require("jquery");
_ = require("underscore");
Annotation = require("./annotation");
logger = require("../../core/logging").logger;
p = require("../../core/properties");
TooltipView = (function(superClass) {
extend(TooltipView, superClass);
function TooltipView() {
return TooltipView.__super__.constructor.apply(this, arguments);
}
TooltipView.prototype.className = "bk-tooltip";
TooltipView.prototype.initialize = function(options) {
TooltipView.__super__.initialize.call(this, options);
this.$el.appendTo(this.plot_view.$el.find('div.bk-canvas-overlays'));
this.$el.css({
'z-index': 1010
});
return this.$el.hide();
};
TooltipView.prototype.bind_bokeh_events = function() {
return this.listenTo(this.model, 'change:data', this._draw_tips);
};
TooltipView.prototype.render = function() {
return this._draw_tips();
};
TooltipView.prototype._draw_tips = function() {
var arrow_size, attachment, bottom, content, data, height, i, left, len, side, sx, sy, tip, top, val, vx, vy, width;
data = this.model.data;
this.$el.empty();
this.$el.hide();
this.$el.toggleClass("bk-tooltip-custom", this.mget("custom"));
if (_.isEmpty(data)) {
return;
}
for (i = 0, len = data.length; i < len; i++) {
val = data[i];
vx = val[0], vy = val[1], content = val[2];
if (this.mget('inner_only') && !this.plot_view.frame.contains(vx, vy)) {
continue;
}
tip = $('<div />').appendTo(this.$el);
tip.append(content);
}
sx = this.plot_view.mget('canvas').vx_to_sx(vx);
sy = this.plot_view.mget('canvas').vy_to_sy(vy);
attachment = this.model.attachment;
switch (attachment) {
case "horizontal":
width = this.plot_view.frame.get('width');
left = this.plot_view.frame.get('left');
if (vx - left < width / 2) {
side = 'right';
} else {
side = 'left';
}
break;
case "vertical":
height = this.plot_view.frame.get('height');
bottom = this.plot_view.frame.get('bottom');
if (vy - bottom < height / 2) {
side = 'below';
} else {
side = 'above';
}
break;
default:
side = attachment;
}
this.$el.removeClass('bk-right bk-left bk-above bk-below');
arrow_size = 10;
switch (side) {
case "right":
this.$el.addClass("bk-left");
left = sx + (this.$el.outerWidth() - this.$el.innerWidth()) + arrow_size;
top = sy - this.$el.outerHeight() / 2;
break;
case "left":
this.$el.addClass("bk-right");
left = sx - this.$el.outerWidth() - arrow_size;
top = sy - this.$el.outerHeight() / 2;
break;
case "above":
this.$el.addClass("bk-above");
top = sy + (this.$el.outerHeight() - this.$el.innerHeight()) + arrow_size;
left = Math.round(sx - this.$el.outerWidth() / 2);
break;
case "below":
this.$el.addClass("bk-below");
top = sy - this.$el.outerHeight() - arrow_size;
left = Math.round(sx - this.$el.outerWidth() / 2);
}
if (this.model.show_arrow) {
this.$el.addClass("bk-tooltip-arrow");
}
if (this.$el.children().length > 0) {
this.$el.css({
top: top,
left: left
});
return this.$el.show();
}
};
return TooltipView;
})(Annotation.View);
Tooltip = (function(superClass) {
extend(Tooltip, superClass);
function Tooltip() {
return Tooltip.__super__.constructor.apply(this, arguments);
}
Tooltip.prototype.default_view = TooltipView;
Tooltip.prototype.type = 'Tooltip';
Tooltip.define({
attachment: [p.String, 'horizontal'],
inner_only: [p.Bool, true],
show_arrow: [p.Bool, true]
});
Tooltip.override({
level: 'overlay'
});
Tooltip.internal({
data: [p.Any, []],
custom: [p.Any]
});
Tooltip.prototype.clear = function() {
return this.data = [];
};
Tooltip.prototype.add = function(vx, vy, content) {
var data;
data = this.data;
data.push([vx, vy, content]);
this.data = data;
return this.trigger('change:data');
};
return Tooltip;
})(Annotation.Model);
module.exports = {
Model: Tooltip,
View: TooltipView
};

View File

@ -0,0 +1,467 @@
var Axis, AxisView, GE, GuideRenderer, Renderer, SidePanel, _, logger, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
SidePanel = require("../../core/layout/side_panel");
GuideRenderer = require("../renderers/guide_renderer");
Renderer = require("../renderers/renderer");
GE = require("../../core/layout/solver").GE;
logger = require("../../core/logging").logger;
p = require("../../core/properties");
AxisView = (function(superClass) {
extend(AxisView, superClass);
function AxisView() {
return AxisView.__super__.constructor.apply(this, arguments);
}
AxisView.prototype.initialize = function(options) {
AxisView.__super__.initialize.call(this, options);
this._x_range_name = this.mget('x_range_name');
return this._y_range_name = this.mget('y_range_name');
};
AxisView.prototype.render = function() {
var ctx;
if (this.model.visible === false) {
return;
}
ctx = this.plot_view.canvas_view.ctx;
ctx.save();
this._draw_rule(ctx);
this._draw_major_ticks(ctx);
this._draw_minor_ticks(ctx);
this._draw_major_labels(ctx);
this._draw_axis_label(ctx);
return ctx.restore();
};
AxisView.prototype.bind_bokeh_events = function() {
return this.listenTo(this.model, 'change', this.plot_view.request_render);
};
AxisView.prototype._get_size = function() {
return this._tick_extent() + this._tick_label_extent() + this._axis_label_extent();
};
AxisView.prototype._draw_rule = function(ctx) {
var coords, i, k, nx, ny, ref, ref1, ref2, ref3, ref4, sx, sy, x, xoff, y, yoff;
if (!this.visuals.axis_line.doit) {
return;
}
ref = coords = this.mget('rule_coords'), x = ref[0], y = ref[1];
ref1 = this.plot_view.map_to_screen(x, y, this._x_range_name, this._y_range_name), sx = ref1[0], sy = ref1[1];
ref2 = this.mget('normals'), nx = ref2[0], ny = ref2[1];
ref3 = this.mget('offsets'), xoff = ref3[0], yoff = ref3[1];
this.visuals.axis_line.set_value(ctx);
ctx.beginPath();
ctx.moveTo(Math.round(sx[0] + nx * xoff), Math.round(sy[0] + ny * yoff));
for (i = k = 1, ref4 = sx.length; 1 <= ref4 ? k < ref4 : k > ref4; i = 1 <= ref4 ? ++k : --k) {
ctx.lineTo(Math.round(sx[i] + nx * xoff), Math.round(sy[i] + ny * yoff));
}
return ctx.stroke();
};
AxisView.prototype._draw_major_ticks = function(ctx) {
var coords, i, k, nx, ny, ref, ref1, ref2, ref3, ref4, results, sx, sy, tin, tout, x, xoff, y, yoff;
if (!this.visuals.major_tick_line.doit) {
return;
}
coords = this.mget('tick_coords');
ref = coords.major, x = ref[0], y = ref[1];
ref1 = this.plot_view.map_to_screen(x, y, this._x_range_name, this._y_range_name), sx = ref1[0], sy = ref1[1];
ref2 = this.mget('normals'), nx = ref2[0], ny = ref2[1];
ref3 = this.mget('offsets'), xoff = ref3[0], yoff = ref3[1];
tin = this.mget('major_tick_in');
tout = this.mget('major_tick_out');
this.visuals.major_tick_line.set_value(ctx);
results = [];
for (i = k = 0, ref4 = sx.length; 0 <= ref4 ? k < ref4 : k > ref4; i = 0 <= ref4 ? ++k : --k) {
ctx.beginPath();
ctx.moveTo(Math.round(sx[i] + nx * tout + nx * xoff), Math.round(sy[i] + ny * tout + ny * yoff));
ctx.lineTo(Math.round(sx[i] - nx * tin + nx * xoff), Math.round(sy[i] - ny * tin + ny * yoff));
results.push(ctx.stroke());
}
return results;
};
AxisView.prototype._draw_minor_ticks = function(ctx) {
var coords, i, k, nx, ny, ref, ref1, ref2, ref3, ref4, results, sx, sy, tin, tout, x, xoff, y, yoff;
if (!this.visuals.minor_tick_line.doit) {
return;
}
coords = this.mget('tick_coords');
ref = coords.minor, x = ref[0], y = ref[1];
ref1 = this.plot_view.map_to_screen(x, y, this._x_range_name, this._y_range_name), sx = ref1[0], sy = ref1[1];
ref2 = this.mget('normals'), nx = ref2[0], ny = ref2[1];
ref3 = this.mget('offsets'), xoff = ref3[0], yoff = ref3[1];
tin = this.mget('minor_tick_in');
tout = this.mget('minor_tick_out');
this.visuals.minor_tick_line.set_value(ctx);
results = [];
for (i = k = 0, ref4 = sx.length; 0 <= ref4 ? k < ref4 : k > ref4; i = 0 <= ref4 ? ++k : --k) {
ctx.beginPath();
ctx.moveTo(Math.round(sx[i] + nx * tout + nx * xoff), Math.round(sy[i] + ny * tout + ny * yoff));
ctx.lineTo(Math.round(sx[i] - nx * tin + nx * xoff), Math.round(sy[i] - ny * tin + ny * yoff));
results.push(ctx.stroke());
}
return results;
};
AxisView.prototype._draw_major_labels = function(ctx) {
var angle, coords, dim, i, k, labels, nx, ny, orient, ref, ref1, ref2, ref3, ref4, results, side, standoff, sx, sy, x, xoff, y, yoff;
coords = this.mget('tick_coords');
ref = coords.major, x = ref[0], y = ref[1];
ref1 = this.plot_view.map_to_screen(x, y, this._x_range_name, this._y_range_name), sx = ref1[0], sy = ref1[1];
ref2 = this.mget('normals'), nx = ref2[0], ny = ref2[1];
ref3 = this.mget('offsets'), xoff = ref3[0], yoff = ref3[1];
dim = this.mget('dimension');
side = this.mget('panel_side');
orient = this.mget('major_label_orientation');
if (_.isString(orient)) {
angle = this.model.panel.get_label_angle_heuristic(orient);
} else {
angle = -orient;
}
standoff = this._tick_extent() + this.mget('major_label_standoff');
labels = this.mget('formatter').doFormat(coords.major[dim]);
this.visuals.major_label_text.set_value(ctx);
this.model.panel.apply_label_text_heuristics(ctx, orient);
results = [];
for (i = k = 0, ref4 = sx.length; 0 <= ref4 ? k < ref4 : k > ref4; i = 0 <= ref4 ? ++k : --k) {
if (angle) {
ctx.translate(sx[i] + nx * standoff + nx * xoff, sy[i] + ny * standoff + ny * yoff);
ctx.rotate(angle);
ctx.fillText(labels[i], 0, 0);
ctx.rotate(-angle);
results.push(ctx.translate(-sx[i] - nx * standoff + nx * xoff, -sy[i] - ny * standoff + ny * yoff));
} else {
results.push(ctx.fillText(labels[i], Math.round(sx[i] + nx * standoff + nx * xoff), Math.round(sy[i] + ny * standoff + ny * yoff)));
}
}
return results;
};
AxisView.prototype._draw_axis_label = function(ctx) {
var angle, label, nx, ny, orient, ref, ref1, ref2, ref3, side, standoff, sx, sy, x, xoff, y, yoff;
label = this.mget('axis_label');
if (label == null) {
return;
}
ref = this.mget('rule_coords'), x = ref[0], y = ref[1];
ref1 = this.plot_view.map_to_screen(x, y, this._x_range_name, this._y_range_name), sx = ref1[0], sy = ref1[1];
ref2 = this.mget('normals'), nx = ref2[0], ny = ref2[1];
ref3 = this.mget('offsets'), xoff = ref3[0], yoff = ref3[1];
side = this.mget('panel_side');
orient = 'parallel';
angle = this.model.panel.get_label_angle_heuristic(orient);
standoff = this._tick_extent() + this._tick_label_extent() + this.mget('axis_label_standoff');
sx = (sx[0] + sx[sx.length - 1]) / 2;
sy = (sy[0] + sy[sy.length - 1]) / 2;
this.visuals.axis_label_text.set_value(ctx);
this.model.panel.apply_label_text_heuristics(ctx, orient);
x = sx + nx * standoff + nx * xoff;
y = sy + ny * standoff + ny * yoff;
if (isNaN(x) || isNaN(y)) {
return;
}
if (angle) {
ctx.translate(x, y);
ctx.rotate(angle);
ctx.fillText(label, 0, 0);
ctx.rotate(-angle);
return ctx.translate(-x, -y);
} else {
return ctx.fillText(label, x, y);
}
};
AxisView.prototype._tick_extent = function() {
return this.mget('major_tick_out');
};
AxisView.prototype._tick_label_extent = function() {
var angle, c, coords, ctx, dim, extent, h, hfactor, hscale, i, k, labels, orient, ref, s, side, val, w, wfactor;
extent = 0;
ctx = this.plot_view.canvas_view.ctx;
dim = this.mget('dimension');
coords = this.mget('tick_coords').major;
side = this.mget('panel_side');
orient = this.mget('major_label_orientation');
labels = this.mget('formatter').doFormat(coords[dim]);
this.visuals.major_label_text.set_value(ctx);
if (_.isString(orient)) {
hscale = 1;
angle = this.model.panel.get_label_angle_heuristic(orient);
} else {
hscale = 2;
angle = -orient;
}
angle = Math.abs(angle);
c = Math.cos(angle);
s = Math.sin(angle);
if (side === "above" || side === "below") {
wfactor = s;
hfactor = c;
} else {
wfactor = c;
hfactor = s;
}
for (i = k = 0, ref = labels.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
if (labels[i] == null) {
continue;
}
w = ctx.measureText(labels[i]).width * 1.1;
h = ctx.measureText(labels[i]).ascent * 0.9;
val = w * wfactor + (h / hscale) * hfactor;
if (val > extent) {
extent = val;
}
}
if (extent > 0) {
extent += this.mget('major_label_standoff');
}
return extent;
};
AxisView.prototype._axis_label_extent = function() {
var angle, axis_label, c, ctx, extent, h, orient, s, side, w;
extent = 0;
side = this.mget('panel_side');
axis_label = this.mget('axis_label');
orient = 'parallel';
ctx = this.plot_view.canvas_view.ctx;
this.visuals.axis_label_text.set_value(ctx);
angle = Math.abs(this.model.panel.get_label_angle_heuristic(orient));
c = Math.cos(angle);
s = Math.sin(angle);
if (axis_label) {
extent += this.mget('axis_label_standoff');
this.visuals.axis_label_text.set_value(ctx);
w = ctx.measureText(axis_label).width * 1.1;
h = ctx.measureText(axis_label).ascent * 0.9;
if (side === "above" || side === "below") {
extent += w * s + h * c;
} else {
extent += w * c + h * s;
}
}
return extent;
};
return AxisView;
})(Renderer.View);
Axis = (function(superClass) {
extend(Axis, superClass);
function Axis() {
return Axis.__super__.constructor.apply(this, arguments);
}
Axis.prototype.default_view = AxisView;
Axis.prototype.type = 'Axis';
Axis.mixins(['line:axis_', 'line:major_tick_', 'line:minor_tick_', 'text:major_label_', 'text:axis_label_']);
Axis.define({
bounds: [p.Any, 'auto'],
ticker: [p.Instance, null],
formatter: [p.Instance, null],
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_tick_in: [p.Number, 2],
major_tick_out: [p.Number, 6],
minor_tick_in: [p.Number, 0],
minor_tick_out: [p.Number, 4]
});
Axis.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"
});
Axis.internal({
panel_side: [p.Any]
});
Axis.prototype.initialize = function(attrs, options) {
Axis.__super__.initialize.call(this, attrs, options);
this.define_computed_property('computed_bounds', this._computed_bounds, false);
this.add_dependencies('computed_bounds', this, ['bounds']);
this.add_dependencies('computed_bounds', this.get('plot'), ['x_range', 'y_range']);
this.define_computed_property('rule_coords', this._rule_coords, false);
this.add_dependencies('rule_coords', this, ['computed_bounds', 'side']);
this.define_computed_property('tick_coords', this._tick_coords, false);
this.add_dependencies('tick_coords', this, ['computed_bounds', 'panel_side']);
this.define_computed_property('ranges', this._ranges, true);
this.define_computed_property('normals', (function() {
return this.panel._normals;
}), true);
this.define_computed_property('dimension', (function() {
return this.panel._dim;
}), true);
return this.define_computed_property('offsets', this._offsets, true);
};
Axis.prototype.add_panel = function(side) {
this.panel = new SidePanel.Model({
side: side
});
this.panel.attach_document(this.document);
return this.set('panel_side', side);
};
Axis.prototype._offsets = function() {
var frame, ref, side, xoff, yoff;
side = this.get('panel_side');
ref = [0, 0], xoff = ref[0], yoff = ref[1];
frame = this.plot.plot_canvas.get('frame');
if (side === "below") {
yoff = Math.abs(this.panel.get("top") - frame.get("bottom"));
} else if (side === "above") {
yoff = Math.abs(this.panel.get("bottom") - frame.get("top"));
} else if (side === "right") {
xoff = Math.abs(this.panel.get("left") - frame.get("right"));
} else if (side === "left") {
xoff = Math.abs(this.panel.get("right") - frame.get("left"));
}
return [xoff, yoff];
};
Axis.prototype._ranges = function() {
var frame, i, j, ranges;
i = this.get('dimension');
j = (i + 1) % 2;
frame = this.plot.plot_canvas.get('frame');
ranges = [frame.get('x_ranges')[this.get('x_range_name')], frame.get('y_ranges')[this.get('y_range_name')]];
return [ranges[i], ranges[j]];
};
Axis.prototype._computed_bounds = function() {
var cross_range, end, range, range_bounds, ref, ref1, start, user_bounds;
ref = this.get('ranges'), range = ref[0], cross_range = ref[1];
user_bounds = (ref1 = this.get('bounds')) != null ? ref1 : 'auto';
range_bounds = [range.get('min'), range.get('max')];
if (user_bounds === 'auto') {
return range_bounds;
}
if (_.isArray(user_bounds)) {
if (Math.abs(user_bounds[0] - user_bounds[1]) > Math.abs(range_bounds[0] - range_bounds[1])) {
start = Math.max(Math.min(user_bounds[0], user_bounds[1]), range_bounds[0]);
end = Math.min(Math.max(user_bounds[0], user_bounds[1]), range_bounds[1]);
} else {
start = Math.min(user_bounds[0], user_bounds[1]);
end = Math.max(user_bounds[0], user_bounds[1]);
}
return [start, end];
}
logger.error("user bounds '" + user_bounds + "' not understood");
return null;
};
Axis.prototype._rule_coords = function() {
var coords, cross_range, end, i, j, loc, range, ref, ref1, start, xs, ys;
i = this.get('dimension');
j = (i + 1) % 2;
ref = this.get('ranges'), range = ref[0], cross_range = ref[1];
ref1 = this.get('computed_bounds'), start = ref1[0], end = ref1[1];
xs = new Array(2);
ys = new Array(2);
coords = [xs, ys];
loc = this._get_loc(cross_range);
coords[i][0] = Math.max(start, range.get('min'));
coords[i][1] = Math.min(end, range.get('max'));
if (coords[i][0] > coords[i][1]) {
coords[i][0] = coords[i][1] = NaN;
}
coords[j][0] = loc;
coords[j][1] = loc;
return coords;
};
Axis.prototype._tick_coords = function() {
var coords, cross_range, end, i, ii, j, k, l, loc, m, majors, minor_coords, minor_xs, minor_ys, minors, range, range_max, range_min, ref, ref1, ref2, ref3, ref4, ref5, start, ticks, xs, ys;
i = this.get('dimension');
j = (i + 1) % 2;
ref = this.get('ranges'), range = ref[0], cross_range = ref[1];
ref1 = this.get('computed_bounds'), start = ref1[0], end = ref1[1];
ticks = this.get('ticker').get_ticks(start, end, range, {});
majors = ticks.major;
minors = ticks.minor;
loc = this._get_loc(cross_range);
xs = [];
ys = [];
coords = [xs, ys];
minor_xs = [];
minor_ys = [];
minor_coords = [minor_xs, minor_ys];
if (range.type === "FactorRange") {
for (ii = k = 0, ref2 = majors.length; 0 <= ref2 ? k < ref2 : k > ref2; ii = 0 <= ref2 ? ++k : --k) {
coords[i].push(majors[ii]);
coords[j].push(loc);
}
} else {
ref3 = [range.get('min'), range.get('max')], range_min = ref3[0], range_max = ref3[1];
for (ii = l = 0, ref4 = majors.length; 0 <= ref4 ? l < ref4 : l > ref4; ii = 0 <= ref4 ? ++l : --l) {
if (majors[ii] < range_min || majors[ii] > range_max) {
continue;
}
coords[i].push(majors[ii]);
coords[j].push(loc);
}
for (ii = m = 0, ref5 = minors.length; 0 <= ref5 ? m < ref5 : m > ref5; ii = 0 <= ref5 ? ++m : --m) {
if (minors[ii] < range_min || minors[ii] > range_max) {
continue;
}
minor_coords[i].push(minors[ii]);
minor_coords[j].push(loc);
}
}
return {
"major": coords,
"minor": minor_coords
};
};
Axis.prototype._get_loc = function(cross_range) {
var cend, cstart, loc, side;
cstart = cross_range.get('start');
cend = cross_range.get('end');
side = this.get('panel_side');
if (side === 'left' || side === 'below') {
loc = 'start';
} else if (side === 'right' || side === 'above') {
loc = 'end';
}
return cross_range.get(loc);
};
return Axis;
})(GuideRenderer.Model);
module.exports = {
Model: Axis,
View: AxisView
};

View File

@ -0,0 +1,64 @@
var Axis, CategoricalAxis, CategoricalAxisView, CategoricalTickFormatter, CategoricalTicker, _, logger,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Axis = require("./axis");
CategoricalTickFormatter = require("../formatters/categorical_tick_formatter");
CategoricalTicker = require("../tickers/categorical_ticker");
logger = require("../../core/logging").logger;
CategoricalAxisView = (function(superClass) {
extend(CategoricalAxisView, superClass);
function CategoricalAxisView() {
return CategoricalAxisView.__super__.constructor.apply(this, arguments);
}
return CategoricalAxisView;
})(Axis.View);
CategoricalAxis = (function(superClass) {
extend(CategoricalAxis, superClass);
function CategoricalAxis() {
return CategoricalAxis.__super__.constructor.apply(this, arguments);
}
CategoricalAxis.prototype.default_view = CategoricalAxisView;
CategoricalAxis.prototype.type = 'CategoricalAxis';
CategoricalAxis.override({
ticker: function() {
return new CategoricalTicker.Model();
},
formatter: function() {
return new CategoricalTickFormatter.Model();
}
});
CategoricalAxis.prototype._computed_bounds = function() {
var cross_range, range, range_bounds, ref, ref1, user_bounds;
ref = this.get('ranges'), range = ref[0], cross_range = ref[1];
user_bounds = (ref1 = this.get('bounds')) != null ? ref1 : 'auto';
range_bounds = [range.get('min'), range.get('max')];
if (user_bounds !== 'auto') {
logger.warn("Categorical Axes only support user_bounds='auto', ignoring");
}
return range_bounds;
};
return CategoricalAxis;
})(Axis.Model);
module.exports = {
Model: CategoricalAxis,
View: CategoricalAxisView
};

View File

@ -0,0 +1,22 @@
var Axis, ContinuousAxis,
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;
Axis = require("./axis");
ContinuousAxis = (function(superClass) {
extend(ContinuousAxis, superClass);
function ContinuousAxis() {
return ContinuousAxis.__super__.constructor.apply(this, arguments);
}
ContinuousAxis.prototype.type = 'ContinuousAxis';
return ContinuousAxis;
})(Axis.Model);
module.exports = {
Model: ContinuousAxis
};

View File

@ -0,0 +1,51 @@
var DatetimeAxis, DatetimeAxisView, DatetimeTickFormatter, DatetimeTicker, LinearAxis, _,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
LinearAxis = require("./axis");
DatetimeTickFormatter = require("../formatters/datetime_tick_formatter");
DatetimeTicker = require("../tickers/datetime_ticker");
DatetimeAxisView = (function(superClass) {
extend(DatetimeAxisView, superClass);
function DatetimeAxisView() {
return DatetimeAxisView.__super__.constructor.apply(this, arguments);
}
return DatetimeAxisView;
})(LinearAxis.View);
DatetimeAxis = (function(superClass) {
extend(DatetimeAxis, superClass);
function DatetimeAxis() {
return DatetimeAxis.__super__.constructor.apply(this, arguments);
}
DatetimeAxis.prototype.default_view = DatetimeAxisView;
DatetimeAxis.prototype.type = 'DatetimeAxis';
DatetimeAxis.override({
ticker: function() {
return new DatetimeTicker.Model();
},
formatter: function() {
return new DatetimeTickFormatter.Model();
}
});
return DatetimeAxis;
})(LinearAxis.Model);
module.exports = {
Model: DatetimeAxis,
View: DatetimeAxisView
};

View File

@ -0,0 +1,53 @@
var Axis, BasicTickFormatter, BasicTicker, ContinuousAxis, LinearAxis, LinearAxisView, _,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Axis = require("./axis");
ContinuousAxis = require("./continuous_axis");
BasicTickFormatter = require("../formatters/basic_tick_formatter");
BasicTicker = require("../tickers/basic_ticker");
LinearAxisView = (function(superClass) {
extend(LinearAxisView, superClass);
function LinearAxisView() {
return LinearAxisView.__super__.constructor.apply(this, arguments);
}
return LinearAxisView;
})(Axis.View);
LinearAxis = (function(superClass) {
extend(LinearAxis, superClass);
function LinearAxis() {
return LinearAxis.__super__.constructor.apply(this, arguments);
}
LinearAxis.prototype.default_view = LinearAxisView;
LinearAxis.prototype.type = 'LinearAxis';
LinearAxis.override({
ticker: function() {
return new BasicTicker.Model();
},
formatter: function() {
return new BasicTickFormatter.Model();
}
});
return LinearAxis;
})(ContinuousAxis.Model);
module.exports = {
Model: LinearAxis,
View: LinearAxisView
};

View File

@ -0,0 +1,53 @@
var Axis, ContinuousAxis, LogAxis, LogAxisView, LogTickFormatter, LogTicker, _,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Axis = require("./axis");
ContinuousAxis = require("./continuous_axis");
LogTickFormatter = require("../formatters/log_tick_formatter");
LogTicker = require("../tickers/log_ticker");
LogAxisView = (function(superClass) {
extend(LogAxisView, superClass);
function LogAxisView() {
return LogAxisView.__super__.constructor.apply(this, arguments);
}
return LogAxisView;
})(Axis.View);
LogAxis = (function(superClass) {
extend(LogAxis, superClass);
function LogAxis() {
return LogAxis.__super__.constructor.apply(this, arguments);
}
LogAxis.prototype.default_view = LogAxisView;
LogAxis.prototype.type = 'LogAxis';
LogAxis.override({
ticker: function() {
return new LogTicker.Model();
},
formatter: function() {
return new LogTickFormatter.Model();
}
});
return LogAxis;
})(ContinuousAxis.Model);
module.exports = {
Model: LogAxis,
View: LogAxisView
};

View File

@ -0,0 +1,71 @@
var CustomJS, Model, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty,
slice = [].slice;
_ = require("underscore");
p = require("../../core/properties");
Model = require("../../model");
CustomJS = (function(superClass) {
extend(CustomJS, superClass);
function CustomJS() {
return CustomJS.__super__.constructor.apply(this, arguments);
}
CustomJS.prototype.type = 'CustomJS';
CustomJS.define({
args: [p.Any, {}],
code: [p.String, ''],
lang: [p.String, 'javascript']
});
CustomJS.prototype.initialize = function(attrs, options) {
CustomJS.__super__.initialize.call(this, attrs, options);
this.define_computed_property('values', this._make_values, true);
this.add_dependencies('values', this, ['args']);
this.define_computed_property('func', this._make_func, true);
return this.add_dependencies('func', this, ['args', 'code']);
};
CustomJS.prototype.execute = function(cb_obj, cb_data) {
return this.get('func').apply(null, slice.call(this.get('values')).concat([cb_obj], [cb_data], [require]));
};
CustomJS.prototype._make_values = function() {
return _.values(this.get("args"));
};
CustomJS.prototype._make_func = function() {
var code, coffee;
code = this.get("code");
code = (function() {
switch (this.get("lang")) {
case "javascript":
return code;
case "coffeescript":
coffee = require("coffee-script");
return coffee.compile(code, {
bare: true,
shiftLine: true
});
}
}).call(this);
return (function(func, args, ctor) {
ctor.prototype = func.prototype;
var child = new ctor, result = func.apply(child, args);
return Object(result) === result ? result : child;
})(Function, slice.call(_.keys(this.get("args"))).concat(["cb_obj"], ["cb_data"], ["require"], [code]), function(){});
};
return CustomJS;
})(Model);
module.exports = {
Model: CustomJS
};

View File

@ -0,0 +1,43 @@
var Model, OpenURL, Util, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
p = require("../../core/properties");
Model = require("../../model");
Util = require("../../util/util");
OpenURL = (function(superClass) {
extend(OpenURL, superClass);
function OpenURL() {
return OpenURL.__super__.constructor.apply(this, arguments);
}
OpenURL.prototype.type = 'OpenURL';
OpenURL.define({
url: [p.String, 'http://']
});
OpenURL.prototype.execute = function(data_source) {
var i, j, len, ref, url;
ref = Util.get_indices(data_source);
for (j = 0, len = ref.length; j < len; j++) {
i = ref[j];
url = Util.replace_placeholders(this.get("url"), data_source, i);
window.open(url);
}
return null;
};
return OpenURL;
})(Model);
module.exports = {
Model: OpenURL
};

View File

@ -0,0 +1,225 @@
var BokehView, Canvas, CanvasView, EQ, GE, LayoutCanvas, _, canvas_template, fixup_ellipse, fixup_image_smoothing, fixup_line_dash, fixup_line_dash_offset, fixup_measure_text, get_scale_ratio, logger, p, ref, ref1,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
canvas_template = require("./canvas_template");
LayoutCanvas = require("../../core/layout/layout_canvas");
BokehView = require("../../core/bokeh_view");
ref = require("../../core/layout/solver"), GE = ref.GE, EQ = ref.EQ;
logger = require("../../core/logging").logger;
p = require("../../core/properties");
ref1 = require("../../core/util/canvas"), fixup_image_smoothing = ref1.fixup_image_smoothing, fixup_line_dash = ref1.fixup_line_dash, fixup_line_dash_offset = ref1.fixup_line_dash_offset, fixup_measure_text = ref1.fixup_measure_text, get_scale_ratio = ref1.get_scale_ratio, fixup_ellipse = ref1.fixup_ellipse;
CanvasView = (function(superClass) {
extend(CanvasView, superClass);
function CanvasView() {
return CanvasView.__super__.constructor.apply(this, arguments);
}
CanvasView.prototype.className = "bk-canvas-wrapper";
CanvasView.prototype.template = canvas_template;
CanvasView.prototype.initialize = function(options) {
var html, ref2;
CanvasView.__super__.initialize.call(this, options);
html = this.template({
map: this.mget('map')
});
this.$el.html(html);
this.ctx = this.get_ctx();
this.ctx.glcanvas = null;
fixup_line_dash(this.ctx);
fixup_line_dash_offset(this.ctx);
fixup_image_smoothing(this.ctx);
fixup_measure_text(this.ctx);
fixup_ellipse(this.ctx);
this.map_div = (ref2 = this.$('div.bk-canvas-map')) != null ? ref2 : null;
this.set_dims([this.model.initial_width, this.model.initial_height]);
return logger.debug("CanvasView initialized");
};
CanvasView.prototype.get_canvas_element = function() {
return this.$('canvas.bk-canvas')[0];
};
CanvasView.prototype.get_ctx = function() {
var canvas_el, ctx;
canvas_el = this.$('canvas.bk-canvas');
ctx = canvas_el[0].getContext('2d');
return ctx;
};
CanvasView.prototype.prepare_canvas = function(force) {
var canvas_el, dpr, height, ratio, width;
if (force == null) {
force = false;
}
width = this.model._width._value;
height = this.model._height._value;
dpr = window.devicePixelRatio;
if (!_.isEqual(this.last_dims, [width, height, dpr]) || force) {
this.$el.css({
width: width,
height: height
});
this.pixel_ratio = ratio = get_scale_ratio(this.ctx, this.mget('use_hidpi'));
canvas_el = this.$('.bk-canvas');
canvas_el.css({
width: width,
height: height
});
canvas_el.attr('width', width * ratio);
canvas_el.attr('height', height * ratio);
logger.debug("Rendering CanvasView [force=" + force + "] with width: " + width + ", height: " + height + ", ratio: " + ratio);
this.model.pixel_ratio = this.pixel_ratio;
return this.last_dims = [width, height, dpr];
}
};
CanvasView.prototype.set_dims = function(dims, trigger) {
if (trigger == null) {
trigger = true;
}
this.requested_width = dims[0];
this.requested_height = dims[1];
this.update_constraints(trigger);
};
CanvasView.prototype.update_constraints = function(trigger) {
var MIN_SIZE, requested_height, requested_width, s;
if (trigger == null) {
trigger = true;
}
requested_width = this.requested_width;
requested_height = this.requested_height;
if ((requested_width == null) || (requested_height == null)) {
return;
}
MIN_SIZE = 50;
if (requested_width < MIN_SIZE || requested_height < MIN_SIZE) {
return;
}
if (_.isEqual(this.last_requested_dims, [requested_width, requested_height])) {
return;
}
s = this.model.document.solver();
if (this._width_constraint != null) {
s.remove_constraint(this._width_constraint);
}
this._width_constraint = EQ(this.model._width, -requested_width);
s.add_constraint(this._width_constraint);
if (this._height_constraint != null) {
s.remove_constraint(this._height_constraint);
}
this._height_constraint = EQ(this.model._height, -requested_height);
s.add_constraint(this._height_constraint);
this.last_requested_dims = [requested_width, requested_height];
return s.update_variables(trigger);
};
return CanvasView;
})(BokehView);
Canvas = (function(superClass) {
extend(Canvas, superClass);
function Canvas() {
return Canvas.__super__.constructor.apply(this, arguments);
}
Canvas.prototype.type = 'Canvas';
Canvas.prototype.default_view = CanvasView;
Canvas.internal({
map: [p.Boolean, false],
initial_width: [p.Number],
initial_height: [p.Number],
use_hidpi: [p.Boolean, true],
pixel_ratio: [p.Number]
});
Canvas.prototype.initialize = function(attrs, options) {
Canvas.__super__.initialize.call(this, attrs, options);
return this.panel = this;
};
Canvas.prototype.vx_to_sx = function(x) {
return x;
};
Canvas.prototype.vy_to_sy = function(y) {
return this._height._value - (y + 1);
};
Canvas.prototype.v_vx_to_sx = function(xx) {
return new Float64Array(xx);
};
Canvas.prototype.v_vy_to_sy = function(yy) {
var _yy, height, i, idx, len, y;
_yy = new Float64Array(yy.length);
height = this._height._value;
for (idx = i = 0, len = yy.length; i < len; idx = ++i) {
y = yy[idx];
_yy[idx] = height - (y + 1);
}
return _yy;
};
Canvas.prototype.sx_to_vx = function(x) {
return x;
};
Canvas.prototype.sy_to_vy = function(y) {
return this._height._value - (y + 1);
};
Canvas.prototype.v_sx_to_vx = function(xx) {
return new Float64Array(xx);
};
Canvas.prototype.v_sy_to_vy = function(yy) {
var _yy, height, i, idx, len, y;
_yy = new Float64Array(yy.length);
height = this._height._value;
for (idx = i = 0, len = yy.length; i < len; idx = ++i) {
y = yy[idx];
_yy[idx] = height - (y + 1);
}
return _yy;
};
Canvas.prototype.get_constraints = function() {
var constraints;
constraints = Canvas.__super__.get_constraints.call(this);
constraints.push(GE(this._top));
constraints.push(GE(this._bottom));
constraints.push(GE(this._left));
constraints.push(GE(this._right));
constraints.push(GE(this._width));
constraints.push(GE(this._height));
constraints.push(EQ(this._width, [-1, this._right]));
constraints.push(EQ(this._height, [-1, this._top]));
return constraints;
};
return Canvas;
})(LayoutCanvas.Model);
module.exports = {
Model: Canvas,
View: CanvasView
};

View File

@ -0,0 +1,50 @@
module.exports = function(__obj) {
if (!__obj) __obj = {};
var __out = [];
var __capture = function(callback) {
var out = __out, result;
__out = [];
callback.call(this);
result = __out.join('');
__out = out;
return __safe(result);
};
var __sanitize = function(value) {
if (value && value.ecoSafe) {
return value;
} else if (typeof value !== 'undefined' && value != null) {
return __escape(value);
} else {
return '';
}
};
var __safe = function(value) {
if (value && value.ecoSafe) {
return value;
} else {
if (!(typeof value !== 'undefined' && value != null)) value = '';
var result = new String(value);
result.ecoSafe = true;
return result;
}
};
var __escape = function(value) {
return ('' + value)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
};
(function() {
(function() {
if (this.map) {
__out.push('\n<div class="bk-canvas-map"></div>\n');
}
__out.push('\n<div class="bk-canvas-events" />\n<div class="bk-canvas-overlays" />\n<canvas class=\'bk-canvas\'></canvas>');
}).call(this);
}).call(__obj);
return __out.join('');
};

View File

@ -0,0 +1,194 @@
var CartesianFrame, CategoricalMapper, EQ, GE, GridMapper, LayoutCanvas, LinearMapper, LogMapper, Range1d, _, logging, p, ref,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
CategoricalMapper = require("../mappers/categorical_mapper");
GridMapper = require("../mappers/grid_mapper");
LinearMapper = require("../mappers/linear_mapper");
LogMapper = require("../mappers/log_mapper");
Range1d = require("../ranges/range1d");
ref = require("../../core/layout/solver"), EQ = ref.EQ, GE = ref.GE;
LayoutCanvas = require("../../core/layout/layout_canvas");
logging = require("../../core/logging").logging;
p = require("../../core/properties");
CartesianFrame = (function(superClass) {
extend(CartesianFrame, superClass);
function CartesianFrame() {
return CartesianFrame.__super__.constructor.apply(this, arguments);
}
CartesianFrame.prototype.type = 'CartesianFrame';
CartesianFrame.prototype.initialize = function(attrs, options) {
CartesianFrame.__super__.initialize.call(this, attrs, options);
this.panel = this;
this.define_computed_property('x_ranges', function() {
return this._get_ranges('x');
}, true);
this.add_dependencies('x_ranges', this, ['x_range', 'extra_x_ranges']);
this.define_computed_property('y_ranges', function() {
return this._get_ranges('y');
}, true);
this.add_dependencies('y_ranges', this, ['y_range', 'extra_y_ranges']);
this.define_computed_property('x_mappers', function() {
return this._get_mappers('x', this.get('x_ranges'), this.get('h_range'));
}, true);
this.add_dependencies('x_ranges', this, ['x_ranges', 'h_range']);
this.define_computed_property('y_mappers', function() {
return this._get_mappers('y', this.get('y_ranges'), this.get('v_range'));
}, true);
this.add_dependencies('y_ranges', this, ['y_ranges', 'v_range']);
this.define_computed_property('mapper', function() {
return new GridMapper.Model({
domain_mapper: this.get('x_mapper'),
codomain_mapper: this.get('y_mapper')
});
}, true);
this.add_dependencies('mapper', this, ['x_mapper', 'y_mapper']);
this._h_range = new Range1d.Model({
start: this.get('left'),
end: this.get('left') + this.get('width')
});
this.define_computed_property('h_range', (function(_this) {
return function() {
_this._h_range.set('start', _this.get('left'));
_this._h_range.set('end', _this.get('left') + _this.get('width'));
return _this._h_range;
};
})(this), false);
this.add_dependencies('h_range', this, ['left', 'width']);
this._v_range = new Range1d.Model({
start: this.get('bottom'),
end: this.get('bottom') + this.get('height')
});
this.define_computed_property('v_range', (function(_this) {
return function() {
_this._v_range.set('start', _this.get('bottom'));
_this._v_range.set('end', _this.get('bottom') + _this.get('height'));
return _this._v_range;
};
})(this), false);
this.add_dependencies('v_range', this, ['bottom', 'height']);
return null;
};
CartesianFrame.prototype._doc_attached = function() {
this.listenTo(this.document.solver(), 'layout_update', this._update_mappers);
return null;
};
CartesianFrame.prototype.contains = function(vx, vy) {
return vx >= this.get('left') && vx <= this.get('right') && vy >= this.get('bottom') && vy <= this.get('top');
};
CartesianFrame.prototype.map_to_screen = function(x, y, canvas, x_name, y_name) {
var sx, sy, vx, vy;
if (x_name == null) {
x_name = 'default';
}
if (y_name == null) {
y_name = 'default';
}
vx = this.get('x_mappers')[x_name].v_map_to_target(x);
sx = canvas.v_vx_to_sx(vx);
vy = this.get('y_mappers')[y_name].v_map_to_target(y);
sy = canvas.v_vy_to_sy(vy);
return [sx, sy];
};
CartesianFrame.prototype._get_ranges = function(dim) {
var extra_ranges, name, range, ranges;
ranges = {};
ranges['default'] = this.get(dim + "_range");
extra_ranges = this.get("extra_" + dim + "_ranges");
if (extra_ranges != null) {
for (name in extra_ranges) {
range = extra_ranges[name];
ranges[name] = range;
}
}
return ranges;
};
CartesianFrame.prototype._get_mappers = function(dim, ranges, frame_range) {
var mapper_type, mappers, name, range;
mappers = {};
for (name in ranges) {
range = ranges[name];
if (range.type === "Range1d" || range.type === "DataRange1d") {
if (this.get(dim + "_mapper_type") === "log") {
mapper_type = LogMapper.Model;
} else {
mapper_type = LinearMapper.Model;
}
} else if (range.type === "FactorRange") {
mapper_type = CategoricalMapper.Model;
} else {
logger.warn("unknown range type for range '" + name + "': " + range);
return null;
}
mappers[name] = new mapper_type({
source_range: range,
target_range: frame_range
});
}
return mappers;
};
CartesianFrame.prototype._update_mappers = function() {
var mapper, name, ref1, ref2;
ref1 = this.get('x_mappers');
for (name in ref1) {
mapper = ref1[name];
mapper.set('target_range', this.get('h_range'));
}
ref2 = this.get('y_mappers');
for (name in ref2) {
mapper = ref2[name];
mapper.set('target_range', this.get('v_range'));
}
return null;
};
CartesianFrame.internal({
extra_x_ranges: [p.Any, {}],
extra_y_ranges: [p.Any, {}],
x_range: [p.Instance],
y_range: [p.Instance],
x_mapper_type: [p.Any],
y_mapper_type: [p.Any]
});
CartesianFrame.prototype.get_constraints = function() {
var constraints;
constraints = [];
constraints.push(GE(this._top));
constraints.push(GE(this._bottom));
constraints.push(GE(this._left));
constraints.push(GE(this._right));
constraints.push(GE(this._width));
constraints.push(GE(this._height));
constraints.push(EQ(this._left, this._width, [-1, this._right]));
constraints.push(EQ(this._bottom, this._height, [-1, this._top]));
return constraints;
};
return CartesianFrame;
})(LayoutCanvas.Model);
module.exports = {
Model: CartesianFrame
};

View File

@ -0,0 +1,119 @@
var BasicTickFormatter, TickFormatter, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
TickFormatter = require("./tick_formatter");
p = require("../../core/properties");
BasicTickFormatter = (function(superClass) {
extend(BasicTickFormatter, superClass);
function BasicTickFormatter() {
return BasicTickFormatter.__super__.constructor.apply(this, arguments);
}
BasicTickFormatter.prototype.type = 'BasicTickFormatter';
BasicTickFormatter.define({
precision: [p.Any, 'auto'],
use_scientific: [p.Bool, true],
power_limit_high: [p.Number, 5],
power_limit_low: [p.Number, -3]
});
BasicTickFormatter.prototype.initialize = function(attrs, options) {
BasicTickFormatter.__super__.initialize.call(this, attrs, options);
this.define_computed_property('scientific_limit_low', function() {
return Math.pow(10.0, this.get('power_limit_low'));
}, true);
this.add_dependencies('scientific_limit_low', this, ['power_limit_low']);
this.define_computed_property('scientific_limit_high', function() {
return Math.pow(10.0, this.get('power_limit_high'));
}, true);
this.add_dependencies('scientific_limit_high', this, ['power_limit_high']);
return this.last_precision = 3;
};
BasicTickFormatter.prototype.doFormat = function(ticks) {
var i, is_ok, j, k, l, labels, len, m, n, need_sci, o, precision, ref, ref1, ref2, ref3, ref4, tick, tick_abs, x, zero_eps;
if (ticks.length === 0) {
return [];
}
zero_eps = 0;
if (ticks.length >= 2) {
zero_eps = Math.abs(ticks[1] - ticks[0]) / 10000;
}
need_sci = false;
if (this.get('use_scientific')) {
for (j = 0, len = ticks.length; j < len; j++) {
tick = ticks[j];
tick_abs = Math.abs(tick);
if (tick_abs > zero_eps && (tick_abs >= this.get('scientific_limit_high') || tick_abs <= this.get('scientific_limit_low'))) {
need_sci = true;
break;
}
}
}
precision = this.get('precision');
if ((precision == null) || _.isNumber(precision)) {
labels = new Array(ticks.length);
if (need_sci) {
for (i = k = 0, ref = ticks.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
labels[i] = ticks[i].toExponential(precision || void 0);
}
} else {
for (i = l = 0, ref1 = ticks.length; 0 <= ref1 ? l < ref1 : l > ref1; i = 0 <= ref1 ? ++l : --l) {
labels[i] = ticks[i].toFixed(precision || void 0).replace(/(\.[0-9]*?)0+$/, "$1").replace(/\.$/, "");
}
}
return labels;
} else if (precision === 'auto') {
labels = new Array(ticks.length);
for (x = m = ref2 = this.last_precision; ref2 <= 15 ? m <= 15 : m >= 15; x = ref2 <= 15 ? ++m : --m) {
is_ok = true;
if (need_sci) {
for (i = n = 0, ref3 = ticks.length; 0 <= ref3 ? n < ref3 : n > ref3; i = 0 <= ref3 ? ++n : --n) {
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 (i = o = 0, ref4 = ticks.length; 0 <= ref4 ? o < ref4 : o > ref4; i = 0 <= ref4 ? ++o : --o) {
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;
return labels;
}
}
}
return labels;
};
return BasicTickFormatter;
})(TickFormatter.Model);
module.exports = {
Model: BasicTickFormatter
};

View File

@ -0,0 +1,26 @@
var CategoricalTickFormatter, TickFormatter,
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;
TickFormatter = require("../formatters/tick_formatter");
CategoricalTickFormatter = (function(superClass) {
extend(CategoricalTickFormatter, superClass);
function CategoricalTickFormatter() {
return CategoricalTickFormatter.__super__.constructor.apply(this, arguments);
}
CategoricalTickFormatter.prototype.type = 'CategoricalTickFormatter';
CategoricalTickFormatter.prototype.doFormat = function(ticks) {
return ticks;
};
return CategoricalTickFormatter;
})(TickFormatter.Model);
module.exports = {
Model: CategoricalTickFormatter
};

View File

@ -0,0 +1,234 @@
var DEFAULT_DATETIME_FORMATS, DatetimeTickFormatter, SPrintf, TickFormatter, _, _array, _strftime, _us, logger, p, tz,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
SPrintf = require("sprintf");
tz = require("timezone");
TickFormatter = require("./tick_formatter");
logger = require("../../core/logging").logger;
p = require("../../core/properties");
_us = function(t) {
return Math.round(((t / 1000) % 1) * 1000000);
};
_array = function(t) {
return tz(t, "%Y %m %d %H %M %S").split(/\s+/).map(function(e) {
return parseInt(e, 10);
});
};
_strftime = function(t, format) {
var microsecond_replacement_string;
if (_.isFunction(format)) {
return format(t);
} else {
microsecond_replacement_string = SPrintf.sprintf("$1%06d", _us(t));
format = format.replace(/((^|[^%])(%%)*)%f/, microsecond_replacement_string);
if (format.indexOf("%") === -1) {
return format;
}
return tz(t, format);
}
};
DEFAULT_DATETIME_FORMATS = {
'microseconds': ['%fus'],
'milliseconds': ['%3Nms', '%S.%3Ns'],
'seconds': ['%Ss'],
'minsec': [':%M:%S'],
'minutes': [':%M', '%Mm'],
'hourmin': ['%H:%M'],
'hours': ['%Hh', '%H:%M'],
'days': ['%m/%d', '%a%d'],
'months': ['%m/%Y', '%b%y'],
'years': ['%Y']
};
DatetimeTickFormatter = (function(superClass) {
extend(DatetimeTickFormatter, superClass);
function DatetimeTickFormatter() {
return DatetimeTickFormatter.__super__.constructor.apply(this, arguments);
}
DatetimeTickFormatter.prototype.type = 'DatetimeTickFormatter';
DatetimeTickFormatter.define({
formats: [p.Any, DEFAULT_DATETIME_FORMATS]
});
DatetimeTickFormatter.prototype.format_order = ['microseconds', 'milliseconds', 'seconds', 'minsec', 'minutes', 'hourmin', 'hours', 'days', 'months', 'years'];
DatetimeTickFormatter.prototype.strip_leading_zeros = true;
DatetimeTickFormatter.prototype.initialize = function(attrs, options) {
DatetimeTickFormatter.__super__.initialize.call(this, attrs, options);
return this._update_width_formats();
};
DatetimeTickFormatter.prototype._update_width_formats = function() {
var fmt_name, fmt_string, fmt_strings, now, ref, results, sizes, sorted;
now = tz(new Date());
this._width_formats = {};
ref = this.formats;
results = [];
for (fmt_name in ref) {
fmt_strings = ref[fmt_name];
sizes = (function() {
var j, len, results1;
results1 = [];
for (j = 0, len = fmt_strings.length; j < len; j++) {
fmt_string = fmt_strings[j];
results1.push(_strftime(now, fmt_string).length);
}
return results1;
})();
sorted = _.sortBy(_.zip(sizes, fmt_strings), function(arg) {
var fmt, size;
size = arg[0], fmt = arg[1];
return size;
});
results.push(this._width_formats[fmt_name] = _.zip.apply(_, sorted));
}
return results;
};
DatetimeTickFormatter.prototype._get_resolution_str = function(resolution_secs, span_secs) {
var adjusted_resolution_secs, str;
adjusted_resolution_secs = resolution_secs * 1.1;
if (adjusted_resolution_secs < 1e-3) {
str = "microseconds";
} else if (adjusted_resolution_secs < 1.0) {
str = "milliseconds";
} else if (adjusted_resolution_secs < 60) {
if (span_secs >= 60) {
str = "minsec";
} else {
str = "seconds";
}
} else if (adjusted_resolution_secs < 3600) {
if (span_secs >= 3600) {
str = "hourmin";
} else {
str = "minutes";
}
} else if (adjusted_resolution_secs < 24 * 3600) {
str = "hours";
} else if (adjusted_resolution_secs < 31 * 24 * 3600) {
str = "days";
} else if (adjusted_resolution_secs < 365 * 24 * 3600) {
str = "months";
} else {
str = "years";
}
return str;
};
DatetimeTickFormatter.prototype.doFormat = function(ticks, num_labels, char_width, fill_ratio, ticker) {
var error, error1, fmt, format, formats, good_formats, hybrid_handled, i, j, k, l, labels, len, len1, next_format, next_ndx, r, ref, ref1, ref2, resol, resol_ndx, s, span, ss, t, time_tuple_ndx_for_resol, tm, widths;
if (num_labels == null) {
num_labels = null;
}
if (char_width == null) {
char_width = null;
}
if (fill_ratio == null) {
fill_ratio = 0.3;
}
if (ticker == null) {
ticker = null;
}
if (ticks.length === 0) {
return [];
}
span = Math.abs(ticks[ticks.length - 1] - ticks[0]) / 1000.0;
if (ticker) {
r = ticker.resolution;
} else {
r = span / (ticks.length - 1);
}
resol = this._get_resolution_str(r, span);
ref = this._width_formats[resol], widths = ref[0], formats = ref[1];
format = formats[0];
if (char_width) {
good_formats = [];
for (i = j = 0, ref1 = widths.length; 0 <= ref1 ? j < ref1 : j > ref1; i = 0 <= ref1 ? ++j : --j) {
if (widths[i] * ticks.length < fill_ratio * char_width) {
good_formats.push(this._width_formats[i]);
}
}
if (good_formats.length > 0) {
format = _.last(good_formats);
}
}
labels = [];
resol_ndx = this.format_order.indexOf(resol);
time_tuple_ndx_for_resol = {};
ref2 = this.format_order;
for (k = 0, len = ref2.length; k < len; k++) {
fmt = ref2[k];
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;
for (l = 0, len1 = ticks.length; l < len1; l++) {
t = ticks[l];
try {
tm = _array(t);
s = _strftime(t, format);
} catch (error1) {
error = error1;
logger.warn("unable to format tick for timestamp value " + t);
logger.warn(" - " + error);
labels.push("ERR");
continue;
}
hybrid_handled = false;
next_ndx = resol_ndx;
while (tm[time_tuple_ndx_for_resol[this.format_order[next_ndx]]] === 0) {
next_ndx += 1;
if (next_ndx === this.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[this.format_order[resol_ndx - 1]][1][0];
s = _strftime(t, next_format);
break;
} else {
hybrid_handled = true;
}
}
next_format = this._width_formats[this.format_order[next_ndx]][1][0];
s = _strftime(t, next_format);
}
if (this.strip_leading_zeros) {
ss = s.replace(/^0+/g, "");
if (ss !== s && isNaN(parseInt(ss))) {
ss = '0' + ss;
}
labels.push(ss);
} else {
labels.push(s);
}
}
return labels;
};
return DatetimeTickFormatter;
})(TickFormatter.Model);
module.exports = {
Model: DatetimeTickFormatter
};

View File

@ -0,0 +1,50 @@
var FuncTickFormatter, TickFormatter, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
p = require("../../core/properties");
TickFormatter = require("../formatters/tick_formatter");
FuncTickFormatter = (function(superClass) {
extend(FuncTickFormatter, superClass);
function FuncTickFormatter() {
return FuncTickFormatter.__super__.constructor.apply(this, arguments);
}
FuncTickFormatter.prototype.type = 'FuncTickFormatter';
FuncTickFormatter.define({
code: [p.String, ''],
lang: [p.String, 'javascript']
});
FuncTickFormatter.prototype.doFormat = function(ticks) {
var code, coffee, func;
code = this.get("code");
code = (function() {
switch (this.get("lang")) {
case "javascript":
return code;
case "coffeescript":
coffee = require("coffee-script");
return coffee.compile(code, {
bare: true,
shiftLine: true
});
}
}).call(this);
func = new Function("tick", "var func = " + code + "return func(tick)");
return _.map(ticks, func);
};
return FuncTickFormatter;
})(TickFormatter.Model);
module.exports = {
Model: FuncTickFormatter
};

View File

@ -0,0 +1,67 @@
var BasicTickFormatter, LogTickFormatter, TickFormatter, _, logger, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
BasicTickFormatter = require("./basic_tick_formatter");
TickFormatter = require("./tick_formatter");
logger = require("../../core/logging").logger;
p = require("../../core/properties");
LogTickFormatter = (function(superClass) {
extend(LogTickFormatter, superClass);
function LogTickFormatter() {
return LogTickFormatter.__super__.constructor.apply(this, arguments);
}
LogTickFormatter.prototype.type = 'LogTickFormatter';
LogTickFormatter.define({
ticker: [p.Instance, null]
});
LogTickFormatter.prototype.initialize = function(attrs, options) {
LogTickFormatter.__super__.initialize.call(this, attrs, options);
this.basic_formatter = new BasicTickFormatter.Model();
if (this.get('ticker') == null) {
return 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) {
var base, i, j, labels, ref, small_interval;
if (ticks.length === 0) {
return [];
}
if (this.get('ticker') != null) {
base = this.get('ticker').get('base');
} else {
base = 10;
}
small_interval = false;
labels = new Array(ticks.length);
for (i = j = 0, ref = ticks.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
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) {
labels = this.basic_formatter.doFormat(ticks);
}
return labels;
};
return LogTickFormatter;
})(TickFormatter.Model);
module.exports = {
Model: LogTickFormatter
};

View File

@ -0,0 +1,63 @@
var Numbro, NumeralTickFormatter, TickFormatter, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Numbro = require("numbro");
TickFormatter = require("./tick_formatter");
p = require("../../core/properties");
NumeralTickFormatter = (function(superClass) {
extend(NumeralTickFormatter, superClass);
function NumeralTickFormatter() {
return NumeralTickFormatter.__super__.constructor.apply(this, arguments);
}
NumeralTickFormatter.prototype.type = 'NumeralTickFormatter';
NumeralTickFormatter.define({
format: [p.String, '0,0'],
language: [p.String, 'en'],
rounding: [p.String, 'round']
});
NumeralTickFormatter.prototype.doFormat = function(ticks) {
var format, labels, language, rounding, tick;
format = this.get("format");
language = this.get("language");
rounding = (function() {
switch (this.get("rounding")) {
case "round":
case "nearest":
return Math.round;
case "floor":
case "rounddown":
return Math.floor;
case "ceil":
case "roundup":
return Math.ceil;
}
}).call(this);
labels = (function() {
var i, len, results;
results = [];
for (i = 0, len = ticks.length; i < len; i++) {
tick = ticks[i];
results.push(Numbro.format(tick, format, language, rounding));
}
return results;
})();
return labels;
};
return NumeralTickFormatter;
})(TickFormatter.Model);
module.exports = {
Model: NumeralTickFormatter
};

View File

@ -0,0 +1,47 @@
var PrintfTickFormatter, SPrintf, TickFormatter, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
SPrintf = require("sprintf");
TickFormatter = require("./tick_formatter");
p = require("../../core/properties");
PrintfTickFormatter = (function(superClass) {
extend(PrintfTickFormatter, superClass);
function PrintfTickFormatter() {
return PrintfTickFormatter.__super__.constructor.apply(this, arguments);
}
PrintfTickFormatter.prototype.type = 'PrintfTickFormatter';
PrintfTickFormatter.define({
format: [p.String, '%s']
});
PrintfTickFormatter.prototype.doFormat = function(ticks) {
var format, labels, tick;
format = this.get("format");
labels = (function() {
var i, len, results;
results = [];
for (i = 0, len = ticks.length; i < len; i++) {
tick = ticks[i];
results.push(SPrintf.sprintf(format, tick));
}
return results;
})();
return labels;
};
return PrintfTickFormatter;
})(TickFormatter.Model);
module.exports = {
Model: PrintfTickFormatter
};

View File

@ -0,0 +1,26 @@
var Model, TickFormatter, _,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Model = require("../../model");
TickFormatter = (function(superClass) {
extend(TickFormatter, superClass);
function TickFormatter() {
return TickFormatter.__super__.constructor.apply(this, arguments);
}
TickFormatter.prototype.type = 'TickFormatter';
TickFormatter.prototype.doFormat = function(ticks) {};
return TickFormatter;
})(Model);
module.exports = {
Model: TickFormatter
};

View File

@ -0,0 +1,200 @@
var AnnularWedge, AnnularWedgeView, Glyph, _, angle_between, hittest, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Glyph = require("./glyph");
hittest = require("../../common/hittest");
p = require("../../core/properties");
angle_between = require("../../core/util/math").angle_between;
AnnularWedgeView = (function(superClass) {
extend(AnnularWedgeView, superClass);
function AnnularWedgeView() {
return AnnularWedgeView.__super__.constructor.apply(this, arguments);
}
AnnularWedgeView.prototype._index_data = function() {
return this._xy_index();
};
AnnularWedgeView.prototype._map_data = function() {
var i, j, ref, results;
if (this.model.properties.inner_radius.units === "data") {
this.sinner_radius = this.sdist(this.renderer.xmapper, 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.xmapper, this._x, this._outer_radius);
} else {
this.souter_radius = this._outer_radius;
}
this._angle = new Float32Array(this._start_angle.length);
results = [];
for (i = j = 0, ref = this._start_angle.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
results.push(this._angle[i] = this._end_angle[i] - this._start_angle[i]);
}
return results;
};
AnnularWedgeView.prototype._render = function(ctx, indices, arg) {
var _angle, _start_angle, direction, i, j, len, results, sinner_radius, souter_radius, sx, sy;
sx = arg.sx, sy = arg.sy, _start_angle = arg._start_angle, _angle = arg._angle, sinner_radius = arg.sinner_radius, souter_radius = arg.souter_radius;
direction = this.model.properties.direction.value();
results = [];
for (j = 0, len = indices.length; j < len; j++) {
i = indices[j];
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);
results.push(ctx.stroke());
} else {
results.push(void 0);
}
}
return results;
};
AnnularWedgeView.prototype._hit_point = function(geometry) {
var angle, bbox, candidates, direction, dist, hits, i, ir2, j, k, len, len1, or2, pt, ref, ref1, ref2, ref3, ref4, result, sx, sx0, sx1, sy, sy0, sy1, vx, vx0, vx1, vy, vy0, vy1, x, x0, x1, y, y0, y1;
ref = [geometry.vx, geometry.vy], vx = ref[0], vy = ref[1];
x = this.renderer.xmapper.map_from_target(vx, true);
y = this.renderer.ymapper.map_from_target(vy, true);
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 {
vx0 = vx - this.max_outer_radius;
vx1 = vx + this.max_outer_radius;
ref1 = this.renderer.xmapper.v_map_from_target([vx0, vx1], true), x0 = ref1[0], x1 = ref1[1];
vy0 = vy - this.max_outer_radius;
vy1 = vy + this.max_outer_radius;
ref2 = this.renderer.ymapper.v_map_from_target([vy0, vy1], true), y0 = ref2[0], y1 = ref2[1];
}
candidates = [];
bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
ref3 = (function() {
var k, len, ref3, results;
ref3 = this.index.search(bbox);
results = [];
for (k = 0, len = ref3.length; k < len; k++) {
pt = ref3[k];
results.push(pt.i);
}
return results;
}).call(this);
for (j = 0, len = ref3.length; j < len; j++) {
i = ref3[j];
or2 = Math.pow(this.souter_radius[i], 2);
ir2 = Math.pow(this.sinner_radius[i], 2);
sx0 = this.renderer.xmapper.map_to_target(x, true);
sx1 = this.renderer.xmapper.map_to_target(this._x[i], true);
sy0 = this.renderer.ymapper.map_to_target(y, true);
sy1 = this.renderer.ymapper.map_to_target(this._y[i], true);
dist = Math.pow(sx0 - sx1, 2) + Math.pow(sy0 - sy1, 2);
if (dist <= or2 && dist >= ir2) {
candidates.push([i, dist]);
}
}
direction = this.model.properties.direction.value();
hits = [];
for (k = 0, len1 = candidates.length; k < len1; k++) {
ref4 = candidates[k], i = ref4[0], dist = ref4[1];
sx = this.renderer.plot_view.canvas.vx_to_sx(vx);
sy = this.renderer.plot_view.canvas.vy_to_sy(vy);
angle = Math.atan2(sy - this.sy[i], sx - this.sx[i]);
if (angle_between(-angle, -this._start_angle[i], -this._end_angle[i], direction)) {
hits.push([i, dist]);
}
}
result = hittest.create_hit_test_result();
result['1d'].indices = _.chain(hits).sortBy(function(elt) {
return elt[1];
}).map(function(elt) {
return elt[0];
}).value();
return result;
};
AnnularWedgeView.prototype.draw_legend = function(ctx, x0, x1, y0, y1) {
return this._generic_area_legend(ctx, x0, x1, y0, y1);
};
AnnularWedgeView.prototype._scxy = function(i) {
var a, r;
r = (this.sinner_radius[i] + this.souter_radius[i]) / 2;
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.scx = function(i) {
return this._scxy(i).x;
};
AnnularWedgeView.prototype.scy = function(i) {
return this._scxy(i).y;
};
return AnnularWedgeView;
})(Glyph.View);
AnnularWedge = (function(superClass) {
extend(AnnularWedge, superClass);
function AnnularWedge() {
return AnnularWedge.__super__.constructor.apply(this, arguments);
}
AnnularWedge.prototype.default_view = AnnularWedgeView;
AnnularWedge.prototype.type = 'AnnularWedge';
AnnularWedge.coords([['x', 'y']]);
AnnularWedge.mixins(['line', 'fill']);
AnnularWedge.define({
direction: [p.Direction, 'anticlock'],
inner_radius: [p.DistanceSpec],
outer_radius: [p.DistanceSpec],
start_angle: [p.AngleSpec],
end_angle: [p.AngleSpec]
});
return AnnularWedge;
})(Glyph.Model);
module.exports = {
Model: AnnularWedge,
View: AnnularWedgeView
};

View File

@ -0,0 +1,173 @@
var Annulus, AnnulusView, Glyph, _, hittest, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Glyph = require("./glyph");
hittest = require("../../common/hittest");
p = require("../../core/properties");
AnnulusView = (function(superClass) {
extend(AnnulusView, superClass);
function AnnulusView() {
return AnnulusView.__super__.constructor.apply(this, arguments);
}
AnnulusView.prototype._index_data = function() {
return this._xy_index();
};
AnnulusView.prototype._map_data = function() {
if (this.model.properties.inner_radius.units === "data") {
this.sinner_radius = this.sdist(this.renderer.xmapper, this._x, this._inner_radius);
} else {
this.sinner_radius = this._inner_radius;
}
if (this.model.properties.outer_radius.units === "data") {
return this.souter_radius = this.sdist(this.renderer.xmapper, this._x, this._outer_radius);
} else {
return this.souter_radius = this._outer_radius;
}
};
AnnulusView.prototype._render = function(ctx, indices, arg) {
var clockwise, i, isie, j, k, len, len1, ref, results, sinner_radius, souter_radius, sx, sy;
sx = arg.sx, sy = arg.sy, sinner_radius = arg.sinner_radius, souter_radius = arg.souter_radius;
results = [];
for (j = 0, len = indices.length; j < len; j++) {
i = indices[j];
if (isNaN(sx[i] + sy[i] + sinner_radius[i] + souter_radius[i])) {
continue;
}
isie = navigator.userAgent.indexOf('MSIE') >= 0 || navigator.userAgent.indexOf('Trident') > 0 || navigator.userAgent.indexOf('Edge') > 0;
if (this.visuals.fill.doit) {
this.visuals.fill.set_vectorize(ctx, i);
ctx.beginPath();
if (isie) {
ref = [false, true];
for (k = 0, len1 = ref.length; k < len1; k++) {
clockwise = ref[k];
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 {
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);
results.push(ctx.stroke());
} else {
results.push(void 0);
}
}
return results;
};
AnnulusView.prototype._hit_point = function(geometry) {
var bbox, dist, hits, i, ir2, j, len, or2, pt, ref, ref1, result, sx0, sx1, sy0, sy1, vx, vy, x, x0, x1, y, y0, y1;
ref = [geometry.vx, geometry.vy], vx = ref[0], vy = ref[1];
x = this.renderer.xmapper.map_from_target(vx, true);
x0 = x - this.max_radius;
x1 = x + this.max_radius;
y = this.renderer.ymapper.map_from_target(vy, true);
y0 = y - this.max_radius;
y1 = y + this.max_radius;
hits = [];
bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
ref1 = (function() {
var k, len, ref1, results;
ref1 = this.index.search(bbox);
results = [];
for (k = 0, len = ref1.length; k < len; k++) {
pt = ref1[k];
results.push(pt.i);
}
return results;
}).call(this);
for (j = 0, len = ref1.length; j < len; j++) {
i = ref1[j];
or2 = Math.pow(this.souter_radius[i], 2);
ir2 = Math.pow(this.sinner_radius[i], 2);
sx0 = this.renderer.xmapper.map_to_target(x);
sx1 = this.renderer.xmapper.map_to_target(this._x[i]);
sy0 = this.renderer.ymapper.map_to_target(y);
sy1 = this.renderer.ymapper.map_to_target(this._y[i]);
dist = Math.pow(sx0 - sx1, 2) + Math.pow(sy0 - sy1, 2);
if (dist <= or2 && dist >= ir2) {
hits.push([i, dist]);
}
}
result = hittest.create_hit_test_result();
result['1d'].indices = _.chain(hits).sortBy(function(elt) {
return elt[1];
}).map(function(elt) {
return elt[0];
}).value();
return result;
};
AnnulusView.prototype.draw_legend = function(ctx, x0, x1, y0, y1) {
var data, indices, r, ref, reference_point, sinner_radius, souter_radius, sx, sy;
reference_point = (ref = this.get_reference_point()) != null ? ref : 0;
indices = [reference_point];
sx = {};
sx[reference_point] = (x0 + x1) / 2;
sy = {};
sy[reference_point] = (y0 + y1) / 2;
r = Math.min(Math.abs(x1 - x0), Math.abs(y1 - y0)) * 0.5;
sinner_radius = {};
sinner_radius[reference_point] = r * 0.4;
souter_radius = {};
souter_radius[reference_point] = r * 0.8;
data = {
sx: sx,
sy: sy,
sinner_radius: sinner_radius,
souter_radius: souter_radius
};
return this._render(ctx, indices, data);
};
return AnnulusView;
})(Glyph.View);
Annulus = (function(superClass) {
extend(Annulus, superClass);
function Annulus() {
return Annulus.__super__.constructor.apply(this, arguments);
}
Annulus.prototype.default_view = AnnulusView;
Annulus.prototype.type = 'Annulus';
Annulus.coords([['x', 'y']]);
Annulus.mixins(['line', 'fill']);
Annulus.define({
inner_radius: [p.DistanceSpec],
outer_radius: [p.DistanceSpec]
});
return Annulus;
})(Glyph.Model);
module.exports = {
Model: Annulus,
View: AnnulusView
};

View File

@ -0,0 +1,87 @@
var Arc, ArcView, Glyph, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Glyph = require("./glyph");
p = require("../../core/properties");
ArcView = (function(superClass) {
extend(ArcView, superClass);
function ArcView() {
return ArcView.__super__.constructor.apply(this, arguments);
}
ArcView.prototype._index_data = function() {
return this._xy_index();
};
ArcView.prototype._map_data = function() {
if (this.model.properties.radius.units === "data") {
return this.sradius = this.sdist(this.renderer.xmapper, this._x, this._radius);
} else {
return this.sradius = this._radius;
}
};
ArcView.prototype._render = function(ctx, indices, arg) {
var _end_angle, _start_angle, direction, i, j, len, results, sradius, sx, sy;
sx = arg.sx, sy = arg.sy, sradius = arg.sradius, _start_angle = arg._start_angle, _end_angle = arg._end_angle;
if (this.visuals.line.doit) {
direction = this.model.properties.direction.value();
results = [];
for (j = 0, len = indices.length; j < len; j++) {
i = indices[j];
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);
results.push(ctx.stroke());
}
return results;
}
};
ArcView.prototype.draw_legend = function(ctx, x0, x1, y0, y1) {
return this._generic_line_legend(ctx, x0, x1, y0, y1);
};
return ArcView;
})(Glyph.View);
Arc = (function(superClass) {
extend(Arc, superClass);
function Arc() {
return Arc.__super__.constructor.apply(this, arguments);
}
Arc.prototype.default_view = ArcView;
Arc.prototype.type = 'Arc';
Arc.coords([['x', 'y']]);
Arc.mixins(['line']);
Arc.define({
direction: [p.Direction, 'anticlock'],
radius: [p.DistanceSpec],
start_angle: [p.AngleSpec],
end_angle: [p.AngleSpec]
});
return Arc;
})(Glyph.Model);
module.exports = {
Model: Arc,
View: ArcView
};

View File

@ -0,0 +1,144 @@
var Bezier, BezierView, Glyph, _, _cbb, rbush,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
rbush = require("rbush");
Glyph = require("./glyph");
_cbb = function(x0, y0, x1, y1, x2, y2, x3, y3) {
var a, b, b2ac, bounds, c, i, j, jlen, k, mt, sqrtb2ac, t, t1, t2, tvalues, x, y;
tvalues = [];
bounds = [[], []];
for (i = k = 0; k <= 2; i = ++k) {
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) {
if (Math.abs(b) < 1e-12) {
continue;
}
t = -c / b;
if (0 < t && t < 1) {
tvalues.push(t);
}
continue;
}
b2ac = b * b - 4 * c * a;
sqrtb2ac = Math.sqrt(b2ac);
if (b2ac < 0) {
continue;
}
t1 = (-b + sqrtb2ac) / (2 * a);
if (0 < t1 && t1 < 1) {
tvalues.push(t1);
}
t2 = (-b - sqrtb2ac) / (2 * a);
if (0 < t2 && t2 < 1) {
tvalues.push(t2);
}
}
j = tvalues.length;
jlen = j;
while (j--) {
t = tvalues[j];
mt = 1 - t;
x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);
bounds[0][j] = x;
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(null, bounds[0]), Math.max.apply(null, bounds[1]), Math.max.apply(null, bounds[0]), Math.min.apply(null, bounds[1])];
};
BezierView = (function(superClass) {
extend(BezierView, superClass);
function BezierView() {
return BezierView.__super__.constructor.apply(this, arguments);
}
BezierView.prototype._index_data = function() {
var i, index, k, pts, ref, ref1, x0, x1, y0, y1;
index = rbush();
pts = [];
for (i = k = 0, ref = this._x0.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
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;
}
ref1 = _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 = ref1[0], y0 = ref1[1], x1 = ref1[2], y1 = ref1[3];
pts.push({
minX: x0,
minY: y0,
maxX: x1,
maxY: y1,
i: i
});
}
index.load(pts);
return index;
};
BezierView.prototype._render = function(ctx, indices, arg) {
var i, k, len, results, scx, scx0, scx1, scy0, scy1, sx0, sx1, sy0, sy1;
sx0 = arg.sx0, sy0 = arg.sy0, sx1 = arg.sx1, sy1 = arg.sy1, scx = arg.scx, scx0 = arg.scx0, scy0 = arg.scy0, scx1 = arg.scx1, scy1 = arg.scy1;
if (this.visuals.line.doit) {
results = [];
for (k = 0, len = indices.length; k < len; k++) {
i = indices[k];
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);
results.push(ctx.stroke());
}
return results;
}
};
BezierView.prototype.draw_legend = function(ctx, x0, x1, y0, y1) {
return this._generic_line_legend(ctx, x0, x1, y0, y1);
};
return BezierView;
})(Glyph.View);
Bezier = (function(superClass) {
extend(Bezier, superClass);
function Bezier() {
return Bezier.__super__.constructor.apply(this, arguments);
}
Bezier.prototype.default_view = BezierView;
Bezier.prototype.type = 'Bezier';
Bezier.coords([['x0', 'y0'], ['x1', 'y1'], ['cx0', 'cy0'], ['cx1', 'cy1']]);
Bezier.mixins(['line']);
return Bezier;
})(Glyph.Model);
module.exports = {
Model: Bezier,
View: BezierView
};

View File

@ -0,0 +1,325 @@
var Circle, CircleView, Glyph, _, hittest, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Glyph = require("./glyph");
hittest = require("../../common/hittest");
p = require("../../core/properties");
CircleView = (function(superClass) {
extend(CircleView, superClass);
function CircleView() {
return CircleView.__super__.constructor.apply(this, arguments);
}
CircleView.prototype._index_data = function() {
return this._xy_index();
};
CircleView.prototype._map_data = function() {
var rd, s;
if (this._radius != null) {
if (this.model.properties.radius.spec.units === "data") {
rd = this.model.properties.radius_dimension.spec.value;
return this.sradius = this.sdist(this.renderer[rd + "mapper"], this["_" + rd], this._radius);
} else {
this.sradius = this._radius;
return this.max_size = 2 * this.max_radius;
}
} else {
return this.sradius = (function() {
var j, len, ref, results;
ref = this._size;
results = [];
for (j = 0, len = ref.length; j < len; j++) {
s = ref[j];
results.push(s / 2);
}
return results;
}).call(this);
}
};
CircleView.prototype._mask_data = function(all_indices) {
var bbox, hr, ref, ref1, ref2, ref3, sx0, sx1, sy0, sy1, vr, x, x0, x1, y0, y1;
hr = this.renderer.plot_view.frame.get('h_range');
vr = this.renderer.plot_view.frame.get('v_range');
if ((this._radius != null) && this.model.properties.radius.units === "data") {
sx0 = hr.get('start');
sx1 = hr.get('end');
ref = this.renderer.xmapper.v_map_from_target([sx0, sx1], true), x0 = ref[0], x1 = ref[1];
x0 -= this.max_radius;
x1 += this.max_radius;
sy0 = vr.get('start');
sy1 = vr.get('end');
ref1 = this.renderer.ymapper.v_map_from_target([sy0, sy1], true), y0 = ref1[0], y1 = ref1[1];
y0 -= this.max_radius;
y1 += this.max_radius;
} else {
sx0 = hr.get('start') - this.max_size;
sx1 = hr.get('end') + this.max_size;
ref2 = this.renderer.xmapper.v_map_from_target([sx0, sx1], true), x0 = ref2[0], x1 = ref2[1];
sy0 = vr.get('start') - this.max_size;
sy1 = vr.get('end') + this.max_size;
ref3 = this.renderer.ymapper.v_map_from_target([sy0, sy1], true), y0 = ref3[0], y1 = ref3[1];
}
bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
return (function() {
var j, len, ref4, results;
ref4 = this.index.search(bbox);
results = [];
for (j = 0, len = ref4.length; j < len; j++) {
x = ref4[j];
results.push(x.i);
}
return results;
}).call(this);
};
CircleView.prototype._render = function(ctx, indices, arg) {
var i, j, len, results, sradius, sx, sy;
sx = arg.sx, sy = arg.sy, sradius = arg.sradius;
results = [];
for (j = 0, len = indices.length; j < len; j++) {
i = indices[j];
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);
results.push(ctx.stroke());
} else {
results.push(void 0);
}
}
return results;
};
CircleView.prototype._hit_point = function(geometry) {
var bbox, candidates, dist, hits, i, j, k, len, len1, pt, r2, ref, ref1, ref2, ref3, ref4, result, sx, sx0, sx1, sy, sy0, sy1, vx, vx0, vx1, vy, vy0, vy1, x, x0, x1, y, y0, y1;
ref = [geometry.vx, geometry.vy], vx = ref[0], vy = ref[1];
x = this.renderer.xmapper.map_from_target(vx, true);
y = this.renderer.ymapper.map_from_target(vy, true);
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 {
vx0 = vx - this.max_size;
vx1 = vx + this.max_size;
ref1 = this.renderer.xmapper.v_map_from_target([vx0, vx1], true), x0 = ref1[0], x1 = ref1[1];
ref2 = [Math.min(x0, x1), Math.max(x0, x1)], x0 = ref2[0], x1 = ref2[1];
vy0 = vy - this.max_size;
vy1 = vy + this.max_size;
ref3 = this.renderer.ymapper.v_map_from_target([vy0, vy1], true), y0 = ref3[0], y1 = ref3[1];
ref4 = [Math.min(y0, y1), Math.max(y0, y1)], y0 = ref4[0], y1 = ref4[1];
}
bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
candidates = (function() {
var j, len, ref5, results;
ref5 = this.index.search(bbox);
results = [];
for (j = 0, len = ref5.length; j < len; j++) {
pt = ref5[j];
results.push(pt.i);
}
return results;
}).call(this);
hits = [];
if ((this._radius != null) && this.model.properties.radius.units === "data") {
for (j = 0, len = candidates.length; j < len; j++) {
i = candidates[j];
r2 = Math.pow(this.sradius[i], 2);
sx0 = this.renderer.xmapper.map_to_target(x, true);
sx1 = this.renderer.xmapper.map_to_target(this._x[i], true);
sy0 = this.renderer.ymapper.map_to_target(y, true);
sy1 = this.renderer.ymapper.map_to_target(this._y[i], true);
dist = Math.pow(sx0 - sx1, 2) + Math.pow(sy0 - sy1, 2);
if (dist <= r2) {
hits.push([i, dist]);
}
}
} else {
sx = this.renderer.plot_view.canvas.vx_to_sx(vx);
sy = this.renderer.plot_view.canvas.vy_to_sy(vy);
for (k = 0, len1 = candidates.length; k < len1; k++) {
i = candidates[k];
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]);
}
}
}
hits = _.chain(hits).sortBy(function(elt) {
return elt[1];
}).map(function(elt) {
return elt[0];
}).value();
result = hittest.create_hit_test_result();
result['1d'].indices = hits;
return result;
};
CircleView.prototype._hit_span = function(geometry) {
var bbox, hits, maxX, maxY, minX, minY, ms, ref, ref1, ref2, ref3, ref4, ref5, result, vx, vx0, vx1, vy, vy0, vy1, x0, x1, xx, y0, y1;
ref = [geometry.vx, geometry.vy], vx = ref[0], vy = ref[1];
ref1 = this.bounds(), minX = ref1.minX, minY = ref1.minY, maxX = ref1.maxX, maxY = ref1.maxY;
result = hittest.create_hit_test_result();
if (geometry.direction === 'h') {
y0 = minY;
y1 = maxY;
if ((this._radius != null) && this.model.properties.radius.units === "data") {
vx0 = vx - this.max_radius;
vx1 = vx + this.max_radius;
ref2 = this.renderer.xmapper.v_map_from_target([vx0, vx1]), x0 = ref2[0], x1 = ref2[1];
} else {
ms = this.max_size / 2;
vx0 = vx - ms;
vx1 = vx + ms;
ref3 = this.renderer.xmapper.v_map_from_target([vx0, vx1], true), x0 = ref3[0], x1 = ref3[1];
}
} else {
x0 = minX;
x1 = maxX;
if ((this._radius != null) && this.model.properties.radius.units === "data") {
vy0 = vy - this.max_radius;
vy1 = vy + this.max_radius;
ref4 = this.renderer.ymapper.v_map_from_target([vy0, vy1]), y0 = ref4[0], y1 = ref4[1];
} else {
ms = this.max_size / 2;
vy0 = vy - ms;
vy1 = vy + ms;
ref5 = this.renderer.ymapper.v_map_from_target([vy0, vy1], true), y0 = ref5[0], y1 = ref5[1];
}
}
bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
hits = (function() {
var j, len, ref6, results;
ref6 = this.index.search(bbox);
results = [];
for (j = 0, len = ref6.length; j < len; j++) {
xx = ref6[j];
results.push(xx.i);
}
return results;
}).call(this);
result['1d'].indices = hits;
return result;
};
CircleView.prototype._hit_rect = function(geometry) {
var bbox, ref, ref1, result, x, x0, x1, y0, y1;
ref = this.renderer.xmapper.v_map_from_target([geometry.vx0, geometry.vx1], true), x0 = ref[0], x1 = ref[1];
ref1 = this.renderer.ymapper.v_map_from_target([geometry.vy0, geometry.vy1], true), y0 = ref1[0], y1 = ref1[1];
bbox = hittest.validate_bbox_coords([x0, x1], [y0, y1]);
result = hittest.create_hit_test_result();
result['1d'].indices = (function() {
var j, len, ref2, results;
ref2 = this.index.search(bbox);
results = [];
for (j = 0, len = ref2.length; j < len; j++) {
x = ref2[j];
results.push(x.i);
}
return results;
}).call(this);
return result;
};
CircleView.prototype._hit_poly = function(geometry) {
var candidates, hits, i, idx, j, k, ref, ref1, ref2, result, results, sx, sy, vx, vy;
ref = [geometry.vx, geometry.vy], vx = ref[0], vy = ref[1];
sx = this.renderer.plot_view.canvas.v_vx_to_sx(vx);
sy = this.renderer.plot_view.canvas.v_vy_to_sy(vy);
candidates = (function() {
results = [];
for (var j = 0, ref1 = this.sx.length; 0 <= ref1 ? j < ref1 : j > ref1; 0 <= ref1 ? j++ : j--){ results.push(j); }
return results;
}).apply(this);
hits = [];
for (i = k = 0, ref2 = candidates.length; 0 <= ref2 ? k < ref2 : k > ref2; i = 0 <= ref2 ? ++k : --k) {
idx = candidates[i];
if (hittest.point_in_poly(this.sx[i], this.sy[i], sx, sy)) {
hits.push(idx);
}
}
result = hittest.create_hit_test_result();
result['1d'].indices = hits;
return result;
};
CircleView.prototype.draw_legend = function(ctx, x0, x1, y0, y1) {
var data, indices, ref, reference_point, sradius, sx, sy;
reference_point = (ref = this.get_reference_point()) != null ? ref : 0;
indices = [reference_point];
sx = {};
sx[reference_point] = (x0 + x1) / 2;
sy = {};
sy[reference_point] = (y0 + y1) / 2;
sradius = {};
sradius[reference_point] = Math.min(Math.abs(x1 - x0), Math.abs(y1 - y0)) * 0.2;
data = {
sx: sx,
sy: sy,
sradius: sradius
};
return this._render(ctx, indices, data);
};
return CircleView;
})(Glyph.View);
Circle = (function(superClass) {
extend(Circle, superClass);
function Circle() {
return Circle.__super__.constructor.apply(this, arguments);
}
Circle.prototype.default_view = CircleView;
Circle.prototype.type = 'Circle';
Circle.coords([['x', 'y']]);
Circle.mixins(['line', 'fill']);
Circle.define({
angle: [p.AngleSpec, 0],
size: [
p.DistanceSpec, {
units: "screen",
value: 4
}
],
radius: [p.DistanceSpec, null],
radius_dimension: [p.String, 'x']
});
Circle.prototype.initialize = function(attrs, options) {
Circle.__super__.initialize.call(this, attrs, options);
return this.properties.radius.optional = true;
};
return Circle;
})(Glyph.Model);
module.exports = {
Model: Circle,
View: CircleView
};

View File

@ -0,0 +1,135 @@
var Ellipse, EllipseView, Glyph, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Glyph = require("./glyph");
p = require("../../core/properties");
EllipseView = (function(superClass) {
extend(EllipseView, superClass);
function EllipseView() {
return EllipseView.__super__.constructor.apply(this, arguments);
}
EllipseView.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") {
return this.max_h2 = this.max_height / 2;
}
};
EllipseView.prototype._index_data = function() {
return this._xy_index();
};
EllipseView.prototype._map_data = function() {
if (this.model.properties.width.units === "data") {
this.sw = this.sdist(this.renderer.xmapper, this._x, this._width, 'center');
} else {
this.sw = this._width;
}
if (this.model.properties.height.units === "data") {
return this.sh = this.sdist(this.renderer.ymapper, this._y, this._height, 'center');
} else {
return this.sh = this._height;
}
};
EllipseView.prototype._render = function(ctx, indices, arg) {
var i, j, len, results, sh, sw, sx, sy;
sx = arg.sx, sy = arg.sy, sw = arg.sw, sh = arg.sh;
results = [];
for (j = 0, len = indices.length; j < len; j++) {
i = indices[j];
if (isNaN(sx[i] + sy[i] + sw[i] + sh[i] + this._angle[i])) {
continue;
}
ctx.beginPath();
ctx.ellipse(sx[i], sy[i], sw[i] / 2.0, sh[i] / 2.0, this._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);
results.push(ctx.stroke());
} else {
results.push(void 0);
}
}
return results;
};
EllipseView.prototype.draw_legend = function(ctx, x0, x1, y0, y1) {
var d, data, indices, ref, reference_point, scale, sh, sw, sx, sy;
reference_point = (ref = this.get_reference_point()) != null ? ref : 0;
indices = [reference_point];
sx = {};
sx[reference_point] = (x0 + x1) / 2;
sy = {};
sy[reference_point] = (y0 + y1) / 2;
scale = this.sw[reference_point] / this.sh[reference_point];
d = Math.min(Math.abs(x1 - x0), Math.abs(y1 - y0)) * 0.8;
sw = {};
sh = {};
if (scale > 1) {
sw[reference_point] = d;
sh[reference_point] = d / scale;
} else {
sw[reference_point] = d * scale;
sh[reference_point] = d;
}
data = {
sx: sx,
sy: sy,
sw: sw,
sh: sh
};
return this._render(ctx, indices, data);
};
EllipseView.prototype._bounds = function(bds) {
return this.max_wh2_bounds(bds);
};
return EllipseView;
})(Glyph.View);
Ellipse = (function(superClass) {
extend(Ellipse, superClass);
function Ellipse() {
return Ellipse.__super__.constructor.apply(this, arguments);
}
Ellipse.prototype.default_view = EllipseView;
Ellipse.prototype.type = 'Ellipse';
Ellipse.coords([['x', 'y']]);
Ellipse.mixins(['line', 'fill']);
Ellipse.define({
angle: [p.AngleSpec, 0.0],
width: [p.DistanceSpec],
height: [p.DistanceSpec]
});
return Ellipse;
})(Glyph.Model);
module.exports = {
Model: Ellipse,
View: EllipseView
};

View File

@ -0,0 +1,167 @@
var Bezier, Gear, GearUtils, GearView, Glyph, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Glyph = require("./glyph");
GearUtils = require("gear_utils");
p = require("../../core/properties");
Bezier = require("../../util/bezier");
GearView = (function(superClass) {
extend(GearView, superClass);
function GearView() {
return GearView.__super__.constructor.apply(this, arguments);
}
GearView.prototype._index_data = function() {
return this._xy_index();
};
GearView.prototype._map_data = function() {
return this.smodule = this.sdist(this.renderer.xmapper, this._x, this._module, 'edge');
};
GearView.prototype._render = function(ctx, indices, arg) {
var M, _angle, _internal, _pressure_angle, _shaft_size, _teeth, fn, i, j, k, l, len, pitch_radius, ref, ref1, rim_radius, rot, seq, seq0, shaft_radius, smodule, sx, sy, x, y;
sx = arg.sx, sy = arg.sy, smodule = arg.smodule, _angle = arg._angle, _teeth = arg._teeth, _pressure_angle = arg._pressure_angle, _shaft_size = arg._shaft_size, _internal = arg._internal;
for (k = 0, len = indices.length; k < len; k++) {
i = indices[k];
if (isNaN(sx[i] + sy[i] + _angle[i] + smodule[i] + _teeth[i] + _pressure_angle[i] + _shaft_size[i] + _internal[i])) {
continue;
}
pitch_radius = smodule[i] * _teeth[i] / 2;
if (_internal[i]) {
fn = GearUtils.create_internal_gear_tooth;
} else {
fn = GearUtils.create_gear_tooth;
}
seq0 = fn(smodule[i], _teeth[i], _pressure_angle[i]);
ref = seq0.slice(0, 3), M = ref[0], x = ref[1], y = ref[2];
seq = seq0.slice(3);
ctx.save();
ctx.translate(sx[i], sy[i]);
ctx.rotate(_angle[i]);
ctx.beginPath();
rot = 2 * Math.PI / _teeth[i];
ctx.moveTo(x, y);
for (j = l = 0, ref1 = _teeth[i]; 0 <= ref1 ? l < ref1 : l > ref1; j = 0 <= ref1 ? ++l : --l) {
this._render_seq(ctx, seq);
ctx.rotate(rot);
}
ctx.closePath();
if (_internal[i]) {
rim_radius = pitch_radius + 2.75 * smodule[i];
ctx.moveTo(rim_radius, 0);
ctx.arc(0, 0, rim_radius, 0, 2 * Math.PI, true);
} else if (_shaft_size[i] > 0) {
shaft_radius = pitch_radius * _shaft_size[i];
ctx.moveTo(shaft_radius, 0);
ctx.arc(0, 0, shaft_radius, 0, 2 * Math.PI, true);
}
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();
}
ctx.restore();
}
};
GearView.prototype._render_seq = function(ctx, seq) {
var c, cx0, cx1, cy0, cy1, i, k, large_arc, len, px, py, ref, ref1, ref10, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, rx, ry, segments, sweep, x, x_rotation, y;
i = 0;
while (i < seq.length) {
if (_.isString(seq[i])) {
c = seq[i];
i += 1;
}
switch (c) {
case "M":
ref = seq.slice(i, i + 2), x = ref[0], y = ref[1];
ctx.moveTo(x, y);
ref1 = [x, y], px = ref1[0], py = ref1[1];
i += 2;
break;
case "L":
ref2 = seq.slice(i, i + 2), x = ref2[0], y = ref2[1];
ctx.lineTo(x, y);
ref3 = [x, y], px = ref3[0], py = ref3[1];
i += 2;
break;
case "C":
ref4 = seq.slice(i, i + 6), cx0 = ref4[0], cy0 = ref4[1], cx1 = ref4[2], cy1 = ref4[3], x = ref4[4], y = ref4[5];
ctx.bezierCurveTo(cx0, cy0, cx1, cy1, x, y);
ref5 = [x, y], px = ref5[0], py = ref5[1];
i += 6;
break;
case "Q":
ref6 = seq.slice(i, i + 4), cx0 = ref6[0], cy0 = ref6[1], x = ref6[2], y = ref6[3];
ctx.quadraticCurveTo(cx0, cy0, x, y);
ref7 = [x, y], px = ref7[0], py = ref7[1];
i += 4;
break;
case "A":
ref8 = seq.slice(i, i + 7), rx = ref8[0], ry = ref8[1], x_rotation = ref8[2], large_arc = ref8[3], sweep = ref8[4], x = ref8[5], y = ref8[6];
segments = Bezier.arc_to_bezier(px, py, rx, ry, -x_rotation, large_arc, 1 - sweep, x, y);
for (k = 0, len = segments.length; k < len; k++) {
ref9 = segments[k], cx0 = ref9[0], cy0 = ref9[1], cx1 = ref9[2], cy1 = ref9[3], x = ref9[4], y = ref9[5];
ctx.bezierCurveTo(cx0, cy0, cx1, cy1, x, y);
}
ref10 = [x, y], px = ref10[0], py = ref10[1];
i += 7;
break;
default:
throw new Error("unexpected command: " + c);
}
}
};
GearView.prototype.draw_legend = function(ctx, x0, x1, y0, y1) {
return this._generic_area_legend(ctx, x0, x1, y0, y1);
};
return GearView;
})(Glyph.View);
Gear = (function(superClass) {
extend(Gear, superClass);
function Gear() {
return Gear.__super__.constructor.apply(this, arguments);
}
Gear.prototype.default_view = GearView;
Gear.prototype.type = 'Gear';
Gear.coords([['x', 'y']]);
Gear.mixins(['line', 'fill']);
Gear.define({
angle: [p.AngleSpec, 0],
module: [p.NumberSpec, null],
pressure_angle: [p.NumberSpec, 20],
shaft_size: [p.NumberSpec, 0.3],
teeth: [p.NumberSpec, null],
internal: [p.NumberSpec, false]
});
return Gear;
})(Glyph.Model);
module.exports = {
Model: Gear,
View: GearView
};

View File

@ -0,0 +1,304 @@
var CategoricalMapper, Glyph, GlyphView, Model, Renderer, _, bbox, bokehgl, p, rbush,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
rbush = require("rbush");
CategoricalMapper = require("../mappers/categorical_mapper");
Renderer = require("../renderers/renderer");
p = require("../../core/properties");
bbox = require("../../core/util/bbox");
Model = require("../../model");
bokehgl = require("./webgl/main");
GlyphView = (function(superClass) {
extend(GlyphView, superClass);
function GlyphView() {
return GlyphView.__super__.constructor.apply(this, arguments);
}
GlyphView.prototype.initialize = function(options) {
var Cls, ctx, ref;
GlyphView.__super__.initialize.call(this, options);
this.renderer = options.renderer;
if (((ref = this.renderer) != null ? ref.plot_view : void 0) != null) {
ctx = this.renderer.plot_view.canvas_view.ctx;
if (ctx.glcanvas != null) {
Cls = bokehgl[this.model.type + 'GLGlyph'];
if (Cls) {
return this.glglyph = new Cls(ctx.glcanvas.gl, this);
}
}
}
};
GlyphView.prototype.render = function(ctx, indices, data) {
if (this.mget("visible")) {
ctx.beginPath();
if (this.glglyph != null) {
if (this._render_gl(ctx, indices, data)) {
return;
}
}
this._render(ctx, indices, data);
}
};
GlyphView.prototype._render_gl = function(ctx, indices, mainglyph) {
var dx, dy, ref, ref1, ref2, sx, sy, trans, wx, wy;
wx = wy = 1;
ref = this.renderer.map_to_screen([0 * wx, 1 * wx, 2 * wx], [0 * wy, 1 * wy, 2 * wy]), dx = ref[0], dy = ref[1];
wx = 100 / Math.min(Math.max(Math.abs(dx[1] - dx[0]), 1e-12), 1e12);
wy = 100 / Math.min(Math.max(Math.abs(dy[1] - dy[0]), 1e-12), 1e12);
ref1 = this.renderer.map_to_screen([0 * wx, 1 * wx, 2 * wx], [0 * wy, 1 * wy, 2 * wy]), dx = ref1[0], dy = ref1[1];
if (Math.abs((dx[1] - dx[0]) - (dx[2] - dx[1])) > 1e-6 || Math.abs((dy[1] - dy[0]) - (dy[2] - dy[1])) > 1e-6) {
return false;
}
ref2 = [(dx[1] - dx[0]) / wx, (dy[1] - dy[0]) / wy], sx = ref2[0], sy = ref2[1];
trans = {
pixel_ratio: ctx.pixel_ratio,
width: ctx.glcanvas.width,
height: ctx.glcanvas.height,
dx: dx[0] / sx,
dy: dy[0] / sy,
sx: sx,
sy: sy
};
this.glglyph.draw(indices, mainglyph, trans);
return true;
};
GlyphView.prototype.bounds = function() {
var bb, d;
if (this.index == null) {
return bbox.empty();
}
d = this.index.data;
bb = {
minX: d.minX,
minY: d.minY,
maxX: d.maxX,
maxY: d.maxY
};
return this._bounds(bb);
};
GlyphView.prototype.max_wh2_bounds = function(bds) {
return {
minX: bds.minX - this.max_w2,
maxX: bds.maxX + this.max_w2,
minY: bds.minY - this.max_h2,
maxY: bds.maxY + this.max_h2
};
};
GlyphView.prototype.get_anchor_point = function(anchor, i, arg) {
var sx, sy;
sx = arg[0], sy = arg[1];
switch (anchor) {
case "center":
return {
x: this.scx(i, sx, sy),
y: this.scy(i, sx, sy)
};
default:
return null;
}
};
GlyphView.prototype.scx = function(i) {
return this.sx[i];
};
GlyphView.prototype.scy = function(i) {
return this.sy[i];
};
GlyphView.prototype._xy_index = function() {
var i, index, j, pts, ref, x, xx, y, yy;
index = rbush();
pts = [];
if (this.renderer.xmapper instanceof CategoricalMapper.Model) {
xx = this.renderer.xmapper.v_map_to_target(this._x, true);
} else {
xx = this._x;
}
if (this.renderer.ymapper instanceof CategoricalMapper.Model) {
yy = this.renderer.ymapper.v_map_to_target(this._y, true);
} else {
yy = this._y;
}
for (i = j = 0, ref = xx.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
x = xx[i];
if (isNaN(x) || !isFinite(x)) {
continue;
}
y = yy[i];
if (isNaN(y) || !isFinite(y)) {
continue;
}
pts.push({
minX: x,
minY: y,
maxX: x,
maxY: y,
i: i
});
}
index.load(pts);
return index;
};
GlyphView.prototype.sdist = function(mapper, pts, spans, pts_location, dilate) {
var d, halfspan, i, pt0, pt1, spt0, spt1;
if (pts_location == null) {
pts_location = "edge";
}
if (dilate == null) {
dilate = false;
}
if (_.isString(pts[0])) {
pts = mapper.v_map_to_target(pts);
}
if (pts_location === 'center') {
halfspan = (function() {
var j, len, results;
results = [];
for (j = 0, len = spans.length; j < len; j++) {
d = spans[j];
results.push(d / 2);
}
return results;
})();
pt0 = (function() {
var j, ref, results;
results = [];
for (i = j = 0, ref = pts.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
results.push(pts[i] - halfspan[i]);
}
return results;
})();
pt1 = (function() {
var j, ref, results;
results = [];
for (i = j = 0, ref = pts.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
results.push(pts[i] + halfspan[i]);
}
return results;
})();
} else {
pt0 = pts;
pt1 = (function() {
var j, ref, results;
results = [];
for (i = j = 0, ref = pt0.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
results.push(pt0[i] + spans[i]);
}
return results;
})();
}
spt0 = mapper.v_map_to_target(pt0);
spt1 = mapper.v_map_to_target(pt1);
if (dilate) {
return (function() {
var j, ref, results;
results = [];
for (i = j = 0, ref = spt0.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
results.push(Math.ceil(Math.abs(spt1[i] - spt0[i])));
}
return results;
})();
} else {
return (function() {
var j, ref, results;
results = [];
for (i = j = 0, ref = spt0.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
results.push(Math.abs(spt1[i] - spt0[i]));
}
return results;
})();
}
};
GlyphView.prototype.get_reference_point = function() {
return void 0;
};
GlyphView.prototype.draw_legend = function(ctx, x0, x1, y0, y1) {
return null;
};
GlyphView.prototype._generic_line_legend = function(ctx, x0, x1, y0, y1) {
var ref, reference_point;
reference_point = (ref = this.get_reference_point()) != null ? ref : 0;
ctx.save();
ctx.beginPath();
ctx.moveTo(x0, (y0 + y1) / 2);
ctx.lineTo(x1, (y0 + y1) / 2);
if (this.visuals.line.doit) {
this.visuals.line.set_vectorize(ctx, reference_point);
ctx.stroke();
}
return ctx.restore();
};
GlyphView.prototype._generic_area_legend = function(ctx, x0, x1, y0, y1) {
var dh, dw, h, indices, ref, reference_point, sx0, sx1, sy0, sy1, w;
reference_point = (ref = this.get_reference_point()) != null ? ref : 0;
indices = [reference_point];
w = Math.abs(x1 - x0);
dw = w * 0.1;
h = Math.abs(y1 - y0);
dh = h * 0.1;
sx0 = x0 + dw;
sx1 = x1 - dw;
sy0 = y0 + dh;
sy1 = y1 - dh;
if (this.visuals.fill.doit) {
this.visuals.fill.set_vectorize(ctx, reference_point);
ctx.fillRect(sx0, sy0, sx1 - sx0, sy1 - sy0);
}
if (this.visuals.line.doit) {
ctx.beginPath();
ctx.rect(sx0, sy0, sx1 - sx0, sy1 - sy0);
this.visuals.line.set_vectorize(ctx, reference_point);
return ctx.stroke();
}
};
return GlyphView;
})(Renderer.View);
Glyph = (function(superClass) {
extend(Glyph, superClass);
function Glyph() {
return Glyph.__super__.constructor.apply(this, arguments);
}
Glyph.define({
visible: [p.Bool, true]
});
Glyph.internal({
x_range_name: [p.String, 'default'],
y_range_name: [p.String, 'default']
});
return Glyph;
})(Model);
module.exports = {
Model: Glyph,
View: GlyphView
};

View File

@ -0,0 +1,164 @@
var CategoricalMapper, Glyph, HBar, HBarView, Quad, _, hittest, p, rbush,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
rbush = require("rbush");
Quad = require("./quad");
Glyph = require("./glyph");
CategoricalMapper = require("../mappers/categorical_mapper");
hittest = require("../../common/hittest");
p = require("../../core/properties");
HBarView = (function(superClass) {
extend(HBarView, superClass);
function HBarView() {
return HBarView.__super__.constructor.apply(this, arguments);
}
HBarView.prototype._map_data = function() {
var i, j, ref, vleft, vright, vy;
vy = this.renderer.ymapper.v_map_to_target(this._y);
this.sy = this.plot_view.canvas.v_vy_to_sy(vy);
vright = this.renderer.xmapper.v_map_to_target(this._right);
vleft = this.renderer.xmapper.v_map_to_target(this._left);
this.sright = this.plot_view.canvas.v_vx_to_sx(vright);
this.sleft = this.plot_view.canvas.v_vx_to_sx(vleft);
this.stop = [];
this.sbottom = [];
this.sh = this.sdist(this.renderer.ymapper, this._y, this._height, 'center');
for (i = j = 0, ref = this.sy.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
this.stop.push(this.sy[i] - this.sh[i] / 2);
this.sbottom.push(this.sy[i] + this.sh[i] / 2);
}
return null;
};
HBarView.prototype._index_data = function() {
var b, height, i, index, j, l, left, map_to_synthetic, pts, r, ref, right, t, y;
map_to_synthetic = function(mapper, array) {
if (mapper instanceof CategoricalMapper.Model) {
return mapper.v_map_to_target(array, true);
} else {
return array;
}
};
left = map_to_synthetic(this.renderer.xmapper, this._left);
right = map_to_synthetic(this.renderer.xmapper, this._right);
y = map_to_synthetic(this.renderer.ymapper, this._y);
height = map_to_synthetic(this.renderer.ymapper, this._height);
index = rbush();
pts = [];
for (i = j = 0, ref = y.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
l = left[i];
r = right[i];
t = y[i] + 0.5 * height[i];
b = y[i] - 0.5 * height[i];
if (isNaN(l + r + t + b) || !isFinite(l + r + t + b)) {
continue;
}
pts.push({
minX: l,
minY: b,
maxX: r,
maxY: t,
i: i
});
}
index.load(pts);
return index;
};
HBarView.prototype._render = function(ctx, indices, arg) {
var i, j, len, results, sbottom, sleft, sright, stop;
sleft = arg.sleft, sright = arg.sright, stop = arg.stop, sbottom = arg.sbottom;
results = [];
for (j = 0, len = indices.length; j < len; j++) {
i = indices[j];
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);
results.push(ctx.stroke());
} else {
results.push(void 0);
}
}
return results;
};
HBarView.prototype._hit_point = function(geometry) {
var hits, ref, result, vx, vy, x, y;
ref = [geometry.vx, geometry.vy], vx = ref[0], vy = ref[1];
x = this.renderer.xmapper.map_from_target(vx, true);
y = this.renderer.ymapper.map_from_target(vy, true);
hits = (function() {
var j, len, ref1, results;
ref1 = this.index.search({
minX: x,
minY: y,
maxX: x,
maxY: y
});
results = [];
for (j = 0, len = ref1.length; j < len; j++) {
x = ref1[j];
results.push(x.i);
}
return results;
}).call(this);
result = hittest.create_hit_test_result();
result['1d'].indices = hits;
return result;
};
HBarView.prototype.scx = function(i) {
return (this.sleft[i] + this.sright[i]) / 2;
};
return HBarView;
})(Glyph.View);
HBar = (function(superClass) {
extend(HBar, superClass);
function HBar() {
return HBar.__super__.constructor.apply(this, arguments);
}
HBar.prototype.default_view = HBarView;
HBar.prototype.type = 'HBar';
HBar.mixins(['line', 'fill']);
HBar.define({
y: [p.NumberSpec],
height: [p.DistanceSpec],
left: [p.NumberSpec, 0],
right: [p.NumberSpec]
});
return HBar;
})(Glyph.Model);
module.exports = {
Model: HBar,
View: HBarView
};

View File

@ -0,0 +1,179 @@
var Glyph, Greys, Image, ImageView, LinearColorMapper, _, p,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require("underscore");
Glyph = require("../glyphs/glyph");
LinearColorMapper = require("../mappers/linear_color_mapper");
p = require("../../core/properties");
Greys = require('../../palettes/palettes').Greys;
ImageView = (function(superClass) {
extend(ImageView, superClass);
function ImageView() {
return ImageView.__super__.constructor.apply(this, arguments);
}
ImageView.prototype.initialize = function(options) {
ImageView.__super__.initialize.call(this, options);
return this.listenTo(this.model.color_mapper, 'change', this._update_image);
};
ImageView.prototype._update_image = function() {
if (this.image_data != null) {
this._set_data();
return this.plot_view.request_render();
}
};
ImageView.prototype._index_data = function() {
return this._xy_index();
};
ImageView.prototype._set_data = function() {
var buf, buf8, canvas, cmap, ctx, i, image_data, img, j, ref, results;
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);
}
results = [];
for (i = j = 0, ref = this._image.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
if (this._rows != null) {
this._height[i] = this._rows[i];
this._width[i] = this._cols[i];
} else {
this._height[i] = this._image[i].length;
this._width[i] = this._image[i][0].length;
}
canvas = document.createElement('canvas');
canvas.width = this._width[i];
canvas.height = this._height[i];
ctx = canvas.getContext('2d');
image_data = ctx.getImageData(0, 0, this._width[i], this._height[i]);
cmap = this.mget('color_mapper');
if (this._rows != null) {
img = this._image[i];
} else {
img = _.flatten(this._image[i]);
}
buf = cmap.v_map_screen(img);
buf8 = new Uint8ClampedArray(buf);
image_data.data.set(buf8);
ctx.putImageData(image_data, 0, 0);
this.image_data[i] = canvas;
this.max_dw = 0;
if (this._dw.units === "data") {
this.max_dw = _.max(this._dw);
}
this.max_dh = 0;
if (this._dh.units === "data") {
this.max_dh = _.max(this._dh);
}
results.push(this._xy_index());
}
return results;
};
ImageView.prototype._map_data = function() {
switch (this.model.properties.dw.units) {
case "data":
this.sw = this.sdist(this.renderer.xmapper, this._x, this._dw, 'edge', this.mget('dilate'));
break;
case "screen":
this.sw = this._dw;
}
switch (this.model.properties.dh.units) {
case "data":
return this.sh = this.sdist(this.renderer.ymapper, this._y, this._dh, 'edge', this.mget('dilate'));
case "screen":
return this.sh = this._dh;
}
};
ImageView.prototype._render = function(ctx, indices, arg) {
var i, image_data, j, len, old_smoothing, sh, sw, sx, sy, y_offset;
image_data = arg.image_data, sx = arg.sx, sy = arg.sy, sw = arg.sw, sh = arg.sh;
old_smoothing = ctx.getImageSmoothingEnabled();
ctx.setImageSmoothingEnabled(false);
for (j = 0, len = indices.length; j < len; j++) {
i = indices[j];
if (image_data[i] == null) {
continue;
}
if (isNaN(sx[i] + sy[i] + sw[i] + sh[i])) {
continue;
}
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);
}
return ctx.setImageSmoothingEnabled(old_smoothing);
};
ImageView.prototype.bounds = function() {
var d;
d = this.index.data;
return {
minX: d.minX,
minY: d.minY,
maxX: d.maxX + this.max_dw,
maxY: d.maxY + this.max_dh
};
};
return ImageView;
})(Glyph.View);
Image = (function(superClass) {
extend(Image, superClass);
function Image() {
return Image.__super__.constructor.apply(this, arguments);
}
Image.prototype.default_view = ImageView;
Image.prototype.type = 'Image';
Image.coords([['x', 'y']]);
Image.mixins([]);
Image.define({
image: [p.NumberSpec],
dw: [p.DistanceSpec],
dh: [p.DistanceSpec],
dilate: [p.Bool, false],
color_mapper: [
p.Instance, function() {
return new LinearColorMapper.Model({
palette: Greys.Greys9
});
}
]
});
return Image;
})(Glyph.Model);
module.exports = {
Model: Image,
View: ImageView
};

Some files were not shown because too many files have changed in this diff Show More