簡體   English   中英

如何更改 dash_table.DataTable 單元格並更新其他回調

[英]how to alter a dash_table.DataTable cell and update other callbacks

我在這里有一個 Plotly-Dash 儀表板,它使用左側的變量輸入以及一些“固定”變量進行更新。

這些固定變量顯示在圖像底部的 dash_table.DataTable 中。 如果用戶選擇更改 DataTable 中的值,我想更新使用這些固定值的回調。

截至目前,回調使用下拉菜單和數字輸入作為 [Input(' ', ' ')] 並且固定變量存儲為變量,並在相關方程中使用。

有沒有辦法:

  • 使用回調來定義這些固定變量值。 當表發生變化時,這些“固定”變量也會發生變化,..
  • 或者,使用回調來搜索表,如果進行了更改,則更新固定變量值。

我知道一個有點模糊的問題,我幾乎用谷歌搜索過這個問題,大部分信息都與過濾數據表和顯示行有關,而不是選擇和存儲單元格值作為變量。

我真正需要的是一個使用單元格數值的示例,用作回調 [Input()],以及使用基本代數公式中的輸入的回調。

我附上了代碼,你會看到我一直在修補第一個回調,其余的代碼工作正常。

儀表盤輸出

import dash
import dash_design_kit as ddk
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objects as go
import pandas as pd
import dash_daq as daq
import dash_table
from dash.dependencies import Input, Output
import math

import pandas as pd
import pathlib

from crunch_numbers import *
num_datacards = 5

# theme.js supplies some additional styling, generated using editor

# REQUIRED FOR DEPLOYMENT
app = dash.Dash(__name__, suppress_callback_exceptions=True) # keep suppress_ in production code
server = app.server # expose server variable for Procfile


app.layout = ddk.App(show_editor=True, children=[
    
    ddk.Header([
            ddk.Logo("assets/komatsuLogo.png",
                style={
                    "height": "30px",
                    "margin-right":"0px",
                    "width": "auto",
                },
            ),
            
            ddk.Title('Drivetrain Selection'),
        ]), # end of ddk.Header



  
    ddk.Block(width=20,children=[ # left-side (inputs)
        ddk.Card([ # machine Configuration
            ddk.CardHeader("Machine Configuration"),
            html.Br(),
            dcc.Dropdown(
                id='Platform',
                options=[
                        {'label': 'Badger', 'value': 'Badger'},
                        {'label': 'Weasel', 'value': 'Weasel'},
                    ],
                value='Badger',
                clearable=False,
                placeholder="Select Machine",
            ),
            html.Br(),
            dcc.Dropdown(
                id='battery_size',
                options=[
                        {'label': '5S1P ( 66kWh)', 'value': 66},
                        {'label': '5S2P (132kWh)', 'value': 132},
                    ],
                value=66,
                clearable=False,
                #placeholder="Battery Size (kWh)",
            ),
            html.Br(),
            dcc.Dropdown(
                id='Motor Selection',
                options=[
                        {'label': 'MD 2200', 'value': 'sumo_md_2200'},
                    ],
                value='sumo_md_2200',
                clearable=False,
                placeholder="Motor Selection",
            ),
        ]), # end of Machine Configuration

        ddk.Card([ # "Inputs"
            ddk.CardHeader("Inputs"),

            daq.NumericInput(
                id='ramp_angle',
                label='% Grade',
                labelPosition='top',
                value=0,
                min=0,
                max=18,
                size='auto',
            ),
            html.Br(),
            daq.NumericInput(
                id='ground_speed',
                label='Speed (kph)',
                labelPosition='top',
                value=0,
                min=0,
                max=15,
                size='auto',
            ),
            html.Br(),
            daq.NumericInput(
                id='parasitics',
                label='Parasitic Loads (kw)',
                labelPosition='top',
                value=0,
                min=0,
                max=30,
                size='auto',
            ),
            #html.Br(),

        ]), # end of "Inputs"
    
    ]), # end of left-side

    ddk.Block(width=80, children=[ # right side block
        ddk.Card([ # datacards and plot
            ddk.DataCard(
                width=100/num_datacards, # num_datacards is defined at top of file
                id='motor_speed',
                value=0,
                label="(RPM)",
            ),
            ddk.DataCard(
                width=100/num_datacards,
                id='motor_torque',
                value=0,
                label="(NM)",
            ),
            ddk.DataCard(
                width=100/num_datacards,
                id='traction_efficiency',
                value=0,
                label="(Tot. %)",
            ),
            ddk.DataCard(
                width=100/num_datacards,
                id='total_power',
                value=0,
                label="(kW)",
            ),
            ddk.DataCard(
                width=100/num_datacards,
                id='autonomy',
                value=0,
                label="(km)",
            ),
            dcc.Graph(id='plot'),
        ]), # end datacards and plot

        ddk.Card(width=100,children=[ # table card

            ddk.CardHeader("Machine Characteristics"),

            dcc.Markdown(
                    """
                    Update values in the table to modify machine performance.
                    """,
                    style={'textAlign': 'justify'}
            ),

            dash_table.DataTable(
                    id='machine_spec_table',
                    data=Badger.to_dict("rows"),
                    columns=[ # only 'Values' and 'Mechanical Efficiency' are editable!
                        {"name": i, "id": i,"editable":False,"selectable":True} 
                        if i == "Description" or i == "Units"
                        else  {"name": i, "id": i,"selectable":True} 
                        for i in Badger.columns
                        

                    ],
                    style_as_list_view=True,
                    style_header={"fontWeight": "bold", "textTransform": "capitalize"},
                    style_data_conditional=[
                        {
                            "if": {"row_index": "even"},
                            "backgroundColor": "var(--report_background_page)",
                        }
                    ],
                    editable=True,
            ),

        ]) # end of table card
    ]) # end of right side block
]) # end of ddk.App


""" 
Example of how to manage column width, should the need arise
    style_cell_conditional=[   
        {
            'if': {'column_id': 'Units'},
            'width': 25
        } for c in ['Units']
    ],
"""

############################# TABLE CALLBACKS ##################################################
################################################################################################

def find_fixed_variables(dict_list,var):
    return dict_list[]
    


############################# DRIVETRAIN SELECTION CALLBACKS ###################################
################################################################################################

@app.callback(
    Output('motor_speed', 'value'),
    [Input('ground_speed', 'value'),
     Input('machine_spec_table','data')] # , Input('tire_rr', 'value'), Input('diff_ratio', 'value'), Input('transfer_ratio', 'value')
)
def update_output(ground_speed,dict_list): #tire_rr, diff_ratio, transfer_ratio

    return math.floor((ground_speed*1000)/60/(2*math.pi*tire_rr)*diff_ratio*transfer_ratio)

@app.callback(
        Output('total_power', 'value'),
        [Input('ground_speed', 'value'), 
         Input('ramp_angle', 'value')] #, Input('parasitics', 'value')] # Input('GVW', 'value'), Input('RR', 'value'),, Input('traction_efficiency', 'value')
)
def update_output(ground_speed, ramp_angle): #, traction_efficiency

    power = math.floor(((RR/100)*(ground_speed*0.278) * GVW * gravity_cnst * math.cos(math.atan(ramp_angle/100))
                        / 0.9 / 1000)
                       + ((ground_speed * 0.278) * GVW * gravity_cnst * math.sin(math.atan(ramp_angle / 100))
                          / 0.9 / 1000)
                       )

    if ground_speed == 0:
        return 0
    else:
        return power

@app.callback(
    Output('motor_torque', 'value'),
    [Input('ground_speed', 'value'), 
     Input('motor_speed', 'value'), 
     Input('total_power', 'value'),]
)
def update_output(ground_speed, motor_speed, total_power):
    if ground_speed == 0:
        return 0
    elif math.floor(9.5488*total_power*1000/motor_speed) < 50:
        return 50
    else:
        return math.floor(9.5488*total_power*1000/motor_speed)

@app.callback(
    Output('plot', 'figure'),
    [Input('motor_speed', 'value'), 
     Input('motor_torque', 'value')] #Input('Motor Selection', 'value')
)
def update_output(motor_speed, motor_torque): # , Motor_Selection

    fig = go.Figure(
        layout=go.Layout(
            # title="Motor Efficiency Plot",
            # autosize=False,
            # width=500,
            paper_bgcolor="rgba(0,0,0,0)",
            plot_bgcolor="rgba(0,0,0,0)",
            yaxis=dict(title="Motor Torque (Nm)"),
            xaxis=dict(title="Motor Speed (RPM)"),
        )
    )
    fig.update_layout(legend=dict(
        orientation="h",
        yanchor="bottom",
        y=1,
        xanchor="left",
        x=0
    )
    )

    fig.add_trace(go.Scatter(
        x=TM4_BoundaryCurve['Speed (rpm)'],
        y=TM4_BoundaryCurve['Peak Torque (Nm)'],
        name="Peak Torque",
    )
    )
    fig.add_trace(go.Scatter(
        x=TM4_BoundaryCurve['Speed (rpm)'],
        y=TM4_BoundaryCurve['Continuous Torque (Nm)'],
        name="Cont. Torque",
    )
    )

    fig.add_trace(go.Contour(
        z=[TM4_EfficiencyMap['0'], TM4_EfficiencyMap['280'], TM4_EfficiencyMap['420'], TM4_EfficiencyMap['560'],
           TM4_EfficiencyMap['700'],
           TM4_EfficiencyMap['840'], TM4_EfficiencyMap['980'], TM4_EfficiencyMap['1120'], TM4_EfficiencyMap['1260'],
           TM4_EfficiencyMap['1400'],
           TM4_EfficiencyMap['1540'], TM4_EfficiencyMap['1680'], TM4_EfficiencyMap['1820'], TM4_EfficiencyMap['1960'],
           TM4_EfficiencyMap['2100'],
           TM4_EfficiencyMap['2240'], TM4_EfficiencyMap['2380'], TM4_EfficiencyMap['2520'], TM4_EfficiencyMap['2660'],
           TM4_EfficiencyMap['2800'],
           TM4_EfficiencyMap['2940'], TM4_EfficiencyMap['3080'], TM4_EfficiencyMap['3220'], TM4_EfficiencyMap['3360'],
           TM4_EfficiencyMap['3500'], ],
        x=TM4_EfficiencyMap['Speed'],
        y=TM4_EfficiencyMap['Torque'],
        transpose=True,
        colorscale='Blues',
        ncontours=20,
        opacity=0.5,
        showscale=False,
        contours=dict(
            showlabels=True,  # show labels on contours
            labelfont=dict(  # label font properties
                size=12,
                color='white',
            )
        )
    )
    )

    fig.add_trace(go.Scatter(
        x=[motor_speed],
        y=[motor_torque],
        name="Actual",
        mode="markers",
        marker=dict(size=20, color='black', symbol="x"),
    )
    )
    return fig

@app.callback(
    Output('autonomy', 'value'),
    [Input('ground_speed', 'value'), 
     Input('total_power', 'value'), 
     Input('battery_size', 'value')]
)
def update_output(ground_speed, total_power, battery_size):
    if ground_speed == 0 or total_power == 0:
        return 0
    else:
        return round((battery_size * DOD / total_power) * ground_speed, 2)
    
@app.callback(
    Output('traction_efficiency', 'value'),
    [Input('motor_speed', 'value'), 
     Input('motor_torque', 'value')]
)
def update_output(motor_speed, motor_torque):
    df = pd.DataFrame(TM4_EfficiencyMap)
    if motor_speed <= 280:
        speed = str(0)
        torque = 50
    else:
        speed = str(int((round(motor_speed / 140, 0) / 2) * 280))
        torque = round(motor_torque / 50, 0) * 50

    z = sum(round(df.loc[df['Torque'] == torque, speed] / 100 * diff_eff * transfer_eff * driveshaft_mt * driveshaft_td, 2))
    return z





################################# MANDATORY SERVER CODE ##################################
if __name__ == '__main__':
    app.run_server(debug=True)

好吧,這么簡單的修復,沒有什么是一些 print() 測試語句無法修復的,哈哈。 基本上取決於您用於 Input('machine_spec_table','data') 的回調輸入類型

在這里我使用了“數據”,還有很多其他可用的並在文檔中進行了解釋,

該函數的輸入如下:

your_var = [
    {'Description': 'Gross Vehicle Weight', 'Values': 29500, 'Units': 'kg', 'Mechanical Efficiency': '-'}, 
    {'Description': 'Weight Distribution', 'Values': '60/40', 'Units': '', 'Mechanical Efficiency': '-'}, 
    {'Description': 'Tire Rolling Radius', 'Values': 0.589, 'Units': 'm', 'Mechanical Efficiency': '-'}, 
    {'Description': 'Differential Ratio', 'Values': 20.65, 'Units': '', 'Mechanical Efficiency': 0.93}, 
    {'Description': 'Transfer Case Ratio', 'Values': 2.48, 'Units': '', 'Mechanical Efficiency': 0.98}, 
    {'Description': 'Rolling Resistance', 'Values': 0.02, 'Units': '', 'Mechanical Efficiency': '-'}, 
    {'Description': 'Drive Shaft', 'Values': '-', 'Units': '', 'Mechanical Efficiency': 0.98}
]

字典列表! 易於訪問,類似於table[0]['Values]做得很好:)(0 是列表索引,'Values' 是字典鍵)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM