feat: Added ElectronJS app to display the app
feat: Removed fullscreen dialogs to display them in popup window
This commit is contained in:
BIN
3D_app/assets/settings.png
Normal file
BIN
3D_app/assets/settings.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 219 KiB |
@ -1,4 +1,5 @@
|
||||
from dash import State, Output, Input, callback
|
||||
from tkinter import NONE
|
||||
from dash import State, Output, Input, callback, clientside_callback
|
||||
import dash
|
||||
import numpy as np
|
||||
import plotly.graph_objects as go
|
||||
@ -74,50 +75,19 @@ def get_callbacks():
|
||||
)
|
||||
return [fig, True]
|
||||
|
||||
# callback pour le plot 3D en plein écran
|
||||
@callback(
|
||||
Output("3dplot-fullscreen", "figure"),
|
||||
[
|
||||
Input("iso-slider-fullscreen", "value"),
|
||||
Input("y-slider-fullscreen", "value"),
|
||||
],
|
||||
# callback pour le plein écran du plot 3D
|
||||
clientside_callback(
|
||||
"""
|
||||
function toggle_fullscreen_3dplot(n1) {
|
||||
if (n1) {
|
||||
window.open("fullscreen/3dplot", "", "width=800,height=600,popup=true");
|
||||
}
|
||||
}
|
||||
""",
|
||||
Output("js", "children", allow_duplicate=True),
|
||||
[Input("fullscreen-button-3dplot", "n_clicks")],
|
||||
prevent_initial_call=True,
|
||||
)
|
||||
def update_3dplot_fullscreen(iso_value, y_values):
|
||||
y_min, y_max = y_values
|
||||
selected_volume = volume[0:dim_x, int(y_min) : int(y_max), 0:dim_z]
|
||||
X, Y, Z = np.mgrid[
|
||||
0 : selected_volume.shape[0],
|
||||
0 : selected_volume.shape[1],
|
||||
0 : selected_volume.shape[2],
|
||||
]
|
||||
|
||||
fig = go.Figure(
|
||||
data=go.Volume(
|
||||
x=X.flatten(),
|
||||
y=Y.flatten(),
|
||||
z=Z.flatten(),
|
||||
value=selected_volume.flatten(),
|
||||
isomin=iso_value,
|
||||
isomax=selected_volume.max(),
|
||||
opacity=0.1,
|
||||
surface_count=20,
|
||||
colorscale="Jet",
|
||||
)
|
||||
)
|
||||
|
||||
return fig
|
||||
|
||||
# callback pour le plein écran du plot 3D
|
||||
@callback(
|
||||
Output("modal-3dplot", "is_open"),
|
||||
[Input("fullscreen-button-3dplot", "n_clicks")],
|
||||
[dash.dependencies.State("modal-3dplot", "is_open")],
|
||||
)
|
||||
def toggle_fullscreen_3dplot(n1, is_open):
|
||||
if n1:
|
||||
return not is_open
|
||||
return is_open
|
||||
|
||||
# callback pour les paramètres du plot 3D
|
||||
@callback(
|
||||
@ -152,8 +122,6 @@ def get_callbacks():
|
||||
[
|
||||
Output("iso-slider-container", "children"),
|
||||
Output("y-slider-container", "children"),
|
||||
Output("iso-slider-fullscreen-container", "children"),
|
||||
Output("y-slider-fullscreen-container", "children"),
|
||||
],
|
||||
Input("3dplot-settings", "data"),
|
||||
)
|
||||
@ -197,47 +165,8 @@ def get_callbacks():
|
||||
),
|
||||
]
|
||||
)
|
||||
iso_slider_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("Iso value: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.Slider(
|
||||
id="iso-slider-fullscreen",
|
||||
min=0,
|
||||
max=volume.max() / 2,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
0,
|
||||
int(volume.max() / 2) + 1,
|
||||
int((volume.max() / 2) / 20),
|
||||
)
|
||||
},
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
y_slider_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("Y crop: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.RangeSlider(
|
||||
id="y-slider-fullscreen",
|
||||
min=0,
|
||||
max=dim_y,
|
||||
value=[0, dim_y],
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(0, dim_y + 1, max(1, int(dim_y / 20)))
|
||||
},
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
if data is None:
|
||||
return [None, None, None, None]
|
||||
return [None, None]
|
||||
else:
|
||||
if (
|
||||
data["card_settings"] is None
|
||||
@ -246,22 +175,10 @@ def get_callbacks():
|
||||
iso_slider = None
|
||||
if data["card_settings"] is None or "y_slider" not in data["card_settings"]:
|
||||
y_slider = None
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "iso_slider" not in data["fullscreen_settings"]
|
||||
):
|
||||
iso_slider_fullscreen = None
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "y_slider" not in data["fullscreen_settings"]
|
||||
):
|
||||
y_slider_fullscreen = None
|
||||
|
||||
return [
|
||||
iso_slider,
|
||||
y_slider,
|
||||
iso_slider_fullscreen,
|
||||
y_slider_fullscreen,
|
||||
]
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
@ -295,40 +212,19 @@ def get_callbacks():
|
||||
|
||||
return [fig, True]
|
||||
|
||||
# callback pour le A-scan en plein écran
|
||||
@callback(
|
||||
Output("heatmap-ascan-fullscreen", "figure"),
|
||||
[
|
||||
Input("layer-slider-x-ascan-fullscreen", "value"),
|
||||
Input("layer-slider-z-ascan-fullscreen", "value"),
|
||||
Input("crop-slider-fullscreen", "value"),
|
||||
],
|
||||
State("store-settings", "data"),
|
||||
)
|
||||
def update_heatmap_ascan_fullscreen(layer_x, layer_z, crop, settings):
|
||||
y_min, y_max = crop or [0, dim_y]
|
||||
layer_x = layer_x or 0
|
||||
layer_z = layer_z or 0
|
||||
if settings["apply_sampling_everywhere"]:
|
||||
data = volume
|
||||
else:
|
||||
data = pre_volume
|
||||
|
||||
fig = px.line(
|
||||
y=data[layer_x - 1, int(y_min) : int(y_max), layer_z], title="A-scan"
|
||||
)
|
||||
return fig
|
||||
|
||||
# callback pour le plein écran du A-scan
|
||||
@callback(
|
||||
Output("modal-ascan", "is_open"),
|
||||
# callback pour le plein écran du plot 3D
|
||||
clientside_callback(
|
||||
"""
|
||||
function toggle_fullscreen_ascant(n1) {
|
||||
if (n1) {
|
||||
window.open("fullscreen/ascan", "", "width=800,height=600,popup=true");
|
||||
}
|
||||
}
|
||||
""",
|
||||
Output("js", "children", allow_duplicate=True),
|
||||
[Input("fullscreen-button-ascan", "n_clicks")],
|
||||
[dash.dependencies.State("modal-ascan", "is_open")],
|
||||
prevent_initial_call=True,
|
||||
)
|
||||
def toggle_fullscreen_ascan(n1, is_open):
|
||||
if n1:
|
||||
return not is_open
|
||||
return is_open
|
||||
|
||||
# callback pour les paramètres du A-scan
|
||||
@callback(
|
||||
@ -362,9 +258,6 @@ def get_callbacks():
|
||||
@callback(
|
||||
[
|
||||
Output("crop-slider-container", "children"),
|
||||
Output("layer-slider-x-ascan-fullscreen-container", "children"),
|
||||
Output("layer-slider-z-ascan-fullscreen-container", "children"),
|
||||
Output("crop-slider-fullscreen-container", "children"),
|
||||
],
|
||||
Input("ascan-settings", "data"),
|
||||
)
|
||||
@ -390,92 +283,16 @@ def get_callbacks():
|
||||
),
|
||||
]
|
||||
)
|
||||
slider_x_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("Layer X: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.Slider(
|
||||
id="layer-slider-x-ascan-fullscreen",
|
||||
min=0,
|
||||
max=dim_x,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(0, dim_x, max(1, int(dim_x / 50)))
|
||||
},
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
slider_z_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("Layer Z: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.Slider(
|
||||
id="layer-slider-z-ascan-fullscreen",
|
||||
min=1,
|
||||
max=dim_z - 1,
|
||||
value=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(1, dim_z - 1, max(1, int(dim_z / 20)))
|
||||
},
|
||||
step=1,
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
crop_slider_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("Crop: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.RangeSlider(
|
||||
id="crop-slider-fullscreen",
|
||||
min=0,
|
||||
max=dim_y,
|
||||
value=[0, dim_y],
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
0,
|
||||
dim_y + 1,
|
||||
max(1, int(dim_y / 20)),
|
||||
)
|
||||
},
|
||||
step=1,
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
if data is None:
|
||||
return [None, None, None, None]
|
||||
return [None]
|
||||
else:
|
||||
if (
|
||||
data["card_settings"] is None
|
||||
or "crop_slider" not in data["card_settings"]
|
||||
):
|
||||
crop_slider = None
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "layer_slider_x" not in data["fullscreen_settings"]
|
||||
):
|
||||
slider_x_fullscreen = None
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "layer_slider_z" not in data["fullscreen_settings"]
|
||||
):
|
||||
slider_z_fullscreen = None
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "crop_slider" not in data["fullscreen_settings"]
|
||||
):
|
||||
crop_slider_fullscreen = None
|
||||
return [
|
||||
crop_slider,
|
||||
slider_x_fullscreen,
|
||||
slider_z_fullscreen,
|
||||
crop_slider_fullscreen,
|
||||
]
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
@ -512,37 +329,19 @@ def get_callbacks():
|
||||
|
||||
return [fig, layer, True]
|
||||
|
||||
# callback pour les B-scan ZX en plein écran
|
||||
@callback(
|
||||
Output("heatmap-bscan-zx-fullscreen", "figure"),
|
||||
Input("layer-slider-bscan-zx-fullscreen", "value"),
|
||||
State("store-settings", "data"),
|
||||
)
|
||||
def update_heatmap_bscan_zx_fullscreen(layer, settings):
|
||||
if settings["apply_sampling_everywhere"]:
|
||||
data = volume
|
||||
else:
|
||||
data = pre_volume
|
||||
|
||||
fig = px.imshow(
|
||||
data[layer - 1, :, :],
|
||||
color_continuous_scale="Jet",
|
||||
aspect="auto",
|
||||
title="B-scan ZX",
|
||||
)
|
||||
|
||||
return fig
|
||||
|
||||
# callback pour le plein écran du B-scan ZX
|
||||
@callback(
|
||||
Output("modal-bscan-zx", "is_open"),
|
||||
clientside_callback(
|
||||
"""
|
||||
function toggle_fullscreen_bscan_zx(n1) {
|
||||
if (n1) {
|
||||
window.open("fullscreen/bscan-zx", "", "width=800,height=600,popup=true");
|
||||
}
|
||||
}
|
||||
""",
|
||||
Output("js", "children", allow_duplicate=True),
|
||||
[Input("fullscreen-button-bscan-zx", "n_clicks")],
|
||||
[dash.dependencies.State("modal-bscan-zx", "is_open")],
|
||||
prevent_initial_call=True,
|
||||
)
|
||||
def toggle_fullscreen_bscan_zx(n1, is_open):
|
||||
if n1:
|
||||
return not is_open
|
||||
return is_open
|
||||
|
||||
# callback pour les paramètres du B-scan ZX
|
||||
@callback(
|
||||
@ -576,7 +375,6 @@ def get_callbacks():
|
||||
@callback(
|
||||
[
|
||||
Output("layer-slider-bscan-zx-container", "children"),
|
||||
Output("layer-slider-bscan-zx-fullscreen-container", "children"),
|
||||
],
|
||||
Input("bscan-zx-settings", "data"),
|
||||
)
|
||||
@ -599,56 +397,14 @@ def get_callbacks():
|
||||
),
|
||||
]
|
||||
)
|
||||
x_slider_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("X layer: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.Slider(
|
||||
id="layer-slider-bscan-zx-fullscreen",
|
||||
min=0,
|
||||
max=dim_z,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(0, dim_z, max(1, int(dim_z / 50)))
|
||||
},
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
y_slider_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("Y layer: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.Slider(
|
||||
id="layer-slider-bscan-xy-fullscreen",
|
||||
min=0,
|
||||
max=dim_z,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(0, dim_z, max(1, int(dim_z / 50)))
|
||||
},
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
if data is None:
|
||||
return [None, None]
|
||||
return [None]
|
||||
else:
|
||||
if data["card_settings"] is None or "x_slider" not in data["card_settings"]:
|
||||
slider = None
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "layer_slider" not in data["fullscreen_settings"]
|
||||
):
|
||||
slider_fullscreen = None
|
||||
|
||||
return [
|
||||
slider,
|
||||
slider_fullscreen,
|
||||
]
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
@ -682,34 +438,20 @@ def get_callbacks():
|
||||
fig.update_layout(title="B-scan XY")
|
||||
|
||||
return [fig, layer, True]
|
||||
|
||||
# callback pour les B-scan ZX en plein écran
|
||||
@callback(
|
||||
Output("heatmap-bscan-xy-fullscreen", "figure"),
|
||||
Input("layer-slider-bscan-xy-fullscreen", "value"),
|
||||
State("store-settings", "data"),
|
||||
)
|
||||
def update_heatmap_bscan_xy_fullscreen(layer, settings):
|
||||
if settings["apply_sampling_everywhere"]:
|
||||
data = volume
|
||||
else:
|
||||
data = pre_volume
|
||||
|
||||
fig = go.Figure(data=go.Heatmap(z=data[:, :, layer], colorscale="Jet"))
|
||||
fig.update_layout(title="B-scan XY")
|
||||
|
||||
return fig
|
||||
|
||||
|
||||
# callback pour le plein écran du B-scan XY
|
||||
@callback(
|
||||
Output("modal-bscan-xy", "is_open"),
|
||||
clientside_callback(
|
||||
"""
|
||||
function toggle_fullscreen_bscan_xy(n1) {
|
||||
if (n1) {
|
||||
window.open("fullscreen/bscan-xy", "", "width=800,height=600,popup=true");
|
||||
}
|
||||
}
|
||||
""",
|
||||
Output("js", "children", allow_duplicate=True),
|
||||
[Input("fullscreen-button-bscan-xy", "n_clicks")],
|
||||
[dash.dependencies.State("modal-bscan-xy", "is_open")],
|
||||
prevent_initial_call=True,
|
||||
)
|
||||
def toggle_fullscreen_bscan_xy(n1, is_open):
|
||||
if n1:
|
||||
return not is_open
|
||||
return is_open
|
||||
|
||||
@callback(
|
||||
[
|
||||
@ -758,7 +500,6 @@ def get_callbacks():
|
||||
@callback(
|
||||
[
|
||||
Output("layer-slider-bscan-xy-container", "children"),
|
||||
Output("layer-slider-bscan-xy-fullscreen-container", "children"),
|
||||
],
|
||||
Input("bscan-xy-settings", "data"),
|
||||
)
|
||||
@ -781,56 +522,14 @@ def get_callbacks():
|
||||
),
|
||||
]
|
||||
)
|
||||
x_slider_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("X layer: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.Slider(
|
||||
id="layer-slider-bscan-xy-fullscreen",
|
||||
min=0,
|
||||
max=dim_x,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(0, dim_x, max(1, int(dim_x / 50)))
|
||||
},
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
y_slider_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("Y layer: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.Slider(
|
||||
id="layer-slider-bscan-zx-fullscreen",
|
||||
min=0,
|
||||
max=dim_x,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(0, dim_x, max(1, int(dim_x / 50)))
|
||||
},
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
if data is None:
|
||||
return [None, None]
|
||||
return [None]
|
||||
else:
|
||||
if data["card_settings"] is None or "x_slider" not in data["card_settings"]:
|
||||
slider = None
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "layer_slider" not in data["fullscreen_settings"]
|
||||
):
|
||||
slider_fullscreen = None
|
||||
|
||||
return [
|
||||
slider,
|
||||
slider_fullscreen,
|
||||
]
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
@ -1107,9 +806,9 @@ def get_callbacks():
|
||||
|
||||
# Mettre à jour les graphiques
|
||||
update_3dplot(0, [0, dim_y // 2], settings, False)
|
||||
update_heatmap_ascan(0, 0, False, settings)
|
||||
update_heatmap_bscan_zx(0, False, settings)
|
||||
update_heatmap_bscan_xy(0, False, settings)
|
||||
update_heatmap_ascan(0, 0, False, settings) # type: ignore
|
||||
update_heatmap_bscan_zx(0, False, settings) # type: ignore
|
||||
update_heatmap_bscan_xy(0, False, settings) # type: ignore
|
||||
|
||||
return None
|
||||
|
||||
|
@ -4,6 +4,7 @@ from os import listdir
|
||||
from os.path import isfile, join
|
||||
import dash_bootstrap_components as dbc
|
||||
|
||||
|
||||
def get_callbacks():
|
||||
# callback pour le modal
|
||||
@callback(
|
||||
@ -16,7 +17,6 @@ def get_callbacks():
|
||||
return not is_open
|
||||
return is_open
|
||||
|
||||
|
||||
@callback(
|
||||
Output("settings-modal", "is_open"),
|
||||
[Input("settings-open", "n_clicks"), Input("settings-close", "n_clicks")],
|
||||
@ -27,7 +27,6 @@ def get_callbacks():
|
||||
return not is_open
|
||||
return is_open
|
||||
|
||||
|
||||
# callback pour le navmenu
|
||||
@callback(
|
||||
Output("offcanvas-menu", "is_open"),
|
||||
@ -39,10 +38,13 @@ def get_callbacks():
|
||||
return not is_open
|
||||
return is_open
|
||||
|
||||
|
||||
@callback(
|
||||
Output("open-modal", "is_open"),
|
||||
[Input("open-button", "n_clicks"), Input("open-close", "n_clicks"), Input("open-refresh", "n_clicks")],
|
||||
[
|
||||
Input("open-button", "n_clicks"),
|
||||
Input("open-close", "n_clicks"),
|
||||
Input("open-refresh", "n_clicks"),
|
||||
],
|
||||
[dash.dependencies.State("open-modal", "is_open")],
|
||||
)
|
||||
def toggle_open(n1, n2, n3, is_open):
|
||||
@ -52,7 +54,6 @@ def get_callbacks():
|
||||
return True
|
||||
return is_open
|
||||
|
||||
|
||||
@callback(
|
||||
Output("save-modal", "is_open"),
|
||||
[
|
||||
@ -67,7 +68,6 @@ def get_callbacks():
|
||||
return not is_open
|
||||
return is_open
|
||||
|
||||
|
||||
@callback(
|
||||
Output("file-list", "children"),
|
||||
[Input("open-refresh", "n_clicks")],
|
||||
@ -85,7 +85,6 @@ def get_callbacks():
|
||||
if isfile(join("Dataset/saves", file))
|
||||
]
|
||||
|
||||
|
||||
@callback(
|
||||
[
|
||||
Output("open-modal", "is_open", allow_duplicate=True),
|
||||
@ -105,7 +104,6 @@ def get_callbacks():
|
||||
filename = filenames[file_index["index"]]
|
||||
return [False, filename, f"Opened file: {filename}"]
|
||||
|
||||
|
||||
@callback(
|
||||
Output("save-format", "options"),
|
||||
[Input("store-filters", "data")],
|
||||
@ -121,3 +119,11 @@ def get_callbacks():
|
||||
{"label": "Save filtered dataset", "value": "filt", "disabled": True},
|
||||
]
|
||||
|
||||
@callback(
|
||||
Output("navbar", "style"),
|
||||
Input("loc", "pathname"),
|
||||
)
|
||||
def hide_navbar(pathname):
|
||||
if not str.startswith(pathname, "/fullscreen"):
|
||||
return {"display": "block"}
|
||||
return {"display": "none"}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import dash
|
||||
from dash import dcc, html, ALL, DiskcacheManager
|
||||
import dash_bootstrap_components as dbc
|
||||
from os import listdir, mkdir, path
|
||||
from os import listdir, mkdir
|
||||
from os.path import isfile, join
|
||||
import diskcache
|
||||
from json import load
|
||||
@ -69,7 +69,7 @@ modal_overlay = dbc.Modal(
|
||||
|
||||
modal_settings = dbc.Modal(
|
||||
[
|
||||
dbc.ModalHeader("Settings"),
|
||||
dbc.ModalHeader(dbc.ModalTitle("Settings")),
|
||||
dbc.ModalBody(
|
||||
[
|
||||
dbc.Switch(
|
||||
@ -146,7 +146,7 @@ modal_settings = dbc.Modal(
|
||||
|
||||
modal_open = dbc.Modal(
|
||||
[
|
||||
dbc.ModalHeader("Open a file"),
|
||||
dbc.ModalHeader(dbc.ModalTitle("Open a file")),
|
||||
dbc.ModalBody(
|
||||
[
|
||||
dbc.ListGroup(
|
||||
@ -177,7 +177,7 @@ modal_open = dbc.Modal(
|
||||
|
||||
modal_save = dbc.Modal(
|
||||
[
|
||||
dbc.ModalHeader("Save a file"),
|
||||
dbc.ModalHeader(dbc.ModalTitle("Save a file")),
|
||||
dbc.ModalBody(
|
||||
[
|
||||
dbc.Input(id="save-input", placeholder="Filename"),
|
||||
@ -383,6 +383,8 @@ nav_bar = dbc.Navbar(
|
||||
style={"--bs-gutter-x": "0"},
|
||||
),
|
||||
dark=True,
|
||||
style={"display": "none"},
|
||||
id="navbar",
|
||||
)
|
||||
|
||||
# on défini le layout de l'application
|
||||
@ -408,8 +410,10 @@ app.layout = dbc.Container(
|
||||
dcc.Store(id="3dplot-settings"),
|
||||
dcc.Store(id="bscan-zx-settings"),
|
||||
dcc.Store(id="bscan-xy-settings"),
|
||||
html.Div(id="js", hidden=True),
|
||||
],
|
||||
id="app-container",
|
||||
style={"paddingLeft": "0 !important", "paddingRight": "0 !important"},
|
||||
fluid=True,
|
||||
)
|
||||
|
||||
@ -418,5 +422,5 @@ get_callbacks()
|
||||
# on lance l'application
|
||||
if __name__ == "__main__":
|
||||
app.run(
|
||||
debug=config["debug"] or False, port=config["port"] or "8051", threaded=True
|
||||
debug=config["debug"] or False, dev_tools_ui=config['debug'] or False, port=config["port"] or "8051", threaded=True
|
||||
)
|
||||
|
194
3D_app/pages/fullscreen/3dplot.py
Normal file
194
3D_app/pages/fullscreen/3dplot.py
Normal file
@ -0,0 +1,194 @@
|
||||
from dash import html, dcc, callback, Output, Input, clientside_callback
|
||||
import dash_bootstrap_components as dbc
|
||||
import numpy as np
|
||||
import plotly.graph_objects as go
|
||||
import plotly.io as pio
|
||||
import dash
|
||||
from callbacks.home import pre_volume, volume, dim_x, dim_y, dim_z, X, Y, Z
|
||||
|
||||
dash.register_page(
|
||||
__name__,
|
||||
path="/fullscreen/3dplot",
|
||||
title="3D Plot",
|
||||
)
|
||||
|
||||
# on défini le thème de l'application
|
||||
pio.templates.default = "plotly_dark"
|
||||
|
||||
# on crée le plot 3D
|
||||
fig = go.Figure(
|
||||
data=go.Volume(
|
||||
x=X.flatten(),
|
||||
y=Y.flatten(),
|
||||
z=Z.flatten(),
|
||||
value=volume.flatten(),
|
||||
isomin=5000,
|
||||
isomax=volume.max(),
|
||||
opacity=0.1, # needs to be small to see through all surfaces
|
||||
surface_count=20, # needs to be a large number for good volume rendering
|
||||
colorscale="Jet",
|
||||
)
|
||||
)
|
||||
|
||||
# on défini les configurations des plots
|
||||
config3DPlot = {
|
||||
"toImageButtonOptions": {
|
||||
"format": "svg", # one of png, svg, jpeg, webp
|
||||
"filename": "3D-Plot",
|
||||
"height": 1000,
|
||||
"width": 1400,
|
||||
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
|
||||
},
|
||||
"displaylogo": False,
|
||||
}
|
||||
|
||||
layout = html.Div(
|
||||
[
|
||||
html.Div(id="3dplot-js", hidden=True),
|
||||
dbc.Spinner(id="loading-3dplot", color="primary", fullscreen=True, fullscreen_style={"backgroundColor": "var(--bs-body-bg)"}),
|
||||
dcc.Graph(
|
||||
id="3dplot-fullscreen",
|
||||
figure=fig,
|
||||
config=config3DPlot,
|
||||
style={"marginBottom": "15px", "height": "85vh"},
|
||||
), # 'fig' is your 3D plotly figure
|
||||
html.Div(
|
||||
dcc.Slider(
|
||||
id="iso-slider-fullscreen",
|
||||
min=volume.min(),
|
||||
max=volume.max() / 2,
|
||||
value=volume.min(),
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
int(volume.min()),
|
||||
int(volume.max() / 2) + 1,
|
||||
int((volume.max() / 2 - volume.min()) / 20),
|
||||
)
|
||||
},
|
||||
step=1,
|
||||
),
|
||||
id="iso-slider-fullscreen-container",
|
||||
),
|
||||
html.Div(
|
||||
dcc.RangeSlider(
|
||||
id="y-slider-fullscreen",
|
||||
min=0,
|
||||
max=dim_y,
|
||||
value=[0, dim_y / 2],
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
0,
|
||||
int(dim_y) + 1,
|
||||
max(1, int(dim_y / 50)),
|
||||
)
|
||||
},
|
||||
step=1,
|
||||
),
|
||||
id="y-slider-fullscreen-container",
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# callback pour le plot 3D en plein écran
|
||||
@callback(
|
||||
[Output("3dplot-fullscreen", "figure"), Output("loading-3dplot", "children")],
|
||||
[
|
||||
Input("iso-slider-fullscreen", "value"),
|
||||
Input("y-slider-fullscreen", "value"),
|
||||
],
|
||||
)
|
||||
def update_3dplot_fullscreen(iso_value, y_values):
|
||||
y_min, y_max = y_values
|
||||
selected_volume = volume[0:dim_x, int(y_min) : int(y_max), 0:dim_z]
|
||||
X, Y, Z = np.mgrid[
|
||||
0 : selected_volume.shape[0],
|
||||
0 : selected_volume.shape[1],
|
||||
0 : selected_volume.shape[2],
|
||||
]
|
||||
|
||||
fig = go.Figure(
|
||||
data=go.Volume(
|
||||
x=X.flatten(),
|
||||
y=Y.flatten(),
|
||||
z=Z.flatten(),
|
||||
value=selected_volume.flatten(),
|
||||
isomin=iso_value,
|
||||
isomax=selected_volume.max(),
|
||||
opacity=0.1,
|
||||
surface_count=20,
|
||||
colorscale="Jet",
|
||||
)
|
||||
)
|
||||
|
||||
return [fig, html.Div()]
|
||||
|
||||
|
||||
@callback(
|
||||
[
|
||||
Output("iso-slider-fullscreen-container", "children"),
|
||||
Output("y-slider-fullscreen-container", "children"),
|
||||
],
|
||||
Input("3dplot-settings", "data"),
|
||||
)
|
||||
def update_3dplot_sliders(data):
|
||||
print(data)
|
||||
iso_slider = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("Iso value: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.Slider(
|
||||
id="iso-slider-fullscreen",
|
||||
min=0,
|
||||
max=volume.max() / 2,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
0,
|
||||
int(volume.max() / 2) + 1,
|
||||
int((volume.max() / 2) / 20),
|
||||
)
|
||||
},
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
y_slider = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("Y crop: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.RangeSlider(
|
||||
id="y-slider-fullscreen",
|
||||
min=0,
|
||||
max=dim_y,
|
||||
value=[0, dim_y],
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(0, dim_y + 1, max(1, int(dim_y / 20)))
|
||||
},
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
if data is None:
|
||||
return [None, None]
|
||||
else:
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "iso_slider" not in data["fullscreen_settings"]
|
||||
):
|
||||
iso_slider = None
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "y_slider" not in data["fullscreen_settings"]
|
||||
):
|
||||
y_slider = None
|
||||
|
||||
return [
|
||||
iso_slider,
|
||||
y_slider,
|
||||
]
|
199
3D_app/pages/fullscreen/ascan.py
Normal file
199
3D_app/pages/fullscreen/ascan.py
Normal file
@ -0,0 +1,199 @@
|
||||
import dash
|
||||
from dash import dcc, html, Input, Output, State, callback
|
||||
import dash_bootstrap_components as dbc
|
||||
import plotly.express as px
|
||||
from callbacks.home import pre_volume, volume, dim_x, dim_y, dim_z, X, Y, Z
|
||||
|
||||
dash.register_page(__name__, path="/fullscreen/ascan", title="A-Scan")
|
||||
|
||||
configAScan = {
|
||||
"toImageButtonOptions": {
|
||||
"format": "svg", # one of png, svg, jpeg, webp
|
||||
"filename": "A-Scan",
|
||||
"height": 1000,
|
||||
"width": 1400,
|
||||
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
|
||||
},
|
||||
"displaylogo": False,
|
||||
}
|
||||
|
||||
layout = html.Div(
|
||||
[
|
||||
dbc.Spinner(
|
||||
id="loading-ascan",
|
||||
color="primary",
|
||||
fullscreen=True,
|
||||
fullscreen_style={"backgroundColor": "var(--bs-body-bg)"},
|
||||
),
|
||||
dcc.Graph(
|
||||
id="heatmap-ascan-fullscreen",
|
||||
config=configAScan,
|
||||
style={"marginBottom": "15px", "height": "85vh"},
|
||||
), # 'fig' is your 2D plotly figure
|
||||
html.Div(
|
||||
dcc.Slider(
|
||||
id="layer-slider-x-ascan-fullscreen",
|
||||
min=0,
|
||||
max=dim_x,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
0,
|
||||
dim_x,
|
||||
max(1, int(dim_x / 50)),
|
||||
)
|
||||
},
|
||||
),
|
||||
id="layer-slider-x-ascan-fullscreen-container",
|
||||
),
|
||||
html.Div(
|
||||
dcc.Slider(
|
||||
id="layer-slider-z-ascan-fullscreen",
|
||||
min=1,
|
||||
max=dim_z,
|
||||
value=1,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
1,
|
||||
dim_z,
|
||||
max(1, int(dim_z / 20)),
|
||||
)
|
||||
},
|
||||
),
|
||||
id="layer-slider-z-ascan-fullscreen-container",
|
||||
),
|
||||
html.Div(
|
||||
dcc.RangeSlider(
|
||||
id="crop-slider-fullscreen",
|
||||
min=0,
|
||||
max=dim_y,
|
||||
value=[0, dim_y],
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
0,
|
||||
dim_y + 1,
|
||||
max(1, int(dim_y / 20)),
|
||||
)
|
||||
},
|
||||
step=1,
|
||||
),
|
||||
id="crop-slider-fullscreen-container",
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# callback pour le A-scan en plein écran
|
||||
@callback(
|
||||
[Output("heatmap-ascan-fullscreen", "figure"), Output("loading-ascan", "children")],
|
||||
[
|
||||
Input("layer-slider-x-ascan-fullscreen", "value"),
|
||||
Input("layer-slider-z-ascan-fullscreen", "value"),
|
||||
Input("crop-slider-fullscreen", "value"),
|
||||
],
|
||||
State("store-settings", "data"),
|
||||
)
|
||||
def update_heatmap_ascan_fullscreen(layer_x, layer_z, crop, settings):
|
||||
y_min, y_max = crop or [0, dim_y]
|
||||
layer_x = layer_x or 0
|
||||
layer_z = layer_z or 0
|
||||
if settings["apply_sampling_everywhere"]:
|
||||
data = volume
|
||||
else:
|
||||
data = pre_volume
|
||||
|
||||
fig = px.line(y=data[layer_x - 1, int(y_min) : int(y_max), layer_z], title="A-scan")
|
||||
|
||||
return [fig, html.Div()]
|
||||
|
||||
|
||||
@callback(
|
||||
[
|
||||
Output("layer-slider-x-ascan-fullscreen-container", "children"),
|
||||
Output("layer-slider-z-ascan-fullscreen-container", "children"),
|
||||
Output("crop-slider-fullscreen-container", "children"),
|
||||
],
|
||||
Input("ascan-settings", "data"),
|
||||
)
|
||||
def update_sliders(data):
|
||||
slider_x_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("Layer X: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.Slider(
|
||||
id="layer-slider-x-ascan-fullscreen",
|
||||
min=0,
|
||||
max=dim_x,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i) for i in range(0, dim_x, max(1, int(dim_x / 50)))
|
||||
},
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
slider_z_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("Layer Z: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.Slider(
|
||||
id="layer-slider-z-ascan-fullscreen",
|
||||
min=1,
|
||||
max=dim_z - 1,
|
||||
value=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(1, dim_z - 1, max(1, int(dim_z / 20)))
|
||||
},
|
||||
step=1,
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
crop_slider_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("Crop: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.RangeSlider(
|
||||
id="crop-slider-fullscreen",
|
||||
min=0,
|
||||
max=dim_y,
|
||||
value=[0, dim_y],
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
0,
|
||||
dim_y + 1,
|
||||
max(1, int(dim_y / 20)),
|
||||
)
|
||||
},
|
||||
step=1,
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
if data is None:
|
||||
return [None, None, None]
|
||||
else:
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "layer_slider_x" not in data["fullscreen_settings"]
|
||||
):
|
||||
slider_x_fullscreen = None
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "layer_slider_z" not in data["fullscreen_settings"]
|
||||
):
|
||||
slider_z_fullscreen = None
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "crop_slider" not in data["fullscreen_settings"]
|
||||
):
|
||||
crop_slider_fullscreen = None
|
||||
return [slider_x_fullscreen, slider_z_fullscreen, crop_slider_fullscreen]
|
104
3D_app/pages/fullscreen/bscan-xy.py
Normal file
104
3D_app/pages/fullscreen/bscan-xy.py
Normal file
@ -0,0 +1,104 @@
|
||||
import re
|
||||
import dash
|
||||
from dash import html, dcc, Input, Output, State, callback
|
||||
import plotly.graph_objects as go
|
||||
import dash_bootstrap_components as dbc
|
||||
from callbacks.home import pre_volume, volume, dim_x, dim_y, dim_z, X, Y, Z
|
||||
|
||||
dash.register_page(__name__, path="/fullscreen/bscan-xy", title="B-Scan XY")
|
||||
|
||||
configBScanXY = {
|
||||
"toImageButtonOptions": {
|
||||
"format": "svg", # one of png, svg, jpeg, webp
|
||||
"filename": "B-Scan XY",
|
||||
"height": 1000,
|
||||
"width": 1400,
|
||||
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
|
||||
},
|
||||
"displaylogo": False,
|
||||
}
|
||||
|
||||
layout = html.Div(
|
||||
[
|
||||
dbc.Spinner(
|
||||
id="loading-bscan-xy",
|
||||
color="primary",
|
||||
fullscreen=True,
|
||||
fullscreen_style={"backgroundColor": "var(--bs-body-bg)"},
|
||||
),
|
||||
dcc.Graph(
|
||||
id="heatmap-bscan-xy-fullscreen",
|
||||
config=configBScanXY,
|
||||
style={"marginBottom": "15px", "height": "85vh"},
|
||||
), # 'fig' is your 2D plotly figure
|
||||
html.Div(
|
||||
dcc.Slider(
|
||||
id="layer-slider-bscan-xy-fullscreen",
|
||||
min=1,
|
||||
max=dim_z - 1,
|
||||
value=1,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
1,
|
||||
dim_z + 1,
|
||||
max(1, int(dim_z / 50)),
|
||||
)
|
||||
},
|
||||
),
|
||||
id="layer-slider-bscan-xy-fullscreen-container",
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# callback pour les B-scan ZX en plein écran
|
||||
@callback(
|
||||
[Output("heatmap-bscan-xy-fullscreen", "figure"), Output("loading-bscan-xy", "children")],
|
||||
Input("layer-slider-bscan-xy-fullscreen", "value"),
|
||||
State("store-settings", "data"),
|
||||
)
|
||||
def update_heatmap_bscan_xy_fullscreen(layer, settings):
|
||||
if settings["apply_sampling_everywhere"]:
|
||||
data = volume
|
||||
else:
|
||||
data = pre_volume
|
||||
|
||||
fig = go.Figure(data=go.Heatmap(z=data[:, :, layer], colorscale="Jet"))
|
||||
fig.update_layout(title="B-scan XY")
|
||||
|
||||
return [fig, html.Div()]
|
||||
|
||||
|
||||
@callback(
|
||||
Output("layer-slider-bscan-xy-fullscreen-container", "children"),
|
||||
Input("bscan-xy-settings", "data"),
|
||||
)
|
||||
def update_sliders(data):
|
||||
slider_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("X layer: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.Slider(
|
||||
id="layer-slider-bscan-xy-fullscreen",
|
||||
min=0,
|
||||
max=dim_x,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i) for i in range(0, dim_x, max(1, int(dim_x / 50)))
|
||||
},
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
if data is None:
|
||||
return [None]
|
||||
else:
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "layer_slider" not in data["fullscreen_settings"]
|
||||
):
|
||||
slider_fullscreen = None
|
||||
return [slider_fullscreen]
|
107
3D_app/pages/fullscreen/bscan-zx.py
Normal file
107
3D_app/pages/fullscreen/bscan-zx.py
Normal file
@ -0,0 +1,107 @@
|
||||
import dash
|
||||
from dash import html, dcc, Input, Output, State, callback
|
||||
import plotly.express as px
|
||||
import dash_bootstrap_components as dbc
|
||||
from callbacks.home import pre_volume, volume, dim_x, dim_y, dim_z, X, Y, Z
|
||||
|
||||
dash.register_page(__name__, path="/fullscreen/bscan-zx", title="B-Scan ZX")
|
||||
|
||||
configBScanXY = {
|
||||
"toImageButtonOptions": {
|
||||
"format": "svg", # one of png, svg, jpeg, webp
|
||||
"filename": "B-Scan ZX",
|
||||
"height": 1000,
|
||||
"width": 1400,
|
||||
"scale": 1, # Multiply title/legend/axis/canvas sizes by this factor
|
||||
},
|
||||
"displaylogo": False,
|
||||
}
|
||||
|
||||
layout = html.Div(
|
||||
[
|
||||
dbc.Spinner(
|
||||
id="loading-bscan-zx",
|
||||
color="primary",
|
||||
fullscreen=True,
|
||||
fullscreen_style={"backgroundColor": "var(--bs-body-bg)"},
|
||||
),
|
||||
dcc.Graph(
|
||||
id="heatmap-bscan-zx-fullscreen",
|
||||
config=configBScanXY,
|
||||
style={"marginBottom": "15px", "height": "85vh"},
|
||||
), # 'fig' is your 2D plotly figure
|
||||
html.Div(
|
||||
dcc.Slider(
|
||||
id="layer-slider-bscan-zx-fullscreen",
|
||||
min=0,
|
||||
max=dim_x,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
0,
|
||||
dim_x + 1,
|
||||
max(1, int(dim_x / 50)),
|
||||
)
|
||||
},
|
||||
),
|
||||
id="layer-slider-bscan-zx-fullscreen-container",
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# callback pour les B-scan ZX en plein écran
|
||||
@callback(
|
||||
[Output("heatmap-bscan-zx-fullscreen", "figure"), Output("loading-bscan-zx", "children")],
|
||||
Input("layer-slider-bscan-zx-fullscreen", "value"),
|
||||
State("store-settings", "data"),
|
||||
)
|
||||
def update_heatmap_bscan_zx_fullscreen(layer, settings):
|
||||
if settings["apply_sampling_everywhere"]:
|
||||
data = volume
|
||||
else:
|
||||
data = pre_volume
|
||||
|
||||
fig = px.imshow(
|
||||
data[layer - 1, :, :],
|
||||
color_continuous_scale="Jet",
|
||||
aspect="auto",
|
||||
title="B-scan ZX",
|
||||
)
|
||||
|
||||
return [fig, html.Div()]
|
||||
|
||||
@callback(
|
||||
Output("layer-slider-bscan-zx-fullscreen-container", "children"),
|
||||
Input("bscan-zx-settings", "data"),
|
||||
)
|
||||
def update_sliders(data):
|
||||
slider_fullscreen = dbc.Row(
|
||||
[
|
||||
dbc.Col(html.Span("X layer: "), width="auto"),
|
||||
dbc.Col(
|
||||
dcc.Slider(
|
||||
id="layer-slider-bscan-zx-fullscreen",
|
||||
min=0,
|
||||
max=dim_x,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(0, dim_x, max(1, int(dim_x / 50)))
|
||||
},
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
if data is None:
|
||||
return None
|
||||
else:
|
||||
if (
|
||||
data["fullscreen_settings"] is None
|
||||
or "layer_slider" not in data["fullscreen_settings"]
|
||||
):
|
||||
slider_fullscreen = None
|
||||
return slider_fullscreen
|
@ -1,5 +1,5 @@
|
||||
import dash
|
||||
from dash import html, dcc, DiskcacheManager
|
||||
from dash import html, dcc, DiskcacheManager, get_asset_url
|
||||
import dash_bootstrap_components as dbc
|
||||
import plotly.graph_objects as go
|
||||
import numpy as np
|
||||
@ -178,66 +178,7 @@ mesh_card = dbc.Fade(
|
||||
),
|
||||
dbc.Modal(
|
||||
[
|
||||
dbc.ModalHeader(dbc.ModalTitle("3D Plot")),
|
||||
dbc.ModalBody(
|
||||
[
|
||||
dcc.Graph(
|
||||
id="3dplot-fullscreen",
|
||||
figure=fig,
|
||||
config=config3DPlot,
|
||||
style={"marginBottom": "15px", "height": "90%"},
|
||||
), # 'fig' is your 3D plotly figure
|
||||
html.Div(
|
||||
dcc.Slider(
|
||||
id="iso-slider-fullscreen",
|
||||
min=volume.min(),
|
||||
max=volume.max() / 2,
|
||||
value=volume.min(),
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
int(volume.min()),
|
||||
int(volume.max() / 2) + 1,
|
||||
int(
|
||||
(
|
||||
volume.max() / 2
|
||||
- volume.min()
|
||||
)
|
||||
/ 20
|
||||
),
|
||||
)
|
||||
},
|
||||
step=1,
|
||||
),
|
||||
id="iso-slider-fullscreen-container",
|
||||
),
|
||||
html.Div(
|
||||
dcc.RangeSlider(
|
||||
id="y-slider-fullscreen",
|
||||
min=0,
|
||||
max=dim_y,
|
||||
value=[0, dim_y / 2],
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
0,
|
||||
int(dim_y) + 1,
|
||||
max(1, int(dim_y / 50)),
|
||||
)
|
||||
},
|
||||
step=1,
|
||||
),
|
||||
id="y-slider-fullscreen-container",
|
||||
),
|
||||
]
|
||||
),
|
||||
],
|
||||
id="modal-3dplot",
|
||||
fullscreen=True,
|
||||
),
|
||||
dbc.Modal(
|
||||
[
|
||||
dbc.ModalHeader(dbc.ModalTitle("3D plot settings")),
|
||||
dbc.ModalHeader([html.Img(src=get_asset_url("settings.png"), height="32px", style={"marginRight": "5px"}), dbc.ModalTitle("3D plot settings")]),
|
||||
dbc.ModalBody(
|
||||
[
|
||||
html.Span("Card display: "),
|
||||
@ -352,77 +293,7 @@ Ascan_card = dbc.Fade(
|
||||
),
|
||||
dbc.Modal(
|
||||
[
|
||||
dbc.ModalHeader(dbc.ModalTitle("A-Scan")),
|
||||
dbc.ModalBody(
|
||||
[
|
||||
dcc.Graph(
|
||||
id="heatmap-ascan-fullscreen",
|
||||
config=configAScan,
|
||||
style={"marginBottom": "15px"},
|
||||
), # 'fig' is your 2D plotly figure
|
||||
html.Div(
|
||||
dcc.Slider(
|
||||
id="layer-slider-x-ascan-fullscreen",
|
||||
min=0,
|
||||
max=dim_x,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
0,
|
||||
dim_x,
|
||||
max(1, int(dim_x / 50)),
|
||||
)
|
||||
},
|
||||
),
|
||||
id="layer-slider-x-ascan-fullscreen-container",
|
||||
),
|
||||
html.Div(
|
||||
dcc.Slider(
|
||||
id="layer-slider-z-ascan-fullscreen",
|
||||
min=1,
|
||||
max=dim_z,
|
||||
value=1,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
1,
|
||||
dim_z,
|
||||
max(1, int(dim_z / 20)),
|
||||
)
|
||||
},
|
||||
),
|
||||
id="layer-slider-z-ascan-fullscreen-container",
|
||||
),
|
||||
html.Div(
|
||||
dcc.RangeSlider(
|
||||
id="crop-slider-fullscreen",
|
||||
min=0,
|
||||
max=dim_y,
|
||||
value=[0, dim_y],
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
0,
|
||||
dim_y + 1,
|
||||
max(1, int(dim_y / 20)),
|
||||
)
|
||||
},
|
||||
step=1,
|
||||
),
|
||||
id="crop-slider-fullscreen-container",
|
||||
),
|
||||
]
|
||||
),
|
||||
],
|
||||
id="modal-ascan",
|
||||
fullscreen=True,
|
||||
),
|
||||
dbc.Modal(
|
||||
[
|
||||
dbc.ModalHeader(dbc.ModalTitle("A-Scan settings")),
|
||||
dbc.ModalHeader([html.Img(src=get_asset_url("settings.png"), height="32px", style={"marginRight": "5px"}), dbc.ModalTitle("A-Scan settings")]),
|
||||
dbc.ModalBody(
|
||||
[
|
||||
html.Span("Card display: "),
|
||||
@ -537,41 +408,7 @@ Bscan_card_xy = dbc.Fade(
|
||||
),
|
||||
dbc.Modal(
|
||||
[
|
||||
dbc.ModalHeader(dbc.ModalTitle("B-Scan ZX")),
|
||||
dbc.ModalBody(
|
||||
[
|
||||
dcc.Graph(
|
||||
id="heatmap-bscan-zx-fullscreen",
|
||||
config=configBScanXY,
|
||||
style={"marginBottom": "15px", "height": "90%"},
|
||||
), # 'fig' is your 2D plotly figure
|
||||
html.Div(
|
||||
dcc.Slider(
|
||||
id="layer-slider-bscan-zx-fullscreen",
|
||||
min=0,
|
||||
max=dim_x,
|
||||
value=0,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
0,
|
||||
dim_x + 1,
|
||||
max(1, int(dim_x / 50)),
|
||||
)
|
||||
},
|
||||
),
|
||||
id="layer-slider-bscan-zx-fullscreen-container",
|
||||
),
|
||||
]
|
||||
),
|
||||
],
|
||||
id="modal-bscan-zx",
|
||||
fullscreen=True,
|
||||
),
|
||||
dbc.Modal(
|
||||
[
|
||||
dbc.ModalHeader(dbc.ModalTitle("B-Scan ZX settings")),
|
||||
dbc.ModalHeader([html.Img(src=get_asset_url("settings.png"), height="32px", style={"marginRight": "5px"}), dbc.ModalTitle("B-Scan ZX settings")]),
|
||||
dbc.ModalBody(
|
||||
[
|
||||
html.Span("Card display: "),
|
||||
@ -689,41 +526,7 @@ Bscan_card_zx = dbc.Fade(
|
||||
),
|
||||
dbc.Modal(
|
||||
[
|
||||
dbc.ModalHeader(dbc.ModalTitle("B-Scan XY")),
|
||||
dbc.ModalBody(
|
||||
[
|
||||
dcc.Graph(
|
||||
id="heatmap-bscan-xy-fullscreen",
|
||||
config=configBScanXY,
|
||||
style={"marginBottom": "15px", "height": "90%"},
|
||||
), # 'fig' is your 2D plotly figure
|
||||
html.Div(
|
||||
dcc.Slider(
|
||||
id="layer-slider-bscan-xy-fullscreen",
|
||||
min=1,
|
||||
max=dim_z - 1,
|
||||
value=1,
|
||||
step=1,
|
||||
marks={
|
||||
str(i): str(i)
|
||||
for i in range(
|
||||
1,
|
||||
dim_z + 1,
|
||||
max(1, int(dim_z / 50)),
|
||||
)
|
||||
},
|
||||
),
|
||||
id="layer-slider-bscan-xy-fullscreen-container",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
id="modal-bscan-xy",
|
||||
fullscreen=True,
|
||||
),
|
||||
dbc.Modal(
|
||||
[
|
||||
dbc.ModalHeader(dbc.ModalTitle("B-Scan XY settings")),
|
||||
dbc.ModalHeader([html.Img(src=get_asset_url("settings.png"), height="32px", style={"marginRight": "5px"}), dbc.ModalTitle("B-Scan XY settings")]),
|
||||
dbc.ModalBody(
|
||||
[
|
||||
html.Span("Card display: "),
|
||||
|
@ -1,5 +1,6 @@
|
||||
dash==2.17.0
|
||||
dash_bootstrap_components==1.6.0
|
||||
dash_extensions==1.0.16
|
||||
diskcache==5.6.3
|
||||
matplotlib==3.8.4
|
||||
numpy==2.0.0
|
||||
@ -7,5 +8,5 @@ pandas==2.2.2
|
||||
plotly==5.22.0
|
||||
progress==1.6
|
||||
python_igraph==0.11.5
|
||||
scipy==1.13.1
|
||||
scipy==1.14.0
|
||||
tqdm==4.66.4
|
||||
|
Reference in New Issue
Block a user