@quartic/bokehjs
Version:
Interactive, novel data visualization
117 lines (93 loc) • 3.55 kB
text/coffeescript
import {XYGlyph, XYGlyphView} from "./xy_glyph"
import {LinearColorMapper} from "../mappers/linear_color_mapper"
import * as p from "core/properties"
import {max, concat} from "core/util/array"
export class ImageView extends XYGlyphView
initialize: (options) ->
super(options)
_update_image: () ->
# Only reset image_data if already initialized
if ?
.plot_view.request_render()
_set_data: () ->
if not ? or .length != .length
= new Array(.length)
if not ? or .length != .length
= new Array(.length)
if not ? or .length != .length
= new Array(.length)
for i in [0....length]
shape = []
if ?
shape = [i]
if shape.length > 0
img = [i]
[i] = shape[0]
[i] = shape[1]
else
img = concat([i])
[i] = [i].length
[i] = [i][0].length
if [i]? and [i].width == [i] and [i].height == [i]
canvas = [i]
else
canvas = document.createElement('canvas')
canvas.width = [i]
canvas.height = [i]
ctx = canvas.getContext('2d')
image_data = ctx.getImageData(0, 0, [i], [i])
cmap = .color_mapper
buf = cmap.v_map_screen(img, true)
buf8 = new Uint8Array(buf)
image_data.data.set(buf8)
ctx.putImageData(image_data, 0, 0)
[i] = canvas
= 0
if .units == "data"
= max()
= 0
if .units == "data"
= max()
_map_data: () ->
switch .properties.dw.units
when "data" then =
when "screen" then =
switch .properties.dh.units
when "data" then =
when "screen" then =
_render: (ctx, indices, {image_data, sx, sy, sw, sh}) ->
old_smoothing = ctx.getImageSmoothingEnabled()
ctx.setImageSmoothingEnabled(false)
for i in indices
if not image_data[i]?
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)
ctx.setImageSmoothingEnabled(old_smoothing)
bounds: () ->
bbox = .bbox
bbox.maxX +=
bbox.maxY +=
return bbox
# NOTE: this needs to be redefined here, because palettes are located in bokeh-api.js bundle
Greys9 = () -> [0x000000, 0x252525, 0x525252, 0x737373, 0x969696, 0xbdbdbd, 0xd9d9d9, 0xf0f0f0, 0xffffff]
export class Image extends XYGlyph
default_view: ImageView
type: 'Image'
{
image: [ p.NumberSpec ] # TODO (bev) array spec?
dw: [ p.DistanceSpec ]
dh: [ p.DistanceSpec ]
dilate: [ p.Bool, false ]
color_mapper: [ p.Instance, () -> new LinearColorMapper({palette: Greys9()}) ]
}