Пользовательская директива Angular с D3.
Оглавление:
Добро пожаловать. Настроив Angular вместе с загрузочным счетчиком и нашим реорганизованным контроллером Angular, перейдем к последней части и создадим настраиваемую директиву Angular для отображения диаграммы распределения частот с помощью JavaScript и библиотеки D3.
Помните, что мы создаем приложение Flask, которое вычисляет пары частотности слов на основе текста из заданного URL-адреса.
- Часть первая: настройте локальную среду разработки, а затем разверните как промежуточную, так и производственную среду на Heroku.
- Часть вторая: настройте базу данных PostgreSQL вместе с SQLAlchemy и Alembic для обработки миграций.
- Часть третья: добавьте внутреннюю логику для очистки, а затем обработки количества слов с веб-страницы с помощью библиотек запросов, BeautifulSoup и Natural Language Toolkit (NLTK).
- Часть четвертая: реализация очереди задач Redis для обработки текста.
- Часть пятая: настройте Angular во внешнем интерфейсе, чтобы постоянно опрашивать серверную часть, чтобы узнать, обработан ли запрос.
- Часть шестая: Отправка на промежуточный сервер на Heroku - настройка Redis и подробное описание того, как запустить два процесса (веб и рабочий) на одном Dyno.
- Часть седьмая: Обновите интерфейс, чтобы сделать его более удобным для пользователя.
- Часть восьмая: Создайте настраиваемую директиву Angular для отображения диаграммы частотного распределения с использованием JavaScript и D3. ( текущий )
Давайте посмотрим, что мы имеем...
Текущий пользовательский интерфейс
Запустите 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
Вы должны увидеть, что ваш счетчик слов работает. Теперь мы можем добавить настраиваемую директиву Angular для отображения результатов на диаграмме D3.
Директива Angular
Начните с добавления библиотеки D3 (v3) в файл index.html :
<!-- scripts --> <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> <script src="//code.jquery.com/jquery-2.2.1.min.js"></script> <script src="//netdna.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script> <script src="{{ url_for('static', filename='main.js') }}"></script>
Теперь давайте настроим новую настраиваемую директиву.
Директивы Angular - это маркеры на элементе DOM, которые позволяют нам вставлять разделы HTML с определенными событиями и атрибутами, прикрепленными к нему. Давайте создадим первую часть нашей Директивы, добавив следующий код чуть ниже контроллера в main.js :
.directive('wordCountChart', ['$parse', function ($parse) { return { restrict: 'E', replace: true, template: '<div id="chart"></div>', 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">
:
<br> <word-count-chart data="wordcounts"></word-count-chart>
Установив Директиву, давайте обратим наше внимание на библиотеку 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
через соединение данных .
Попробуйте запустить код.
Что происходит? Ничего не появляется, правда? Проверьте 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:
<link rel="stylesheet" type="text/css" href="../static/main.css">
Запустите приложение в браузере. Что произошло?
При поиске веб-сайта вы должны увидеть серую область с тонкими синими полосами с левой стороны. Итак, вы можете видеть, что мы генерируем полосу для каждого возвращаемого элемента данных - всего их 10. Однако нам нужно изменить наш код D3, чтобы увеличить ширину каждой полосы, чтобы они были удобочитаемыми.
Шаг 3. Сделайте гистограмму более интерактивной
Мы можем связать это с нашим существующим кодом и использовать функцию стиля D3 :
scope.$watch('wordcounts', function() {
var data = scope.wordcounts;
for (var word in data) {
var key = data[word][0];
var value = data[word][1];
d3.select('#chart')
.append('div')
.selectAll('div')
.data(word)
.enter()
.append('div')
.style('width', function() {
return (value * 3) + 'px';
})
.text(function(d){
return key;
});
}
}, true);
Теперь мы динамически создаем ширину на основе числового значения того, как часто слово появляется на веб-странице:
.style('width', function() {
return (value * 3) + 'px';
})
.text(function(d){
return key;
});
Стиль вычисляется путем возврата значения, связанного с каждым словом, умножения этого числа на 3 и последующего преобразования его в пиксели. Мы также можем добавить текст к каждому элементу панели, вставив строковое значение слова вместе с тем, как часто оно появляется на странице.
Проверьте это. Вы должны увидеть что-то вроде этого:
Однако по-прежнему не хватает одной вещи. Что происходит, когда вы ищете новый веб-сайт? Новая диаграмма добавляется под предыдущей. Нам нужно очистить наш блок диаграммы перед созданием нового.
Шаг 4. Очистите для следующего поиска URL
Обновите функцию link
в Директиве:
link: function (scope) {
scope.$watch('wordcounts', function() {
d3.select('#chart').selectAll('*').remove();
var data = scope.wordcounts;
for (var word in data) {
var key = data[word][0];
var value = data[word][1];
d3.select('#chart')
.append('div')
.selectAll('div')
.data(word)
.enter()
.append('div')
.style('width', function() {
return (value * 3) + 'px';
})
.text(function(d){
return key;
});
}
}, true);
}
d3.select('#chart').selectAll('*').remove();
просто очищает диаграмму каждый раз при запуске функции $scope.watch
. Теперь у нас есть таблица, которая очищается перед каждым новым использованием, и у нас есть полностью функциональное приложение для подсчета слов!
Проверьте это!
Заключение и следующие шаги
Вот и все. Отправьте свои изменения на промежуточный и рабочий серверы. Давайте рассмотрим, над чем мы работали:
- Мы начали с конфигурации и рабочего процесса, настройки промежуточных и производственных серверов.
- Оттуда мы добавили базовую функциональность - парсинг веб-страниц, анализ данных - и настроили очередь задач с Redis.
- После настройки серверной функциональности внимание переключилось на интерфейсную часть, где мы добавили Angular, создали специальную директиву и добавили D3 в смесь.
В целом сделан достаточно понятный перевод, имеются небольшие изъяны связанные с название фреймворка Angular, который был переведен как "Угловой", что делать не стоило, имеется пару речевых ошибок например: "вычисляет пары частотность слова", в некоторых местах не хватает пробелов, по типу "linkфункцию". В за заключении хочу сказать, что статья переведена без потери ключевых смыслов.