Test: Difference between revisions

From Open Source Ecology
Jump to navigation Jump to search
No edit summary
No edit summary
 
(4 intermediate revisions by the same user not shown)
Line 1: Line 1:
{| class="wikitable"
<html>
|+ Enterprise Template
<div id="ose-3d-mindmap" style="width:100%; height:700px; border:1px solid #ccc; overflow:hidden; position:relative;"></div>
!
! Description
! Link to Work Product
! %


|-
<script src="https://unpkg.com/three@0.160.0/build/three.min.js"></script>
! scope=row |
<script src="https://unpkg.com/three@0.160.0/examples/js/controls/OrbitControls.js"></script>
| '''PRODUCT''' ||  || 


|-
<script>
! scope=row | 0
(function () {
| [[Benchmarking]] || [[{{{1}}} Benchmarking]] || 0
  const container = document.getElementById('ose-3d-mindmap');
  if (!container) return;


|-
  const words = [
! scope=row | 1
    "collaborative",
| [[Unique Value Proposition]] || [[{{{1}}} Unique Value Proposition]] || 0
    "design",
    "for",
    "a",
    "transparent",
    "and",
    "inclusive",
    "economy",
    "of",
    "abundance"
  ];


|-
  const scene = new THREE.Scene();
! scope=row | 2
  scene.background = new THREE.Color(0xffffff);
| [[Product Strategy]] || [[{{{1}}} Product Strategy]] || 0


|-
  const camera = new THREE.PerspectiveCamera(
! scope=row | 3
    50,
| [[Cost Structure]] || [[{{{1}}} Cost Structure]] || 0
    container.clientWidth / container.clientHeight,
    0.1,
    2000
  );
  camera.position.set(0, 0, 260);


|-
  const renderer = new THREE.WebGLRenderer({ antialias: true });
! scope=row | 4
  renderer.setPixelRatio(window.devicePixelRatio || 1);
| [[Business Plan]] || [[{{{1}}} Business Plan]] || 0
  renderer.setSize(container.clientWidth, container.clientHeight);
  container.appendChild(renderer.domElement);


|-
  const controls = new THREE.OrbitControls(camera, renderer.domElement);
! scope=row | 5
  controls.enableDamping = true;
| [[Open Source Franchise]] || [[{{{1}}} Open Source Franchise]] || 0
  controls.dampingFactor = 0.08;
  controls.rotateSpeed = 0.8;
  controls.zoomSpeed = 0.9;
  controls.panSpeed = 0.7;


|-
  const ambient = new THREE.AmbientLight(0xffffff, 1.2);
! scope=row |
  scene.add(ambient);
| '''PRODUCTION''' ||  ||


|-
  const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
! scope=row | 6
  dirLight.position.set(120, 150, 200);
| [[Operations Plan]] || [[{{{1}}} Operations Plan]] || 0
  scene.add(dirLight);


|-
  function makeTextSprite(message) {
! scope=row | 7
    const canvas = document.createElement('canvas');
| [[Data Collection]] || [[{{{1}}} Data Collection]] || 0
    const ctx = canvas.getContext('2d');


|-
    const fontSize = 48;
! scope=row | 8
    const paddingX = 28;
| [[Training and Management]] || [[{{{1}}} Training and Management]] || 0
    const paddingY = 18;
    ctx.font = 'bold ' + fontSize + 'px Arial';


|-
    const textWidth = Math.ceil(ctx.measureText(message).width);
! scope=row | 9
    canvas.width = textWidth + paddingX * 2;
| [[Facility Design]] || [[{{{1}}} Facility Design]] || 0
    canvas.height = fontSize + paddingY * 2;


|-
    ctx.font = 'bold ' + fontSize + 'px Arial';
! scope=row | 10
    ctx.textBaseline = 'middle';
| [[Supply Chain Development]] || [[{{{1}}} Supply Chain Development]] || 0
    ctx.textAlign = 'center';


|-
    ctx.fillStyle = 'rgba(255,255,255,0.92)';
! scope=row | 11
    ctx.strokeStyle = 'rgba(40,40,40,0.9)';
| [[Production]] || [[{{{1}}} Production]] || 0
    ctx.lineWidth = 3;
    roundRect(ctx, 2, 2, canvas.width - 4, canvas.height - 4, 14, true, true);


|-
    ctx.fillStyle = '#111111';
! scope=row | 12
    ctx.fillText(message, canvas.width / 2, canvas.height / 2);
| [[Quality Control]] || [[{{{1}}} Quality Control]] || 0


|-
    const texture = new THREE.CanvasTexture(canvas);
! scope=row |
    texture.needsUpdate = true;
| '''MARKETING''' ||  ||


|-
    const material = new THREE.SpriteMaterial({
! scope=row | 13
      map: texture,
| [[Product Assets]] || [[{{{1}}} Product Assets]] || 0
      transparent: true
    });


|-
    const sprite = new THREE.Sprite(material);
! scope=row | 14
| [[Marketing Strategy]] || [[{{{1}}} Marketing Strategy]] || 0


|-
    const scale = 0.34;
! scope=row | 15
    sprite.scale.set(canvas.width * scale, canvas.height * scale, 1);
| [[Marketing Plan]] || [[{{{1}}} Marketing Plan]] || 0


|-
    return sprite;
! scope=row | 16
  }
| [[Product Webpage]] || [[{{{1}}} Product Webpage]] || 0


|-
  function roundRect(ctx, x, y, w, h, r, fill, stroke) {
! scope=row |
    if (w < 2 * r) r = w / 2;
| '''SALES AND SUPPORT''' ||  ||
    if (h < 2 * r) r = h / 2;
    ctx.beginPath();
    ctx.moveTo(x + r, y);
    ctx.arcTo(x + w, y, x + w, y + h, r);
    ctx.arcTo(x + w, y + h, x, y + h, r);
    ctx.arcTo(x, y + h, x, y, r);
    ctx.arcTo(x, y, x + w, y, r);
    ctx.closePath();
    if (fill) ctx.fill();
    if (stroke) ctx.stroke();
  }


|-
  const nodeGroup = new THREE.Group();
! scope=row | 17
  scene.add(nodeGroup);
| [[Sales Strategy|Sales and Distribution Strategy]] || [[{{{1}}} Sales Strategy]] || 0


|-
  const positions = [];
! scope=row | 18
  const radius = 95;
| [[Customer Support]] || [[{{{1}}} Customer Support]] || 0


|-
  // Distribute words across a sphere
! scope=row | 19
  for (let i = 0; i < words.length; i++) {
| [[Shipping]] || [[{{{1}}} Shipping]] || 0
    const phi = Math.acos(-1 + (2 * i + 1) / words.length);
    const theta = Math.sqrt(words.length * Math.PI) * phi;


|-
    const x = radius * Math.cos(theta) * Math.sin(phi);
! scope=row | 20
    const y = radius * Math.sin(theta) * Math.sin(phi);
| [[Open Source Everything Store]] || [[{{{1}}} Open Source Everything Store]] || 0
    const z = radius * Math.cos(phi);


|-
    positions.push(new THREE.Vector3(x, y, z));
! scope=row |
| '''IMPROVEMENT''' || ||


|-
    const sprite = makeTextSprite(words[i]);
! scope=row | 21
    sprite.position.set(x, y, z);
| [[Marketing and Sales Data]] || [[{{{1}}} Marketing and Sales Data]] || 0
    sprite.userData.word = words[i];
    nodeGroup.add(sprite);
  }


|-
  // Connect every word to every other word
! scope=row | 22
  const lineMaterial = new THREE.LineBasicMaterial({
| [[Customer Feedback]] || [[{{{1}}} Customer Feedback]] || 0
    color: 0x777777,
    transparent: true,
    opacity: 0.45
  });


|-
  for (let i = 0; i < positions.length; i++) {
! scope=row | 23
    for (let j = i + 1; j < positions.length; j++) {
| [[Continuing Improvement]] || [[{{{1}}} Continuing Improvement]] || 0
      const geometry = new THREE.BufferGeometry().setFromPoints([
        positions[i],
        positions[j]
      ]);
      const line = new THREE.Line(geometry, lineMaterial);
      scene.add(line);
    }
  }


|-
  // Small center marker
! scope=row | 24
  const centerGeom = new THREE.SphereGeometry(3, 16, 16);
| [[Future Work]] || [[{{{1}}} Enterprise Future Work]] || 0
  const centerMat = new THREE.MeshBasicMaterial({ color: 0x222222 });
  const centerDot = new THREE.Mesh(centerGeom, centerMat);
  scene.add(centerDot);


|}
  const raycaster = new THREE.Raycaster();
<noinclude>
  const pointer = new THREE.Vector2();
=Notes=
*Added Benchmarking 12/8/21


=Usage=
  const info = document.createElement('div');
This template follows the same rules as the [[Development Template]]
  info.style.position = 'absolute';
</noinclude>
  info.style.left = '12px';
  info.style.top = '12px';
  info.style.padding = '8px 10px';
  info.style.background = 'rgba(255,255,255,0.9)';
  info.style.border = '1px solid #ccc';
  info.style.fontFamily = 'Arial, sans-serif';
  info.style.fontSize = '14px';
  info.style.color = '#111';
  info.style.zIndex = '10';
  info.innerHTML = 'Drag to rotate. Scroll to zoom. Click a word.';
  container.appendChild(info);
 
  function onPointerMove(event) {
    const rect = renderer.domElement.getBoundingClientRect();
    pointer.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
    pointer.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
  }
 
  function onClick() {
    raycaster.setFromCamera(pointer, camera);
    const intersects = raycaster.intersectObjects(nodeGroup.children, true);
 
    if (intersects.length > 0) {
      const obj = intersects[0].object;
      if (obj.userData && obj.userData.word) {
        info.innerHTML = 'Selected: <b>' + obj.userData.word + '</b>';
      }
    }
  }
 
  renderer.domElement.addEventListener('mousemove', onPointerMove);
  renderer.domElement.addEventListener('click', onClick);
 
  function resize() {
    const w = container.clientWidth;
    const h = container.clientHeight;
    camera.aspect = w / h;
    camera.updateProjectionMatrix();
    renderer.setSize(w, h);
  }
 
  window.addEventListener('resize', resize);
 
  function animate() {
    requestAnimationFrame(animate);
    controls.update();
    renderer.render(scene, camera);
  }
 
  animate();
})();
</script>
</html>

Latest revision as of 15:35, 4 April 2026