0

我的散景应用程序正在处理由几个图形组成的网格,每个图形显示几个字形。为了提高可读性,我希望能够在单击按钮时隐藏/显示数字的图例。尽管这在我看来是工具栏中“保存”和“重置”等工具按钮的完美示例,但此功能尚未在散景中实现。

我发现了一些关于如何自己实现自定义工具的提示,请参见此处此处此处此处此处此处显示了有关如何添加自定义图标的示例。

这是我到目前为止得到的:main.py:

from bokeh.layouts import gridplot
from bokeh.models import ColumnDataSource, Tool
from bokeh.plotting import figure

from os.path import dirname
from jinja2 import FileSystemLoader, Environment
from bokeh.embed.standalone import file_html
from bokeh.resources import CDN

class LegendToggleTool(Tool):
    __implementation__ = """
        import {ActionTool, ActionToolView} from "models/tools/actions/action_tool"
        import * as p from "core/properties"
        
        export class LegendToggleToolView extends ActionToolView {
            model: LegendToggleTool
            
            doit(): void {
                for(const r of this.plot_view.model.panels){
                    if (r.type=="Legend"){
                        r.visible = !r.visible
                    }
                }
            }
        }     
        
        export namespace LegendToggleTool {
          export type Attrs = p.AttrsOf<Props>
        
          export type Props = ActionTool.Props
        }
        
        export interface LegendToggleTool extends LegendToggleTool.Attrs {}
        
        export class LegendToggleTool extends ActionTool {
            properties: LegendToggleTool.Props
            __view_type__: LegendToggleToolView
            
            constructor(attrs?: Partial<LegendToggleTool.Attrs>) {
                super(attrs)
            }
            
            static init_LegendToggleTool(): void {
                this.prototype.default_view = LegendToggleToolView
                this.register_alias("legendtoggle", () => new LegendToggleTool())
            }
        
            tool_name = "LegendToggle"
            icon      = "legend-toggle-icon"
        }
        """

env = Environment(loader=FileSystemLoader(dirname(__file__)))
template = env.get_template('template.html')

source01 = ColumnDataSource(data=dict(x=[0,1,2,3,4], y=[0,1,2,3,4],z=[4,3,2,1,0]))
source02 = ColumnDataSource(data=dict(x=[0,3,1,6,1], y=[0,1,2,3,4],z=[4,3,2,1,0]))

fig01 = figure(x_range=(0, 10), y_range=(0, 10),tools=[LegendToggleTool()])
fig01.line('x', 'y', source=source01, legend_label = 'line_01')
fig01.line('x', 'z', source=source01, legend_label = 'line_02')

fig02 = figure(x_range=(0, 10), y_range=(0, 10),tools=[LegendToggleTool()])
fig02.line('x', 'y', source=source02, legend_label = 'line_03')
fig02.line('x', 'z', source=source02, legend_label = 'line_04')

with open('out.html', 'w') as f:
    f.write(file_html(gridplot([[fig01,fig02]]), resources=CDN, template=template))

template.html (在同一目录中,从此处复制):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>{{ title|e if title else "Bokeh Plot" }}</title>
    {{ bokeh_css }}
    {{ bokeh_js }}
    <style>
        html {
            width: 100%;
            height: 100%;
        }

        body {
            width: 90%;
            height: 100%;
            margin: auto;
        }

        .legend-toggle-icon {
            background-image: url(data:image/png;base64,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);
        }
    </style>
</head>
<body>
{{ plot_div|indent(8) }}
{{ plot_script|indent(8) }}
</body>
</html>

运行 main.py 会生成一个输出文件“out.html”。切换图例的可见性按预期工作,但图标保持空白。所以这是我的问题:

  1. 如何让图标显示?
  2. 假设我想通过运行它bokeh serve --show <dirname>,我需要如何在文件夹中组织上述代码<dirname>
4

0 回答 0