Flacon par exemple - Directive angulaire personnalisée avec D3

Flacon par exemple - Directive angulaire personnalisée avec D3

Nous saluons le retour. Avec la configuration angulaire avec un spinner de chargement et notre contrôleur angulaire remanié, passons à la partie finale et créons une directive angulaire personnalisée pour afficher un graphique de distribution de fréquence avec JavaScript et la bibliothèqueD3.

N'oubliez pas: voici ce que nous construisons: une application Flask qui calcule les paires mot-fréquence en fonction du texte d'une URL donnée.

  1. Part One: Configurez un environnement de développement local, puis déployez à la fois un environnement de préparation et de production sur Heroku.

  2. Part Two: Configurez une base de données PostgreSQL avec SQLAlchemy et Alembic pour gérer les migrations.

  3. Part Three: ajoutez la logique principale pour gratter puis traiter le nombre de mots d'une page Web à l'aide des bibliothèques requests, BeautifulSoup et Natural Language Toolkit (NLTK).

  4. Part Four: implémentez une file d'attente de tâches Redis pour gérer le traitement de texte.

  5. Part Five: configurez Angular sur le front-end pour interroger en continu le back-end pour voir si le traitement de la demande est terminé.

  6. Part Six: Push vers le serveur intermédiaire sur Heroku - configuration de Redis et expliquant comment exécuter deux processus (web et worker) sur un seul Dyno.

  7. Part Seven: Mettez à jour le front-end pour le rendre plus convivial.

  8. Huitième partie: créer une directive angulaire personnalisée pour afficher un graphique de distribution de fréquence à l'aide de JavaScript et D3. (current)

Besoin du code? Récupérez-le dans lesrepo.

Voyons ce que nous avons actuellement…

Interface utilisateur actuelle

Démarrez Redis dans une fenêtre de terminal:

$ redis-server

Ensuite, lancez votre agent de processus dans une autre fenêtre:

$ 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...

Enfin, dans une troisième fenêtre, lancez l'application:

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

Vous devriez voir votre compteur de mots fonctionner. Maintenant, nous pouvons ajouter une directive angulaire personnalisée pour afficher les résultats dans un graphique D3.

Directive angulaire

Commencez par ajouter la bibliothèque D3 (v3) au fichierindex.html:






Créons maintenant une nouvelle directive personnalisée.

Angular Directives sont des marqueurs sur un élément DOM, qui nous permettent d'insérer des sections de HTML avec des événements et des attributs spécifiques qui y sont attachés. Construisons la première partie de notre directive en ajoutant le code suivant juste en dessous du contrôleur dansmain.js:

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

restrict: 'E' crée une directive qui est limitée à un élément HTML. replace: true remplace simplement la directive HTML par le HTML dans lestemplate. La fonctionlink nous donne accès aux variables du périmètre défini dans le contrôleur.

Ensuite, ajoutez une fonctionwatch pour «surveiller» les modifications apportées aux variables et répondre de manière appropriée. Ajoutez ceci à la fonctionlink comme ceci:

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

Enfin, ajoutez la directive juste en dessous du séparateur de clôture à<div class="row">:


Avec la mise en place de la directive, tournons notre attention vers la bibliothèque D3…

Graphique à barres D3

D3 est une bibliothèque puissante qui utilise HTML, CSS et SVG pour afficher des données sur le DOM et JavaScript pour le rendre interactif. Nous allons l'utiliser pour créer un graphique à barres de base.

Étape 1: Logique fonctionnelle

Ajoutez ce qui suit à la fonctionwatch dans la directive angulaire:

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

Désormais, chaque fois quescope.wordcounts change, cette fonction est déclenchée, ce qui met à jour le DOM. Puisqu'un objet est renvoyé de la requête AJAX, nous le parcourons pour ajouter les données spécifiques au graphique. Essentiellement, chaque mot est ajouté à un nouveaudiv via undata join.

Essayez d'exécuter le code.

Ce qui se produit? Rien n'apparaît, non? Consultez le DOM dans les outils de développement de Chrome, après avoir soumis un nouveau site. Vous devriez voir un certain nombre dedivs imbriqués. Nous avons juste besoin d'ajouter des styles…

Étape 2: styliser le graphique à barres

Commencez avec quelques CSS simples:

#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;
}

Assurez-vous de l'inclure en haut de la page HTML, après la feuille de style Bootstrap:

Lancez l'application dans notre navigateur. Qu'est ce qui se passe maintenant?

Lorsque vous recherchez un site Web, vous devriez maintenant voir une zone grise avec quelques fines barres bleues sur le côté gauche. Vous pouvez donc voir que nous générons une barre pour chaque élément de données que nous récupérons - 10 au total. Cependant, nous devons modifier notre code D3 afin d'augmenter la largeur de chaque barre afin qu'elles soient lisibles.

Étape 3: rendre le graphique à barres plus interactif

Nous pouvons enchaîner ceci à notre code existant et utiliser la fonction D3style:

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

Maintenant, nous créons dynamiquement une largeur basée sur la valeur numérique de la fréquence à laquelle un mot apparaît sur une page Web:

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

Le style est calculé en renvoyant la valeur associée à chaque mot, en multipliant ce nombre par 20, puis en le convertissant en pixels. Nous pouvons également ajouter du texte à chaque élément de la barre en insérant la valeur de chaîne du mot ainsi que la fréquence à laquelle il apparaît sur la page.

Essayez ceci. Vous devriez voir quelque chose comme:

Chart: word count and frequencies

Il manque encore une chose. Que se passe-t-il lorsque vous recherchez un nouveau site Web? Essayez-le. Le nouveau graphique est joint en dessous du précédent. Nous devons vider notre division graphique avant d'en créer une nouvelle.

Mettez à jour la fonctionlink dans la directive:

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(); efface simplement le graphique à chaque fois que la fonction$scope.watch est déclenchée. Maintenant, nous avons un tableau qui est effacé avant chaque nouvelle utilisation, et nous avons une application de comptage de mots entièrement fonctionnelle !!

Testez-le!

Conclusion et prochaines étapes

C'est ça. Envoyez vos modifications aux serveurs de production et de transfert. Passons en revue ce que nous avons abordé:

  1. Nous avons commencé avec la configuration et le workflow, en installant des serveurs de production et de transfert

  2. À partir de là, nous avons ajouté les fonctionnalités de base - grattage Web, analyse des données - et mis en place une file d'attente de tâches avec Redis

  3. Avec la fonctionnalité back-end configurée, l'attention s'est tournée vers le front-end où nous avons ajouté Angular, construit une directive personnalisée et ajouté D3 dans le mix

Nous avons un MVP, mais il reste encore beaucoup à faire:

  1. Refactor, refactoriser, refactoriser!

  2. Rédiger des tests

  3. Gérer les erreurs et les exceptions

  4. Résumé de l'état dans l'application angulaire à un service

  5. Travailler sur l'interface utilisateur et UX

Vouloir aider? Ajoutez une fonctionnalité, écrivez la partie 9, obtenezpaid et devenez célèbre sur Internet!

Liens: