定制标记颜色
本项目提供了多种定制标记颜色的方式。默认情况下,所有的标记框都是白色的。要修改标记的默认颜色,可以使用style_annotation。
from typing import Optional
import dash
from dash import html, Output, Input
import dash_picture_annotation as dpa
app = dash.Dash()
get_mark = lambda x, y: {"x": x, "y": y, "width": 50, "height": 50, "type": "RECT"}
app.layout = html.Div(
    (
        html.Div(html.Button(id="btn-color", children="Set color")),
        dpa.DashPictureAnnotation(
            id="annotator",
            data=dpa.sanitize_data(
                [
                    get_mark(50, 50),
                    get_mark(150, 50),
                    {"mark": get_mark(250, 50), "comment": "cls-1"},
                    {"mark": get_mark(350, 50), "comment": "cls-1"},
                    {"mark": get_mark(50, 150), "comment": "cls-1"},
                    {"mark": get_mark(150, 150), "comment": "cls-2"},
                    {"mark": get_mark(250, 150), "comment": "cls-3"},
                    {"mark": get_mark(350, 150), "comment": "cls-4"},
                ],
                deduplicate="add",
            ),
            image="/site-address/to/an/image",
        ),
    )
)
@app.callback(
    Output("annotator", "style_annotation"),
    Input("btn-color", "n_clicks"),
    prevent_initial_call=True,
)
def set_color(n_clicks: Optional[int]):
    if n_clicks:
        return "black"
    return dash.no_update
app.run()
本文中后续的部分,都基于该范例脚本展开。在默认(初始化)情况下,启动应用时,用户可以看见白色的标记框。
| 标记框的默认颜色 | 
|---|
![]()  | 
修改标记的默认色
以上脚本中,callback的定义如下:
@app.callback(
    Output("annotator", "style_annotation"),
    Input("btn-color", "n_clicks"),
    prevent_initial_call=True,
)
def set_color(n_clicks: Optional[int]):
    if n_clicks:
        return "black"
    return dash.no_update
按下按钮时,默认标记色将会修改为black(黑色 )。这是由于向属性style_annotation传递了一个str。该属性值为str时,该值会解释为CSS颜色:
| 修改标记的默认色 | 
|---|
![]()  | 
CSS颜色可以透过多种方式格式化。例如,黑色可以写作black,#000,#000000,rgb(0, 0, 0),hsl(0, 0%, 0%)。
要了解更多信息,参见CSS颜色文档。
修改标记的默认色 (细粒度)
属性style_annotation还可以透过一种更细粒度的方式设置。若向其传递一个可以标记为类型dpa.AnnoStyle的字典,则可以分别为标记框的不同部分、分别设置不同的样式参数。例如,
@app.callback(
    Output("annotator", "style_annotation"),
    Input("btn-color", "n_clicks"),
    prevent_initial_call=True,
)
def set_color(n_clicks: Optional[int]):
    if n_clicks:
        return dpa.AnnoStyle(shapeStrokeStyle="black", fontBackground="yellow")
    return dash.no_update
此例中,标记框的颜色设置为了"black"(黑色),而文字标注的背景色,则设置为了"yellow"(黄色)。若dpa.AnnoStyle的某个关键字成员未设置,其对应的样式将会采用默认值。
| 修改标记的默认色(细粒度) | 
|---|
![]()  | 
按类别修改颜色
还可以按照标记框所包含的文字标注值、设置其对应的颜色。该功能允许用户、按标记对应的类别区分其颜色。该设置透过属性colors完成。例如,可以考虑定义  一个用来设置特定颜色的按钮。按下按钮时,就会触发callback set_colors。
app.layout = html.Div(
    (
        html.Div(html.Button(id="btn-color", children="Set color")),
        html.Div(html.Button(id="btn-colors", children="Set specified colors")),
        dpa.DashPictureAnnotation(id="annotator", ...),
    )
)
@app.callback(
    Output("annotator", "colors"),
    Input("btn-colors", "n_clicks"),
    prevent_initial_call=True,
)
def set_colors(n_clicks: Optional[int]):
    if n_clicks:
        return {"cls-1": "#E00", "cls-2": "#66ccff"}
    return dash.no_update
该callback返回一个字典,其关键字对应的是不同文字标注的值,而字典值对应的是不同的颜色。具有同样文字标注的标记,总会设置为同一颜色。下例中,由于cls-1的颜色设置为了#E00,所有三个具备该文字标注的标记框,都记以相同的颜色。
| 设置文字标注的颜色 Specify the comment color | 
|---|
![]()  | 
属性colors的字典值,可以设置为任何CSS颜色格式。其颜色值的用法和属性style_annotation相关的前述用法相同。
使用属性colors时,只能设置标记框的背景色。标记框的前景色(文字色)通过计算背景色的亮度自动调节。
按类别动态设置颜色
若用户不愿为每种文字标注分别手动设置颜色,可以考虑透过设置二值量is_color_dynamic,令标记框的颜色自动计算。下例中,使用另一按钮btn-dynamic设置该属性。
app.layout = html.Div(
    (
        html.Div(html.Button(id="btn-color", children="Set color")),
        html.Div(html.Button(id="btn-dynamic", children="Set dynamic colors")),
        dpa.DashPictureAnnotation(id="annotator", ...),
    )
)
@app.callback(
    Output("annotator", "is_color_dynamic"),
    Input("btn-dynamic", "n_clicks"),
    prevent_initial_call=True,
)
def set_dynamic(n_clicks: Optional[int]):
    if n_clicks:
        return True
    return dash.no_update
按下按钮时,不同标记框的颜色,会根据其文字标注动态渲染。颜色渲染的方式,可以解释为先计算文字标注的哈希量(hash code),再透过该哈希量决定颜色的色调。因此,同样的文字标注,总会对应同样的颜色。那些不带有文字标注的标记框,仍然会显示为默认色。
| 动态渲染颜色 | 
|---|
![]()  | 
不同颜色属性的优先级
本指南中,提及了三种不同的配置标记色的方式。下图展示的例子中,已经使之前提及的三种颜色修改同时生效。换言之,其对应的颜色设置等价于:
dpa.DashPictureAnnotation(
    id="annotator",
    style_annotation="black",
    colors={"cls-1": "#E00", "cls-2": "#66ccff"},
    is_color_dynamic=True,
)




