散景自定义保存工具

时间:2017-04-12 00:43:16

标签: javascript python coffeescript bokeh

我正在尝试在散景中创建自定义保存工具,这就是我所拥有的:

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

该工具加载并位于工具栏中,但是当我点击按钮时,我得到了

Uncaught TypeError: this.plot_view.save is not a function

这是源中保存工具使用的确切功能,所以有人知道为什么它在这个实例中不起作用吗?

3 个答案:

答案 0 :(得分:3)

回答这个问题,因为我花了太多时间才使它发挥作用 这里的主要变化是'做'虽然我老实说不确定指定的错误来自哪里,但是我从来没有做过的少数错误之一。

工作实施(至少在散景12.13上)是:

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()

实施为:tools = [CustomSaveTool(savename='custom name')]

要实际动态更改保存名称,您必须更改savename属性,例如在小部件回调函数中:plot.tools[0].save_name = 'new save name'

答案 1 :(得分:1)

太好了!有用! 关于上述用法示例的一句话应该是:

tools = [NewSave(savename='custom name')]

这是一个完整的工作示例(使用CustomSaveTool作为类名):

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)

答案 2 :(得分:0)

上面给出的实现不适用于更新版本的散景。

这是基于原始 SaveTool 代码的更新版本。它公开了一个可以在 Python 中设置的 save_name 属性:

from bokeh.models import ActionTool
from bokeh.util.compiler 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')

请注意,与原始 SaveTool 代码相比,我不得不废弃与“复制”功能相关的部分,我认为无论如何都不会真正使用这些部分。