在生成的散景中动态改变值 HTML table

Dynamically changing value in a bokeh generated HTML table

我希望 sin(x) 值在我更改 table 中相应的 x 值后立即更改。 (在 运行 此代码之前在 CMD 中启动 bokeh serve

from bokeh.client import push_session
from bokeh.io import curdoc
from bokeh.layouts import row
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import DataTable, TableColumn
import  math
curdoc().clear()
x=[i for i in range(10)]

def update_y(x):
      y=[]
      for i in x:
            y.append(round(math.sin(int(i)),2))
      return y

y=update_y(x)
data=dict(x=x,y=y)
source=ColumnDataSource(data)
columns = [ TableColumn(field='x',title="x"),TableColumn(field='y',title="sin(x)") ]
dadat= DataTable(source=source, columns=columns, width=600, height=400,editable=True)

def update(attr,new,old):
      print('1')
      y=update_y(old['x'])
      print('2')
      source.data=dict(x=x,y=y)
      print('3')

source.on_change('data',update)
curdoc().add_root(row(dadat))
ses=push_session(curdoc())
ses.show()
ses.loop_until_closed()

在 运行 此代码和更改 x 的值之后,它会更改值几分之一秒,然后返回并进入无限循环。

我认为这是因为 source.on_change,因为当在 update 函数中编辑源值时可能会触发它。有什么解决办法吗?

先初始化source,每次有变化再初始化,这样就不会死循环。 这是完整的代码:(观察 update_table() function

from bokeh.client import push_session
from bokeh.io import curdoc
from bokeh.layouts import row
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import DataTable, TableColumn
curdoc().clear()
#replaced `sin(x)` with `x+2`
x=[i for i in range(10)]
def update_y(x):
      y=[]
      for i in x:
            y.append(int(i)+2)
      return y

def update_table(x):
      y=update_y(x)
      data=dict(x=x,y=y)
      source=ColumnDataSource(data)
      columns=[TableColumn(field='x',title='x'),TableColumn(field='y',title='y')]
      data_table=DataTable(source=source,columns=columns,width=500,height=500,editable=True)
      curdoc().clear()
      curdoc().add_root(row(data_table))
      source.on_change('data',update)
def update(attr,old,new):
      update_table(new['x'])

ses=push_session(curdoc())
update_table(x)  
ses.show()
ses.loop_until_closed()