D3.js - Tipps und Tricks: Unterschied zwischen den Versionen
Aus Wikizone
| Zeile 120: | Zeile 120: | ||
var c10 = d3.scale.ordinal() | var c10 = d3.scale.ordinal() | ||
.range(["#ef7a00", "#f4a24c", "#f7bc7f", "#8aae1a", "#adc65e", "#c4d68c", "#3d3d3c", "#777776", "#9e9e9d", "#899fc4", "#acbcd6", "#c4cfe1"]); | .range(["#ef7a00", "#f4a24c", "#f7bc7f", "#8aae1a", "#adc65e", "#c4d68c", "#3d3d3c", "#777776", "#9e9e9d", "#899fc4", "#acbcd6", "#c4cfe1"]); | ||
| + | |||
| + | == Datensätze verarbeiten == | ||
| + | === JSON File vs Inline JSON === | ||
| + | TODO | ||
| + | <pre> | ||
| + | d3.json("data.json", function(dataset){ | ||
| + | //Extract data from dataset | ||
| + | var nodes = dataset.nodes, | ||
| + | ... | ||
| + | </pre> | ||
| + | <pre> | ||
| + | var data1 = [ { "My JSON data here" } ]; | ||
| + | function getData(){ | ||
| + | return{ "nodes": [{"character": "Design", "id": 0, "influence": 15, "zone": 0 },{"character": "Web", "id": 1,"influence": 15, "zone": 1}],"links": [{"source": 0, "target": 1, "weight": 10}]}; | ||
| + | } | ||
| + | data1.forEach(function (d) { | ||
Aktuelle Version vom 7. Juli 2020, 22:43 Uhr
Aktionen abhängig von den Daten ausführen[Bearbeiten]
Will man beim Daten abarbeiten bestimmte Aktionen abhängig von den Daten Ausführen kann man in vielen Fällen eine anonyme Funktion einsetze oder man nutzt eine Filterfunktion:
Anonyme Funktion für ein HTML-Attribut.
g.selectAll('g')
.data(root.descendants())
.enter().append('g')
.attr("class", "node")
.append('path')
.attr("display", function (d) { return d.depth ? null : "none"; }); // do not show root element
Filterfunktion
newSlice.filter(d => (d.depth > 2))
.on('click', d => {
d3.event.stopPropagation();
focusOn(d);
});
Text Label ausrichten[Bearbeiten]
In Pie Chart Segmenten[Bearbeiten]
Beispiel 1 - Als Speichen oder waagrecht oder tangential
...
// Populate the <text> elements with our data-driven titles.
g.selectAll(".node")
.append("text")
.attr("fill","#FFF")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")rotate(" + computeTextRotation(d) + ")"; })
.attr("dx", "-25")
.attr("dy", ".5em")
.text(function(d) { return d.parent ? d.data.name : "" });
...
function computeTextRotation(d) {
var angle = (d.x0 + d.x1) / Math.PI * 90;
// Avoid upside-down labels
//return (angle < 120 || angle > 270) ? angle : angle + 180; // labels as rims
return (angle < 180) ? angle - 90 : angle + 90; // labels as spokes
//return 0 // labels always horizontal
}
Beispiel 2 - gebogener Text entlang des Kreisbogens
const middleArcLine = d => {
const halfPi = Math.PI/2;
const angles = [x(d.x0) - halfPi, x(d.x1) - halfPi];
const r = Math.max(0, (y(d.y0) + y(d.y1)) / 2);
const middleAngle = (angles[1] + angles[0]) / 2;
const invertDirection = middleAngle > 0 && middleAngle < Math.PI; // On lower quadrants write text ccw
if (invertDirection) {
angles.reverse();
}
const path = d3.path();
path.arc(0, 0, r, angles[0], angles[1], invertDirection);
return path.toString();
};
...
newSlice.append('path')
.attr('class', 'hidden-arc')
.attr('id', (_, i) => `hiddenArc${i}`)
.attr('d', middleArcLine);
const text = newSlice.append('text')
.attr('display', d => textFits(d) ? null : 'none');
text.append('textPath')
.attr('startOffset','50%')
.attr('xlink:href', (_, i) => `#hiddenArc${i}` )
.style('stroke', '#fff')
.text(d => d.data.name);
Element anhängen statt einfügen[Bearbeiten]
Standardmäßig verkettet man Elemente so dass das nächste immer ein Kind Element des vorigen ist. Manchmal (z.B. bei Labels) möche man aber ein Element als Nachfolger nicht als Kind anlegen.
Dazu nutzt man ein selectAll um auf die vorher angelegten Elemente erneut zuzugreifen.
Beispiel
g.selectAll('g')
.data(root.descendants())
.enter().append('g')
.attr("class", "node")
.append('path')
.attr("display", function (d) { return d.depth ? null : "none"; }) // do not show root element
.attr("d", arc)
.attr('id',function(d){return 'path_' + d.data.id})
.style('stroke', '#fff')
.style("fill", function (d) { return color((d.children ? d : d.parent).data.name)})
.on("click",toggleActive);
// Populate the <text> elements with our data-driven titles.
g.selectAll(".node")
.append("text")
.attr("fill","#FFF")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")rotate(" + computeTextRotation(d) + ")"; })
.attr("dx", "-25")
.attr("dy", ".5em")
.text(function(d) { return d.parent ? d.data.name : "" });
Scale - Farbskala[Bearbeiten]
Preset Scale[Bearbeiten]
var colors10 = d3.scale.category10();
Custom Scale[Bearbeiten]
const color = d3.scaleOrdinal() .range(["#ef7a00", "#f4a24c", "#f7bc7f", "#8aae1a", "#adc65e", "#c4d68c", "#3d3d3c", "#777776", "#9e9e9d", "#899fc4", "#acbcd6", "#c4cfe1"]);
in v3:
var c10 = d3.scale.ordinal() .range(["#ef7a00", "#f4a24c", "#f7bc7f", "#8aae1a", "#adc65e", "#c4d68c", "#3d3d3c", "#777776", "#9e9e9d", "#899fc4", "#acbcd6", "#c4cfe1"]);
Datensätze verarbeiten[Bearbeiten]
JSON File vs Inline JSON[Bearbeiten]
TODO
d3.json("data.json", function(dataset){
//Extract data from dataset
var nodes = dataset.nodes,
...
var data1 = [ { "My JSON data here" } ];
function getData(){
return{ "nodes": [{"character": "Design", "id": 0, "influence": 15, "zone": 0 },{"character": "Web", "id": 1,"influence": 15, "zone": 1}],"links": [{"source": 0, "target": 1, "weight": 10}]};
}
data1.forEach(function (d) {