Flasche am Beispiel - Benutzerdefinierte Winkelrichtlinie mit D3

Flasche am Beispiel - Benutzerdefinierte Winkelrichtlinie mit D3

Willkommen zurück. Nachdem Angular zusammen mit einem Ladespinner und unserem überarbeiteten Angular-Controller eingerichtet wurde, fahren wir mit dem letzten Teil fort und erstellen eine benutzerdefinierte Angular-Direktive, um ein Häufigkeitsverteilungsdiagramm mit JavaScript und derD3-Bibliothek anzuzeigen.

Denken Sie daran: Folgendes erstellen wir: Eine Flask-App, die Wort-Frequenz-Paare basierend auf dem Text einer bestimmten URL berechnet.

  1. Part One: Richten Sie eine lokale Entwicklungsumgebung ein und stellen Sie dann sowohl eine Staging- als auch eine Produktionsumgebung auf Heroku bereit.

  2. Part Two: Richten Sie zusammen mit SQLAlchemy und Alembic eine PostgreSQL-Datenbank ein, um Migrationen zu verarbeiten.

  3. Part Three: Fügen Sie die Back-End-Logik hinzu, um die Wortanzahl von einer Webseite mithilfe der Bibliotheken "Requests", "BeautifulSoup" und "Natural Language Toolkit" (NLTK) zu kratzen und dann zu verarbeiten.

  4. Part Four: Implementieren Sie eine Redis-Task-Warteschlange für die Textverarbeitung.

  5. Part Five: Richten Sie Angular im Front-End so ein, dass das Back-End kontinuierlich abgefragt wird, um festzustellen, ob die Verarbeitung der Anforderung abgeschlossen ist.

  6. Part Six: Push auf den Staging-Server in Heroku - Richten Sie Redis ein und erläutern Sie, wie zwei Prozesse (Web und Worker) auf einem einzigen Dyno ausgeführt werden.

  7. Part Seven: Aktualisieren Sie das Front-End, um es benutzerfreundlicher zu gestalten.

  8. Teil 8: Erstellen Sie eine benutzerdefinierte Winkelrichtlinie, um ein Häufigkeitsverteilungsdiagramm mit JavaScript und D3 anzuzeigen. (current)

Benötigen Sie den Code? Nimm es aus denrepo.

Schauen wir uns an, was wir derzeit haben ...

Aktuelle Benutzeroberfläche

Starten Sie Redis in einem Terminalfenster:

$ redis-server

Dann bringen Sie Ihren Prozessarbeiter in ein anderes Fenster:

$ cd flask-by-example
$ python worker.py
17:11:39 RQ worker started, version 0.4.6
17:11:39
17:11:39 *** Listening on default...

Starten Sie schließlich in einem dritten Fenster die App:

$ cd flask-by-example
$ python manage.py runserver

Sie sollten sehen, dass Ihr Wortzähler funktioniert. Jetzt können wir eine benutzerdefinierte Winkelrichtlinie hinzufügen, um die Ergebnisse in einem D3-Diagramm anzuzeigen.

Winkelrichtlinie

Fügen Sie zunächst die D3-Bibliothek (v3) zur Dateiindex.html hinzu:






Jetzt richten wir eine neue benutzerdefinierte Richtlinie ein.

Angular Directives sind Markierungen in einem DOM-Element, mit denen wir HTML-Abschnitte mit bestimmten Ereignissen und Attributen einfügen können. Lassen Sie uns den ersten Teil unserer Richtlinie ausbauen, indem wir den folgenden Code direkt unter dem Controller inmain.js hinzufügen:

.directive('wordCountChart', ['$parse', function ($parse) {
  return {
    restrict: 'E',
    replace: true,
    template: '
', link: function (scope) {} }; }]);

restrict: 'E' erstellt eine Direktive, die auf ein HTML-Element beschränkt ist. replace: true ersetzt einfach die HTML-Direktive durch den HTML-Code intemplate. Die Funktionlink ermöglicht den Zugriff auf Variablen in dem in der Steuerung definierten Bereich.

Fügen Sie als Nächstes einewatch-Funktion hinzu, um nach Änderungen an den Variablen zu suchen und entsprechend zu reagieren. Fügen Sie dies wie folgt zur Funktionlinkhinzu:

link: function (scope) {
  scope.$watch('wordcounts', function() {
    // add code here
  }, true);
}

Fügen Sie abschließend die Richtlinie direkt unter dem schließenden Teiler zu<div class="row"> hinzu:


Wenden wir uns nach der Einrichtung der Richtlinie der D3-Bibliothek zu.

D3 Balkendiagramm

D3 ist eine leistungsstarke Bibliothek, die HTML, CSS und SVG verwendet, um Daten im DOM und JavaScript anzuzeigen und interaktiv zu gestalten. Wir werden es verwenden, um ein einfaches Balkendiagramm zu erstellen.

Schritt 1: Funktionslogik

Fügen Sie derwatch-Funktion in der Winkelrichtlinie Folgendes hinzu:

scope.$watch('wordcounts', function() {
  var data = scope.wordcounts;
  for (var word in data) {
    d3.select('#chart')
      .append('div')
      .selectAll('div')
      .data(word[0])
      .enter()
      .append('div');
  }
}, true);

Wenn sich nunscope.wordcounts ändert, wird diese Funktion ausgelöst, die das DOM aktualisiert. Da ein Objekt von der AJAX-Anforderung zurückgegeben wird, durchlaufen wir es, um die spezifischen Daten zum Diagramm hinzuzufügen. Im Wesentlichen wird jedes Wort über eindata join an ein neuesdiv angehängt.

Versuchen Sie, den Code auszuführen.

Was geschieht? Nichts taucht auf, oder? Überprüfen Sie das DOM in den Entwicklertools von Chrome, nachdem Sie eine neue Website gesendet haben. Sie sollten eine Reihe verschachtelterdivsehen. Wir müssen nur Stile hinzufügen ...

Schritt 2: Gestalten des Balkendiagramms

Beginnen Sie mit einem einfachen CSS:

#chart {
  overflow-y: scroll;
}

#chart {
  background: #eee;
  padding: 3px;
}

#chart div {
  width: 0;
  transition: all 1s ease-out;
  -moz-transition: all 1s ease-out;
  -webkit-transition: all 1s ease-out;
}

#chart div {
  height: 30px;
  font: 15px;
  background-color: #006dcc;
  text-align: right;
  padding: 3px;
  color: white;
  box-shadow: 2px 2px 2px gray;
}

Stellen Sie sicher, dass dies oben auf der HTML-Seite nach dem Bootstrap-Stylesheet eingefügt wird:

Starten Sie die App in unserem Browser. Was passiert jetzt?

Wenn Sie nach einer Website suchen, sollte jetzt ein grauer Bereich mit einigen dünnen blauen Balken auf der linken Seite angezeigt werden. Sie sehen also, dass wir für jedes Datenelement, das wir zurückerhalten, einen Balken generieren - insgesamt 10. Wir müssen jedoch unseren D3-Code ändern, um die Breite jedes Balkens zu erhöhen, damit er lesbar ist.

Schritt 3: Interaktiveres Balkendiagramm

Wir können dies mit unserem bestehenden Code verketten und die Funktion von D3style verwenden:

scope.$watch('wordcounts', function() {
  var data = scope.wordcounts;
  for (var word in data) {
    d3.select('#chart')
      .append('div')
      .selectAll('div')
      .data(word[0])
      .enter()
      .append('div')
      .style('width', function() {
        return (data[word] * 20) + 'px';
      })
      .text(function(d){
        return word;
      });
  }
}, true);

Jetzt erstellen wir dynamisch eine Breite basierend auf dem numerischen Wert, wie oft ein Wort auf einer Webseite angezeigt wird:

.style('width', function() {
  return (data[word] * 20) + 'px';
})
.text(function(d){
  return word;
});

Der Stil wird berechnet, indem der jedem Wort zugeordnete Wert zurückgegeben, diese Zahl mit 20 multipliziert und dann in Pixel konvertiert wird. Wir können jedem Balkenelement auch Text hinzufügen, indem wir den Zeichenfolgenwert des Wortes zusammen mit der Häufigkeit einfügen, mit der es auf der Seite angezeigt wird.

Probieren Sie es aus. Sie sollten etwas sehen wie:

Chart: word count and frequencies

Eines fehlt jedoch noch. Was passiert, wenn Sie nach einer neuen Website suchen? Versuch es. Das neue Diagramm wird unter das vorherige angehängt. Wir müssen unser Diagramm div löschen, bevor ein neues erstellt wird.

Aktualisieren Sie dielink-Funktion in der Richtlinie:

link: function (scope) {
  scope.$watch('wordcounts', function() {
    d3.select('#chart').selectAll('*').remove();
    var data = scope.wordcounts;
    for (var word in data) {
      d3.select('#chart')
        .append('div')
        .selectAll('div')
        .data(word[0])
        .enter()
        .append('div')
        .style('width', function() {
          return (data[word] * 20) + 'px';
        })
        .text(function(d){
          return word;
        });
    }
  }, true);
}

d3.select('#chart').selectAll('*').remove(); löscht das Diagramm einfach jedes Mal, wenn die Funktion$scope.watch ausgelöst wird. Jetzt haben wir ein Diagramm, das vor jeder neuen Verwendung gelöscht wird, und wir haben eine voll funktionsfähige Wortzählanwendung !!

Probieren Sie es aus!

Fazit und nächste Schritte

Das ist es. Übertragen Sie Ihre Änderungen auf die Staging- und Produktionsserver. Sehen wir uns an, was wir angegangen sind:

  1. Wir haben mit der Konfiguration und dem Workflow begonnen und Staging- und Produktionsserver eingerichtet

  2. Von dort aus haben wir die grundlegenden Funktionen hinzugefügt - Web Scraping, Datenanalyse - und mit Redis eine Task-Warteschlange eingerichtet

  3. Nachdem die Back-End-Funktionalität eingerichtet war, richtete sich die Aufmerksamkeit auf das Front-End, wo wir Angular hinzugefügt, eine benutzerdefinierte Direktive erstellt und D3 in den Mix aufgenommen haben

Wir haben einen MVP, aber es gibt noch viel zu tun:

  1. Refactor, Refactor, Refactor!

  2. Schreiben Sie Tests

  3. Behandeln Sie Fehler und Ausnahmen

  4. Abstract out state in der Angular App zu einem Service

  5. Arbeiten Sie an der Benutzeroberfläche und UX

Helfen wollen? Fügen Sie eine Funktion hinzu, schreiben Sie Teil 9, erhalten Siepaid und werden Sie im Internet berühmt!

Links: