GithubHelp home page GithubHelp logo

Comments (16)

wadehenning avatar wadehenning commented on May 17, 2024 1

Hi @vasturiano .

  1. Yes- the example works fine without the nodeThreeObject.
  2. generatesprite always returns a Sprite object created using a canvas and context path. Is this appropriate?

I'm working on a codesandbox.

from react-force-graph.

vasturiano avatar vasturiano commented on May 17, 2024 1

The ctx is the canvas context onto which you should run the drawing commands (like fillRect, beginPath, etc). You can not pre-draw on a separate canvas and then apply it to the chart canvas.

The { id, x, y} is just a way to unpack the node's data. You can simply replace that with:

.nodeCanvasObject((nodeData, ctx) => { ... }

The nodeData is useful to let you define how a particular node should look like. For example, you may want node id = 1 to be drawn red, and id = 2 to be drawn green. You can do that by writing your drawing logic based on the nodeData attributes.

from react-force-graph.

vasturiano avatar vasturiano commented on May 17, 2024 1

@wadehenning you should create a new canvas context as part of the operation of generating a THREE object. Remember that this canvas is not attached to the DOM, it serves only the purpose of the sprite construction, so you don't need to get it from or link it with the 3d graph itself.

from react-force-graph.

vasturiano avatar vasturiano commented on May 17, 2024

@wadehenning thanks for reaching out. You can set any custom geometries for the nodes, using the nodeThreeObject prop.

Here's an example with custom geometries:
https://vasturiano.github.io/react-force-graph/example/custom-node-shape/index-three.html
https://github.com/vasturiano/react-force-graph/blob/master/example/custom-node-shape/index-three.html

from react-force-graph.

wadehenning avatar wadehenning commented on May 17, 2024

Thank you for focusing me on the nodeThreeObject. I think I am close to being able to plot a 2D curve (ignoring the Sprite part for now), but I am getting an error: TypeError: shape.extractPoints is not a function. Any thoughts?

My component code:
<ForceGraph3D
graphData={data}
nodeThreeObject={ ({id}) => new THREE.Mesh(
[
new THREE.ShapeBufferGeometry( {shape} )
][id%1],
new THREE.MeshPhongMaterial(
{ color: 0xf08000} )
)}
/>;

My shape:
// California
var californiaPts = [];
californiaPts.push( new THREE.Vector2( 610, 320 ) );
californiaPts.push( new THREE.Vector2( 450, 300 ) );
..................................
californiaPts.push( new THREE.Vector2( 610, 320 ) );
for( var i = 0; i < californiaPts.length; i ++ ) californiaPts[ i ].multiplyScalar( 0.25 );
var shape = new THREE.Shape( californiaPts );

from react-force-graph.

wadehenning avatar wadehenning commented on May 17, 2024

I think I'm doing something wrong with sending the shape to the component

from react-force-graph.

wadehenning avatar wadehenning commented on May 17, 2024

I have been working to get a simple custom shape plotted and I am getting the error: TypeError: Cannot read property 'extractPoints' of undefined.

Does my simple code look correct?

import React, { Component } from 'react';
import { ForceGraph2D, ForceGraph3D, ForceGraphVR } from 'react-force-graph';
import * as THREE from 'three';

export default class FocusGraph extends React.Component {
render() {
const {data, shape} = this.props;
console.log(shape)
return <ForceGraph3D
graphData={data}
nodeThreeObject={ ( {shape} ) => new THREE.Mesh(
[
new THREE.ShapeBufferGeometry( shape )
],
new THREE.MeshPhongMaterial(
{ color: 0xf08000,
side: THREE.DoubleSide} )
)}
/>;
}
}

My shape looks like this:
// California
var californiaPts = [];
californiaPts.push( new THREE.Vector2( 610, 320 ) );
californiaPts.push( new THREE.Vector2( 450, 300 ) );
...
californiaPts.push( new THREE.Vector2( 610, 320 ) );
for( var i = 0; i < californiaPts.length; i ++ ) californiaPts[ i ].multiplyScalar( 0.25 );
var shape = new THREE.Shape( californiaPts );

Thanks

from react-force-graph.

wadehenning avatar wadehenning commented on May 17, 2024

I'm sure I'll figure it out.

from react-force-graph.

wadehenning avatar wadehenning commented on May 17, 2024

I have been able to get all of your examples working, and I have been able to add custom shapes. But I am still having trouble with custom sprites of shapes. My sprite code seems to generate sprites, but I get an error message:
Uncaught TypeError: Cannot read property 'x' of undefined
at WebGLSpriteRenderer.render (aframe-master.js:12357)
at WebGLRenderer.render (aframe-master.js:27568)
at Function.tick (three-render-objects.module.js:100)
at Function.r.(:3000/anonymous function) [as tick] (http://localhost:3000/static/js/bundle.js:161238:1813)
at animate (3d-force-graph.module.js:391)

I hope that my code is close enough for your review.

First I have a simple React Component, followed by short code to make my sprite.

export default class SpriteCurves extends React.Component {
render() {
const {data, shape, geometry} = this.props;
return <ForceGraph3D
graphData={data}
nodeAutoColorBy="group"
nodeThreeObject={() => {
const sprite = generatesprite(shape);
return sprite;
}}
/>;
}
}

SPRITE CODE:
function generateTexture(shape) {
var canvas = document.createElement( 'canvas' );
canvas.width = 20;
canvas.height = 20;
var context = canvas.getContext( '2d' );
var canvasShape = shape;
return canvas;
};

export function generatesprite(shape){
var texture = new THREE.Texture( generateTexture(shape) );
texture.needsUpdate = true; // important!
var material = new THREE.SpriteMaterial( { map: texture, color: 0xffffff } );
material.sizeAttenuation = false;
var sprite = new THREE.Sprite( material );
console.log(sprite);
return sprite;
};

from react-force-graph.

vasturiano avatar vasturiano commented on May 17, 2024

Hi @wadehenning could you make an example online, on CodePen or similar so that it's easier to debug?

For now, I'd check whether:

  1. Does the example work fine if you don't use the nodeThreeObject prop?
  2. Does generatesprite always return a non-null Three Object3D?

from react-force-graph.

wadehenning avatar wadehenning commented on May 17, 2024

Hi @vasturiano.
Your incisive questions helped me figure out the error I was getting and I think I am getting close. I am now focusing on simply getting my irregular polygons to plot as contexts in 2D. The links plot perfectly and I get no errors, but I also get no nodes at all. Any thoughts on this code? CTX is an array of contexts generated from my polygons. I have tried enclosing {CTX} in curly braces in the nodeCanvasObject with no change. Maybe I am just missing something regarding how to pass data into the component.

    render() {                
      const {Shapes, data, CTX} = this.props;        
      console.log(CTX);
      return <ForceGraph2D    
          graphData={data}  
          nodeLabel="id"  
          nodeCanvasObject={ CTX => {         
                 () => {  CTX.fill(); }
          } }           
    />;
    }
  }

from react-force-graph.

vasturiano avatar vasturiano commented on May 17, 2024

@wadehenning the signature of nodeCanvasObject is

.nodeCanvasObject((<nodeData>, <canvas context>, <current global scale>) => { /* ... do something with the context for representing this node */ })

In your code above, you're not unpacking the function signature correctly, it should be (node, ctx) => {...}.

Also you should do some drawing operations on the context, otherwise ctx.fill() has nothing to fill.

Here's an example of using the nodeCanvasObject that may be of help:
https://github.com/vasturiano/force-graph/blob/master/example/custom-node-shape/index.html

from react-force-graph.

wadehenning avatar wadehenning commented on May 17, 2024

@vasturiano in the line below, I don't understand where the values for the input parameters come from. What is the value of ctx and where is it coming from? Where are id, x,, y coming from when you don't call gData until later? So in my code, I pre-draw the ctx polygons, save it in state and send it through props as array CTX.

.nodeCanvasObject(({ id, x, y }, ctx) => {

If I simply add my nodes data to the function as an input parameter it does not help, so I clearly need something different.
Thank you!

from react-force-graph.

wadehenning avatar wadehenning commented on May 17, 2024

Hi @vasturiano
I would like to generate sprites from irregular polygons in a ForceGraph3D component. The Sprite requires a ctx, ctx only comes from a nodeCanvasObject, but ForceGraph3D requires a nodeThreeObject. Do I need to define a canvas inside the component myself? Also, what do you think about how I try and create a Sprite here in my nodeThreeObject? For me, this 3d-force-sprite component is the whole purpose; everything else is just trying to learn the API. Thank you.

export default class SpriteGraph extends React.Component {

    componentDidMount(){  
        this.fg.d3Force('link').distance(links => links.area_dist)
        .iterations(1);
    }    

    generateTexture = (ctx, points, color) => {
            ctx.fillStyle = color;               
            ctx.beginPath(); 
            ctx.moveTo(points[0][0],points[0][1]); 
            for(let i=1; i<points.length;i++){
                ctx.lineTo(points[i][0], points[i][1]); 
            } 
            ctx.fill();
            return ctx;
        }

    render() {
       const data = this.props.data;   
       const getColor = n => '#' + ((n * 1234567) % Math.pow(2, 24)).toString(16).padStart(6, '0');
        return <ForceGraph3D   
        ref={el => { this.fg = el; }}
            d3Force = { ('link', "distance")}
            cooldownTime={90000}        
            graphData={data}
            nodeLabel="id"
            nodeThreeObject={({ id, points }, ctx) => new THREE.Sprite(
                new THREE.SpriteMaterial(
                new THREE.Texture(this.generateTexture(ctx, points, getColor(id)))                  
                ),               
            )}
           
        />;
    }
}


from react-force-graph.

wadehenning avatar wadehenning commented on May 17, 2024

Hi @vasturiano
I am generating random data and trying to plot a sprite with a circle at each node. I do get tiny squares at each node; which to me indicates that a Sprite is being created, but there is a fail somewhere.

Here is a link to a code sandbox where the preview does not work. I think this is related to the force-graph package (it did preview intermittently when I first copied in the example Custom Node Geometries code) , and maybe you have some experience getting these things to render better in these environments.

from react-force-graph.

wadehenning avatar wadehenning commented on May 17, 2024

@vasturiano , I'm sorry that you've had to walk me through this sprite example-- this is the first time I have ever worked with three.js or canvas. What I have learned here has helped me in other components that require canvas, and I appreciate your time.

I don't know if you have had a chance to look at the code sandbox I put up- even though the preview does not work, at least the code is all on one page and it is a trivial example. Here is what my output looks like. It is making some sort of tiny sprite node, but does not include my circles.
spritegraph

from react-force-graph.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.