0% found this document useful (0 votes)
32 views7 pages

Graph HTML

Uploaded by

2ft5tykyf2
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views7 pages

Graph HTML

Uploaded by

2ft5tykyf2
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

<!

doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>2.5D Spherical Graph — Demo</title>
<style>
html,body{height:100%;margin:0;background:#0b1220;color:#ddd;font-
family:Inter,system-ui,Arial}
#container{width:100%;height:100%;position:relative;overflow:hidden}
#ui {
position:absolute;right:12px;top:12px;background:rgba(10,12,20,0.45);
color:#fff;padding:10px;border-radius:8px;font-size:13px;backdrop-filter:
blur(6px);
}
#legend {position:absolute;left:12px;bottom:12px;background:rgba(10,12,20,0.45);
padding:8px;border-radius:8px;}
.label {
padding:4px 7px;background:rgba(0,0,0,0.6);border-radius:4px;font-weight:600;
font-size:12px;color:#fff;pointer-events:none;white-space:nowrap;
}
[Link]{font-size:12px;color:#9fd; text-decoration:none}
</style>
</head>
<body>
<div id="container"></div>
<div id="ui">
<div><strong>2.5D Spherical Graph</strong></div>
<div style="margin-top:6px">
<label style="display:block">Node scale <input id="nodeScale" type="range"
min="0.2" max="3" step="0.1" value="1"></label>
<label>Auto rotate <input id="autoRotate" type="checkbox" checked></label>
</div>
<div style="margin-top:6px"><small><a class="small" href="#"
id="toggleLabels">Toggle labels</a></small></div>
</div>
<div id="legend">
<div style="font-size:12px;margin-bottom:6px">Legend</div>
<div style="display:flex;gap:8px;align-items:center">
<div style="width:12px;height:12px;border-radius:50%;background:#ff8c42"></
div><div style="font-size:12px">High value</div>
</div>
<div style="display:flex;gap:8px;align-items:center;margin-top:4px">
<div style="width:12px;height:12px;border-radius:50%;background:#4499ff"></
div><div style="font-size:12px">Low value</div>
</div>
</div>

<!-- [Link] from CDN -->


<script src="[Link]
<script
src="[Link]
script>

<script>
/*
2.5D Spherical Graph — Interactive demo
Data format: array of nodes:
{ id, name, lat (deg), lon (deg), value (0..1), group (optional) }
*/

const sampleData = [
{id:1, name:"Core", lat: 10, lon: -10, value: 0.95, group: "A"},
{id:2, name:"Node B", lat: 40, lon: 60, value: 0.7, group: "A"},
{id:3, name:"Node C", lat: -20, lon: 120, value: 0.4, group: "B"},
{id:4, name:"Node D", lat: -45, lon: -140, value: 0.25, group: "B"},
{id:5, name:"Node E", lat: 60, lon: -60, value: 0.5, group: "C"}
];

const connections = [
[1,2],[1,3],[2,5],[3,4],[4,5]
];

const container = [Link]('container');

const scene = new [Link]();


[Link] = new THREE.FogExp2(0x071019, 0.06);

const camera = new [Link](50, innerWidth/innerHeight, 0.1, 1000);


[Link](0, 0, 8);

const renderer = new [Link]({antialias:true, alpha:true});


[Link](innerWidth, innerHeight);
[Link]([Link]([Link], 2));
[Link]([Link]);

// controls
const controls = new [Link](camera, [Link]);
[Link] = true;
[Link] = false;
[Link] = 4;
[Link] = 30;

// lighting
const hemi = new [Link](0xbfe8ff, 0x202030, 0.9);
[Link](hemi);
const spot = new [Link](0xffffff, 0.9);
[Link](5,5,5);
[Link](spot);

// globe base (subtle glassy)


const globeRadius = 3;
const globeGeo = new [Link](globeRadius, 64, 40);
const globeMat = new [Link]({
color: 0x0f2a46,
metalness: 0.1,
roughness: 0.2,
transmission: 0.5,
transparent: true,
opacity: 0.9,
clearcoat: 0.6,
clearcoatRoughness: 0.1
});
const globeMesh = new [Link](globeGeo, globeMat);
[Link] = 0;
[Link](globeMesh);

// faint grid lines (latitude/longitude)


const gridMat = new [Link]({color:0x2b4b6b, transparent:true,
opacity:0.35});
const gridLines = new [Link]();
for(let lat=-80; lat<=80; lat+=20){
const radius = globeRadius * [Link]([Link](lat));
const y = globeRadius * [Link]([Link](lat));
const circle = new [Link](radius, 128);
[Link] = [Link]; // compatibility
const geom = new [Link]();
const pts = [];
for(let i=0;i<=128;i++){
const a = i/128 * [Link] * 2;
[Link](new THREE.Vector3([Link](a)*radius, y, [Link](a)*radius));
}
[Link](pts);
const line = new [Link](geom, gridMat);
[Link](line);
}
[Link](gridLines);

// node group
const nodeGroup = new [Link]();
[Link](nodeGroup);

// helper: lat/lon -> 3D point on sphere


function latLonToVector3(lat, lon, radius){
const phi = [Link](90 - lat);
const theta = [Link](lon + 180);
const x = radius * [Link](phi) * [Link](theta);
const y = radius * [Link](phi);
const z = radius * [Link](phi) * [Link](theta);
return new THREE.Vector3(x,y,z);
}

// color scale: maps value 0..1 into blue->orange


function valueToColor(v){
const c1 = new [Link](0x4499ff); // low
const c2 = new [Link](0xff8c42); // high
return [Link](c2, [Link](v,0,1));
}

// create node sprite label


function makeLabel(text){
const canvas = [Link]('canvas');
const ctx = [Link]('2d');
[Link] = '600 36px sans-serif';
const padding = 12;
const w = [Link]([Link](text).width) + padding*2;
const h = 48;
[Link] = w;
[Link] = h;
// background
[Link] = 'rgba(0,0,0,0.6)';
[Link](0,0,w,h);
// text
[Link] = '#fff';
[Link] = '600 26px sans-serif';
[Link] = 'middle';
[Link](text, padding, h/2 + 2);
const tex = new [Link](canvas);
[Link] = [Link];
const sprite = new [Link](new [Link]({map: tex,
transparent:true}));
[Link]((w/64), (h/64), 1);
return sprite;
}

// add nodes
const nodeData = [];
const labelSprites = [];
for(const d of sampleData){
const pos = latLonToVector3([Link], [Link], globeRadius + 0.06 +
([Link]*0.12)); // slightly above surface
const color = valueToColor([Link]);
// sphere
const sphereGeo = new [Link](0.05 + [Link]*0.14, 16, 12);
const sphereMat = new [Link]({
color: color,
emissive: [Link]().multiplyScalar(0.12),
metalness: 0.4,
roughness: 0.3
});
const nodeMesh = new [Link](sphereGeo, sphereMat);
[Link](pos);
[Link] = {...d, basePos: [Link]()};
[Link](nodeMesh);
[Link](nodeMesh);

// glow (a transparent, slightly larger sprite)


const spriteMat = new [Link]({
map: new [Link]().load(createGlowCanvas([Link]())),
blending: [Link],
opacity: 0.65,
depthWrite: false
});
const glow = new [Link](spriteMat);
[Link](0.6 + [Link]*0.6, 0.6 + [Link]*0.6, 1);
[Link](pos);
[Link](glow);

// label
const sprite = makeLabel([Link] + ' • ' + [Link]([Link]*100) + '%');
[Link]([Link]().multiplyScalar(1.06));
[Link](sprite);
[Link](sprite);
}

// create connectors with smooth curve


const connGroup = new [Link]();
for(const pair of connections){
const a = [Link](n=>[Link]===pair[0]);
const b = [Link](n=>[Link]===pair[1]);
if(!a || !b) continue;
const mid = [Link]().add([Link]).multiplyScalar(0.5);
// push midpoint slightly outwards to create an arc
const direction = [Link]().normalize();
const arcHeight = 0.6 + ([Link] + [Link]) * 0.5;
[Link]([Link](arcHeight));
const curve = new THREE.CatmullRomCurve3([[Link](), mid,
[Link]()]);
const pts = [Link](60);
const geom = new [Link]().setFromPoints(pts);
const mat = new [Link]({color:0xffffff, linewidth:1,
transparent:true, opacity:0.45});
const line = new [Link](geom, mat);
[Link](line);
}
[Link](connGroup);

// small subtle rim outline (2.5D layering effect)


const rim = new [Link](
new [Link](globeRadius + 0.02, 64, 32),
new [Link]({color:0xffffff, transparent:true, opacity:0.035})
);
[Link](rim);

// helpers
function createGlowCanvas(colorStyle){
const size = 128;
const c = [Link]('canvas');
[Link]=[Link]=size;
const ctx = [Link]('2d');
const g = [Link](size/2,size/2,0,size/2,size/2,size/2);
[Link](0, colorStyle);
[Link](0.2, colorStyle);
[Link](0.7, 'rgba(0,0,0,0.05)');
[Link](1, 'rgba(0,0,0,0)');
[Link] = g;
[Link](0,0,size,size);
return [Link]();
}

// interaction: raycast hover for tiny pop


const raycaster = new [Link]();
const pointer = new THREE.Vector2();
let hovered = null;

function onPointerMove(e){
const rect = [Link]();
pointer.x = (([Link] - [Link]) / [Link]) * 2 - 1;
pointer.y = -(([Link] - [Link]) / [Link]) * 2 + 1;
}
[Link]('pointermove', onPointerMove);

[Link]('click', (e)=>{
if(hovered){
alert('Clicked: ' + [Link] + '\\nvalue: ' +
[Link]);
}
});

// UI bindings
const nodeScaleEl = [Link]('nodeScale');
const autoRotateEl = [Link]('autoRotate');
const toggleLabels = [Link]('toggleLabels');
let labelsOn = true;
[Link]('click', (ev)=>{[Link](); labelsOn = !
labelsOn; [Link](s=>[Link]=labelsOn);});

[Link]('resize', ()=>{
[Link] = innerWidth/innerHeight;
[Link]();
[Link](innerWidth, innerHeight);
});

// animation
const clock = new [Link]();

function animate(){
requestAnimationFrame(animate);
const t = [Link]();

// gentle globe breathing / parallax (2.5D feel)


[Link].y += ([Link] ? 0.004 : 0) ;
[Link].y = [Link].y * 0.98;
[Link]([Link]);

// node subtle bob & face labels to camera


const scaleFactor = parseFloat([Link]);
[Link]((n, i)=>{
// bobbing
const offset = 0.06 * [Link](t*1.2 + i);
const target =
[Link]().normalize().multiplyScalar(globeRadius + 0.06 +
[Link]*0.12 + offset);
[Link](target, 0.08);
// scale by UI
[Link](scaleFactor);
// label facing camera
labelSprites[i].[Link]([Link]().multiplyScalar(1.06));
labelSprites[i].lookAt([Link]);
});

// hover detection
[Link](pointer, camera);
const intersects = [Link](nodeData, false);
if([Link]){
const obj = intersects[0].object;
if(hovered !== obj){
if(hovered) [Link](0.2);
hovered = obj;
[Link] = [Link]().add(new
[Link](0x333333));
}
} else {
if(hovered) {
// restore
[Link](0.6);
hovered = null;
}
}

[Link]();
[Link](scene, camera);
}
animate();
</script>
</body>
</html>

You might also like