added better margins for image views, implemented upload of optical image and transparency slider

This commit is contained in:
Pixelguy14 2025-02-03 22:53:08 -06:00
parent 09d680db87
commit fe6508ead8
4 changed files with 201 additions and 56 deletions

160
app.jl
View File

@ -13,6 +13,7 @@ using Images
using LinearAlgebra
using NativeFileDialog # Opens the file explorer depending on the OS
using StipplePlotly
using Base64
include("./julia_imzML_visual.jl")
@genietools
@ -76,7 +77,8 @@ function loadImgPlot(interfaceImg::String)
),
yaxis=PlotlyBase.attr(
visible=false
)
),
margin=attr(l=0,r=0,t=0,b=0,pad=0)
)
# Create the trace for the image
@ -109,6 +111,69 @@ function loadImgPlot(interfaceImg::String)
plotlayout=layout
return plotdata, plotlayout, width, height
end
function loadImgPlot(interfaceImg::String, overlayImg::String, imgTrans::Float64)
timestamp=string(time_ns())
# Load the main image
cleaned_img = replace(interfaceImg, r"\?.*" => "")
cleaned_img = lstrip(cleaned_img, '/')
var = joinpath("./public", cleaned_img)
img = load(var)
# Convert to grayscale
img_gray = Gray.(img)
img_array = Array(img_gray)
elevation = Float32.(Array(img_array)) ./ 255.0
# Get the X, Y coordinates of the image
height, width = size(img_array)
#println("height: $(-height), width: $(width)")
X = collect(1:width)
Y = collect(1:height)
#println("height: $(X), width: $(-Y)")
# Create the layout with overlay image
layoutImg = PlotlyBase.Layout(
images = [attr(
#source = "data:image/png;base64,$overlayImg",
#source = "https://images.plot.ly/language-icons/api-home/python-logo.png",
source = "$(overlayImg)?t=$(timestamp)",
xref = "x",
yref = "y",
x = 0,
y = 0,
sizex = width,
sizey = -height,
sizing = "stretch",
opacity = imgTrans,
layer = "above" # Place the overlay image in the foreground
)],
xaxis = PlotlyBase.attr(
visible = false,
scaleanchor = "y",
range = [1, width]
),
yaxis = PlotlyBase.attr(
visible = false,
range = [-height,-1]
),
margin = attr(l = 0, r = 0, t = 0, b = 0, pad = 0)
)
# Create the trace for the main image
trace = PlotlyBase.heatmap(
z = elevation,
x = X,
y = -Y,
name = "",
showlegend = false,
colorscale = "Viridis",
showscale = false
)
plotdata = [trace]
plotlayout = layoutImg
return plotdata, plotlayout, width, height
end
# loadContourPlot recieves the local directory of the image as a string,
# returns the layout and data for the contour plotly plot
# this function loads the image and applies a gaussian filter
@ -144,6 +209,7 @@ function loadContourPlot(interfaceImg::String)
yaxis=PlotlyBase.attr(
title="Y"
),
margin=attr(l=0,r=0,t=120,b=0,pad=0)
)
trace=PlotlyBase.contour(
z=elevation_smoothed,
@ -203,7 +269,8 @@ function loadSurfacePlot(interfaceImg::String)
zaxis_nticks=z_nticks,
camera=attr(eye=attr(x=0, y=-1, z=0.5)),
aspectratio=aspect_ratio
)
),
margin=attr(l=0,r=0,t=120,b=0,pad=0)
)
# Transpose the elevation_smoothed array if Y axis is longer than X axis to fix chopping
elevation_smoothed=transpose(elevation_smoothed)
@ -346,6 +413,13 @@ end
@out imgWidth=0
@out imgHeight=0
# Optical Image Overlay & Transparency
@in imgTrans = 1.0
@in progressOptical = false
@out btnOpticalDisable = true
@in btnOptical = false
@out opticalImg = ""
# Messages to interface variables
@out msg=""
@out msgimg=""
@ -385,7 +459,8 @@ end
),
yaxis=PlotlyBase.attr(
visible=false
)
),
margin=attr(l=0,r=0,t=0,b=0,pad=0)
)
traceImg=PlotlyBase.heatmap(x=[], y=[])
@out plotdataImg=[traceImg]
@ -403,7 +478,8 @@ end
yaxis=PlotlyBase.attr(
title="Intensity",
showgrid=true
)
),
margin=attr(l=0,r=0,t=120,b=0,pad=0)
)
# Dummy 2D scatter plot
traceSpectra=PlotlyBase.scatter(x=[], y=[], mode="lines")
@ -426,11 +502,12 @@ end
xaxis=PlotlyBase.attr(
title="X",
scaleanchor="y"
),
yaxis=PlotlyBase.attr(
title="Y"
),
)
),
yaxis=PlotlyBase.attr(
title="Y"
),
margin=attr(l=0,r=0,t=120,b=0,pad=0)
)
# Dummy 2D surface plot
traceContour=PlotlyBase.scatter(x=[], y=[], mode="lines")
# Create conection to frontend
@ -450,7 +527,8 @@ end
zaxis_nticks=4,
camera=attr(eye=attr(x=0, y=-1, z=0.5)),
aspectratio=attr(x=1, y=1, z=0.2)
)
),
margin=attr(l=0,r=0,t=120,b=0,pad=0)
)
# Dummy 3D surface plot
@ -655,7 +733,8 @@ end
title="Intensity",
showgrid=true
),
autosize=false
autosize=false,
margin=attr(l=0,r=0,t=120,b=0,pad=0)
)
# dims=size(spectraMz)
# scansMax=dims[2] # we get the total of scansMax
@ -709,7 +788,8 @@ end
title="Intensity",
showgrid=true
),
autosize=false
autosize=false,
margin=attr(l=0,r=0,t=120,b=0,pad=0)
)
xSpectraMz=spectraMz[1,abs(xCoord)]
ySpectraMz=spectraMz[2,abs(yCoord)]
@ -762,6 +842,7 @@ end
msgimg="Image with the Nmass of $(replace(text_nmass, "_" => "."))"
# Process the image in the function
plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt)
btnOpticalDisable = false
else
traceImg=PlotlyBase.heatmap(x=[], y=[])
plotdataImg=[traceImg]
@ -788,6 +869,7 @@ end
msgimg="Image with the Nmass of $(replace(text_nmass, "_" => "."))"
# Process the image in the function
plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt)
btnOpticalDisable = false
else
traceImg=PlotlyBase.heatmap(x=[], y=[])
plotdataImg=[traceImg]
@ -815,6 +897,7 @@ end
msgtriq="TrIQ image with the Nmass of $(replace(text_nmass, "_" => "."))"
# Process the image in the function
plotdataImgT, plotlayoutImgT, imgWidth, imgHeight=loadImgPlot(imgIntT)
btnOpticalDisable = false
else
traceImg=PlotlyBase.heatmap(x=[], y=[])
plotdataImgT=[traceImg]
@ -841,6 +924,7 @@ end
msgtriq="TrIQ image with the Nmass of $(replace(text_nmass, "_" => "."))"
# Process the image in the function
plotdataImgT, plotlayoutImgT, imgWidth, imgHeight=loadImgPlot(imgIntT)
btnOpticalDisable = false
else
traceImg=PlotlyBase.heatmap(x=[], y=[])
plotdataImgT=[traceImg]
@ -1055,17 +1139,18 @@ end
end
end
layoutSpectra=PlotlyBase.Layout(
title="SUM Spectrum plot",
xaxis=PlotlyBase.attr(
title="<i>m/z</i>",
showgrid=true
),
yaxis=PlotlyBase.attr(
title="Intensity",
showgrid=true
),
autosize=false
)
title="SUM Spectrum plot",
xaxis=PlotlyBase.attr(
title="<i>m/z</i>",
showgrid=true
),
yaxis=PlotlyBase.attr(
title="Intensity",
showgrid=true
),
autosize=false,
margin=attr(l=0,r=0,t=120,b=0,pad=0)
)
traceSpectra=PlotlyBase.scatter(x=xSpectraMz, y=ySpectraMz, mode="lines",name="Spectra",showlegend=false)
trace2=PlotlyBase.scatter(x=[Nmass, Nmass],y=[0, maximum(ySpectraMz)],mode="lines",line=attr(color="red", width=0.5),name="<i>m/z</i> selected",showlegend=false)
plotdata=[traceSpectra,trace2] # We add the data from spectra and the red line to the plot
@ -1106,14 +1191,27 @@ end
yCoord=-imgHeight
end # Get the x and y values from the click of the cursor and make sure they don't exceed image proportions
#plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt)
plotdataImg=filter(trace -> !(get(trace, :name, "") in ["Line X", "Line Y"]), plotdataImg)
plotdataImg=filter(trace -> !(get(trace, :name, "") in ["Line X", "Line Y","Optical"]), plotdataImg)
trace1, trace2=crossLinesPlot(xCoord, yCoord, imgWidth, -imgHeight)
plotdataImg=append!(plotdataImg, [trace1, trace2])
end
end
# WIP add an x and y input and a plot to select pixels in an image and then calculate a plot (not the sum of plots)
# optional: red lines to signal which pixel is selected in the image plot
@onbutton btnOptical begin
timestamp=string(time_ns())
imgRoute=pick_file(; filterlist="png,bmp,jpg,jpeg")
if isnothing(imgRoute)
println("No file selected")
else
img=load(imgRoute)
save("./public/css/imgOver.png",img)
plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt,"/css/imgOver.png",imgTrans)
end
end
@onchange imgTrans begin
plotdataImg, plotlayoutImg, imgWidth, imgHeight=loadImgPlot(imgInt,"/css/imgOver.png",imgTrans)
end
@mounted watchplots()
@ -1126,13 +1224,3 @@ end
# Register a new route and the page that will be loaded on access
@page("/", "app.jl.html")
end
# == Advanced features ==
#=
- The @private macro defines a reactive variable that is not sent to the browser.
This is useful for storing data that is unique to each user session but is not needed
in the UI.
@private table=DataFrame(a=1:10, b=10:19, c=20:29)
=#

View File

@ -53,6 +53,12 @@
</q-item>
</q-list>
</q-btn-dropdown>
<q-btn id="btnStyle" icon="search" class="q-ma-sm" :disable="btnOpticalDisable"
v-on:click="btnOptical=true" label="Load your optical Image"></q-btn>
<div class="q-mx-sm">
<q-slider color="black" v-model="imgTrans" :min="0.0" :max="1" :step="0.1" :disable="btnOpticalDisable"/>
<q-badge style="background-color: #009f90;"> Transparency: {{ imgTrans }}</q-badge>
</div>
</div>
<p id="lblFullRoute">full route: {{full_route}}</p>
<!-- Variable Manipulation -->
@ -68,12 +74,13 @@
:rules="[val => !!val || '* Required', val => val >= 0.0 &amp;&amp; val <= 1.0 || 'Needs to be in range between 0 and 1']"></q-input>
</div>
<div class="st-col col-4 col-sm q-ma-sm">
<q-input standout="custom-standout" id="textcolorLevel" step="1" v-model="colorLevel"
label="Color level" type="number" :rules="[ val => !!val || '* Required', val => val >= 2 &amp;&amp; val <= 256 || 'Needs to be in range between 2 and 256']"></q-input>
<q-input standout="custom-standout" id="textcolorLevel" step="1" v-model="colorLevel" label="Color level"
type="number"
:rules="[ val => !!val || '* Required', val => val >= 2 &amp;&amp; val <= 256 || 'Needs to be in range between 2 and 256']"></q-input>
</div>
</div>
<div class="row">
<!-- Triq Variable Manipulation and filters-->
<!-- Triq Variable Manipulation and filters-->
<div class="col-6">
<div class="st-col col-6 col-sm q-ma-sm">
<q-toggle id="btnEnableMFilter" v-on:click="MFilterEnabled" v-model="MFilterEnabled" color="green"
@ -118,14 +125,12 @@
</div>
<div class="row col-6">
<div class="st-col col-4 col-sm-4 q-ma-sm">
<q-input standout="custom-standout" step="1" v-model="xCoord" label="X coord"
type="number" :rules="[
<q-input standout="custom-standout" step="1" v-model="xCoord" label="X coord" type="number" :rules="[
val => SpectraEnabled ? ( '* Required', val >= 0|| 'Needs to be bigger than 0') : true
]" :readonly="!SpectraEnabled" :disable="!SpectraEnabled"></q-input>
</div>
<div class="st-col col-4 col-sm-4 q-ma-sm">
<q-input standout="custom-standout" step="1" v-model="yCoord" label="Y coord"
type="number" :rules="[
<q-input standout="custom-standout" step="1" v-model="yCoord" label="Y coord" type="number" :rules="[
val => SpectraEnabled ? ( '* Required', val <= 0|| 'Needs to be lower than 0') : true
]" :readonly="!SpectraEnabled" :disable="!SpectraEnabled"></q-input>
</div>
@ -161,11 +166,12 @@
</div>
<!-- Image manager -->
<div id="image-container" class="row st-col col-12">
<div class="col-10 q-pa-none q-ma-none ">
<plotly id="plotStyle" :data="plotdataImg" :layout="plotlayoutImg" class="q-pa-none q-ma-none sync_data" @click="data_click"></plotly>
<div class="col-10 q-pa-none q-ma-none">
<plotly id="plotStyle" :data="plotdataImg" :layout="plotlayoutImg" class="q-pa-none q-ma-none sync_data"
@click="data_click"></plotly>
<!--<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgInt" width="80%"></q-img>-->
</div>
<div class="col-2 q-pa-none q-ma-none ">
<div class="col-2 q-pa-none q-ma-none">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbar"></q-img>
</div>
</div>
@ -183,7 +189,8 @@
<!-- Triq Image manager -->
<div id="image-container" class="row st-col col-12">
<div class="col-10 q-pa-none q-ma-none ">
<plotly id="plotStyle" :data="plotdataImgT" :layout="plotlayoutImgT" class="q-pa-none q-ma-none sync_data" @click="data_click"></plotly>
<plotly id="plotStyle" :data="plotdataImgT" :layout="plotlayoutImgT"
class="q-pa-none q-ma-none sync_data" @click="data_click"></plotly>
<!--<q-img id="imgInt" class="q-ma-none q-pa-none" :src="imgIntT" width="80%"></q-img>-->
</div>
<div class="col-2 q-pa-none q-ma-none ">
@ -196,9 +203,10 @@
<q-tab-panel name="tab2">
<!-- Content for Tab 2 -->
<!--<plotly id="plotStyle" :data="plotdata" :layout="plotlayout" class="q-pa-none q-ma-none"></plotly>-->
<plotly id="plotStyle" :data="plotdata" :layout="plotlayout" class="q-pa-none q-ma-none sync_data" @click="data_click"></plotly>
<plotly id="plotStyle" :data="plotdata" :layout="plotlayout" class="q-pa-none q-ma-none sync_data"
@click="data_click"></plotly>
</q-tab-panel>
<q-tab-panel name="tab3">
<!-- Content for Tab 3 -->
<plotly id="plotStyle" :data="plotdataC" :layout="plotlayoutC" class="q-pa-none q-ma-none"></plotly>
@ -230,8 +238,12 @@
<q-dialog v-model="CompareDialog" full-width>
<q-card>
<q-card-section>
<div class="text-h6">Compare two diferent images or plots in a larger screen</div>
<q-card-section class="row">
<div class="text-h6 q-ma-sm">Compare two diferent images or plots in a larger screen</div>
<div class="q-mx-sm">
<q-slider color="black" v-model="imgTrans" :min="0.0" :max="1" :step="0.1" :disable="btnOpticalDisable"/>
<q-badge style="background-color: #009f90;"> Transparency: {{ imgTrans }}</q-badge>
</div>
</q-card-section>
<q-card-section class="q-pt-none col-12">
@ -249,7 +261,8 @@
<!-- Image manager -->
<div id="image-container" class="row st-col col-12">
<div class="col-10 q-pa-none q-ma-none ">
<plotly id="plotStyle" :data="plotdataImg" :layout="plotlayoutImg" class="q-pa-none q-ma-none"></plotly>
<plotly id="plotStyle" :data="plotdataImg" :layout="plotlayoutImg" class="q-pa-none q-ma-none">
</plotly>
</div>
<div class="col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbar"></q-img>
@ -268,7 +281,8 @@
<!-- Triq Image manager -->
<div id="image-container" class="row st-col col-12">
<div class="col-10 q-pa-none q-ma-none ">
<plotly id="plotStyle" :data="plotdataImgT" :layout="plotlayoutImgT" class="q-pa-none q-ma-none"></plotly>
<plotly id="plotStyle" :data="plotdataImgT" :layout="plotlayoutImgT" class="q-pa-none q-ma-none">
</plotly>
</div>
<div class="col-2">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbarT"></q-img>
@ -304,7 +318,8 @@
<!-- Image manager -->
<div id="image-container" class="row st-col col-12">
<div class="col-10 q-pa-none q-ma-none ">
<plotly id="plotStyle" :data="plotdataImg" :layout="plotlayoutImg" class="q-pa-none q-ma-none"></plotly>
<plotly id="plotStyle" :data="plotdataImg" :layout="plotlayoutImg" class="q-pa-none q-ma-none">
</plotly>
</div>
<div class="col-2 q-pa-none q-ma-none ">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbar"></q-img>
@ -323,7 +338,8 @@
<!-- Triq Image manager -->
<div id="image-container" class="row st-col col-12">
<div class="col-10 q-pa-none q-ma-none ">
<plotly id="plotStyle" :data="plotdataImgT" :layout="plotlayoutImgT" class="q-pa-none q-ma-none"></plotly>
<plotly id="plotStyle" :data="plotdataImgT" :layout="plotlayoutImgT" class="q-pa-none q-ma-none">
</plotly>
</div>
<div class="col-2 q-pa-none q-ma-none ">
<q-img id="colorbar" class="q-ma-none q-pa-none" :src="colorbarT"></q-img>

View File

@ -1 +1,42 @@
#btnStyle{background:#009f90;color:rgb(229, 236, 246);}#imgInt{float:left;}#header{display:flex;align-items:center;}#imgLogo{width:100px;height:80px;margin-right:10px;margin-left:10px;}#extDivStyle{background-color:#c9cdb1;border-radius: 10px;}#intDivStyle{padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;background-color: #eff2f5;}#colorbar{float:left;}.custom-standout{background-color:#7f8389!important;color:rgb(0, 0, 0)!important;}#tabHeader{color:#009f90;}
#btnStyle {
background: #009f90;
color: rgb(229, 236, 246);
}
#imgInt {
float: left;
}
#header {
display: flex;
align-items: center;
}
#imgLogo {
width: 100px;
height: 80px;
margin-right: 10px;
margin-left: 10px;
}
#extDivStyle {
background-color: #c9cdb1;
border-radius: 10px;
}
#intDivStyle {
padding-top: 10px;
padding-right: 10px;
padding-bottom: 10px;
padding-left: 10px;
background-color: #eff2f5;
}
.custom-standout {
background-color: #7f8389 !important;
color: rgb(0, 0, 0) !important;
}
#tabHeader {
color: #009f90;
}

BIN
public/css/imgOver.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 963 KiB