为绘图破折号转换绑定。
dash-transcrypt的Python项目详细描述
dash transcrypt的目的是使
- 用Python编写客户端回调
- 将函数句柄作为组件属性传递
在幕后,它利用transcrypt将Python转换成JavaScript。在
入门
建议通过pip安装仪表板收发器
pip install dash-transcrypt
此外,还需要一个可工作的java安装(在缩小过程中使用)。要运行与函数属性相关的示例,还需要dash-shelf和geobuf
^{pr2}$客户端回调
要用作客户端回调的函数必须放在单独的模块(文件)中,比如calculator_cf.py
。在本例中,我们将考虑一个简单的add
函数
def add(a, b):
return a + b
在add
函数可用作客户端回调之前,calculator_cf
模块必须传递给to_clientside_functions
函数。除了将模块转换成JavaScript之外,它还将模块的函数属性替换为ClientsideFunction
对象,以便在客户端回调中使用它们
import caculator_cf as ccf
from dash_transcrypt import module_to_clientside_functions, inject_js
...
inject_js(app, module_to_clientside_functions(ccf))
app.clientside_callback(ccf.add, ...)
to_clientside_functions
返回JavaScript索引文件的路径,该路径必须对应用程序可用(这就是inject_js
所做的)。为了完整起见,这里是完整的(除了caculator_cf.py
)示例应用程序
import dash
import dash_core_components as dcc
import dash_html_components as html
import caculator_cf as ccf
from dash.dependencies import Output, Input
from dash_transcrypt import module_to_clientside_functions, inject_js
# Create example app.
app = dash.Dash()
app.layout = html.Div([
dcc.Input(id="a", value=2, type="number"), html.Div("+"),
dcc.Input(id="b", value=2, type="number"), html.Div("="), html.Div(id="c"),
])
# Create clientside callback.
inject_js(app, module_to_clientside_functions(ccf))
app.clientside_callback(ccf.add, Output("c", "children"), [Input("a", "value"), Input("b", "value")])
if __name__ == '__main__':
app.run_server()
作为属性的函数
您可能已经知道,not在Dash中传递函数句柄作为组件属性是可能的。为了规避这个限制,dash transcrypt将完整路径作为字符串传递给函数。然后由组件来创建函数。在
支持此流的组件示例是dash-leaflet中的GeoJSON
组件。函数属性之一是pointToLayer
选项,它必须是与基础Leaflet GeoJSON object的pointToLayer
选项的签名匹配的函数(或函数的完整路径)。相关函数必须放在单独的模块(文件)中,比如scatter_js.py
def point_to_layer(feature, latlng, context):
radius = feature.properties.value*10
return L.circleMarker(latlng, dict(radius=radius))
在将函数指定为属性之前,必须通过module_to_props
函数传递模块。除了将模块转换成JavaScript之外,它还用适当的字符串替换模块的函数属性
import scatter_js as sjs
import dash_leaflet as dl
from dash_transcrypt import inject_js, module_to_props
...
js = module_to_props(sjs)
geojson = dl.GeoJSON(data=data, options=dict(pointToLayer=sjs.point_to_layer)) # pass function as prop
...
inject_js(app, js)
为了完整起见,下面是完整的示例应用程序
import random
import dash
import dash_html_components as html
import dash_leaflet as dl
import scatter_js as sjs
import dash_leaflet.express as dlx
from dash_transcrypt import inject_js, module_to_props
# Create some markers.
points = [dict(lat=55.5 + random.random(), lon=9.5 + random.random(), value=random.random()) for i in range(100)]
data = dlx.dicts_to_geojson(points)
# Create geojson.
js = module_to_props(sjs) # compiles the js
geojson = dl.GeoJSON(data=data, options=dict(pointToLayer=sjs.point_to_layer)) # pass function as prop
# Create the app.
app = dash.Dash()
app.layout = html.Div([dl.Map([dl.TileLayer(), geojson], center=(56, 10), zoom=8, style={'height': '50vh'})])
inject_js(app, js) # adds the js to the app
if __name__ == '__main__':
app.run_server()
在编译时传递参数
在编译时,# <kwarg>
后面的变量赋值被dash transcrypt预处理器覆盖。作为前一个例子的扩展,假设可以改变半径的比例。这可以通过将scatter_js.py
修改为
scale = 10 # <kwarg>
def point_to_layer(feature, latlng, context):
radius = feature.properties.value * scale
return L.circleMarker(latlng, dict(radius=radius))
默认值scale
10,但现在可以通过更改应用程序代码中的一行来修改该值
js = module_to_props(cjs, scale=20) # compiles the js
在运行时传递参数
虽然dash transcrypt不强制,但建议将上下文(通常是对this
)的引用传递给所有函数属性。此外,建议添加一个hideout
属性,不做任何,但在运行时充当容器参数。前面示例中的GeoJSON
组件遵循以下准则。因此,通过将scatter_js.py
修改为
def point_to_layer(feature, latlng, context):
scale = context.props.hideout.scale
radius = feature.properties.value * scale
return L.circleMarker(latlng, dict(radius=radius))
现在可以在运行时更改scale
。也就是说,地图可视化现在可以是interactive。这是一个小的应用程序,其中一个滑块可以改变scale
,从而改变制造商的大小
import random
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_leaflet as dl
import scatter_rt_js as rjs
import dash_leaflet.express as dlx
from dash.dependencies import Input, Output
from dash_transcrypt import inject_js, module_to_props
# Create some markers.
points = [dict(lat=55.5 + random.random(), lon=9.5 + random.random(), value=random.random()) for i in range(100)]
data = dlx.dicts_to_geojson(points)
# Create geojson.
js = module_to_props(rjs) # compiles the js
geojson = dl.GeoJSON(data=data, options=dict(pointToLayer=rjs.point_to_layer), # pass function as prop
hideout=dict(scale=10), id="geojson") # pass variables to function
# Create the app.
app = dash.Dash()
app.layout = html.Div([
dl.Map([dl.TileLayer(), geojson], center=(56, 10), zoom=8, style={'height': '50vh'}),
dcc.Slider(min=1, max=100, value=10, id="slider")
])
inject_js(app, js) # adds the js to the app
@app.callback(Output("geojson", "hideout"), [Input("slider", "value")], prevent_initial_call=False)
def update_scale(value):
return dict(scale=value)
if __name__ == '__main__':
app.run_server()
注释
- 浏览器倾向于缓存javascript资产。对python函数进行更改后,可能需要强制重新加载页面(ctrl+F5)以获取更新的函数定义。在
- 项目
标签: