Skip to content

Commit 7bca93d

Browse files
authored
Add files via upload
Added a new example dash app file in which the new components margin, allowOverlap and draggableChildStyle are being used.
1 parent 59cf41a commit 7bca93d

File tree

1 file changed

+264
-0
lines changed

1 file changed

+264
-0
lines changed

Diff for: margin_allowOverlap_draggableChildStyle_example.py

+264
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
import dash_dynamic_grid_layout as dgl
2+
from dash import *
3+
from dash.exceptions import PreventUpdate
4+
import plotly.express as px
5+
import dash_leaflet as dl
6+
import dash_mantine_components as dmc
7+
from dash_iconify import DashIconify
8+
from datetime import datetime, date
9+
import json
10+
import random
11+
import string
12+
import full_calendar_component as fcc
13+
from datetime import datetime
14+
15+
# Set the React version
16+
dash._dash_renderer._set_react_version("18.2.0")
17+
18+
app = Dash(__name__)
19+
20+
# Get today's date
21+
today = datetime.now()
22+
23+
# Format the date
24+
formatted_date = today.strftime("%Y-%m-%d")
25+
26+
# Sample data for the graph
27+
df = px.data.iris()
28+
29+
30+
# Create a Random String ID for the new component
31+
def generate_random_string(length):
32+
# Define the characters to choose from
33+
characters = string.ascii_letters + string.digits
34+
# Generate a random string
35+
random_string = "".join(random.choice(characters) for _ in range(length))
36+
return random_string
37+
38+
39+
app.layout = dmc.MantineProvider(
40+
[
41+
html.Div(
42+
[
43+
html.Center(html.H4("json.dumps(current_layout)")),
44+
html.Hr(),
45+
html.Div(id="layout-output"),
46+
html.Hr(),
47+
dmc.Group([
48+
html.H4("Add items or edit the layout ->"),
49+
dmc.Menu(
50+
[
51+
dmc.MenuTarget(
52+
dmc.ActionIcon(
53+
DashIconify(icon="icon-park:add-web", width=20),
54+
size="lg",
55+
color="#fff",
56+
variant="filled",
57+
id="action-icon",
58+
n_clicks=0,
59+
mb=8,
60+
style={"backgroundColor": "#fff"},
61+
)
62+
),
63+
dmc.MenuDropdown(
64+
[
65+
dmc.MenuItem(
66+
"Add Dynamic Component",
67+
id="add-dynamic-component",
68+
n_clicks=0,
69+
),
70+
dmc.MenuItem(
71+
"Edit Dynamic Layout", id="edit-mode", n_clicks=0
72+
),
73+
]
74+
),
75+
],
76+
transitionProps={
77+
"transition": "rotate-right",
78+
"duration": 150,
79+
},
80+
position="right",
81+
),
82+
]),
83+
dgl.DashGridLayout(
84+
id="grid-layout",
85+
items=[
86+
dgl.DraggableWrapper(
87+
children=[
88+
dl.Map(
89+
dl.TileLayer(),
90+
center=[56, 10],
91+
zoom=6,
92+
style={
93+
"height": "100vh",
94+
"width": "100vw",
95+
},
96+
),
97+
],
98+
id="draggable-map",
99+
handleBackground="rgb(85,85,85)",
100+
),
101+
dgl.DraggableWrapper(
102+
html.Img(
103+
src="https://picsum.photos/200/300",
104+
style={
105+
"width": "100%",
106+
"height": "100%",
107+
"objectFit": "cover",
108+
},
109+
),
110+
id="draggable-image",
111+
),
112+
dgl.DraggableWrapper(
113+
dcc.Graph(
114+
id="example-graph",
115+
figure=px.scatter(
116+
df,
117+
x="sepal_width",
118+
y="sepal_length",
119+
color="species",
120+
),
121+
style={"height": "100%"},
122+
),
123+
id="draggable-graph",
124+
),
125+
dgl.DraggableWrapper(
126+
dmc.ColorPicker(
127+
id="qr-color-picker",
128+
format="rgba",
129+
value="rgba(0, 0, 0, 1)",
130+
fullWidth=True,
131+
),
132+
id="draggable-color-picker",
133+
),
134+
dgl.DraggableWrapper(
135+
fcc.FullCalendarComponent(
136+
id="api_calendar", # Unique ID for the component
137+
initialView='dayGridMonth', # dayGridMonth, timeGridWeek, timeGridDay, listWeek,
138+
# dayGridWeek, dayGridYear, multiMonthYear, resourceTimeline, resourceTimeGridDay, resourceTimeLineWeek
139+
headerToolbar={
140+
"left": "prev,next today",
141+
"center": "",
142+
"right": "",
143+
}, # Calendar header
144+
initialDate=f"{formatted_date}", # Start date for calendar
145+
editable=True, # Allow events to be edited
146+
selectable=True, # Allow dates to be selected
147+
events=[],
148+
nowIndicator=True, # Show current time indicator
149+
navLinks=True, # Allow navigation to other dates
150+
),
151+
id="draggable-calendar"
152+
),
153+
],
154+
itemLayout=[
155+
# wrapper id, x(0-12), y, w(0-12), h(0-12)
156+
{'i': 'draggable-map', 'x': 0, 'y': 0, 'w': 6, 'h': 4},
157+
{'i': 'draggable-image', 'x': 4, 'y': 0, 'w': 4, 'h': 2},
158+
{'i': 'draggable-graph', 'x': 0, 'y': 4, 'w': 6, 'h': 4},
159+
{'i': 'draggable-color-picker', 'x': 6, 'y': 2, 'w': 3, 'h': 2},
160+
{'i': 'draggable-calendar', 'x': 6, 'y': 4, 'w': 6, 'h': 4}
161+
],
162+
showRemoveButton=False,
163+
showResizeHandles=False,
164+
rowHeight=150,
165+
cols={"lg": 12, "md": 10, "sm": 6, "xs": 4, "xxs": 2},
166+
style={"height": "1500px", 'backgroundColor': 'green'},
167+
compactType=None,
168+
autoSize = False,
169+
maxRows = 40,
170+
margin={"lg": [1, 1], "md": [1, 1], "sm": [6, 6], "xs": [4, 4], "xxs": [2, 2]}, #Margin between draggable components in pixels.
171+
allowOverlap = True, #Components can now overlap each other.
172+
draggableChildStyle = { ##Smaller padding, max height and backgroundcolor(for padding in practice)
173+
'overflow': 'hidden',
174+
'maxHeight': '100%',
175+
'maxWidth': '100%',
176+
"border": "5px solid yellow", ## This sort of creates some coloured extra padding for the handles.
177+
"boxSizing": "border-box", # Ensures border doesn't mess up sizing
178+
},
179+
180+
),
181+
dcc.Store(id="layout-store"),
182+
], style={ 'backgroundColor': 'blue', 'overflowY':'hidden', 'height': '1200px'}
183+
)
184+
],
185+
id="mantine-provider",
186+
forceColorScheme="light",
187+
)
188+
189+
190+
@callback(Output("layout-store", "data"), Input("grid-layout", "currentLayout"))
191+
def store_layout(current_layout):
192+
return current_layout
193+
194+
195+
@callback(
196+
Output("grid-layout", "showRemoveButton"),
197+
Output("grid-layout", "showResizeHandles"),
198+
# show how to dynamically change the handle background color of a wrapped component
199+
Output("draggable-map", "handleBackground"),
200+
Input("edit-mode", "n_clicks"),
201+
State("grid-layout", "showRemoveButton"),
202+
State("grid-layout", "showResizeHandles"),
203+
prevent_initial_call=True,
204+
)
205+
def enter_editable_mode(n_clicks, current_remove, current_resize):
206+
print("Edit mode clicked:", n_clicks) # Debug print
207+
if n_clicks is None:
208+
raise PreventUpdate
209+
return not current_remove, not current_resize, "red"
210+
211+
212+
@callback(Output("layout-output", "children"), Input("grid-layout", "itemLayout"))
213+
def display_layout(current_layout):
214+
if current_layout and isinstance(current_layout, list):
215+
return html.Div(json.dumps(current_layout))
216+
return "No layout data available"
217+
218+
219+
@callback(
220+
Output("grid-layout", "items"),
221+
Output("grid-layout", "itemLayout"),
222+
Input("add-dynamic-component", "n_clicks"),
223+
prevent_initial_call=True,
224+
)
225+
def add_dynamic_component(n):
226+
if n:
227+
items = Patch()
228+
new_id = generate_random_string(10)
229+
items.append(
230+
dgl.DraggableWrapper(
231+
dcc.Graph(
232+
figure=px.scatter(
233+
df, x="petal_width", y="petal_length", color="species"
234+
),
235+
style={"height": "100%"},
236+
),
237+
id=new_id
238+
)
239+
)
240+
itemLayout = Patch()
241+
itemLayout.append({"i": f"{new_id}", "w": 6})
242+
return items, itemLayout
243+
return no_update, no_update
244+
245+
@callback(
246+
Output("grid-layout", "items", allow_duplicate=True),
247+
Input("grid-layout", "itemToRemove"),
248+
State("grid-layout", "itemLayout"),
249+
prevent_initial_call=True,
250+
)
251+
def remove_component(key, layout):
252+
if key:
253+
items = Patch()
254+
print(key)
255+
for i in range(len(layout)):
256+
if layout[i]['i'] == key:
257+
del items[i]
258+
break
259+
return items
260+
return no_update
261+
262+
263+
if __name__ == "__main__":
264+
app.run(debug=True)

0 commit comments

Comments
 (0)