python - 如果值已更改,可编辑 Bokeh DataTable 中的颜色文本
问题描述
我正在使用 Bokeh DataTable 来呈现一个可编辑的表格,如果用户更改了值,我希望为单元格中的文本着色。
我试图使用HTMLTemplateFormatter
,但我不知道该怎么做。
如果用户更改了第 2 行的值,我希望文本像这样着色:
基于如何为 Bokeh DataTable 中的行和/或单元格着色的示例?:
from bokeh.plotting import curdoc
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import DataTable, TableColumn, HTMLTemplateFormatter
orig_data = dict(
cola=[1, 2, 3, 4, 5, 6],
)
data = orig_data
source = ColumnDataSource(data)
template = """
<div style="color: <%=
(function colorfromint(){
if(orig_data.cola != data.cola){return('red')} // I don't know what to write here
}()) %>;">
<%= value %>
</font>
</div>
"""
formatter = HTMLTemplateFormatter(template=template)
columns = [TableColumn(field="cola", title="CL1", formatter=formatter, width=100)]
data_table = DataTable(source=source,
columns=columns,
editable=True,
width=100)
curdoc().add_root(data_table)
我可以使用HTMLTemplateFormatter
块比较不同的表吗?
如果没有,来自HTMLTemplateFormatter Bokeh 文档:
“格式化程序可以通过传递给格式化的 dataContext 对象访问行中的其他项目”
所以我能想到的一种解决方案是加入表格并与 dataContext 对象进行比较,仅呈现我选择的列
但是,我不知道该怎么做,在我看来,这就像一个“肮脏”的解决方法
我对 python 很熟悉,但我对 Bokeh 很陌生。
有没有一个好的和简单的方法来做到这一点?
也许除了其他方法HTMLTemplateFormatter
?
解决方案
由于默认的 Bokeh 格式化程序适用于整个列,因此您必须创建自己的格式化程序。
下面的示例即使没有 Bokeh 服务器也可以工作,这就是它使用show
. 但是您可以将其替换为curdoc().add_root
- 它应该可以正常工作。
from bokeh.core.property.container import List
from bokeh.core.property.primitive import Int
from bokeh.io import show
from bokeh.models import ColumnDataSource, CustomJS, StringFormatter
from bokeh.models.widgets import DataTable, TableColumn
data = dict(cola=[1, 2, 3, 4, 5, 6],
colb=[1, 2, 3, 4, 5, 6])
orig_ds = ColumnDataSource(data)
ds = ColumnDataSource(copy.deepcopy(data))
class RowIndexFormatter(StringFormatter):
rows = List(Int, default=[])
# language=TypeScript
__implementation__ = """\
import {StringFormatter} from "models/widgets/tables/cell_formatters"
import * as p from "core/properties"
import {div} from "core/dom"
export namespace RowIndexFormatter {
export type Attrs = p.AttrsOf<Props>
export type Props = StringFormatter.Props & {
rows: p.Property<number[]>
}
}
export interface RowIndexFormatter extends RowIndexFormatter.Attrs {}
export class RowIndexFormatter extends StringFormatter {
properties: RowIndexFormatter.Props
constructor(attrs?: Partial<RowIndexFormatter.Attrs>) {
super(attrs)
}
static init_RowIndexFormatter(): void {
this.define<RowIndexFormatter.Props>({
rows: [ p.Array, [] ]
})
}
doFormat(row: any, _cell: any, value: any, _columnDef: any, _dataContext: any): string {
// Mostly copied from `StringFormatter`, except for taking `rows` into account.
const {font_style, text_align, text_color} = this
const text = div({}, value == null ? "" : `${value}`)
switch (font_style) {
case "bold":
text.style.fontWeight = "bold"
break
case "italic":
text.style.fontStyle = "italic"
break
}
if (text_align != null)
text.style.textAlign = text_align
if (text_color != null && this.rows.includes(row))
text.style.color = text_color
return text.outerHTML
}
}
"""
columns = [TableColumn(field="cola", title="CL1", formatter=RowIndexFormatter(text_color='red')),
TableColumn(field="colb", title="CL2", formatter=RowIndexFormatter(text_color='blue'))]
table = DataTable(source=ds, columns=columns, editable=True)
cb = CustomJS(args=dict(orig_ds=orig_ds, table=table),
code="""\
const columns = new Map(table.columns.map(c => [c.field, c]));
for (const c of cb_obj.columns()) {
const orig_col = orig_ds.data[c];
const formatter = columns.get(c).formatter;
formatter.rows = [];
cb_obj.data[c].forEach((val, idx) => {
if (val != orig_col[idx]) {
formatter.rows.push(idx);
}
});
}
table.change.emit();
""")
ds.js_on_change('data', cb)
ds.js_on_change('patching', cb)
show(table)
推荐阅读
- python - 训练神经网络时如何在准确性/减少损失方面给予特定输出更高的优先级
- sass - Gulp 错误:找不到要导入的文件或无法读取
- vba - 如何使用 VBA 在其他列长度范围内的列中查找?
- c# - 无法在我的 UWP 项目中添加对 Xamarin 应用程序的引用
- hadoop - 由于 MEMORY 问题,Hadoop HA 备用 Namenode 启动在安全模式下挂起
- regex - Apache目录不使用正则表达式
- ios - 如何使用 Swift 更改 UITableviewController 静态单元格部分背景颜色更改?
- c - Paul Davis 的 2002 年“中断驱动”ALSA 示例代码今天仍然有效吗?
- haskell - 用字符串映射行为
- powerbi - 将查询数据源更改为新的更新工作表问题