As I see it, you just need a cylinder and a texture.
You have to make an off-screen canvas, at a high-aspect ratio rectangular shape, and then draw the background color, and straight lines vertically to the longer dimension.
In fact canvas lines are inappropriate, because their apparent position is affected by their width. The way to do it is via fillRect(), because the ring width isn’t affected by any other factor than the coordinates.
Then wrap it on a cylinder/catmulrom3/etc, and have your perfect tube-like shape with all your information.
Every time you want to update your info-tube, you’ll just have to draw on the offscreen canvas, create an image, assign it to a texture, update the texture, assign it to a material as map, update the material and your changes will be apparent to that tube.
I was in the mood, so here is a rough cylinder-based example (the rings are auto-stacked based on their width) - I made it thick to have a better view of the (few) lines.
const geo = new THREE.CylinderGeometry( 32, 32, 512, 64, 64, false);
const cmat = new THREE.MeshBasicMaterial( );
// cmat.transparent = true;
cmat.side = THREE.DoubleSide;
const m = new THREE.Mesh( geo, cmat );
m.position.set(0,0,-800)
scene.add( m );
//_________ CANVAS _______________
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const w = 64;
const h = 4096;
ctx.canvas.width = w;
ctx.canvas.height = h;
var img, tex;
var startpos = 0.0;
var defwidth = 0.01;//default width
drawtext();
function drawtext(){
ctx.clearRect(0, 0, w, h);//just clear without fill to make the plain's background transparent
ctx.fillStyle = "#cccccc"; // ***
ctx.fillRect(0, 0, w, h); // ***
// replace these lines with smarter code
infoLineDraw(startpos, 2, "#ffff00");
infoLineDraw(startpos, 1, "#ff0000");
infoLineDraw(startpos, 2, "#ff8800");
infoLineDraw(startpos, 1, "#0000ff");
img = ctx.getImageData(0, 0, w, h);
tex = new THREE.Texture(img);
tex.needsUpdate = true;
m.material.map = tex;
m.material.needsUpdate = true;
tex.dispose();
}
// position, width, color
function infoLineDraw(rpos, rw, color){
let wd = defwidth*rw;
ctx.beginPath();
ctx.fillStyle = color;
ctx.fillRect(0, h*rpos, w, h*wd);
startpos += wd;
}
Note: If you omit the two lines marked as // *** and uncomment the third line from the top, your tube will become transparent and you’ll only have rings in the air. For that look, and if you leave space between the rings, you also need to make the material ‘THREE.DoubleSide’.
P.S I have also planned a few ambitious information-visualization projects - after a couple of lighter, gaming ones.