Пример колбы - Пользовательская угловая директива с D3
Добро пожаловать. Настроив Angular вместе с загрузочным счетчиком и нашим переработанным контроллером Angular, давайте перейдем к последней части и создадим настраиваемую директиву Angular для отображения диаграммы распределения частот с помощью JavaScript и библиотекиD3.
Помните: вот что мы создаем - приложение Flask, которое вычисляет пары слов и частоты на основе текста по заданному URL-адресу.
-
Part One: настройте локальную среду разработки, а затем разверните как промежуточную, так и производственную среду на Heroku.
-
Part Two: настроить базу данных PostgreSQL вместе с SQLAlchemy и Alembic для обработки миграций.
-
Part Three: добавьте внутреннюю логику для очистки и последующей обработки количества слов с веб-страницы с помощью библиотек запросов, BeautifulSoup и Natural Language Toolkit (NLTK).
-
Part Four: реализовать очередь задач Redis для обработки текста.
-
Part Five: настройте Angular на внешнем интерфейсе, чтобы постоянно опрашивать серверную часть, чтобы узнать, обработан ли запрос.
-
Part Six: Отправка на промежуточный сервер на Heroku - настройка Redis и подробное описание того, как запустить два процесса (веб-сайт и рабочий) на одном Dyno.
-
Part Seven: обновите интерфейс, чтобы сделать его более удобным для пользователя.
-
Часть восьмая. Создайте пользовательскую директиву Angular для отображения диаграммы распределения частот с использованием JavaScript и D3. (current)
Нужен код? Возьмите его изrepo.
Давайте посмотрим на то, что у нас сейчас есть ...
Текущий пользовательский интерфейс
Запустите Redis в окне терминала:
$ redis-server
Затем включите ваш рабочий процесс в другое окно:
$ 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...
Наконец, в третьем окне запустите приложение:
$ cd flask-by-example
$ python manage.py runserver
Вы должны увидеть, как работает счетчик слов. Теперь мы можем добавить пользовательскую угловую директиву для отображения результатов в диаграмме D3.
Угловая директива
Начните с добавления библиотеки D3 (v3) в файлindex.html:
Теперь давайте создадим новую пользовательскую директиву.
Angular Directives - это маркеры на элементе DOM, которые позволяют нам вставлять разделы HTML с определенными событиями и прикрепленными к нему атрибутами. Давайте создадим первую часть нашей Директивы, добавив следующий код чуть ниже контроллера вmain.js:
.directive('wordCountChart', ['$parse', function ($parse) {
return {
restrict: 'E',
replace: true,
template: '',
link: function (scope) {}
};
}]);
restrict: 'E'
создает директиву, которая ограничена элементом HTML. replace: true
просто заменяет директиву HTML на HTML вtemplate
. Функцияlink
дает нам доступ к переменным в области видимости, определенной в контроллере.
Затем добавьте функциюwatch
, чтобы «отслеживать» любые изменения переменных и реагировать соответствующим образом. Добавьте это в функциюlink
следующим образом:
link: function (scope) {
scope.$watch('wordcounts', function() {
// add code here
}, true);
}
Наконец, добавьте директиву чуть ниже закрывающего разделителя в<div class="row">
:
С установлением Директивы давайте обратим наше внимание на библиотеку D3 ...
Гистограмма D3
D3 - это мощная библиотека, которая использует HTML, CSS и SVG для отображения данных в DOM и JavaScript, чтобы сделать их интерактивными. Мы будем использовать его для создания базовой гистограммы.
Шаг 1: Функциональная логика
Добавьте следующее в функциюwatch
в директиве Angular:
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);
Теперь при измененииscope.wordcounts
запускается эта функция, которая обновляет DOM. Поскольку объект возвращается из запроса AJAX, мы выполняем его итерацию, чтобы добавить конкретные данные в диаграмму. По сути, каждое слово добавляется к новомуdiv
черезdata join.
Попробуйте запустить код.
Что просходит? Ничего не появляется, верно? Проверьте DOM в Инструментах разработчика Chrome после отправки нового сайта. Вы должны увидеть несколько вложенныхdivs
. Нам просто нужно добавить стили ...
Шаг 2: стилизация гистограммы
Начнем с простого 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;
}
Не забудьте включить это в верхней части HTML-страницы после таблицы стилей Bootstrap:
Запустите приложение в нашем браузере. Что сейчас происходит?
При поиске веб-сайта вы должны увидеть серую область с тонкими синими полосами с левой стороны. Итак, вы можете видеть, что мы генерируем столбец для каждого возвращаемого элемента данных - всего 10. Однако нам нужно изменить наш код D3, чтобы увеличить ширину каждой полосы, чтобы они были читабельными.
Шаг 3: сделать гистограмму более интерактивной
Мы можем связать это с нашим существующим кодом и использовать функцию 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);
Теперь мы динамически создаем ширину на основе числового значения того, как часто слово появляется на веб-странице:
.style('width', function() {
return (data[word] * 20) + 'px';
})
.text(function(d){
return word;
});
Стиль рассчитывается путем возврата значения, связанного с каждым словом, умножения этого числа на 20, а затем преобразования его в пиксели. Мы также можем добавить текст к каждому элементу панели, вставив строковое значение слова и частоту его появления на странице.
Попробуйте это. Вы должны увидеть что-то вроде:
Там еще одна вещь отсутствует, хотя. Что происходит при поиске нового сайта? Попытайся. Новый график добавляется под предыдущим. Нам нужно очистить наш div диаграммы перед созданием нового.
Шаг 4: Очистить для следующего поиска URL
Обновите функциюlink
в директиве:
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();
просто очищает график каждый раз, когда запускается функция$scope.watch
. Теперь у нас есть таблица, которая очищается перед каждым новым использованием, и у нас есть полнофункциональное приложение для подсчета слов !!
Проверьте это!
Заключение и последующие шаги
Это оно. Отправьте свои изменения на промежуточные и производственные серверы. Давайте рассмотрим, что мы решили:
-
Мы начали с настройки и рабочего процесса, настройки промежуточных и производственных серверов.
-
Оттуда мы добавили основные функции - очистку веб-страниц, анализ данных - и настроили очередь задач с помощью Redis.
-
С настройкой серверной функциональности внимание обратилось на интерфейс, где мы добавили Angular, создали собственную директиву и добавили D3 в смесь
У нас есть MVP, но многое еще предстоит сделать:
-
Refactor, рефакторинг, рефакторинг!
-
Обрабатывать ошибки и исключения
-
Абстрагировать состояние в приложении Angular к Сервису
-
Работа над UI и UX
Хочу помочь? Добавьте функцию, напишите часть 9, получитеpaid и станьте известным в Интернете!
Ссылки: