how do i do this in dash?
example
in this discussion there is a solution for images. example discussion
How should I do it with vector files (points, lines, polygons)?
any help is appreciated!
how do i do this in dash?
example
in this discussion there is a solution for images. example discussion
How should I do it with vector files (points, lines, polygons)?
any help is appreciated!
Hi @Nicodiaz and welcome to the Dash community
Cool app - I haven’t seen that one. That component is a Dash Enterprise component and is not available open-source.
Alright, so I figured out some stuff just for fun. It’s not perfect. And probably doesn’t have all the features. For example, the graphs arent linked in order to perform the same actions. The code could also get cleaned some more.
app.py
import dash
import dash_bootstrap_components as dbc
from dash import Dash, html, dcc
import plotly.express as px
df = px.data.gapminder()
fig1 = px.scatter(
df.query("year==2007"),
x="gdpPercap",
y="lifeExp",
size="pop",
color="continent",
log_x=True,
size_max=60,
template="plotly_white", # use the pulse themed figure template
title="Gapminder 2007: Plotly White",
)
fig1.update_layout(title_x=0.5)
fig2 = px.scatter(
df.query("year==2007"),
x="gdpPercap",
y="lifeExp",
size="pop",
color="continent",
log_x=True,
size_max=60,
template="plotly_dark",
title="Gapminder 2007: Plotly Dark",
)
fig2.update_layout(title_x=0.5)
app = Dash(
__name__,
external_stylesheets=[dbc.themes.BOOTSTRAP, dbc.icons.FONT_AWESOME],
external_scripts=[
{'src':"https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"}]
)
def beforeAfterSlide(fig1, fig2, style=None):
bfA = []
if not style:
style = {'width':'100vw', 'height':'100vh'}
for key in style:
if '%' in style[key]:
if key in ['width', 'left']:
style[key] = style[key].replace('%','vw')
if key in ['top', 'height']:
style[key] = style[key].replace('%','vh')
fig2.update_layout(title_x=0.5)
fig1.update_layout(title_x=0.5)
bfA.append(html.Div(dcc.Graph(figure=fig2, style={'width':'100%', 'height':'100%'})
, className='after'))
bfA.append(html.Div(className='middle'))
bfA.append(html.Div(dcc.Graph(figure=fig1, style=dict(width=style['width'], height=style['height'])),
className='before'))
return html.Div(bfA, className='beforeAfter', style=style)
app.layout = html.Div(beforeAfterSlide(fig1, fig2, {'height':'75%', 'width':'75%', 'top':'10%', 'left':'6%'}))
if __name__ == "__main__":
app.run_server(debug=True)
css file:
.beforeAfter {
border-radius: 5px;
border: 2px solid silver;
position: relative;
margin: 0;
padding: 0;
}
.after {
height:100%;
width:100%;
z-index: 1;
position: absolute;
}
.before {
height: 100%;
width: 50%;
overflow: hidden;
border-right: 4px solid silver;
z-index: 40;
position: absolute;
}
.middle {
top: 45%;
left: 48%;
z-index: 50;
draggable: true;
position: absolute;
}
.middle:before {
content: '\f1de';
font-family: "Font Awesome 6 Free";
font-size: 30pt;
font-weight: 900;
background-color: silver;
border: 1pt solid black;
cursor: grab;
border-radius: 5pt;
}
.middle:hover:before {
filter: brightness(1.15)
}
.middle:active:before {
cursor: grabbing;
}
js file:
function coolEffects() {
$(".middle").on("mousedown", function () {
$(document).on("mouseup",function() {
$(document).unbind("mousemove")
$(document).unbind("mouseup")
oldX = undefined
oldY = undefined
})
$(document).on("mousemove", function () {
adjustSize()
})
})
$(".before .modebar").css({'left':'0px', 'position':'absolute'})
}
window.fetch = new Proxy(window.fetch, {
apply(fetch, that, args) {
// Forward function call to the original fetch
const result = fetch.apply(that, args);
// Do whatever you want with the resulting Promise
result.then((response) => {
if (args[0] == '/_dash-update-component') {
setTimeout(function() {coolEffects()}, 500)
}})
return result
}
}
)
var oldX;
var oldY;
function adjustSize() {
if (event.screenX != 0) {
if (oldX && !((parseInt($('.before').css("width"))+((event.clientX-$(document).scrollLeft())-oldX)) > $('.beforeAfter').width())) {
$('.before').css("width", parseInt($('.before').css("width"))+((event.clientX-$(document).scrollLeft())-oldX)+'px')
$('.middle').css("left", ($('.before').width()/$('.beforeAfter').width()*100)-2 + '%')
}
if (parseFloat($('.middle').css('left'))> $('.beforeAfter').width()) {
$('.middle').css("left", '99.5%')
$('.before').css("width", $('.beforeAfter').width())
}
}
oldX = event.clientX-$(document).scrollLeft()
event.target.style.cursor = 'grab';
}
$(document).ready(function() {
setTimeout(function() {coolEffects()}, 1000)
})
Have fun.