How is it possible to extract this D3.js code?

Hello,

I would like to work with that:
https://observablehq.com/@jake-low/image-histogram-in-svg

Unfortunately, I have issues to copy the code correctly to let it work independently from this page.

That’s what I have tried:
https://jsfiddle.net/273mx65z/

Could somebody help me to do that correctly? Would be super thankful!

1 Like

Are you aware that you can fork the notebook, name any cells that might need names, and embed it into any webpage you like? Like this one!

If you’re happy with how it looks in an iFrame, you can also just do that:

Hey, thank you! If I do it, it looks for example like that: Edit fiddle - JSFiddle - Code Playground – But I would like to exclude the whole code without any connection to observablehq anymore. Is it possible?

It looks to me like you’ve embedded the whole notebook. I recommend that you embed just the few cells that you need. Unfortunately, Jake didn’t name the image cell that I’m sure you want, which is why I forked the notebook and embedded those cells from there. Here it is in a JSFiddle.

Certainly, this thing could be re-implemented completely outside of Observable. There are a few convenient features of the Observable notebook that would need to be worked around. Specifically, you’d need to specify the file browser as a standard HTML component and hook up some event listeners to get buttons to respond. That’s not particularly hard but it’s not really within the scope of what we do here, since we all love using Observable!

Before doing that please be aware that the author of that notebook hasn’t specified a license yet. This means that strictly speaking the code may not be republished outside of Observable.

To be on the safe side, I suggest that you leave a comment on the notebook and ask the author to set an open source license, e.g. the MIT license.

2 Likes

Good point - thanks for mentioning!

Thank you. I just added a comment to his work.

Thanks a lot! I just would need a version that also works independently offline, but have actually no idea how to reach that. Maybe I should give up :neutral_face:

Don’t give up, Anna! We’re here to help :slightly_smiling_face:

Putting aside Jake’s particular notebook and the associated licensing restrictions (thanks @Fabian), if you are willing to use Observable’s opensource runtime, you may download the code for any notebook and run it offline (provided the notebook doesn’t further require other online resources). The official guide to achieving this is here:

You also often can search this forum to find other elaborations, such as my more detailed response here.

Let us know if this gets you closer :slight_smile:

Of course, if you wish to recreate the visualization without using Observable’s open source reactive runtime, there are several more steps. It’s not always easy to convert a notebook into ‘vanilla’ JavaScript, but there are several other posts on this forum that help to provide insights into this prcess.

Cheers!

Thank you for your answer! Observable seems to be wonderful, and obviously has a strong and active community, that’s great. Just for this thing, I would prefer to have the code completely independent from it and as pure/clean as possible. Does this explain what I need to know?

Yes, that’s a good explanation (Bryan is a gifted teacher!). There are a few other resources, as summarized by Radamés here.

Somewhere on this forum, I think, (I didn’t immediately find it) is a link to a Github project that someone put together to help in these conversions. I will update if / once I come back across it :slight_smile:

I hope you continue to raise questions and to be a part of the community! <3

Oh, looks pretty complicated. I failed for today. Will try tomorrow again :slight_smile:

1 Like

@Anna_B Here is a standalone example:

Note that I’ve included d3 via jsfiddle’s resources option.

1 Like

Ohhhh, thank you sooo much!

Just one additional question: Is there a way to download the different histogram layers as SVG files?

Yes, definitely. But to recommend a strategy I’d have to know a little more about your use case:

  • Are you building this tool for yourself or is it supposed to be used by others?
  • Will it only be used once or continuously?
  • Will it remain standalone, or are you planning to integrate it into another website / app?

It was planned just for myself, wanted to work with infographics based on that. But it would be also cool to make it available for everyone. It was thought to work standalone.

I hope you don’t mind me asking: Why does it have to work outside of Observable?

With Observable’s builtin reactivity, its bundled Standard Library and collaboration features this would be a lot easier to demonstrate, implement and iterate upon. :slight_smile:

I made the switch from standalone JavaScript to Observable roughly four years ago, and I never looked back.

1 Like

Probably you’re right. I just think as a beginner, it’s much easier to start with something that works simply on a local machine, without external scripts, and as less code as possible. But maybe it’s also fine then with just Observable.

I feel confident to say that you will find that in Observable.

To make the notebook from your initial post work as intended (render individual channels, download SVG), we only need to make two small tweaks (an example is linked at the end of this reply).

  1. To get started, fork Jake Low’s notebook via the “Fork …” button in the upper right, which will create your own copy. You can now modify the new notebook without ever losing any changes.

  2. Next, insert a new JavaScript cell (e.g. below the file upload field) with the following content:

    viewof channels = Inputs.checkbox( // Builtin helper to create a list of checkboxes
      [0, 1, 2], // Our checkbox values, in this case the color channel indices
      { // A couple of options
        value: [0, 1, 2], // The initially selected values (all in this case)
        label: 'Color channels', // A label for the form element,
        format: d => ['red', 'green', 'blue'][d] // displaying the channel names instead of just numbers
      }
    )
    

    The result should look like this:

    viewof is an Observable keyword that lets us access the current selection via the variable name channels (if you’re curious about viewof you can read a short introduction here).

  3. Now we go to the histogram cell and replace the last line

      return histogram;
    

    with

      return histogram.filter((c, i) => channels.includes(i));
    

    This will remove all histogram channels which aren’t selected in our checkboxes.

  4. Finally, to download the SVG we simply need to click into the left-hand cell menu of the histogramVisualization cell and select “Download SVG”:
    Kapture 2022-05-26 at 10.55.11

You can find an example fork here. Please note that I will remove that notebook in a couple of days, so be sure to create your own fork from Jake Low’s notebook.