D3.js - Tipps und Tricks: Unterschied zwischen den Versionen

Aus Wikizone
Wechseln zu: Navigation, Suche
(Die Seite wurde neu angelegt: „== Aktionen abhängig von den Daten ausführen == Will man beim Daten abarbeiten bestimmte Aktionen abhängig von den Daten Ausführen kann man in vielen Fäl…“)
 
Zeile 20: Zeile 20:
 
       focusOn(d);
 
       focusOn(d);
 
     });
 
     });
 +
</syntaxhighlight>
 +
 +
== Text Label ausrichten ==
 +
=== In Pie Chart Segmenten ===
 +
Beispiel 1 - Als Speichen oder waagrecht oder tangential
 +
<syntaxhighlight lang="javascript">
 +
...
 +
  // 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
 +
    }
 +
</syntaxhighlight>
 +
Beispiel 2 - gebogener Text entlang des Kreisbogens
 +
 +
<syntaxhighlight lang="javascript">
 +
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);
 
</syntaxhighlight>
 
</syntaxhighlight>

Version vom 2. September 2019, 17:49 Uhr

Aktionen abhängig von den Daten ausführen

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

In Pie Chart Segmenten

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);