Converting Indented Tree chart to pure Javascript. How?

Forgive my blunt objectivity but I’ve spent the last 3 hours trying to understand why when it takes less than 100 lines of pure JavaScript to create a Tidy Chart it takes 5 separate dependency files to achieve the same with Observable.

Allow me to show you a working example of a Tidy Chart in 81 lines of code. Single html file with a single link to flare-2.json.

<!DOCTYPE html>
<meta charset="utf-8">
  <script src=""></script>
    // d3.json returns a Promise, so we have to use .then()
    // also, used a web-accessible link
    var data = d3.json("").then(data => {
      var width = 1200;
      var tree = data => {
        const root = d3.hierarchy(data);
        root.dx = 10;
        root.dy = width / (root.height + 1);
        return d3.tree().nodeSize([root.dx, root.dy])(root);
      // attach chart to HTML body"body").append(() => chart(tree, data, width));
    function chart(tree, data, width) {
        const root = tree(data);

        let x0 = Infinity;
        let x1 = -x0;

        root.each(d => {
          if (d.x > x1) x1 = d.x;
          if (d.x < x0) x0 = d.x;

        const svg = d3.create("svg")
          .attr("viewBox", [0, 0, width, x1 - x0 + root.dx * 2]);

        const g = svg.append("g")
          .attr("font-family", "sans-serif")
          .attr("font-size", 10)
          .attr("transform", `translate(${root.dy / 3},${root.dx - x0})`);

        const link = g.append("g")
          .attr("fill", "none")
          .attr("stroke", "#555")
          .attr("stroke-opacity", 0.4)
          .attr("stroke-width", 1.5)
          .attr("d", d3.linkHorizontal()
            .x(d => d.y)
            .y(d => d.x));

        const node = g.append("g")
          .attr("stroke-linejoin", "round")
          .attr("stroke-width", 3)
          .attr("transform", d => `translate(${d.y},${d.x})`);

          .attr("fill", d => d.children ? "#555" : "#999")
          .attr("r", 2.5);

          .attr("dy", "0.31em")
          .attr("x", d => d.children ? -6 : 6)
          .attr("text-anchor", d => d.children ? "end" : "start")
          .text(d => + " (" + + ")")
          .attr("stroke", "white");

        return svg.node();


Why don’t we get examples like this, no one really knows.

I need to know how to get the Indented-Tree Observable and convert it to D3.js just like the code example above.

I learn by breaking things and then making them better. I need examples. Then once I learn them, I can create an Observable in order to waste someone else’s time who’s just trying to learn about the keyword they’ve typed in Google to inevitably get to this page.

I’ve read a thread on here that had to be closed after countless comments on how D3.js library code examples are nested with Observable code in every way there is.

It’s not clear through the sarcasm if you’re aware how easy it is to embed elements of a notebook into a webpage. Most serious developers using the embed feature would want to embed via the Javascript or React API, but you can also embed a simple iFrame. Here’s the tidy chart, you’re interested in:

I’d prefer not to rehash the “Just why” aspect of it all, as there’s an official statement on that, but I will point out that it is clearly unique and the notebook environment is very comfortable and familiar to many (like myself). :slight_smile:

1 Like

Respectfully, I think you just posted a solution for how to embed an Observable into a webpage.

want to learn the library they searched for. Nothing more.

Yes, that is correct. As I said, it’s quite unclear from your original post whether you are aware of that possibility or not.

Yes. I have let the hours I’ve spent trying to figure this out using examples get the best of me and now I type like an (insert_word_here) which is also not productive at all. Know that my frustrations are with the path it takes to still get nowhere; not anyone here.

sup suchislife, i work for observable and i dm’ed you (here). i’ve been in your position and i have plenty of friends who’ve been frustrated by it too. it’s true that you can’t just copy and paste entire observable examples to other environments, which is how i had used d3 examples for years. my own story is that i had been doing (regular html & javascript) d3 work for several years and got hooked by observable the week it came out, and years later got a job here because i loved it, so it’s worked for me. but yeah, because it’s more opinionated than codepen about making a good coding environment for visualization, it breaks some compatibility. you’re right about that. such is life! hah. not sure what to say except that i literally spend my life working in it and on it lol so hopefully you at least trust that there’s something to it, some reason for the ‘animated donkey’.

anyway i could like screenshare and pair with you on understanding and adapting that particular example if you want


I guess what is still not being understood is that I have no need to understand the reasons why you chose to “wrap the gift with a certain type of wrapping paper”. I need to understand the gift. Nothing else outside of this scope matters. Not how it was built. Not why it was built. Not when it applies. Not how pretty it looks when it’s embedded. Not how it can improve my understanding of it. Nothing.

Just imagine if the amount of effort put into creating this wrapper had been placed into simplifying D3.js…

If you already know how to do this, post the code.

Hi @suchislife801 . I am a novice, so not the best at offering help. I tried re-writing the example you linked in plain HTML and similarly got stuck (so no work of my own to share just yet). Since I also have limited time, and since you appear to be a more advanced user than me, perhaps this external reference might help you?

As Toph indicated, the community is very aware of and very appreciative of the challenges you express. There’s a long and now closed thread on this topic.. So please know that you’re not alone in the challenges you’re experiencing.

That said: there’s an old adage: “You catch more flies with honey”. People here really want to help you and others to learn. A bit of time to frame a question in a way that invites help without sarcasm is likely to get better responses. … but that’s my two cents.

Thank you for being willing to raise your frustrations! We’re all here to learn.

<3 Aaron


Nice. Very. Nice.

1 Like

The Company I work for has a very, very strict and conservative policy with regard to dependencies for their source code and executables, both for internal use and for customers use. This means that an extremely strong case needs to be made in order for the Company to allow any new dependency. I’m still arguing the case for d3.js itself, and hoping to win via the tree-based viz projects I’m leveraging from Observable and converting to straight Javascript where needed - because there’s no hope of my winning the argument to take on the Observable wrapper as a dependency.

So yes, this can be frustrating at times. But I would like to second an observation made here in this thread, that of treating the developers here with respect and seeking to understand their position, even though they have a different perspective than expected when we first came here.

I have to take on more work and responsibility wherever I can, and seek help when I am stuck, which is bound to happen while I’m learning d3.js. I’ve found this place to be helpful, and I appreciate the help very much. I want to contribute whatever I can whenever I can. I think that approach begets more understanding and help from the Observable folks. I’m certainly no milk toast - but I don’t like to see people treated with sarcasm and disrespect. I understand the frustration - I’ve had plenty too. But I think the example of the folks here is worthy of mention - they don’t respond in kind, but rather try to help out and try to point someone in a good direction. I appreciate that because today it’s pretty rare. Another place where you find such respect and helpfulness is on the GreenSock forum. Kudos to the folks that hold to their culture even under trial!