Embed chart function in a webpage

Hi there, Sorry for the probably stupid question, but after a few hours of Googling, I could not find an answer and as the post suggest I am new to Observable.

So, I am an R user. In R, I can use Shiny App to publish an app that allows the user to upload data (in my case, an XML file of financial data extracted from a very well-known database) and do some charting, allowing some interactivity. R makes the whole process pretty easy.

In my understanding, since observable is written in Javascript, I could get my code and embed it on an external website. Is that correct?

For example, If I had to work directly in JavaScript, I could create a function to allow the user to upload the file and parse it (I could even ask ChatGPT to do it). However, I do not understand how I can use the observable charts I created, for example, in my notebook. I saw some examples using Plotly.

However, I wonder if it was possible to use the native charting function of observable embedding the code directly or with minimal work (I do not mind importing external libraries) in a website. I cannot embed an Iframe since I need the user to be able to import his/her own data. Sharing the notebook is not an option either since the user might not have the required skills to work with a notebook. So, I need to use a stand-alone website that I publish somewhere.

Is it possible? What libraries should I import? Is there any example that explains how to pass from a working notebook with a chart to a website embedding the existing code?

At the moment, even a very basic example to point me in the right direction could be very helpful.

Thanks in advance for any help.

Kind regards,

Hi there, have you come across the advanced embeds documentation? It might help in this scenario Advanced embedding and downloading / Observable | Observable .

1 Like

Dear thehogfather,
Thank you so much for your kind and prompt reply. I have been playing with the link you sent me for a while. I hope I found a solution that I am posting for you to check (I am not sure I used the async/await properly in: main.value(“bins”) … any help would be much appreciated) and for other newbies like me who could need it.
It is a very simple notebook (a bar chart of penguins that plots flipper_length_mm selecting the number of bins to show). I imported it into an HTML page. I used a button to change the number of bins from 12 to 3 and vice versa. In this case, I can read the value from the notebook, change it, read it again, and re-render the chart.

So, this is the notebook I am using:

This is the HTML and Javascript code I used:

<html>
<body>
    <div id="observablehq-chart-1c06e182"></div>
    <button id="logButton">Press Me to change the number of Bins</button>
</body>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@observablehq/inspector@5/dist/inspector.css">
<script type="module">
    // imports the required libraries
    import { Runtime, Inspector } from "https://cdn.jsdelivr.net/npm/@observablehq/runtime@5/dist/runtime.js";
    import define from "https://api.observablehq.com/d/d1b505c4739f1024.js?v=3";

    // sets the main variable to read and write into notebook cells
    const main = new Runtime().module(define, name => {
        if (name === "chart") {
            return new Inspector(document.querySelector("#observablehq-chart-1c06e182"))
        } else if (name === "data") {
            return {
                pending() { console.log(`${name} is running…`); },
                fulfilled(value) { console.log(name, value); },
                rejected(error) { console.error(error); }
            }
        };
    });

    // sets an event listener for the click button
    const button = document.getElementById("logButton");
    button.addEventListener("click", changeBins);

    // function to change the number of bins in the notebook
    async function changeBins() {
        const oldValue = await main.value("bins");
        if (oldValue > 6) {
            main.redefine("bins", 3);
            const newValue = await main.value("bins");
            console.log(`clicked to change number of bins from: ${oldValue} to: ${newValue}`)
        } else {
            main.redefine("bins", 12);
            const newValue = await main.value("bins");
            console.log(`clicked to change number of bins from: ${oldValue} to: ${newValue}`)
        }
    }

</script>
</html>
1 Like