Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

希望增加斥力布局自定义demo #2239

Closed
zmcode opened this issue Jun 17, 2022 · 4 comments
Closed

希望增加斥力布局自定义demo #2239

zmcode opened this issue Jun 17, 2022 · 4 comments
Labels
type: feature 新功能 Feature/enhancement requests

Comments

@zmcode
Copy link

zmcode commented Jun 17, 2022

功能描述

https://observablehq.com/@d3/disjoint-force-directed-graph?collection=@d3/d3-force

希望能出一个连接上的demo, 我看了force的源码, forceSimulation这个自定义文档说是Object类型, 但是我看源码, 如果不传, 使用的是d3.forceSimulation(), 但是要使用斥力, 我看都是需要使用这个的吧, 我不怎么懂d3
image
image,

链接上的demo是需要使用
d3的.force("x", d3.forceX())
.force("y", d3.forceY()), 而不使用源码里面的center()
所以我想自己用d3实现, 可是不行, 斥力的范围很小
image

ForceGraph方法就是demo链接上的方法, 最终效果只能这样
image

还有一个问题就是tick方法会多次执行, 我不却不断地formJSON, 会导致页面非常卡, 是否可以只改变节点的位置?, 这样下来无法实现拖动的时候, 再次重新渲染, 就是拖动某个节点, 其他节点会变动,有个动画的效果

需要做的需求是动态的增删数据用拓扑图显示, 因为有编辑功能, 所有考虑使用x6, 不想单独使用g6来实现, 作者帮忙看看,码字不易

琢磨了2天, 实在实现不出来了

期望解决方案

希望出demo的功能

@zmcode
Copy link
Author

zmcode commented Jun 17, 2022

ForceGraph方法可以使用这个, 因为demo里的方法是直接通过svg来塞数据的, 所以我这边直接返回simulation来tick
`

function ForceGraph({
nodes, // an iterable of node objects (typically [{id}, …])
edges // an iterable of link objects (typically [{source, target}, …])
}, {
nodeId = d => d.id, // given d in nodes, returns a unique identifier (string)
nodeGroup, // given d in nodes, returns an (ordinal) value for color
nodeGroups, // an array of ordinal values representing the node groups
nodeTitle, // given d in nodes, a title string
nodeFill = "currentColor", // node stroke fill (if not using a group color encoding)
nodeStroke = "#fff", // node stroke color
nodeStrokeWidth = 1.5, // node stroke width, in pixels
nodeStrokeOpacity = 1, // node stroke opacity
nodeRadius = 5, // node radius, in pixels
nodeStrength,
linkSource = ({source}) => source, // given d in edges, returns a node identifier string
linkTarget = ({target}) => target, // given d in edges, returns a node identifier string
linkStroke = "#999", // link stroke color
linkStrokeOpacity = 0.6, // link stroke opacity
linkStrokeWidth = 1.5, // given d in edges, returns a stroke width in pixels
linkStrokeLinecap = "round", // link stroke linecap
linkStrength,
colors = d3.schemeTableau10, // an array of color strings, for the node groups
width = 640, // outer width, in pixels
height = 400, // outer height, in pixels
invalidation, // when this promise resolves, stop the simulation
tickedFn = () => {}
} = {}) {
// Compute values.
console.log(d3.map(nodes, nodeId), 'd3.map(nodes, nodeId)')
const N = d3.map(nodes, nodeId).map(intern);
const LS = d3.map(edges, linkSource).map(intern);
const LT = d3.map(edges, linkTarget).map(intern);
if (nodeTitle === undefined) nodeTitle = (_, i) => N[i];
const T = nodeTitle == null ? null : d3.map(nodes, nodeTitle);
const G = nodeGroup == null ? null : d3.map(nodes, nodeGroup).map(intern);
const W = typeof linkStrokeWidth !== "function" ? null : d3.map(edges, linkStrokeWidth);

// Replace the input nodes and edges with mutable objects for the simulation.
// nodes = d3.map(nodes, (_, i) => ({id: N[i]}));
// edges = d3.map(edges, (_, i) => ({source: LS[i], target: LT[i]}));

// Compute default domains.
if (G && nodeGroups === undefined) nodeGroups = d3.sort(G);

// Construct the scales.
const color = nodeGroup == null ? null : d3.scaleOrdinal(nodeGroups, colors);

// Construct the forces.
const forceNode = d3.forceManyBody();
const forceLink = d3.forceLink(edges).id(({index: i}) => N[i]);
if (nodeStrength !== undefined) forceNode.strength(nodeStrength);
if (linkStrength !== undefined) forceLink.strength(linkStrength);
console.log(forceLink, 'forceLink')

const simulation = d3.forceSimulation().nodes(nodes)
    .force("link", forceLink)
    .force("charge", forceNode)
    .force("x", d3.forceX())
    .force("y", d3.forceY())



// Handle invalidation.
if (invalidation != null) invalidation.then(() => simulation.stop());

function intern(value) {
    return value !== null && typeof value === "object" ? value.valueOf() : value;
}
return simulation

}

`

@zmcode
Copy link
Author

zmcode commented Jun 19, 2022

现在基本实现功能了,就是每次tick才能改变位置,数据库100就已经很卡了,尝试只改变position也很卡,作者有什么办法吗

@NewByVector
Copy link
Contributor

NewByVector commented Jun 20, 2022

@yaojin2070 tick 执行太频繁了,可以考虑增加一个节流器。

@NewByVector NewByVector added the type: feature 新功能 Feature/enhancement requests label Jun 21, 2022
@x6-bot
Copy link
Contributor

x6-bot bot commented Jul 10, 2023

This thread has been automatically locked because it has not had recent activity.

Please open a new issue for related bugs and link to relevant comments in this thread.

@x6-bot x6-bot bot locked as resolved and limited conversation to collaborators Jul 10, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: feature 新功能 Feature/enhancement requests
Projects
None yet
Development

No branches or pull requests

2 participants