-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using D3.js with Shiny in Python #932
Comments
Hi! I don't know of a similar library in the Python world. The easiest way to connect d3.js and Shiny right now is probably https://anywidget.dev/, which can be used with Shiny via the shinywidgets package. (Unfortunately, the below example doesn't work with shinylive.io, or I would've linked you to a live demo; something within anywidgets and/or shinywidgets is asking where on disk the Shiny app lives, and shinylive.io doesn't have an answer.) import anywidget
import traitlets
from shinywidgets import output_widget, render_widget
from shiny import App, render, ui
class D3PlotWidget(anywidget.AnyWidget):
_esm = """
import * as d3 from "https://esm.sh/d3@7";
export function render({ model, el }) {
// Declare the chart dimensions and margins.
const width = 640;
const height = 400;
const marginTop = 20;
const marginRight = 20;
const marginBottom = 30;
const marginLeft = 40;
// Declare the x (horizontal position) scale.
const x = d3.scaleUtc()
.domain([new Date(model.get("startDate")), new Date(model.get("endDate"))])
.range([marginLeft, width - marginRight]);
// Declare the y (vertical position) scale.
const y = d3.scaleLinear()
.domain([0, 100])
.range([height - marginBottom, marginTop]);
// Create the SVG container.
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);
// Add the x-axis.
svg.append("g")
.attr("transform", `translate(0,${height - marginBottom})`)
.call(d3.axisBottom(x));
// Add the y-axis.
svg.append("g")
.attr("transform", `translate(${marginLeft},0)`)
.call(d3.axisLeft(y));
svg.classed("d3-plot-widget", true)
// Return the SVG element.
el.appendChild(svg.node());
}
"""
_css = """
.d3-plot-widget { border: 1px solid #ea580c; }
"""
startDate = traitlets.Unicode("2023-01-01").tag(sync=True)
endDate = traitlets.Unicode("2024-01-01").tag(sync=True)
app_ui = ui.page_fluid(
ui.input_date_range("dates", "Date range", start="2023-01-01", end="2024-01-01"),
output_widget("widget"),
)
def server(input, output, session):
@render_widget
def widget():
d3plot = D3PlotWidget()
d3plot.startDate = input.dates()[0].strftime("%Y-%m-%d")
d3plot.endDate = input.dates()[1].strftime("%Y-%m-%d")
return d3plot
app = App(app_ui, server) |
@jcheng5 thank you very much! I think this is already what I needed. I'll try to use it for the app I'm developing (I was working on it using R Shiny and r2d2) and if you want I can report back. In the meantime, feel free to close the issue or leave it open, as you consider. Thanks again! |
@tomicapretto Maybe shinyobservable with docs here is also useful for your usecase. |
Thank you for the reference @crazycapivara! For my use case, I was trying to do some 3d visualization and discovered d3 is not good for that. I ended up using {rgl} and {shiny} in R. I you're interested I can point you to the app once it's public :). |
This is more a question than an issue (sorry if this is the wrong place!). I've been using Shiny in R a lot. In the past I used the package {r2d3} to include D3.js visualizations in my Shiny apps.
Thanks in advance!
The text was updated successfully, but these errors were encountered: