博克赫斯

BokehJS是Bokeh用户最终与之交互的浏览器内客户端运行库。这个库主要是用打字机写的,是博克绘图系统的独特之处之一。

BokehJS动机

在研究JavaScript绘图库的广泛领域时,我们发现它们的架构和设计都是为了与其他JavaScript集成。如果它们提供了任何服务器端包装器,那么这些包装器总是“第二类”,主要是为前端JS生成一个简单的配置。在为数不多的几个提供任何级别交互的JS绘图库中,交互并不是真正可以从JS本身外部配置或定制的。很少有JS绘图库考虑到大型流式服务器端数据,而从Python这样的另一种语言提供对这些设施的无缝访问不是一个考虑因素。

开发人员只能在一个浏览器后台生成一堆JavaScript图像,或者说只能在这个环境下生成一个“静态的”。

目标

BokehJS是一个独立的、一流的JavaScript绘图库,并且 交互运行时 实现动态、高度可定制的信息可视化。

界面

BokehJS是一个独立的JavaScript库,用于在浏览器中进行动态和交互式可视化。它构建在HTML5画布之上,设计用于更大数据集的高性能呈现。它的接口是声明性的,样式为 Protovis, 它的实现类似于一个反应式的场景 Chaco) .

更多信息请访问 用JavaScript开发 .

CSS类名

用于控制Bokeh表示的CSS位于 bokeh.css 从几个独立的 .less BokehJS源目录树中的文件。所有专门用于Bokeh DOM元素的CSS类都以字符串作为前缀 bk- . 例如,一些例子是: .bk-plot.bk-toolbar-button 等。

开发

BokehJS的源代码位于 bokehjs/ Bokeh的monorepo存储库中的目录。所有进一步的指令和shell命令都假定 bokehjs/ 是当前目录。

在使用BokehJS时应遵循的一些准则:

  • 不要使用 for-in 环,尤指不受保护的 hasOwnProperty() 使用 for-of 循环与 keys()values() 和/或 entries()core/util/object 模块代替。

要求

  • 节点12*

  • npm 6.14+(最新版本)

  • 铬浏览器80+或同等产品

您可以使用conda安装nodejs:

$ conda install -c conda-forge nodejs

或遵循官方安装 instructions .

在安装或更新nodejs之后,或者在npm要求时升级npm:

$ npm install -g npm

官方支持的平台如下:

  • Linux Ubuntu 18.04+或同等版本

  • Windows 10(或服务器2019)

  • MacOS 10.15

BokehJS可以在上述软件的不同平台和版本上开发,但结果可能会有所不同,尤其是在测试(尤其是可视化测试)时。

建筑物

BokehJS的构建是通过使用一个在视觉上类似于gulp的内部工具来维护的。所有命令都以 node make (不要把它与GNU make混淆)。

最常用的命令:

  • node make build

  • node make test

  • node make lint

使用 node make help 列出所有可用命令。

node make 自动运行 npm install 无论何时 package.json 变化。

你可以使用 tsc 直接用于错误检查(例如在IDE中)。但是,不要将其用于代码发出,因为我们依赖AST转换来生成可行的库代码。

测试

BokehJS测试使用 node make test 命令。您可以使用运行单个测试套件 node make test:suite_name . 已知的测试套件包括:

  • node make test:size

  • node make test:defaults

  • node make test:unit

  • node make test:integration

最后两个可以一起运行 node make test:lib . 单元测试和集成测试在web浏览器中运行(请参阅“要求”),该浏览器使用正确的设置自动启动,以确保测试结果的一致性。

要查看视觉测试的输出,请启动BokehJS的devtools服务器:

$ node test/devtools server
listening on 127.0.0.1:5777

并导航到 /integration/report . Devtools服务器还可以用于手动检查和调试测试。为此,可以使用以下端点:

  • /unit

  • /defaults

  • /integration

那些东西会加载BokehJS和测试,但是什么都不做。你必须发布 Tests.run_all() 在JavaScript控制台中。这允许您在运行代码之前设置断点。可以通过提供字符串关键字或正则表达式筛选出测试。或者,可以使用以下端点立即运行测试:

  • /unit/run

  • /defaults/run

  • /integration/run

你可以使用 ?k=some%20text 按关键字筛选测试。

CI和视觉测试

test:integration 进行两种类型的测试:

  • 文本基线测试

  • 视觉/屏幕截图测试

文本基线是跨平台兼容的,可以在本地(在支持的平台上)或在CI中生成。可视化测试依赖于平台,并且对系统配置相当敏感(尤其是在字体呈现的差异方面)。对于三个可以在本地进行图像比较的CI平台,可以在本地进行图像比较。

目视测试的完整程序如下:

  1. 更改存储库并编写新测试或更新现有测试。

  2. 使用 node make tests 以增量方式测试系统上的更改。

  3. 提交对文本基线的更改 (test/baselines/*

  4. 将更改推送到GitHub并等待CI完成。

  5. 如果您添加了新的测试,CI预期会失败,并显示“缺少基线图像”错误消息。

  6. 如果测试通过,那么你就完成了。

  7. 如果测试失败,去BokehJS GitHub_Actions 第页。找到最新的测试运行为您的公关和下载相关的 bokehjs-report 神器。

  8. 解压缩工件档案。

  9. 假设devtools服务器在后台运行,请转到 /integration/report?platform=name 在哪里? name 要么是 linuxmacoswindows 并检查每个平台的测试输出。如果没有意外的差异,则提交 test/baselines/{{linux,macos,windows}} .

  10. 再次将更改推送到GitHub,并验证这次测试是否通过。

注解

确保监视 test/baselines 目录,这样就不会提交不必要的文件。如果这样做,后续测试将失败。

最小模型/视图模块

模型(和视图)有多种形式和尺寸。至少,实现了一个模型。如果正在实现“可视化”模型,则可能会出现视图。最小模型/视图模块如下所示:

import {BaseModel, BaseModelView} from "models/..."

export class SomeModelView extends BaseModelView {
  model: SomeModel

  initialize(): void {
    super.initialize()
    // perform view initialization (remove if not needed)
  }

  async lazy_initialize(): Promise<void> {
    await super.lazy_initialize()
    // perform view lazy initialization (remove if not needed)
  }
}

export namespace SomeModel {
  export type Attrs = p.AttrsOf<Props>

  export type Props = BaseModel.Props & {
    some_property: p.Property<number>
    // add more property declarations
  }
}

export interface SomeModel extends SomeModel.Attrs {}

export class SomeModel extends BaseModel {
  properties: SomeModel.Props
  __view_type__: SomeModelView

  // do not remove this constructor, or you won't be
  // able to use `new SomeModel({some_property: 1})`
  constructor(attrs?: Partial<SomeModel.Attrs>) {
    super(attrs)
  }

  static init_SomeModel(): void {
    this.prototype.default_view = SomeModelView

    this.define<SomeModel.Props>({
      some_property: [ p.Number, 0 ],
      // add more property definitions
    })
  }
}

对于像这样的琐碎模块,大多数代码只是样板,用于使BokehJS的代码进行静态类型检查,并生成有用的类型声明以供进一步使用(在测试中或由用户使用)。

代码样式指南

BokehJS没有明确的风格指南。使您的更改在格式上保持一致。使用 node make lint . 遵循周围代码中观察到的模式并应用常识。