What does DOM.uid("xxx") do?

I am trying to understand the Zoomable Area Chart so that I can build one in regular javascript / d3.

The line const clip = DOM.uid(“clip”); apparently (according to https://github.com/observablehq/stdlib/blob/master/README.md#dom) creates a unique identifier which seemingly has an id within in.

How do I do this in a non observable world?

chart = {
const zoom = d3.zoom()
.scaleExtent([1, 32])
.extent([[margin.left, 0], [width - margin.right, height]])
.translateExtent([[margin.left, -Infinity], [width - margin.right, Infinity]])
.on(“zoom”, zoomed);

const svg = d3.create(“svg”)
.attr(“viewBox”, [0, 0, width, height]);

const clip = DOM.uid(“clip”);

svg.append(“clipPath”)
.attr(“id”, clip.id)
.append(“rect”)
.attr(“x”, margin.left)
.attr(“y”, margin.top)
.attr(“width”, width - margin.left - margin.right)
.attr(“height”, height - margin.top - margin.bottom);

does.

Could someone help explain? Also, is Infinity an Observable term?

Thanks,

Chris.

Infinity is not specific to Observable: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity

DOM.uid: you can depend on Observable’s stdlib library, or copy the code: https://github.com/observablehq/stdlib/blob/master/src/dom/uid.js which “just” increments a singleton variable and returns a string based on its value

Thanks @severo

1 Like

I can’t see how you were able to use the uid.js to resolve your issue Chris.
I have just come across the same thing myself, but really not getting it.

If you can help me or make it more obvious to others, that would be great thanks :slight_smile:

What are you trying to do, and what are you getting stuck on?

The UID code just makes a unique identifier. This is e.g. useful when you want to have identifiers in your html or svg code, but don’t want them to collide with others embedded on the same page.

If you call DOM.uid() once you get an object containing as property id the string "O-1". Call it again to get “O-2”. If you pass in a string it will be part of the unique identifier. e.g. call DOM.uid('foo') the third time and you get the string "O-foo-3". Etc.

If you want you can construct unique identifiers using whatever other method you prefer.

I see this used quite a bit in the creation of clip paths. How does it work here?

E.g:

       const clip = DOM.uid("squareClip");

       innerG.append("clipPath")
          .attr("id",clip.id)
          .append("path")
          .attr("d", "M" + parentD.join("L") + "Z")


       innerG.append("g")
             .selectAll(".child")
             .data(parentD.values)
          .enter().append("path")
              .attr("clip-path", clip)
              .attr("d", d => d ? "M" + d.join("L") + "Z" : null)
              .attr("stroke-width", 1)
              .attr("stroke", "#000")
              .attr("fill", (d,i) => color(i))
              .attr("fill-opacity", .5);

All it does is generates a unique ID (increments the counter at the end for every invocation, with the counter kept globally throughout the notebook). When you include multiple SVGs directly into the DOM of a single web page, you otherwise end up with name collisions between two different elements with the same ID.

In old versions of Safari, SVG references by ID for an SVG included in an HTML DOM also don’t resolve, but it worked fine to reference SVG elements as full paths using DOM.uid("foo").toString() which is the same as `url(${urlDOM.uid("foo").href})`