hololink-graph-overview's People
hololink-graph-overview's Issues
force diagram - how to overcome NER generate same basestone and stellar keyword on separated output
if key_title not in nodevalidator:
if key_group == "basestone":
d3node.append({"id":f"{key_title}", "level":"basestone", "connection":1})
nodevalidator.append({f"{key_title}":"basestone"})
elif key_group == "stellar":
d3node.append({"id":f"{key_title}", "level":"stellar", "connection":1})
nodevalidator.append({f"{key_title}":"stellar"})
else:
for node in d3node:
if node['id'] == key_title:
if node['level'] == key_group:
node['connection'] += 1
There will be some errors on force diagram
the reason is when we compute NER, the machine may recognize some keywords as basestone and stellar at separated output, so we need to adjust that afterward.
and then I noticed that the code have another fault!
if key_title not in nodevalidator: #because nodevalidator is now a list of dict so it will make some unexpected issue
if key_group == "basestone":
d3node.append({"id":f"{key_title}", "level":"basestone", "connection":1})
nodevalidator.append({f"{key_title}":"basestone"})
elif key_group == "stellar":
d3node.append({"id":f"{key_title}", "level":"stellar", "connection":1})
nodevalidator.append({f"{key_title}":"stellar"})
else:
for node in d3node:
if node['id'] == key_title:
if node['level'] == key_group:
node['connection'] += 1
so we now make nodevalidator to list of string and use other method to detect whether a keystone had been generated as stellar and basestone at same time.
if key_title not in nodevalidator:
if key_group == "basestone":
d3node.append({"id":f"{key_title}", "level":"basestone", "connection":1})
nodevalidator.append(f"{key_title}")
elif key_group == "stellar":
d3node.append({"id":f"{key_title}", "level":"stellar", "connection":1})
nodevalidator.append(f"{key_title}")
else:
for node in d3node:
if node['id'] == key_title:
if node['level'] == key_group:
node['connection'] += 1
else: #只要 basestone 和 stellar 重複出現,則都將其 level 改為 basestone
node['level'] = 'basestone'
node['connection'] += 1
now the diagram work as what we want
How to wrap long text in force diagram?
First of all, there is only a method provide by mbostock on internet, all solution surround that.
https://bl.ocks.org/mbostock/7555321
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
To speed the process of coding I try this solution too, and discover various problems.
- Only support English.
- Base on every English letter, which is not accurate.
- Need to be adjust when use force diagram
But still, thanks mbostock for providing this elegant code.
When I first implement this function this is what I got, Which definitely have some problem. And I discovered when you want to wrap chinese letter you have to customize it.
and I begin working on chinese version. First, I replace this line words = text.text().split(/\s+/).reverse(),
with text.text().split('').reverse(),
to fit chinese characteristic. Then the diagram become:
In the console I discovered that I didn't pass x and y variable correctly. And after dig inside the code I recognized that I misunderstood the whole logic of d3 force. For regular diagram such as bar chart, I believe the x and y parameter of every nodes are computed after you use data().enter()
binding the data. But force diagram is different, the computing process begin when you call simulation on and ticking which is totally logical.
If you want to access the computed x, y and store them inside every nodes as a attribute, you need to initiate simulation first then selectAll and modify it.
From then on, I want to make sure I get the computed x, y parameter.
var nodeElements = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter()
.append("circle")
.attr("r", getNodeSize)
.attr("fill", getNodeColor)
.style("stroke", getLinkColor)
.attr("x", function(d){ return d.x; })
.attr("y", function(d){ return d.y; })
.on('mouseover.fade', fade(0.2))
.on('mouseout.fade', fade(1));
var textElements = g.append("g")
.attr("class", "text")
.selectAll("text")
.data(graph.nodes)
.enter()
.filter(function(d){
return d.connection >= 2 || d.level == 'article'
})
.append('text')
.text(node => node.id)
.attr('text-anchor', 'middle')
.attr('font-family', "'Noto Sans TC', sans-serif")
.attr('font-weight', getTextFontWeight)
.attr('font-size', getTextFontSize)
.attr("x", function(d){ return d.x; })
.attr("y", function(d){ return d.y; })
.style('fill', 'black')
.each(wrap);
function wrap(d) {
if (d.connection >= 2 || d.level == 'article'){
var text = d3.select(this),
width = getNodeSize(d),
words = text.text().split("").reverse(),
word,
x = d.x
y = d.y
line = [],
lineNumber = 0,
lineHeight = 1.1,
tspan = text.text(null).append("tspan").attr("x", x).attr("y", y);
console.log(d, d.x, text.attr('x')) // <= this output interesting data
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(""));
//console.log(word, tspan.node().getComputedTextLength(), x,y)
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(""));
line = [word];
tspan = text.append("tspan").attr("x", x).attr("y", y).attr("dy", ++lineNumber * lineHeight + "em").text(word);
}
};
}
};
d is node's array and is including the computed x, y for sure, but when you try to access d.x it become another data which is node attribute we put into it previously. What exactly is that and how we get the actual computed x,y.
What I had tried:
- Learned the data format you can load into function when use
selectAll() & data()
function (d, i, nodes){
d = node
nodes = arrays contain all nodes
i = index
nodes[i] = d
}
- The process of force diagram
a. simulation: if node is empty then create an empty array.
b. simulation.node(): this method will arrange the position
c. so in theory I should get the x after sinulation.
-
I should put it before selectAll to get x is wrong. The reason is simple, at that moment there is no force, just some nodes. So the nodes will arrange on a line, that is the reason I get a singular x in node array.
-
some data format thought different process
var nodeElements = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter()
.append("circle")
.attr('test', testing)
function testing(d, i, nodes){
node = d3.select(this)
node_data = d3.select(this).datum()
console.log(this, node, node_data ,d)
}
=> 1. ...with node data
=> 2. d3 selection format of node data
=> 3. node array
=> 4. node array
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.