10

我正在使用 Plotly-Dash 并且需要我的文本注释的字体大小与视口宽度一起缩放,就像我的图表一样。对于我的布局中的各种标题,我可以直接设置font-size: '1vw',但vw不是用于设置组件属性的font-size可接受style单位dcc.Graph。这是相关的回溯:

ValueError: Invalid element(s) received for the 'size' property of scatter.textfont 无效元素包括:['1vw', '1vw', '1vw', '1vw', '1vw', '1vw', '1vw' , '1vw', '1vw', '1vw']

The 'size' property is a number and may be specified as:
  - An int or float in the interval [1, inf]
  - A tuple, list, or one-dimensional numpy array of the above

我认为如果dcc.Graph组件可以接受视口单位(例如style = {height: 30vw, width: 30vw})并将它们简单地转换为浏览器端的像素,那么我应该能够使用font-size.

Python 端是否有一种方法可以检索视口宽度(以像素为单位),以便我可以为字体大小执行自己的缩放逻辑?

以下是演示此行为的示例 Dash 应用程序:

import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go

labels = {'Point 1': (3.5,5), 'Point 2': (1.5,2), 'Point 3': (3.5,8)}

app = dash.Dash(__name__)

app.layout = html.Div([

    html.H1('Test', id='test', style={'margin': 50}),

    dcc.Graph(id='my-plot', style={'margin': 10}),

])

@app.callback(
    Output('my-plot', 'figure'),
    [Input('test', 'children')])
def update_graph(val):

    return {

        'data': [go.Scatter(
            x=[v[0]],
            y=[v[1]],
            text=k,
            mode='text'
        ) for k, v in labels.items()],

        'layout': go.Layout(
            margin={'l': 40, 'b': 40, 't': 40, 'r': 40},
            shapes=[
                {
                    'type': 'path',
                    'path': ' M 1 1 L 1 3 L 4 1 Z',
                    'fillcolor': 'rgba(44, 160, 101, 0.5)',
                    'line': {
                        'color': 'rgb(44, 160, 101)',
                    }
                },
                {
                    'type': 'path',
                    'path': ' M 3,7 L2,8 L2,9 L3,10, L4,10 L5,9 L5,8 L4,7 Z',
                    'fillcolor': 'rgba(255, 140, 184, 0.5)',
                    'line': {
                        'color': 'rgb(255, 140, 184)',
                    }
                },
            ]
        )
    }

if __name__ == '__main__':
    app.run_server()
4

2 回答 2

3

从我环顾四周的情况来看,没有办法只使用plotly-dash. 您需要实现的基本上是“响应式”排版,这个主题有一些非常有趣的文章:

Dash 提供了覆盖应用程序默认 CSS 和 JS 的选项,您可以从布局文档中了解如何使用甚至是外部 CSS 文件。

我的建议:研究结果页面以找出文本注释如何被标记(id和/或class),并使用上面文章中提供的方法来创建令人满意的结果。(很抱歉,除了建议,我真的无能为力,但我还没有看到你的代码示例:/)


编辑(评论和问题编辑后):

因此,由于文本注释具有textpoint我们将覆盖默认 CSS的类:

  1. 创建建议的文件夹结构:

    - app.py
    - assets/
    |--- typography.css
    
  2. typography.css应用上述方法之一(我将通过第二个项目符号示例):

    .textpoint{
        font-size: calc(14px + (26 - 14) * ((100vw - 300px) / (1600 - 300)));
    }
    

编辑#2:

我发现了问题和解决方法:

  • 在 Dash 版本 >= 0.22 上添加自定义 CSS 的方法确实是上面的,并且有效。
  • 为了将我们的自定义规则应用于注释,我们需要定位的元素是类text内的标签.textpoint(CSS 语法.textpoint text:)
  • 由于某种原因,自定义 CSS 规则被覆盖(可能出于类似原因,在此 SO 帖子的顶部答案中解释:自定义 css 被 bootstrap css 覆盖)。所以我们需要 的“核”选项!important

利用上面的,typography.css应该是这样的:

.textpoint text{
  font-size: calc(14px + (26 - 14) * ((100vw - 300px) / (1600 - 300))) !important;
}
于 2019-01-08T11:35:50.507 回答
0

错误消息说您应该将大小作为int对象提及。如果您不能在代码中直接使用 vw,请尝试使用 PySide / PyQt 获取它,然后将其转换为int并保存在不同的变量width&下height,您可以插入该变量而不是vw.

from PySide import QtGui
#replace that with "from PyQt4 import QtGui" if you're using PyQt4

app = QtGui.QApplication([])
screen_resolution = app.desktop().screenGeometry()
width = int(screen_resolution.width())
height = int(screen_resolution.height())

我不知道您正在使用什么代码,所以我没有尝试过。让我知道它是否适合你。

于 2019-01-08T12:08:59.263 回答