Mesh zoom material for dynamic recursive treemaps

I am creating recursive tree maps, where a tree map is a rectangular representation of things in a container. For example a file system directory that has 2 sub directories and one file, would be represented at the top level by a square divided into three sections. But each sub directory could be represented by another tree map of the contents of that directory. So recursive.

Tiled map systems, for example leaflet.js provide a way to zoom in to a deeper level of detail like the way google maps lets you zoom in out. I am trying to duplicate that experience with the recursive tree map, using react three fiber and drei.

I am learning a bit about shaders and adapted this example:
https://codesandbox.io/p/sandbox/blissful-driscoll-x37p4kk6p4

But this works on textures and I am not using images so don’t have textures. I do not know if there is a way to take my rectangle and fade the whole collection of MeshStandardMaterials into another set. webglrenderer.copyTextureTOTexture?

Also it needs to be dynamic so the route of first generating image (.png) file like map tiles appears not to be an option.

I could try to understand the drei mesh reflector material and more or less duplicate that. I have not delved deeply, but it appears to work by setting up a virtual camera and then projecting that image. Certainly that would work but it is a daunting task for me at this point. (Maybe a good one though).

The end effect I want is that a user can click on an area and the target area gets larger AND instead of seeing a filler color, the sub tree map is rendered. With a nice fade. The image gallery example https://codesandbox.io/p/sandbox/lx2h8 is a good starting point. I could just draw top level tree map, then draw a more detailed version when it is selected I would be close! Thank!!

Have you seen Troika? There are several data infographic examples pertinent to data infographics. :thinking: Perhaps your data infographic is not a data infographic.

I have used Troika Text but I just looked at the DerivedMaterials which is interesting. I am guessing that knowing about shaders will help me so I’m going to pursue that route.

I’m now wondering if since the things I am drawing are very basic shapes (rectangle in rectangle) if another approach might be to use shaders to create the areas.

So perhaps start with this example https://codesandbox.io/p/sandbox/ib0jc

Which is doing the drawing in glsl.

Thanks for the idea!

The solution in my case is to use shaders. I am generating a grid of rectangles into a square, and I want to dynamically change the contents by zooming in for more detail. I used the Drei RenderTexture - (NOTE: this is really render-to-texture ) but it is sort of hackish. Going from a procedural mesh to texture using a second camera in order to modify what is viewed.

I decided that all I really needed to do was just draw bunches of rectangles in a shader and how hard can that be? The drawing rectangles was less work than working through how to go from shadertoy to shaderMaterial.

My take away is that if you are doing procedural drawing and need to transform that, go the route of shaders rather than rendering to a texture then shading the texture. But fun!

I still have to address having text (in a shader?) and integrating touch events (in a shader?).

A shader isn’t really the best tool for this. You’d be better off using a simple 2D canvas. Just draw the tree whenever the zoom level changes and update the texture. You can even cache the drawings for different zoom levels and states to reuse them instead of redrawing everything from scratch.

Same deal here, shaders aren’t the way to go. Instead, you can use a raycaster to figure out where the pointer is relative to the window, container, scene, and object. Then, just determine which part of the tree should expand or collapse and update the canvas.

As an alternative you can overlay a floating HTML element on top of the scene. This would allow you to take advantage of the browser’s built-in event handling. You could even use a JavaScript framework like Solid, React, Vue, or Svelte to make things smoother.

Thanks! I’m new to all this. I’ve only been using 3js/r3f/r3d for a few months. One of the hard things about such a complex area is there are so many possible ways to approach a problem.

My limited understanding at this point is that everything is a shader. Right? Really 3js is a layer on top of webgl which is using shaders. So while it may be true that the best approach may not be a shader (I’m thinking assembly language vs C as an analogy), it may be the best thing for me right now is to attempt it. And I thought Troika Text was using SDF so …

I have written way too much React stuff and I’m using that where appropriate, but it seems to me that understanding shaders is making my stuff much better.

I’ve been attempting to replace typical burger menu and other navigation methods with more visual methods that are similar map navigation but of treemaps rather than geographic maps. Like google earth navigation. The problem is how you navigate and browse masses of information.

There was a thing recently about a visual presentation of all the book isbn numbers here: Visualizing All ISBNs — $10k by 2025-01-31 - Anna’s Blog that is in the same problem space. I think. :slight_smile:

1 Like

If you’re doing this as a challenge or learning experience, then go for it, and I’d love to see the final result!

But if you’re trying to finalize a product, nature consistently favors the path of least resistance.

You sound like an experienced React developer trying to draw boxes (in boxes). It’s an OS or a map or a gallery or a hamburger menu or a shader. Maybe you could draw a picture to assist assessment?

Troika has design patterns which you could modify and integrate. The community examples show formats which transition from a 2d axis to a 3d plane. That may justify the discussion of ref shaders, but maybe not if it’s just a box in a box.

Do you need to integrate with another app, and conserve performance budget… or what is the technical hurdle?

Pea.zip.tar

Okay. Take something with lots of stuff. A directory in a file system, your emails. A hierarchy of containers, folder with folders, etc. Take the top level container and make a treemap using some metric, like # of children, size or whatever.

That gives you some information about what is there. The top red blob is big because it has more files.

If some of those rectangles represent directories we could add replace the red blob with another treemap for that directory.

This is the same image as the first one except that every container from the first map is shown as a treemap instead of a blob. So just more detail for all the directories.

I’m not tracking colors (yet) so it is difficult to track the correspondence, but the red blob now has the same area, but subdivided.

If you recursively draw all the treemaps for my development directory you get this:

I don’t have a zoom mechanism yet, but I can see two ways to go for zooming.

Option #1 is keep the tiles. Say that the top image (tm0) display size is 1x1. I could create 4 tiles for the next level and show 1 of the tiles. This is how tiling is done with leafletjs, google maps etc.

Alternatively, when a block is chosen (clicked) I could generate a new square treemap ( or something close to square) for that block. For example the tall, dark blue rectangle in the first map would morph into a square, which seems odd to me. On the other hand if the transformation was eased perhaps it would be okay. This system is more bound to the concept of selecting rather than zooming.

Or maybe there is a completely different way to do it?

The goal is a general purpose way to walk through masses of information. And perhaps in multiple dimensions, like the size of the files, the age, or whatever.

The other missing pieces are some text so you an see the name of a blob, and a way to track colors between zoom levels.

Anna’s List presents all ISBN basically as a barcode. A 3d treemap doesn’t add much value, it’s like a PowerPoint gimmick. Users can’t douse for more information in a treemap, by entering it. You could present them with “expert” controls, like a d3 treemap… then they could toggle secondary layers. But you’re not an expert… it would cease to be a simple treemap… and the only benefit is strained 3d transitions. The added dimension negates the legitimacy/validity of the representation, unless done expertly. I think Troika has examples of multimodal visualization and transitions. Also, d3 sanitizes data and you could use provided box dimensions… it also has different stack/sort standards.

I would think Troika, or leverage d3, or reassess what fictitious client wants indeterminately complex treemaps. Can you douse a category and fill it with books, or some meaningful 3d pivot?

I think one of the very hardest things about software is the interface to people. People are weird. My very first ‘real’ task was to write a boot prom, including some basic commands. Then I had to use that boot prom for the next six months. Whoever wrote it was incompetent if not malicious. Of course I wrote it. I had made choices that appeared good, but in daily use were a plague.

I don’t think this is just me. After the iPhone was introduced there was about a year of constant announcements of “iPhone killers”. Often with glee. Like the Zune. None of these impressive technical products made by impressive companies killed the iPhone. At best they provided an alternative. Why is this? I have never read anything that explains this. I could be wrong, but I believe it is because there was some thing about the iPhone that worked well with people. There are other things, Hypercard for example, that repeat the same story and reinforce the idea. If you thing you understand why Hypercard was so very popular, then please build a new and better version.

I am going to draw an imaginary picture next. The picture is not accurate or real but for me illustrates a point. Imagine that google maps or earth, had a different user interface. When you go there you land on the planet page and see a globe of the earth. There is a burger menu that allows you to go to a continent page. On that page is a menu that takes you to the country page, then city page, then area then street.

To my mind this imaginary picture shows something I find wrong about many React and other web apps. On mobile, although the interface varies the process is more or less the same. When I write this kind of stuff I want to kick myself.

There are many ways that I could approach finding another interface for my web apps. Maybe just something by task. However, my tiny brain has settled on the fact, not fiction or opinion, that the way maps work could be adapted to navigate things other than geography.

When I go down this road, need to understand how to use geographic navigation for things that are not geographic. I want to browse books. A newspaper is another. A museum another. I need to find a way to build a sort of geographic representation for other hierarchical domains.

A tree map can be constructed using almost any metric. Popularity, size, category, count, or whatever. My conclusion is that it does provide a sort of “map” portrayal that would help navigate. Once we have a geographic (spatial?) representation for a data domain we can provide users with a visual representation and similar to leafletjs or maps. There is a single navigation element that allows a user to go anywhere in the “world”.

So I have been exploring recursive tree maps as a general way to do this. I certainly could be be wrong, but I think “gimmick” misses the point. I would love to hear better thinking, ideas about how to approach this problem.

Then there is an orthogonal dimension, which again is personal for me. I often find that going down a road, even one that leads nowhere, transforms me. I come out of the experience with more capabilities and I see new possibilities. This particular road may lead nowhere, but it is certainly interesting. And I have new capabilities that I did not have before.

There are ambitious “flyout menus” in XR that don’t induce nausea.