Is converting from screen units to data units (and vice-versa) inside a Transform possible?

I’m trying to display what can be verbally described as a “golf flag”: a vertical segment with a flag-like triangle at the top. This flag is editable/dragable using the point edit tool.

I can achieve the segment and golf flag by plotting two glyphs attached to the same data source, like so:

offset = CustomJSTransform(v_func="""
            var new_xs = new Array(xs.length)
            for(var i = 0; i < xs.length; i++) {
                  new_xs[i] = xs[i] + 50
            }
            return new_xs""")

flag = plot.triangle(x=dict(field="x", transform=offset), y=950, size=50, fill_color="red", angle=dict(value=-90, units="deg"), source=source)
plot.segment(x0='x', x1='x', y0=00, y1=950, line_width=3, color="red" , source=source)
tool = PointDrawTool(renderers=[flag], empty_value="N/A")
plot.add_tools(tool)

This almost works, but the problem is that the size=50 in the triangle glyph is in screen coordinates, whereas the position x is in data coordinates. This means that the flag portion appears in different amounts of offset’edness depending on how zoomed in I am.

At this stage I’m not sure how to approach this at all. There’s two requirements that are fundamentally at odds with each other: I want the flag to be in screen units, but I want its position to be data units. The only proper solution I can see is in converting this at the transform level, but I’m spying through console log events that the transform doesn’t get repeated when zoom levels change.

Any help is appreciated.

Markers sizes are only denominated in screen units. If you want something that scales with zoom level, I’d suggest drawing triangles “by hand” with plot.patches.