<p>好的,这里有一个完整的工作示例:</p>
<pre><code>import dash_html_components as html
import dash_leaflet as dl
import dash_leaflet.express as dlx
import dash_core_components as dcc
from dash import Dash
from dash_extensions.javascript import arrow_function, assign
from dash.dependencies import Output, Input
def get_info(feature=None):
header = [html.H4("US Population Density")]
if not feature:
return header + [html.P("Hoover over a state")]
return header + [html.B(feature["properties"]["name"]), html.Br(),
"{:.3f} people / mi".format(feature["properties"]["density"]), html.Sup("2")]
classes = [0, 10, 20, 50, 100, 200, 500, 1000]
colorscale = ['#FFEDA0', '#FED976', '#FEB24C', '#FD8D3C', '#FC4E2A', '#E31A1C', '#BD0026', '#800026']
style = dict(weight=2, opacity=1, color='white', dashArray='3', fillOpacity=0.7)
# Create colorbar.
ctg = ["{}+".format(cls, classes[i + 1]) for i, cls in enumerate(classes[:-1])] + ["{}+".format(classes[-1])]
colorbar = dlx.categorical_colorbar(categories=ctg, colorscale=colorscale, width=300, height=30, position="bottomleft")
# Geojson rendering logic, must be JavaScript as it is executed in clientside.
style_handle = assign("""function(feature, context){
const {classes, colorscale, style, colorProp} = context.props.hideout; // get props from hideout
const value = feature.properties[colorProp]; // get value the determines the color
for (let i = 0; i < classes.length; ++i) {
if (value > classes[i]) {
style.fillColor = colorscale[i]; // set the fill color according to the class
}
}
return style;
}""")
filter_handle = assign("function(feature, context){console.log(context);return context.props.hideout.name.includes(feature.properties.name);}")
dd_options = [{"value": "Alabama", "label": "Alabama"}, {"value": "Arkansas", "label": "Arkansas"}, {"value": "Florida", "label": "Florida"}]
dd_defaults = ["Alabama", "Arkansas", "Florida"]
# Create geojson.
geojson = dl.GeoJSON(url="/assets/us-states.json", # url to geojson file
options=dict(style=style_handle,filter=filter_handle), # how to style each polygon
zoomToBounds=True, # when true, zooms to bounds when data changes (e.g. on load)
zoomToBoundsOnClick=True, # when true, zooms to bounds of feature (e.g. polygon) on click
hoverStyle=arrow_function(dict(weight=5, color='#666', dashArray='')), # style applied on hover
hideout=dict(colorscale=colorscale, classes=classes, style=style, colorProp="density", name=dd_defaults),
id="geojson")
# Create info control.
info = html.Div(children=get_info(), id="info", className="info",
style={"position": "absolute", "top": "10px", "right": "10px", "z-index": "1000"})
# Create app.
app = Dash(prevent_initial_callbacks=True)
app.layout = html.Div([
dl.Map([dl.TileLayer(), geojson, colorbar, info], style={'width': '100%', 'height': '50vh', 'margin': "auto", "display": "block"}, id="map"
),
html.Div([
dcc.Dropdown(id="dd", value=dd_defaults, options=dd_options, clearable=False, multi=True)
])
])
@app.callback(Output("info", "children"), [Input("geojson", "hover_feature")])
def info_hover(feature):
return get_info(feature)
app.clientside_callback("""
function(x, y){
return {
classes: y.classes,
name: x,
colorProp: y.colorProp,
colorscale: y.colorscale,
style: y.style
};}
""",
Output("geojson", "hideout"), [Input("dd", "value"), Input("geojson", "hideout")]),
if __name__ == '__main__':
app.run_server()
</code></pre>