🏠 back to Observable

Clip-path in IOS not working?


#1

I’m new to JavaScript and D3. Looking for some direction on clipping paths.

The clipping in my masked scatter plot:

looks to work on Observable if viewed in browser (Chrome, Firefox). But when I view the same link on my iPhone the clipping mask fails and the scatter plots spill over the axes.

I used the ES module and embedded the plot in my website following Jeremy Ashkenas post and code. The clipping seems to work as intended irrespective of if I view from PC or on iPhone?.

I’m guessing I’m missing something fundamental in how I’ve coded the clip path?

Do I need to get my head around DOM.uid and defs? Or is the fix simpler?

I looked at:
https://beta.observablehq.com/@mbostock/svg-clipping-test. But not really getting it yet?

So while I don’t really understand my own question - is the IOS treating the local IRI of my Observable notebook post as local-to-the-SVG regardless of a base URL, but the ES module isn’t?

I used D3 margin-convention to define the chart-area (so is a g node within the SVG):

chartArea = svg.append("g").attr("transform","translate(" + margin.left + ", " + margin.top + ")")

I then appended a clip-path to the chart-area and grouped all the plot circles within the clip-path:

allCircles = chartArea.append("g")
   .attr("id", "circles")
   .attr("clip-path", "url(#chart-area)")       // the line where I think I get structure wrong?
   .selectAll("circle")
   .data(data)
   .enter()                                          
   .append("circle")
           .attr("cx", function(d) {
                return xScale(d[0]);
           })  
           .attr("cy", function(d) {
                 return yScale(d[1]);
          })            
          .attr("r", 2)
          .attr("fill", "black")

The subsequent transform is applied to each plot circle (‘this’ in the code below) grouped in the clip path.

d3.select(this)
	.transition()
	.delay(i * 25)
	.duration(2000)
	.ease(d3.easeElasticOut)
	   .style("fill", colors[colorIndex])
        .style("stroke", colors[colorIndex2])
        .attr("stroke-width", "2.0px")
	    .attr("r", 15);

#2

You’re code is all good, it’s just that you’ve encountered a small Observable-specific glitch. As far as I understand it, due to the way the user’s coding is embedded in an iframe, the use of webworkers, and some design decision on URL’s, Observable has a ‘bug’ that makes it less easy to reference urls inside SVG.

See this forum discussion: Url() references within SVGs.

All is not lost, you just need to use the DOM.uid library helper.
Here’s a working version of your code, with the simple patch applied:


#3

Ah, but I see I may have misread your question. You’re saying it doesn’t work specifically after having exported the code (and on iOS). Then, never mind my previous comment :slight_smile:


#4

Thanks so much!
No mis-read. The exported version is ok.
The patch as you’ve applied it and why is what I need to get my head around.
Cheers