xhluca / dash-draggable

react-draggable in Python
Other
19 stars 5 forks source link

Usage.py example and library outdated #11

Open kaburelabs opened 3 years ago

kaburelabs commented 3 years ago

Hey guys @xhlulu @SterlingButters,

I have tried to use the dash-draggable and I found a lot of difficulties because the library methods are different now;

It seems like the library now has 4 different methods:

'DashboardItem' 'DashboardItemResponsive' 'DraggableDashboard' 'DraggableDashboardResponsive'

I did a lot of tests and I have started to understand how it works but I still have some problems that I don't know what's going wrong neither how to solve.

What I'm trying to do: I would like to create a way where I can dynamically add new components with a default size but seems like the component isn't recognizing the command; Note that the size of the new components isn't correct... able-to-add-charts

Could some of you give me some light on how can I solve this problem?

The function that creates the responsive component:


style_close_chart= {
    "display": "flex",
    "justify-content": "space-between",
    "padding": "0 25px"}

def responsive_item(idx, title=None, type_data=px.bar):

    fig = type_data(x=["A", "B", "C"], y=[5, 7, 8])
    fig = fig.update_layout(autosize=True)

    component = DashboardItemResponsive(id=f"draggable-{idx}",
                                        x=6,y=5, w=600,h=700,
                                        minH=300, minW=200,
                                        isBounded=True, moved=True,
                                        children= [html.Div(
                                            [html.Div([html.Div(
                                                [f"{idx} chart - testing" if title == None else title]),
                                                       html.Div(
                                                html.Button('Close', id={"id":idx, "type":'close-chart'}),
                                                       )], style=style_close_chart), 
                                                             #html.Div([components]),
                                                             dcc.Graph(id=f"graph-{idx}", figure=fig,
                                                                       style={"height":"100%"})
                                                            ],
                                                             style={"height":"100%", "minHeight":"250px"})
                                                                    ]
                    )

    return component

The code that runs the app

import dash_draggable
from dash_draggable import DashboardItemResponsive
import dash
from dash.dependencies import Input, Output, State, MATCH, ALL
import dash_html_components as html
import dash_core_components as dcc
import dash_daq as daq
import plotly_express as px

from jupyter_dash import JupyterDash

app =  dash.Dash(__name__) # JupyterDash(__name__)

app.scripts.config.serve_locally = True
app.css.config.serve_locally = True
app.config['suppress_callback_exceptions'] = True

app.layout = html.Div([
    daq.BooleanSwitch(id='toggle-drag', on=True),
    html.Div(id="layout_testing", children=[]),
    html.Div(id="status"),
    html.Div([
        html.Div("Click to create a new chart"),
        html.Button('New', id='submit-new-chart', n_clicks=0),
    ]),
    html.Div(
        style={'display': 'inline-flex', 'background':'lightgrey'},

        children=dash_draggable.DraggableDashboard(id="drag-dashboard", 
                   layout=[{"x": 50, "y":50 , "w": 1400, "h": "100%"}],
                   children=[]
                )
        )
    ], style={"maxWidth":"1240px", "margin":"0px auto"} )

@app.callback(
    Output("drag-dashboard", 'children'),
    [Input('submit-new-chart', 'n_clicks')],
    [State("drag-dashboard", 'children')])
def update_output(n_clicks, value):
    if n_clicks == 0:
        return []

    if value == None:
        value=[]

    component = responsive_item(n_clicks, type_data=px.line)
    list_of_charts = value + [component]

    return list_of_charts

# Tell user if dragging is enabled and for which component
@app.callback(
     Output('status', 'children'),
    [Input('toggle-drag', 'on')]
)
def can_drag(toggle_status):
    return html.P("'Drag Anywhere' Component Draggable: {}".format(toggle_status))

if __name__ == '__main__':
    app.run_server(debug=True)

Thanks in advance for any help. Leonardo

kaburelabs commented 3 years ago

Update: When inspecting I have tried adding min-height and min-width to the component and it worked on the browser, but when I tried to add it directly on the creation of the component, I discovered that it doesn't allow to add style or even className... How should I set the dimensions of my new draggable component?

image

Also, I would like to use a custom background color to the Dashboard "canvas".

Am I doing something wrong or it's really a problem?

kaburelabs commented 3 years ago

Hey fellows...

I kept trying to implement it, and I had some advancements on how to create the draggable cards but it's still not working as expected.

Now I'm able to create the components but they aren't respecting the space of one each other;

creating-charts-errror

I would like to have a dashboard with a specific size where allow the user to add the chart anywhere he wants to.

The app and the function that creates the draggable cards code below:

Draggable components functions:

def responsive_item(idx, title=None, type_data=px.bar):

    fig = type_data(x=["A", "B", "C"], y=[5, 7, 8])
    fig = fig.update_layout(autosize=True, margin=dict(t=30, b=0, l=15, r=15))

    component = DraggableDashboard(id="drag-dashboard", 
                   layout=[{"x": "15", "y":"150" , "w": "100", "h": "100"}],
                   children=[DashboardItemResponsive(id=f"draggable-{idx}",
                                        x=6,y=5, w=450,h=300,
                                        minH=300, minW=200,
                                        isBounded=True, moved=True,
                                        children= [html.Div(
                                            [html.Div([html.Div(
                                                [f"{idx} chart testing" if title == None else title]),
                                                       html.Div(
                                                html.Button('Close', id={"id":idx, "type":'close-chart'}),
                                                       )], style=style_close_chart), 
                                                             #html.Div([components]),
                                                             dcc.Graph(id=f"graph-{idx}", figure=fig,
                                                                       style={"height":"100%"})
                                                            ],
                                                             style={"height":"100%"})
                                                                    ]
                    )])

    return component

App (as I'm doing a lot of tests, I'm using the JupyterDash component to fast iterations)

from dash_draggable import DraggableDashboard, DashboardItem, DashboardItemResponsive, DraggableDashboardResponsive
from jupyter_dash import JupyterDash
import dash_draggable
import dash
from dash.dependencies import Input, Output, State, MATCH, ALL
import dash_html_components as html
import dash_core_components as dcc
import dash_daq as daq
import plotly_express as px

app =  JupyterDash(__name__) # dash.Dash(__name__)

app.scripts.config.serve_locally = True
app.css.config.serve_locally = True
app.config['suppress_callback_exceptions'] = True

app.layout = html.Div([
    daq.BooleanSwitch(id='toggle-drag', on=True),
    html.Div(id="layout_testing", children=[]),
    html.Div(id="status"),

    html.Div([
        html.Div("Click to create a new chart"),
        html.Button('New', id='submit-new-chart', n_clicks=0),
    ]),

    html.Div(
        style={'display': 'inline-flex', 'background':'lightgrey', 'height':'100vh'},
        id="output-content"
                )
    ], style={"maxWidth":"1240px", "margin":"0px auto"} )

@app.callback(
    Output("output-content", 'children'),
    [Input('submit-new-chart', 'n_clicks')],
    [State("output-content", 'children')])
def update_output(n_clicks, value):

    if n_clicks == 0:
        return []

    if value == None:
        value=[]

    component = responsive_item(n_clicks, type_data=px.line)

    list_of_charts = value + [component]

#     print(len(list_of_charts))

    return list_of_charts

# Tell user if dragging is enabled and for which component
@app.callback(
     Output('status', 'children'),
    [Input('toggle-drag', 'on')]
)
def can_drag(toggle_status):
    return html.P("'Drag Anywhere' Component Draggable: {}".format(toggle_status))

if __name__ == '__main__':
    app.run_server(debug=True)

Regards, Leonardo