Bokeh - 如何使 HoverTool 工具提示粘在点击点上?

2024-03-29

下面的代码来自于Jupyter笔记本 https://nbviewer.jupyter.org/github/draperjames/PythonRef/blob/master/Bokeh%20HoverTool%20Custom%20ToolTips.ipynb:

from bokeh.io import show, output_notebook
from bokeh.plotting import ColumnDataSource, figure
from bokeh.models import HoverTool, Range1d

output_notebook()
fig = figure(tools=[HoverTool(tooltips=[("html", '@html{safe}')])])

fig.quad(left="left", top="top", bottom="bottom", right="right",
         source=ColumnDataSource({"left": [1,3], "bottom": [1,3],
                                  "right": [2,4], "top": [2,4],
                                  "html":["<b>I'm bold</b>", "<span 

style='color:red;font-size:32px;'>BIG RED TEXT</span>"]}))
    show(fig)

我需要使 HoverTool 工具提示准确地粘在单击该点时所在的位置,因此如果用户想要突出显示并复制工具提示中的文本,则可以。这codepen http://codepen.io/drapja/pen/MJyxvv有一个我想看到的行为类型的例子。我知道这必须可以通过注入某种类型的 CustomJS 或更改BokehJS 咖啡脚本 https://github.com/bokeh/bokeh/blob/d2ce1971e4b984c7d30728b2378f7c959a3efd06/bokehjs/src/coffee/models/annotations/tooltip.coffee并从头开始构建 BokehJS,但我一直无法弄清楚。有人知道如何做到这一点吗?

UPDATE:
或许可以创建一个定制工具 http://bokeh.pydata.org/en/latest/docs/user_guide/extensions_gallery/tool.html#userguide-extensions-examples-tool使用Tap_tool.咖啡 https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/tools/gestures/tap_tool.coffee, 悬停工具.咖啡 https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/tools/inspectors/hover_tool.coffee or 工具提示.coffee https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/annotations/tooltip.coffee。如果我弄清楚了,我会更新这个。


这是使用以下方法创建您自己的悬停文本的解决方法models.Label在“回调”函数内models.HoverTool . Also models.TapTool用于切换更新标签文本。您无法编辑字形中的文本models.Label,但是一个TextInput widget已添加文本在悬停在图形字形上时更新的位置。

import bokeh
import bokeh.plotting
fig = bokeh.plotting.figure()

d_source = bokeh.models.ColumnDataSource({"left": [1,3,1],
                "bottom": [1,3,3],"right": [2,4,2],"top": [2,4,4]})
h_source = bokeh.models.ColumnDataSource({"do_hover":[True,True]  })
fig.quad(left="left", top="top", bottom="bottom", right="right",
         source=d_source)

myToolTip = bokeh.models.Label(x=2.5,y=2.5, text="",
                               background_fill_color = "#ffffff")

HoverCallback = bokeh.models.CustomJS(args=dict(d_source=d_source,
                    myToolTip=myToolTip,h_source=h_source),code="""
        function findWhereIam(x,y,s){
            // To find where the cursor is. 
            selection = -1;
            for (i = 0; i < s.data.left.length; i++) {
                x0 = s.data.left[i];
                x1 = s.data.right[i];
                y0 = s.data.bottom[i];
                y1 = s.data.top[i];
                if (x>x0 && x<x1 && y>y0 && y<y1){
                    // It's inside rectangle!!!
                    selection = i;
                }
            }
            return selection
        }
        if (h_source.data.do_hover[0]){
            x_data = cb_data['geometry'].x;
            y_data = cb_data['geometry'].y;
            var selection = findWhereIam(x_data,y_data,d_source)
            if (selection>=0){
                x0 = d_source.data.left[selection];
                x1 = d_source.data.right[selection];
                y0 = d_source.data.bottom[selection];
                y1 = d_source.data.top[selection];
                myToolTip.x = 0.5 * (x0+x1);
                myToolTip.y = 0.5 * (y0+y1);
                myToolTip.text = "on:"+selection;
                myToolTip.text_font_size = "24pt";
                myToolTip.background_fill_color = "#ffffff";
                myToolTip.border_line_color = "#000000";
                myToolTip.text_align = "center";
                myToolTip.trigger('change');

                current_selection.value = myToolTip.text;
                current_selection.trigger('change');
            }else{
                myToolTip.text = ""; //erase
                myToolTip.trigger('change');
                current_selection.value = myToolTip.text;
                current_selection.trigger('change');
            }
        }
    """)

TapCallback = bokeh.models.CustomJS(args=dict(h_source=h_source), code="""
        h_source.data.do_hover[0] = !h_source.data.do_hover[0];
    """)

current_selection = bokeh.models.widgets.TextInput(value="",
                                                   title="Selection")

HoverCallback.args.update(dict(current_selection=current_selection))

fig.add_tools(bokeh.models.HoverTool(tooltips=None,callback=HoverCallback))
fig.add_tools(bokeh.models.TapTool(callback=TapCallback))
fig.add_layout(myToolTip)
page = bokeh.plotting.gridplot([[fig],[current_selection]])
bokeh.io.output_notebook()
bokeh.io.show(page)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Bokeh - 如何使 HoverTool 工具提示粘在点击点上? 的相关文章

随机推荐

  • 如何删除空值?

    如何删除底部计数中的空值 即 我只想查看实际销售单位的产品 我尝试过非空和非空但没有成功 with member Measures Amount Sold as Measures Internet Sales Amount format s
  • 为什么“超时”不适用于管道?

    以下命令行调用timeout 这没有意义 只是出于测试原因 无法按预期工作 它会等待 10 秒 并且在 3 秒后不会停止命令的运行 为什么 timeout 3 ls sleep 10 您的命令正在执行的操作正在运行timeout 3 ls并
  • 在 Windows 上的 XAMPP 中哪里可以更改 lower_case_table_names=2 的值?

    我正在使用 Windows 7 和 XAMPP 我正在尝试导出数据库 在此过程中表名称将转换为小写 我搜索了很多 我知道我必须改变的值lower case table names from 0 to 2 但是我必须在哪里更改这个值 在哪个文
  • 将 TypeScript 网站从 GitHub 部署到 Azure

    我有一个 NET 网站 其中包含一些 TypeScript 文件 我尝试将其从 GitHub 部署为 Azure 网站 但收到与 TypeScript 相关的错误 在我看来 这可能与我使用最新版本 1 0 有关 而 kudu 版本只有 0
  • Google 端点和公共 Api 密钥

    要使用 Google 服务 您可以使用 OAuth 身份验证 或者 如果您不需要用户登录 则可以使用公共 api 密钥 将授权域定义为请求的来源 现在 我正在使用 google 端点编写自己的 API 并且我将允许用户通过公共 api 密钥
  • 使用sessionStorage有什么好处? [复制]

    这个问题在这里已经有答案了 只是想知道在存储要在 Javascript 轮播中使用的 HTML 内容时使用 HTML5 的 sessionStorage 的实际好处是什么 与性能有关吗 加载时间 带宽 是的 您将使用更少的带宽 这会提高性能
  • 使用 ggdendro 在树状图的片段下显示变量标签

    我的问题与安德里的有关answer https i stack imgur com JW0m1 png我之前的问题 我的问题是是否可以在树状图的相应段下显示变量标签和汽车标签 library ggplot2 library ggdendro
  • 扩展 Android 的默认 Gmail/电子邮件应用程序

    我想通过插入 ContentProvider 或使用意图过滤器来扩展 Android 平台的默认 Gmail 电子邮件应用程序 本质上 我希望能够扫描传入的电子邮件以查找将在我的 Android 应用程序中触发事件的特殊规则 如果自动扫描电
  • 立即终止无循环线程,无需中止或挂起

    我正在实现一个协议库 这里有一个简化的描述 main 函数中的主线程将始终检查网络流 在 tcpclient 内 上是否有某些数据可用 假设响应是收到的消息 线程是正在运行的线程 thread new Thread new ThreadSt
  • 在 Sparklyr 中创建虚拟变量?

    我正在尝试扩展我的一些 ML 管道 我喜欢 Sparklyr 打开的 rstudio spark 和 h2o 的组合 http spark rstudio com http spark rstudio com 我试图弄清楚的一件事是如何使用
  • 多个组的可反应聚合函数

    使用 Rreactable包中 我试图使用两个 groupBy 变量显示标记读数的百分比 在较低级别的分组中 这是计算正确的百分比 但在分组的第二 外部 级别上 它没有显示正确的百分比 这是数据 dat lt structure list
  • PHP:查询 MySQL 最快的方法是什么?因为 PDO 慢得令人痛苦

    我需要执行一个简单的查询 从字面上看 我需要执行的是 SELECT price sqft zipcode FROM homes WHERE home id X 当我使用 PHP 时PDO 我读过的是连接到 MySQL 数据库的推荐方法 简单
  • 如何通过id查找页面上的控件

    有没有一种简单的方法可以通过 id 在任何嵌套容器中 在 ASP NET 中查找控件 除了遍历整个控件树之外 像这个例子 TextBox tb new TextBox ID textboxId panel3 Controls Add tb
  • Spring Boot如何选择外部化的Spring属性文件

    我有这个配置需要用于 Spring Boot 应用程序 server port 8085 server servlet context path authserver data source spring jpa hibernate ddl
  • Windows 上的 Python 包:pip 还是本机安装程序?

    与使用打包安装程序 exe msi 相比 使用 pip 在 Windows 上安装 python 软件包的相对优点是什么 对于初学者来说 有些对我来说不起作用 MySQLdb 是 我的新规则 Try pip or easy install
  • NodeJS + Mysql 与 Docker Compose 2

    我正在尝试构建一个 docker compose 文件来在本地部署连接到 mysql 服务器的 NodeJS 应用程序 我已经尝试了所有方法 在 Stackoverflow 中阅读了大量教程和一些问题 但我不断收到 ECONNREFUSED
  • Apache .htaccess:如何在 Firefox 上用斜杠重写反斜杠?

    如何重写反斜杠 带斜线 在火狐浏览器上 Chrome IE Safari Opera 已构建浏览器用斜杠重写反斜杠 但 Firefox 3 6 13 回归404错误页面 Why Firefox returns 404 error page
  • 使用history.pushState()更新URL中的参数

    我在用history pushState在我的页面上进行 AJAX 调用后 将一些参数附加到当前页面 URL 现在 在基于用户操作的同一页面上 我想使用相同或附加的参数集再次更新页面 URL 所以我的代码如下所示 var pageUrl w
  • 如何使用有状态 LSTM 和 batch_size > 1 布置训练数据

    背景 我想在 Keras 中对 有状态 LSTM 进行小批量训练 我的输入训练数据位于一个大矩阵 X 中 其维度为 m x n 其中 m number of subsequences n number of time steps per s
  • Bokeh - 如何使 HoverTool 工具提示粘在点击点上?

    下面的代码来自于Jupyter笔记本 https nbviewer jupyter org github draperjames PythonRef blob master Bokeh 20HoverTool 20Custom 20Tool