• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

Anfängerfrage zu D3.js....

milesdavis

New member
Hey liebe Leute,

man kann in einem Graphen mit der Bibliothek D3.js per Mausklick auf einen Knoten klicken und dadurch seine Verbindungen zu anderen Knoten hervorheben, indem die anderen unverbundenen Knoten durchschtig werden. Zwei Knoten sind mit einer Kante verbunden, die von einem Knoten ausgeht (source) und in den anderen mündet (target).

Dazu folgender Code:

HTML:
//Toggle stores whether the highlighting is on
var toggle = 0;
//Create an array logging what is connected to what
var linkedByIndex = {};
for (i = 0; i < graph.nodes.length; i++) {
    linkedByIndex[i + "," + i] = 1;
};
graph.links.forEach(function (d) {
    linkedByIndex[d.source.index + "," + d.target.index] = 1;
});
//This function looks up whether a pair are neighbours
function neighboring(a, b) {
    return linkedByIndex[a.index + "," + b.index];
}
function connectedNodes() {
    if (toggle == 0) {
        //Reduce the opacity of all but the neighbouring nodes
        d = d3.select(this).node().__data__;
        node.style("opacity", function (o) {
            return neighboring(d, o) | neighboring(o, d) ? 1 : 0.1;
        });
        link.style("opacity", function (o) {
            return d.index==o.source.index | d.index==o.target.index ? 1 : 0.1;
        });
        //Reduce the op
        toggle = 1;
    } else {
        //Put them back to opacity=1
        node.style("opacity", 1);
        link.style("opacity", 1);
        toggle = 0;
    }
}

Im Grunde habe ich verstanden, dass man die Knoten durchgeht und schaut, welche Knoten miteinander verbunden sind.
Nur verstehe ich diese Zeile nicht. Man kreiert ein Array namens linkedByIndex und geht alle Knoten durch:

HTML:
//Create an array logging what is connected to what
var linkedByIndex = {};
for (i = 0; i < graph.nodes.length; i++) {
    linkedByIndex[i + "," + i] = 1;
};

Aber was bedeutet linkedByIndex[i + "," + i] = 1 ? Was soll die eins bedeuten?

Das gleiche hier im nächsten Schritt.
HTML:
graph.links.forEach(function (d) {
    linkedByIndex[d.source.index + "," + d.target.index] = 1;
});

Ausserdem verstehe ich diese Zeile Code ebenso wenig:
HTML:
//This function looks up whether a pair are neighbours
function neighboring(a, b) {
    return linkedByIndex[a.index + "," + b.index];
}

Ich hoffe, jemand hat Erbarmen und hilft mir aus.
Vielen Dank liebe Freunde.
 
Zuletzt bearbeitet von einem Moderator:
" Das soll bedeuten, dass jeder Knoten mit sich selbst verbunden ist."

Wozu soll dies denn gut sein?

- - - Aktualisiert - - -

Noch eine Frage hierzu:

Code:
graph.links.forEach(function (d) {
    linkedByIndex[d.source.index + "," + d.target.index] = 1;
});

Er bildet quasi für jedes Element der JSON-Datei mit
Code:
forEach
ein
Code:
linkedByIndex[d.source.index + "," + d.target.index] = 1
.

Heisst also für zum Bespiel für eine Kante mit Source-Index 0 und Target-Index 2:


linkedByIndex[0 , 2] = 1

Und dann wird geschaut, ob die Knoten jeweils verbunden sind durch diese Zeilen:

Code:
//This function looks up whether a pair are neighbours
function neighboring(a, b) {
    return linkedByIndex[a.index + "," + b.index];
}



Aber was ist hier genau "a" und was ist "b"? In dem praktischen Beispiel wählt man einen Knoten und es werden alle verbundenen Knoten hervorgehoben. Ist dann "a" der ausgewählte Knoten?
 
Habe nochmal versucht auf die Lösung zu kommen.
Angenommen wir haben fünf Nodes mit gewissen size-Werten, die hier unwichtig sind und 5 Links mit jeweils source-und target Werten:

nodes: [
{size: 10},
{size: 5},
{size: 2},
{size: 3},
{size: 30},
{size: 40}
],
links: [
{source: 0,target: 1},
{source: 0,target: 2},
{source: 1,target: 0},
{source: 3,target: 0},
{source: 4,target: 1}



Nun bilde ich ja mit
Code:
linkedByIndex[i + "," + i] = 1
eine Einheitsmatrix, die so aussieht:




1 0 0 0 0

0 1 0 0 0

0 0 1 0 0

0 0 0 1 0

0 0 0 0 1


Danach wird mit dem Code
Code:
graph.links.forEach(function (d) {
    linkedByIndex[d.source.index + "," + d.target.index] = 1;
});

und den links-Eigenschaften

links: [
{source: 0,target: 1},
{source: 0,target: 2},
{source: 1,target: 0},
{source: 3,target: 0},
{source: 4,target: 1}

eine Adjazenzmatrix erzeugt:



0 1 1 0 0

1 0 0 0 0

0 0 0 0 0

1 0 0 0 0

0 1 0 0 0


Nun habe ich zwei Matrizen...

Aber was macht der Code mithilfe dieser beiden Matrizen mit dem Code unten?


Code:
//This function looks up whether a pair are neighbours
function neighboring(a, b) {
    return linkedByIndex[a.index + "," + b.index];
}
 
Zuletzt bearbeitet:
Wozu soll dies denn gut sein?
Damit die markierte Node nicht transparent gemacht wird...

für jedes Element der JSON-Datei
Ich bin mir ziemlich sicher, dass das keine Elemente sind, die über eine JSON-Datei definiert wurden... wenn dann nur indirekt, aber für eine genauere Aussage bräuchten wir den kompletten Code.

Aber ja, forEach iteriert über ein Array.

Heisst also für zum Bespiel für eine Kante mit Source-Index 0 und Target-Index 2:

linkedByIndex[0 , 2] = 1

Nein. Das hatte ich auch schon im anderen Thread geschireben. Das, was du da geschrieben hast, ist keine valide JS-Syntax. Es bedeutet linkedByIndes["0,2"] = 1 - das ist was anderes.

Und dann wird geschaut, ob die Knoten jeweils verbunden sind durch diese Zeilen:
Ja.

Aber was ist hier genau "a" und was ist "b"?
Das kannst du doch dort ansehen, wo die Funktion aufgerufen wird...

Ist dann "a" der ausgewählte Knoten?
Nicht immer - schau' dir den Funktionsaufruf an.

Einheitsmatrix [...] Adjazenzmatrix
NEIN. Du hast da keine Matrix! Nur ein Objekt; und auch wirklich nur ein einziges.
Das sieht bei deinem Beispiel am Ende so aus:
Code:
{
	"0,0": 1,
	"1,1": 1,
	"2,2": 1,
	"3,3": 1,
	"4,4": 1,
	"0,1": 1,
	"0,2": 1,
	"1,0": 1,
	"3,0": 1,
	"4,1": 1
}

Aber was macht der Code mithilfe dieser beiden Matrizen mit dem Code unten?
Da wird einfach der Wert aus dem Objekt ausgelesen... was irritiert dich denn eigentlich so stark?
 
Zurück
Oben