如何将Bokeh集成到已有的Angular 4 Web应用中?
把Bokeh图表嵌入Angular 4应用的步骤
既然你已经用bokeh.components拿到了图表对应的div容器和渲染脚本,接下来咱们一步步把它嵌入到Angular 4项目里:
1. 确保前端引入匹配版本的Bokeh依赖
首先在项目的index.html里添加Bokeh的CSS和JS文件,重点:版本必须和你后端生成图表用的Bokeh版本完全一致,不然大概率会出现渲染异常或者交互失效的问题。比如后端用的是2.4.3版本,就加这两行:
<link rel="stylesheet" href="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.css" /> <script src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.min.js"></script>
2. 处理Bokeh返回的两个部分
bokeh.components会返回两个字符串:一个是div容器(图表的占位符),另一个是渲染脚本(用来初始化图表的JS代码)。咱们分开处理这两部分:
3. 在Angular组件模板里嵌入div容器
因为Angular默认会过滤不安全的HTML,所以需要用DomSanitizer来标记div内容为安全的。比如在你的组件模板(比如chart.component.html)里:
<div [innerHTML]="chartDiv"></div>
4. 在组件TS文件里执行渲染脚本
直接在模板里放<script>标签的话,Angular不会执行它,所以咱们需要动态创建脚本并执行。在组件的ngAfterViewInit钩子(DOM加载完成后)里做这件事:
import { Component, AfterViewInit, OnInit } from '@angular/core'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; @Component({ selector: 'app-chart', templateUrl: './chart.component.html', styleUrls: ['./chart.component.css'] }) export class ChartComponent implements OnInit, AfterViewInit { chartDiv: SafeHtml; chartScriptContent: string; constructor(private sanitizer: DomSanitizer) { // 替换成你从后端拿到的div字符串 const rawChartDiv = '<div class="bk-root" id="d199dc51-c663-4220-800f-a5f0d7c3a97a"></div>'; this.chartDiv = this.sanitizer.bypassSecurityTrustHtml(rawChartDiv); // 替换成你从后端拿到的<script>标签里的内容(去掉外层的<script>标记) this.chartScriptContent = `(function() { var fn = function() { Bokeh.safely(function() { (function(root) { function embed_document(root) { var docs_json = '{"d199dc51-c663-4220-800f-a5f0d7c3a97a":{"roots":{"references":[{"attributes":{"bottom_units":"screen",...}}]}}'; var render_items = [{"docid":"d199dc51-c663-4220-800f-a5f0d7c3a97a","root_id":"6fbff9b0-a4fc-4fc1-a50e-d34f906928b2","elementid":"d199dc51-c663-4220-800f-a5f0d7c3a97a"}]; Bokeh.embed.embed_items(docs_json, render_items); } embed_document(window); })(); })(); })();`; } ngOnInit(): void { } ngAfterViewInit(): void { // 动态创建script标签并执行 const scriptEl = document.createElement('script'); scriptEl.textContent = this.chartScriptContent; document.body.appendChild(scriptEl); // 执行完可以移除标签,避免重复执行 document.body.removeChild(scriptEl); } }
几个关键注意事项
- 版本一致性:再次强调,前后端Bokeh版本必须完全匹配,这是很多人踩坑的点。
- 安全风险:使用
bypassSecurityTrustHtml和动态脚本时,要确保后端返回的内容是可信的,避免XSS攻击。 - 动态获取图表:如果你的图表是后端动态生成的,可以用Angular的
HttpClient请求后端接口,拿到components返回的结果后再赋值给chartDiv和chartScriptContent,这样就能实现动态加载图表了。
内容的提问来源于stack exchange,提问作者Rags Gupta
相关产品推荐
相关产品推荐

