vasturiano / react-force-graph Goto Github PK
View Code? Open in Web Editor NEWReact component for 2D, 3D, VR and AR force directed graphs
Home Page: https://vasturiano.github.io/react-force-graph/example/large-graph/
License: MIT License
React component for 2D, 3D, VR and AR force directed graphs
Home Page: https://vasturiano.github.io/react-force-graph/example/large-graph/
License: MIT License
Hello
I am trying to pass new data into the graph with
this.setState({graph: this.state.graph.concat(newGraph)})
and the graph ist bound to
graphData={this.state.graph}
It renders correctly but onhover and onclick are not working anymore, but only after i passed in new Data.
The nodeCanvasObject function is called, i logged it to the console.
I can pan and zoom on the canvas .
I hope i gave you enough information so that
Thank you in advance
Best regards,
PatStadler
Thank you for this beautiful repo. How do I replace the 3D Text nodes with irregular shapes? For example, my shapes might look something California in this example.
https://threejs.org/examples/#webgl_geometry_shapes
EDIT/ SOLUTION: @vasturiano was extremely patient and helpful as I got up to speed on canvas
and three.js
; the rest of this post is my journey. Here is my bare-bones solution to my original question:
import { ForceGraph3D } from 'react-force-graph';
import { genRandomTree } from './random-data';
var THREE = require('three');
export default class SpriteGraph extends React.Component {
generateMaterial = () => {
//create a canvas
let canvas = document.createElement('canvas');
canvas.width = 160;
canvas.height = 160;
let ctx = canvas.getContext('2d');
//draw a shape
let PI2 = Math.PI * 2;
ctx.beginPath();
ctx.fillStyle = 'blue';
ctx.arc(canvas.width/2, canvas.height/2, 80, 0, PI2, true);
ctx.fill();
//return a material
let texture = new THREE.CanvasTexture(canvas);
let material = new THREE.SpriteMaterial({map: texture})
return material
}
render() {
const data = genRandomTree(100);
return <ForceGraph3D
graphData={data}
nodeLabel="id"
nodeThreeObject={({ id }) => {
let sprite = new THREE.Sprite(this.generateMaterial())
sprite.scale.set(30,30,1)
return sprite
}}
/>;
}
}
Seems with my production builds we are getting a minify issue with TweenLite:
║> react-scripts build ║
║Creating an optimized production build... ║
║Failed to compile. ║
║Failed to minify the code from this file: ║
║ ./node_modules/gsap/esm/TweenLite.js:1966 ║
nodeCanvasObject is excellent for allowing custom painting code over nodes on the graph. Is it possible to also expose a similar method to draw over links?
Add backgroundColor: "rgba(0,0,0,0)"
to ForceGraph3D props.
Background color is clear
Background color is black
"react-force-graph-3d": "^1.2.0",
macOS + Chrome
Is there any control available to dictate the framing of the nodes in the graph on load?
The reason I ask is that I'm building a project where you can add a node at any time (disconnected) and boom it appears there in the graph for you to then grab and connect to others or leave on its own. The issue is that these are sometimes incredibly far from the pre-existing cluster of nodes.
For instance if I add 6-7 new disconnected nodes in a row they end up so far away that I have to zoom far out, pan for a while and drag the little buggers back over to the remainder of the graph.
At first I thought this was an effect of the Node radius I had set rather high but it appears this happens at all values of 'r'. I'm wondering if some constraint value that lets you tighten loose nodes closer to the average centroid of all other nodes is possible in an efficient manner.
Thoughts?
NOTE: I am working in 2D mode specifically.
Is something like this possible to do with react-force-graph?
https://bl.ocks.org/pkerpedjiev/f2e6ebb2532dae603de13f0606563f5b
@vasturiano is it possible to use an image for a node as opposed to the default circle?
The way to use this method to change the charge of the nodes is very unclear!
Can i somehow connect couple of nodes in 1 group but without visible links?
Just a request! Thanks
<ForceGraph3D
ref={el => { this.fg = el; }}
graphData={this.props.GraphReducer}
nodeThreeObject={() =>
new THREE.Mesh(new THREE.DodecahedronGeometry(Math.random() * 10),
new THREE.MeshLambertMaterial({color: Math.round(Math.random() * Math.pow(2, 24)),transparent: true,opacity: 0.75}))}
/>
Do you have some methods help me import THREE into react environment?
Apologies, I know this isn't specifically a Force Graph issue, but I'm a bit confused about how to use ForceGraph when including the CDN reference:
<script src="//unpkg.com/react-force-graph"></script>I'm getting the issue that it cannot find the 2d and 3d definition:
Line 623: 'ForceGraph3D' is not defined react/jsx-no-undef
Line 634: 'ForceGraph2D' is not defined react/jsx-no-undef
I'm not sure how to pull in from the CDN in a React friendly way:
import { ForceGraph3D } from 'react-force-graph'
import { ForceGraph2D } from 'react-force-graph'
Thanks!
Is there any possibility to access scene renderer from my component?
I need to add a shadow to my graph, and add a parameter { antialias: true }
to make it less sharp.
Hi I cannot load graph because of Uncaught TypeError: selection.interrupt is not a function in my react app.
I tried:
import { ForceGraph2D} from 'react-force-graph';
or
const{ ForceGraph2D} = require('react-force-graph');
...
return (
)
Detail error:
Uncaught TypeError: selection.interrupt is not a function
at Function../node_modules/force-graph/node_modules/d3-zoom/src/zoom.js.webpack_exports.default.zoom.transform (zoom.js:90)
at Function../node_modules/force-graph/node_modules/d3-zoom/src/zoom.js.webpack_exports.default.zoom.translateBy (zoom.js:119)
at adjustCanvasSize (force-graph.module.js:605)
at Function.init (force-graph.module.js:852)
at u (kapsule.min.js:1)
at Object.r [as comp] (kapsule.min.js:1)
at FromKapsuleComp.componentDidMount (react-kapsule.module.js:85)
at commitLifeCycles (react-dom.development.js:14685)
at commitAllLifeCycles (react-dom.development.js:15905)
at HTMLUnknownElement.callCallback (react-dom.development.js:145)
I have newest version of package.
What's wrong with my code?
Web canvas requires additional scaling to support Retina displays. See here: https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Syntax
I would like to use the code snippet mentioned in the link above, but the ideal time to adjust the canvas scaling is when the animation/forceSimulation is done. Scaling the canvas on every tick causes major performance issues in my graph that has hundreds of nodes/links.
But I don't see any kind of "onSimulationEnd" callback/prop, so I'm not sure how to execute code specifically when the simulation has ended. Any ideas on how to scale the canvas for Retina displays without trying to re-scale the canvas through nodeCanvasObject
prop?
Right now, the only solution I can think of is:
cooldownTime
prop to X milliseconds.setTimeout
to run canvas scaling code snippet after X+1 milliseconds.But of course, the above solution is crummy because it's hard to pick a good value for X.
Actually, it's worse than I thought. Pan/Zoom will undo the canvas scaling, causing bizarre painting. So even using a setTimeout
doesn't work for graphs that allow pan/zoom.
How am i supposed to use method if i have no instance in react?
add gitignore
I'm trying to implement node selection in ForceGraph3D component.
As I can see, every time I'm calling setState(), graph restarts physics simulation even if graph data wasn't modified.
Part of code which shows selected links
linkWidth={link => this.state.DataProvider.isSelectedLink(link) ? 3 : 1}
Following code works pretty well and all needed links are changing their width, but graph also restarts physics simulation and all nodes are jumping and oscillating
If I'm not calling setState() and just update selected links in my DataProvider class, I can't see any changes in the graph
Without react bindings I've achieved pretty good effect just calling (without simulation restart on select)
Graph.nodeRelSize(this.relSize);
Hello
Is it somehow possible to set the cursor to 'pointer' when hovering over nodes?
I've tried different approaches now, like setting body css if mouse enters a node and back to auto if it leaves. But i can't figure out how to do it. Maybe you can help me with this problem.
Thank you in advance
Best regards,
PatStadler
I'm adding a new component to my app. The component uses react-force-graph
. I test my app using Enzyme + jsdom. But when I try to test my new component, I run into: "screen is not defined" error that causes the tests to crash.
I noticed the error disappears if I comment out import { ForceGraph2D } from 'react-force-graph';
.
At first, I simply added globals to my test setup.js
file as seen in this example: https://gist.github.com/yan130/386d6c79d975de580c8c343a0423b66d (notice how it adds window.screen
and global.screen
). But then the error became "self is not defined". I added self
to my setup.js
, and now the error is "XMLHttpRequest is not defined".
So now I imagine there is something very wrong with my approach. I must be doing something wrong. I can't just keep adding every browser API to my setup.js
. And it seems odd that the error occurs when I import
the ForceGraph2D component.
Anybody have success using ForceGraph2D
in their app and testing it with Enzyme?
I'd like to add a label to the curved links in the 2D version very similar to https://developer.mozilla.org/en-US/docs/Web/SVG/Element/textPath, do you have any suggestions on how to achieve this? Maybe using https://github.com/Viglino/Canvas-TextPath?
Feature request to randomize the timing of link particle emission. It feels too uniform currently because they all emit at the same time. Perhaps introduce linkDirectionalParticleRandomizationFactor
?
I tried npm i react-force-graph and kept hitting the same error:
warning: templates not found C:\Users\USERNAME\AppData\Local\Temp\pacote-git-template-tmp\git-clone-169f0298
Fatal: The remote end hung up unexpectedly
when trying with --verbose, it seems to hang on https://registry.npmjs.org/@tweenjs%2ftween.js
any idea why?
I've noticed that in the 2D graph, the hover label is centered directly on the mouse so it prevents the mouse from being able to directly drag the node.
I believe it's caused by the following CSS:
.graph-tooltip {
...
transform: translate(-50%, 25px);
...
}
In my project I overwrote this by changing the 25px to 15px.
Thoughts?
I have some invisible links, but somehow they appear over other links sometimes.
Example: http://ec2-52-14-138-28.us-east-2.compute.amazonaws.com/
Hello
I can't see the nodeLabel.
How can I solve this?
This is an excellent module..
I want to solve this ASAP.
Best Regards,
Gordal18
Hi,
Thanks for this great library!! :)
How can I get the following one?
Addition to showing labels on hovering, need an option to show all the labels of a particular attribute across the graph. Like labeled nodes with name or id or val?
Hi @vasturiano
I have calculated the distance between each of my variables and included that distance in the links data. What is the simplest way to use this as the distance between nodes my component? d3Force=???
I know below is incorrect, but just to give an idea.
export default class TextGraph extends React.Component {
render() {
const {data} = this.props;
return <ForceGraph3D
graphData={data}
d3Force = { ('link', "distance")}
nodeLabel = "desc"
cooldownTime={15000}
d3AlphaDecay={0}
d3VelocityDecay={0}
nodeAutoColorBy="group"
enableNodeDrag={false}
nodeThreeObject={node => {
const sprite = new SpriteText(node.id);
sprite.color = node.color;
sprite.textHeight = node.revenue;
return sprite;
}}
/>;
}
}
Thank you.
While the API shows methods for onHover and onClick of both nodes and links, there doesn't readily appear to be a way of detecting drag events. In my own project I save the locations of elements and would like to do this at the end of a drag event. Are there plans / an existing strategy to accomplish this detection of drag states?
I'm having trouble making the force graph horizontal. (ex: http://d3indepth.com/force-layout/#forcex-and-forcey)
I'm trying to do this using d3Force methods but since there's only the three default ones I don't know how to use forceX or forceY to change the position.
thanks!
edge position does not update for ForceGraphVR in all-modes example
it looks like this occurs when
random-data.js
)live example to reproduce the issue https://bl.ocks.org/micahstubbs/1d0c15a8dbb33f39b5e2a70e69514712
I need the same functionality as nodeThreeObject
, but for links, as i need to change it's material to MeshBasicMaterial
. Thanks
Hello,
I see there is an option to use custom shapes for nodes.. Is it possible to use that approach to set an SVG image for different nodes? Or maybe there is a different node to do so... something like
"nodes": [
{
"id": "id1",
"name": "name1",
"val": 1 ,
"icon": svg_object_here // <----- is something like that possible?
},
....
Thanks!
<ForceGraph3D
ref={el => { this.fg = el; }}
graphData={this.props.GraphReducer}
linkWidth={3}
linkCurvature="curvature"
/>
The linkCurvaure will be disabled if I set linkWidth. If I delete linkWidth, the Curvature will work.
Is it possible to add a callback to the Graph so that it fires a callback on idle of the camera? When a user interacts via mouse scrolling and panning I'd like to actively memorize where they left off for later usage. Currently I have a zoom in and zoom out button in my own implementation and these keep track of zoom value but mouse panning/zooming disrupts this binding of zoom value.
Many thanks again for this excellent library!
Feature request:
Would be awesome to have a function to emit particles on-demand.
this.graph.emitDirectionalParticle(linkId)
// or
this.graph.emitDirectionalParticle(linkSrc, linkDest)
Love this library, saved me some serious start up time on my current project!
While attempting to use the linkCurvature property in conjunction with the onLinkHover property I noticed that the curvature does not apply to the hit box of the hover. So although the line visually curves properly, hovering over the curved line will not trigger the onHover. However, hovering over the space where a straight link would be will fire the event as though the link is still straight.
Easy to reproduce using a curvature of .5 with onLinkHover.
It seems like the THREE imports are clashing when I import ForceGraph3D from react-force-graph into an existing AFrame application (which has its own THREE dependency).
NotSupportedError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'a-node'. A type with that name is already registered.
Is there a way around this issue?
@vasturiano have you tried any examples loading from a state manager like Mobx or Redux? Getting some errors populating data from a Mobx observable variable.
warning.js:33 Warning: Failed prop type: Invalid prop
graphData.nodesof type
objectsupplied to
ForceGraph2D, expected an array.
Looks like rendering the data gets caught in a wonky state.
I need to open a context menu when clicking on the node. The problem is that the onNodeClick callback parameter gives me the values which don't look like absolute position:
fx: undefined, fy: undefined, vx: 0, vy: 0, x: 12.152664474162155, y: 12.520373695711815
In Javascirpt verions, we can have:
const Graph = ForceGraph3D()
I want to access the Graph in React so I can do some changes.
I found this link and know someone has already implemented the feature:
In the issue, we can have: Graph.nodeRelSize(this.relSize);
Can anyone tell me a method to do it? Thanks
Hello! Thank you for writing this plugin - it has been extremely helpful.
I noticed a bug, which is that the label position is appears to be affected by how much content is "above" the graph renderer. I believe this may be the same issue referenced in #16. Here are screenshots demonstrating the effect:
The default functionality, which can be seen in demos, is that the label is just below the cursor:
When I added a large header with buttons for testing things, the label appears above the cursor:
In production, we'll have a much smaller toolbar. The labels are now displaying directly in front of the cursor, preventing interaction with the underlying nodes:
For some context: the header is just some div
s with buttons and a p
tag (nothing remarkable).
Is there a property I can set to get the desired behavior (text is always below)? In the meantime I may dive into the source to find the original problem, but I'm not familiar with building applications using rollup
Hi,
and thanks for this great package you made available here.
Everything is working well for us but optimization wise, I'd like to know if there is a way to only import the <ForceGraph2D>
component without having to load and embed in my package the VR and the 3D components and underlying libraries.
For know webpack produces builds with everything and I end up having to load AFrame and Three.js in the browser, even though I don't use them.
Thanks in advance for informations around that matter.
I was wondering what the best approach to smoothly moving to a point would be given (x,y,z)?
I'm currently using a 2D graph and when I add a node I'd like to smoothly pan the camera to wherever it ends up being made. I took a look at some underlying d3 code and see you can use interpolators to "tween" from one value to another but I'm not sure how to expose that via this library.
Also, for now I've just added an arbitrary timeout to wait for the graph to stop animating since the location of the new node is unknown/fluid until the animation completes but I'm sure there is a better solution to this.
Thoughts?
Please add a callback function for component to know when the render starts.
As you can see on attached video, there is a white screen between loader and view render.
Component is already rendered(as nav info is visible at the bottom), but I need to know when I can hide preloader to prevent this white screen.
https://www.useloom.com/share/c0e5a82021e749c9a3c9099aaa1fbfaf
If I want to change a specific node(or edge), how can I do it?
For example, suppose every node has an id, after drawing the graph, I want to change node one(id: node1)'s color if I click a button outside the graph.
After clicking the button, what I did is to iterate the node list of the graph, and find the id to change the graph's color. However, how can I update the graph? I don't want to redraw the layout. Only change the node's color is enough.
Thanks in advance.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.