admin管理员组文章数量:1429684
I'm Trying to create a custom Save tool in bokeh, and here's what I have:
class NewSaveTool(Tool):
JS_CODE = """
import * as p from "core/properties"
import {ActionTool, ActionToolView} from "models/tools/actions/action_tool"
export class NewSaveToolView extends ActionToolView
do: () ->
save_name = @model.source
@plot_view.save(save_name)
export class NewSaveTool extends ActionTool
default_view: NewSaveToolView
type: "SaveTool"
tool_name: "Save"
icon: "bk-tool-icon-save"
@define {
source: [ p.String ]
}
"""
source = String
__implementation__ = JS_CODE
The tool loads and is in the toolbar, but when I click the button, I get
Uncaught TypeError: this.plot_view.save is not a function
This is the exact function that the save tool in the source uses, so does anyone know why it didn't work in this instance?
I'm Trying to create a custom Save tool in bokeh, and here's what I have:
class NewSaveTool(Tool):
JS_CODE = """
import * as p from "core/properties"
import {ActionTool, ActionToolView} from "models/tools/actions/action_tool"
export class NewSaveToolView extends ActionToolView
do: () ->
save_name = @model.source
@plot_view.save(save_name)
export class NewSaveTool extends ActionTool
default_view: NewSaveToolView
type: "SaveTool"
tool_name: "Save"
icon: "bk-tool-icon-save"
@define {
source: [ p.String ]
}
"""
source = String
__implementation__ = JS_CODE
The tool loads and is in the toolbar, but when I click the button, I get
Uncaught TypeError: this.plot_view.save is not a function
This is the exact function that the save tool in the source uses, so does anyone know why it didn't work in this instance?
Share Improve this question asked Apr 12, 2017 at 0:43 G WG W 311 silver badge3 bronze badges3 Answers
Reset to default 3Answering this late on since it took me far too much time to make it work.
The main change here is 'do' to 'doit', though I'm honestly not sure where the specified error is from, one of the few I never got.
A working implementation (on bokeh 12.13 at least) is:
JS_CODE_SAVE = """
import * as p from "core/properties"
import {ActionTool, ActionToolView} from "models/tools/actions/action_tool"
export class NewSaveView extends ActionToolView
# this is executed when the button is clicked
doit: () ->
@plot_view.save(@model.save_name)
export class NewSave extends ActionTool
default_view: NewSaveView
type: "NewSave"
tool_name: "Save"
icon: "bk-tool-icon-save"
@define { save_name: [ p.String ] }
"""
class NewSave(Tool):
"""
Save a plot with a custom name.
Usage: NewSaveTool(save_name=name)
"""
__implementation__ = JS_CODE_SAVE
save_name = String()
Implemented as: tools = [CustomSaveTool(savename='custom name')]
To actually dynamically change the save name, you have to change the savename attribute, so eg in a widget callback function: plot.tools[0].save_name = 'new save name'
The implementation given in the initial response does not work with more recent versions of bokeh.
Here is an updated version based on the code for the original SaveTool. It exposes a save_name property which can be set in Python:
from bokeh.models import ActionTool
from bokeh.util.piler import TypeScript
from bokeh.core.properties import String
CUSTOM_SAVE_TS = """
import {ActionTool, ActionToolView} from "models/tools/actions/action_tool"
import * as p from "core/properties"
import {tool_icon_save} from "styles/icons.css"
export class CustomSaveToolView extends ActionToolView {
model: CustomSaveTool
async save(name: string): Promise<void> {
const blob = await this.plot_view.to_blob()
const link = document.createElement("a")
link.href = URL.createObjectURL(blob)
link.download = name // + ".png" | "svg" (inferred from MIME type)
link.target = "_blank"
link.dispatchEvent(new MouseEvent("click"))
}
doit(): void {
this.save(this.model.save_name)
}
}
export namespace CustomSaveTool {
export type Attrs = p.AttrsOf<Props>
export type Props = ActionTool.Props & {
save_name: p.Property<string>
}
}
export interface CustomSaveTool extends CustomSaveTool.Attrs {}
export class CustomSaveTool extends ActionTool {
properties: CustomSaveTool.Props
__view_type__: CustomSaveToolView
constructor(attrs?: Partial<CustomSaveTool.Attrs>) {
super(attrs)
}
static init_CustomSaveTool(): void {
this.prototype.default_view = CustomSaveToolView
this.register_alias("save", () => new CustomSaveTool())
this.define<CustomSaveTool.Props>(({String}) => ({
save_name: [ String ],
}))
}
tool_name = "Custom Save"
icon = tool_icon_save
}
"""
class CustomSaveTool(ActionTool):
"""Modified save tool allowing custom file names"""
__implementation__ = TypeScript(CUSTOM_SAVE_TS)
save_name = String()
save_tool = CustomSaveTool(save_name='custom_filename')
Note that pared to the original SaveTool code I had to scrap the parts related to the 'copy' function which I do not think is really used anyway.
Great! It works! Just one remark about the usage example above which should be:
tools = [NewSave(savename='custom name')]
Here is a plete working example (using CustomSaveTool as class name):
from bokeh.models import Tool, String
from bokeh.plotting import figure
from bokeh.io import show
JS_CODE_SAVE = """
import * as p from "core/properties"
import {ActionTool, ActionToolView} from "models/tools/actions/action_tool"
export class NewSaveView extends ActionToolView
# this is executed when the button is clicked
doit: () ->
@plot_view.save(@model.save_name)
export class CustomSaveTool extends ActionTool
default_view: NewSaveView
type: "CustomSaveTool"
tool_name: "Save"
icon: "bk-tool-icon-save"
@define { save_name: [ p.String ] } """
class CustomSaveTool(Tool):
"""
Save a plot with a custom name.
Usage: CustomSaveTool(save_name = name)
"""
__implementation__ = JS_CODE_SAVE
save_name = String()
tools = [CustomSaveTool(save_name = 'custom name 1')]
plot = figure(x_range = (0, 10), y_range = (0, 10), tools = tools)
plot.line(x = [1, 2, 3], y = [4, 5, 6])
plot.tools[0].save_name = 'custom name 2'
show(plot)
本文标签: javascriptBokeh Custom Save ToolStack Overflow
版权声明:本文标题:javascript - Bokeh Custom Save Tool - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745540287a2662462.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论