main
reng 3 weeks ago
parent 81ae2c7e29
commit dc6d69f92a
  1. 71
      v2/app/src/components/graph.jsx
  2. 2
      v2/app/src/components/point.jsx
  3. 41
      v2/app/src/utils/color.js
  4. 2
      v2/app/src/utils/osc.js

@ -6,11 +6,8 @@ import { OrbitControls, PerspectiveCamera, Bounds, useBounds, Line } from '@reac
import Point, {PointContentType} from './point.jsx'; import Point, {PointContentType} from './point.jsx';
import { useControls, button } from "leva"; import { useControls, button } from "leva";
import { sendOsc } from '../utils/osc.js'; import { sendOsc } from '../utils/osc.js';
import { rgbToCss, getRgbFromIndex } from '../utils/color.js';
function getColorFromIndex(index, length){
const hue = (index / length) * 360;
return `hsl(${hue}, 100%, 50%)`;
}
export default function Graph({results}){ export default function Graph({results}){
@ -46,25 +43,33 @@ export default function Graph({results}){
function getColorByGroup(result){ function getColorByGroup(result){
if(!keywordColor) return 'white'; if(!keywordColor) return [1,1,1];
if(!result || !result.payload ) if(!result || !result.payload )
return 'white'; return [1,1,1];
if(result.type==='keyword'){ if(result.type==='keyword'){
return getColorFromIndex(parseInt(result.id), 20); return getRgbFromIndex(parseInt(result.id), 20);
} }
const group = result.payload.group[0]; const groupId = getGroupId(result);
if(group.distance<distToKeywords){ if(groupId != -1){
const index=parseInt(group.id); console.log("group id:", groupId);
console.log("Group color index:", index, "for group id:", group.id); return getRgbFromIndex(groupId, 20);
return getColorFromIndex(index, 20);
} }
return 'white'; return [1,1,1];
}
function getGroupId(result){
if(!result || !result.payload )
return -1;
if(result.type==='keyword'){
return parseInt(result.id);
}
const group = result.payload.group?.[0];
return group ? parseInt(group.id) : -1;
} }
useEffect(()=>{ useEffect(()=>{
@ -72,17 +77,51 @@ export default function Graph({results}){
if(!points || points.length===0) return; if(!points || points.length===0) return;
const keywords=results.filter((point, index)=>point?.type==='keyword');
let i=0;
points.forEach((point, index)=>{ points.forEach((point, index)=>{
// if keyword, skip
if(results?.[index]?.type==='keyword') return;
// console.log(`send osc Point ${index}: (${point[0].toFixed(2)}, ${point[1].toFixed(2)}, ${point[2].toFixed(2)})`); // console.log(`send osc Point ${index}: (${point[0].toFixed(2)}, ${point[1].toFixed(2)}, ${point[2].toFixed(2)})`);
let dist=results?.[index]?.payload.group?.map(el=>el.distance) || [];
if(dist.length<4){
dist = dist.concat(new Array(4 - dist.length).fill(-1));
}
let group = results?.[index]?.payload.group?.[0];
const keyword = keywords.find(kw=>kw.id===group?.id);
const group_index = keyword ? keywords.indexOf(keyword) : -1;
sendOsc('/point',JSON.stringify({ sendOsc('/point',JSON.stringify({
index: i,
x: point[0],
y: point[1],
z: point[2],
content: results?.[index]?.payload.teaser,
dist: dist,
color: getColorByGroup(results?.[index]),
group: group_index
}));
i++;
});
keywords.forEach((point, index)=>{
// console.log(`send osc Keyword Point ${index}: (${point[0].toFixed(2)}, ${point[1].toFixed(2)}, ${point[2].toFixed(2)})`);
sendOsc('/keyword',JSON.stringify({
index: index, index: index,
x: point[0], x: point[0],
y: point[1], y: point[1],
z: point[2], z: point[2],
content: results?.[index]?.payload.teaser content: JSON.parse(results?.[index]?.payload.text||'{}').title || 'Keyword',
color: getColorByGroup(results?.[index]),
group: index,
})); }));
}); });
}, [points]); }, [points]);
useEffect(()=>{ useEffect(()=>{
if(!results || results.length===0){ if(!results || results.length===0){
@ -138,7 +177,7 @@ export default function Graph({results}){
result={results?.[index]} result={results?.[index]}
showContent={showContent} showKeyword={showKeywords} contentType={contentType} showContent={showContent} showKeyword={showKeywords} contentType={contentType}
textToShow={textToShow} textToShow={textToShow}
color={getColorByGroup(results?.[index])} color={rgbToCss(getColorByGroup(results?.[index]))}
/> />
))} ))}
</group> </group>

@ -230,7 +230,7 @@ export default function Point({point, index, totalPoints, result, showContent, s
if(!result) return; if(!result) return;
console.log("Point result:", result); console.log("Point result:", result, color);
if(result?.type==='keyword'){ if(result?.type==='keyword'){
const title=JSON.parse(result.payload.text??'{}').title; const title=JSON.parse(result.payload.text??'{}').title;
const payloadKeyword={ const payloadKeyword={

@ -0,0 +1,41 @@
export function rgbToCss(rgbArray){
const r255 = Math.round(rgbArray[0] * 255);
const g255 = Math.round(rgbArray[1] * 255);
const b255 = Math.round(rgbArray[2] * 255);
return `rgb(${r255}, ${g255}, ${b255})`;
}
export function getRgbFromIndex(index, length){
const hue = (index / length) * 360;
const saturation = 1;
const lightness = 0.5;
return hslToRgb(hue, saturation, lightness);
}
function hslToRgb(h, s, l) {
let r, g, b;
// normalize h to [0,1] if provided in degrees (0..360)
let hh = h;
if (hh > 1) hh = hh / 360;
if (s === 0) {
r = g = b = l; // achromatic
} else {
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, hh + 1 / 3);
g = hue2rgb(p, q, hh);
b = hue2rgb(p, q, hh - 1 / 3);
}
return [r, g, b];
}

@ -3,6 +3,6 @@ import { invoke } from "@tauri-apps/api/core";
const TD_OSC_PORT=7000; const TD_OSC_PORT=7000;
export function sendOsc(key, message){ export function sendOsc(key, message){
// console.log("Sending OSC:", key, message); console.log("Sending OSC:", key, message);
invoke('send_osc_message', {key: `${key}`, message: message, host:'0.0.0.0:0', target:`127.0.0.1:${TD_OSC_PORT}`}) invoke('send_osc_message', {key: `${key}`, message: message, host:'0.0.0.0:0', target:`127.0.0.1:${TD_OSC_PORT}`})
} }
Loading…
Cancel
Save