...

суббота, 27 декабря 2014 г.

[Перевод] 15 лучших JavaScript-библиотек для построения диаграмм и схем

Практически невозможно представить себе информационную панель без диаграмм и графиков. Они быстро и эффективно отображают сложные статистические данные. Более того, хорошая диаграмма также улучшает общий дизайн вашего сайта.

В этой статье я покажу вам некоторые из лучших JavaScript библиотек для построения диаграмм/схем (и сводных таблиц). Эти библиотеки помогут вам в создании красивых и настраиваемых графиков для ваших будущих проектов.


Хотя большинство библиотек являются бесплатными и свободно распространяемыми, для некоторых из них есть платные версии с дополнительным функционалом.


D3.js – документы, ориентированные на данные







Сегодня, когда мы задумываемся о графиках, то первое, что приходит в голову – это D3.js Являясь open source проектом, D3.js, вне всякого сомнения, дарит много полезных возможностей, которых не хватает большинству существующих библиотек. Такие возможности как “Enter and Exit”, мощные переходы, и синтаксис, схожий с jQuery или Prototype, делают его одной из лучших JavaScript библиотек для создания графиков и диаграмм. В D3.js они генерируются посредством HTML, SVG и CSS.

В отличие от многих других JavaScript библиотек, D3.js не поставляется с заранее созданными графиками прямо из коробки. Однако вы можете взглянуть на перечень графиков, созданных на D3.js, чтобы получить общее представление.


D3.js не работает должным образом со старыми браузерами, такими как IE8. Но вы всегда можете применить такие плагины как aight plugin для кроссбраузерной совместимости.


D3.js ранее широко использовался на таких вебсайтах как NYTimes, Uber и Weather.com


Google Charts







Google Charts – JavaScript библиотека, которую я регулярно использую для простого и лёгкого создания графиков. Предоставляет множество предварительно созданных диаграмм, таких как комбинированные гистограммы, столбчатые диаграммы, календарные графики, секторные диаграммы, гео схемы, и др.

В Google charts также имеется множество конфигурационных настроек, которые помогают изменить внешний вид графика. Графики формируются с помощью HTML5/SVG добы обеспечить кроссбраузерную совместимость и кроссплатформенную портируемость на IPhone, IPad и Android. Также содержит VML для поддержки старых IE версий.


Вот замечательный список с примерами, построенными на Google charts.


ChartJS







ChartJS наделяет графики красивым плоским дизайном. Он использует HTML5 canvas для рендеринга. Поддержка для старых браузеров, таких как IE7/8, добавляется с помощью полифилла.

Графики ChartJS отзывчивы по умолчанию. Они отлично работают на мобильных устройствах и планшетах. Благодаря 6 основным разновидностям графиков прямо из коробки (core, столбчатый, кольцевой, лепестковый, линейчатый и полярный), ChartJS определённо является одной из наиболее впечатляющих open source библиотек для построения графиков и диаграмм, за последнее время.


Chartlist.js







Chartlist.js предоставляет красивые отзывчивые графики. Также как и ChartJS, Chartlist.js является результатом труда сообщества, которое разочаровалось в дорогих диаграммных библиотеках JavaScript. Он использует SVG для рендеринга графиков/схем. Может управляться и конфигурироваться посредством CSS3 media queries и Sass. Также, примите к сведению, что замечательная анимация, предоставляемая Chartlist.js, будет работать только в современных браузерах.

n3-charts







Если Вы – AngularJS разработчик, то n3-charts определённо вам покажется необычайно полезным и интересным. n3-charts создан поверх D3.js и AngularJS. Он предоставляет множество стандартных графиков в виде настраиваемых AngularJS директив.

Ознакомьтесь с перечнем графиков, созданных с помощью на n3-charts.

Ember Charts







EmberCharts – ещё один великолепный open source репозиторий, построенный на D3.js и Ember.js Предоставляет легко настраиваемые графики временного ряда, гистограммы, секторные диаграммы и диаграммы рассеяния. Использует SVG для рендеринга графиков.

Smoothie Charts







Если вы имеете дело с потоком данных в реальном времени, то вам может пригодиться Smoothie Charts. Для рендеринга графика здесь используется элемент HTML5 canvas. Это библиотека на чистом JavaScript, которая предоставляет такие опциональные возможности для графиков реального времени как задержка и вспышка цвета.

Chartkick







Chartkick – JavaScript библиотека для построения графиков/схем в Ruby приложениях. Предоставляет все основные типы диаграмм, такие как секторная, столбчатая, гистограмма, комбинированная гистограмма, гео, временная и диаграмма кратного ряда. Диаграммы генерируются через SVG.

MeteorCharts







Вы ещё не пробовали работать с Meteor v 1.0? Ладно, MeteorCharts поможет вам в создании красивых диаграмм для Meteor приложений. Для рендеринга графиков предоставляется возможность выбора любой из этих технологий: HTML5 canvas, WebGL, SVG и даже DOM.

Это замечательный генератор графиков, который позволяет вам выбрать его тип, тему, а затем выполнить генерацию. Бесплатен для использования в некоммерческих проектах. Подсчитать стоимость коммерческой лицензии можно здесь.

Highcharts JS







Highcharts JS – ещё одна весьма популярная библиотека для построения графиков. Комплектуется большим количеством анимации разнообразного типа, способной привлечь множество внимания к вашему сайту. Как и другие библиотеки, HighchartsJS содержит множество предварительно созданных диаграмм: сплайновых, фигурных, комбинированных, столбчатых, гистограмм, круговых, точечных и пр.

Одно из самых больших преимуществ применения HighchartsJS – совместимость со старыми браузерами, такими как Internet Explorer 6. Стандартные браузеры используют SVG для рендеринга графиков. В устаревшем IE графики строятся через VML.


Хотя HighchartsJS и бесплатен для персонального использования, вам необходимо приобрести лицензию для коммерческого применения.


Fusioncharts







Fusioncharts – одна из наиболее старых JavaScript библиотек, которая была впервые выпущена в 2002 году. Графики генерируются посредством HTML5/SVG и VML для лучшей портируемости и совместимости.

В отличие от множества библиотек, Fusioncharts предоставляет возможность парсинга как JSON данных, так и XML. Вы также можете экспортировать эти графики в 3 разных формата: PNG, JPG и PDF.


Fusioncharts хорошо совместим со старыми браузерами, такими как IE6. И по этой причине он стал одной из наиболее предпочитаемых библиотек во множестве торговых организаций.


Вы можете бесплатно использовать версию Fusioncharts с водяным знаком как в личных так и в коммерческих проектах. Однако, вам необходимо приобрести лицензию, чтобы избавиться от водяного знака.


Flot







Flot – JavaScript библиотека для JQuery, позволяющая создавать графики/диаграммы. Одна из старейших и наиболее популярных диаграммных библиотек.

Flot поддерживает линейчатые, точечные, гистограммы, столбчатые и любые комбинации из этих видов диаграмм. Также совместим со старыми браузерами, такими как IE 6 и Firefox 2.


Flot полностью бесплатен, коммерческая поддержка предоставляется по специальному запросу разработчику. Вот список примеров с графиками, созданных на Flot.


amCharts







amCharts, несомненно, одна из наиболее красивых диаграммных библиотек. Она в полной мере разделилась на 3 независимых вида: JavaScript Charts, Maps Charts (amMaps) и Stock charts.

amMaps – мой любимый из этих трёх, что указаны выше. Предоставляет такие возможности, как теплокарты, рисование линий, добавление текста на карту, загрузка иконок или фотографий в верхнюю часть вашей карты, изменение масштаба и пр.

amCharts использует SVG для рендеринга графиков который работает только в современных браузерах. Графики могут не правильно отображаться в IE ниже 9й версии.


Ознакомьтесь с этой фантастической коллекцией замечательных демок, созданных на amCharts.


Бесплатная версия amCharts будет оставлять обратную ссылку на этот вебсайт в верхней части каждого графика. Коммерческие лицензии слегка дороже большинства платных библиотек на рынке.


EJSChart







EJS Chart заявляют о своём практичном решении для предприятий. Графики выглядят аккуратней и читабельней чем большинство других из более старых библиотек. Также имеется совместимость с IE6+ и другими старыми браузерами. Ознакомьтесь с этим списком примеров.

EJS Chart предоставляется в бесплатной и платной версиях. Бесплатная версия имеет ограничение, не позволяющее вам использовать более 1 графика на странице и более двух (числовых) последовательностей на графике. Ознакомьтесь с ценовыми подробностями здесь.


uvCharts







uvCharts – JavaScript библиотека с открытым исходным кодом, заявляется о наличии более 100 конфигурационных опций. У неё имеются графики 12 различных стандартов прямо из коробки.

uvCharts построен на D3.js библиотеке. Этот проект обещает устранить все сложные нюансы кодинга D3.js и обеспечить лёгкую реализацию графиков стандартного вида. uvCharts генерируется посредством SVG, HTML и CSS.


Заключение




Теперь выбор наилучшей диаграммной библиотеки для своих будущих проектов остаётся только за вами. Разработчики, которым нужен полный контроль над графиками, определённо выберут D3.js Практически все вышеуказанные библиотеки обзавелись хорошей поддержкой на форумах Stackoverflow.

Если вы ищите инструменты для генерации уже готовых графиков, то перейдите к статье 5 Инструментов Для Создания Удивительных Онлайн Графиков. Вы также можете прочесть Создание Простых Линейных и Столбчатых Диаграмм с Помощью D3.js, для того чтобы начать знакомство с D3.js. Также у нас есть выпуски, посвящённые GoogleCharts с AngularJS.


Надеюсь вам понравилась эта статья. Хорошего дня.


This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


OpenGL ES 1.1 в Windows 8 и Windows Phone 8.1

В далеком 1998 году я пытался сделать свою игру с OpenGL. Разработка с трудом дошла до альфы и была заброшена, но что особо запомнилось, так это как удобно было делать под GL интерфейсы — ортогональная проекция, пара трансформаций, биндинг нескольких вершин с GL_TRIANGLE_STRIP и у нас уже есть кнопка. И вот, спустя шестнадцать лет и занимаясь мобильным игростроем я столкнулся с таким же подходом в OpenGL ES 1.*, разве что 2D текстуры без вращений можно теперь рисовать через glDrawTexfOES.

Я поддерживал несколько проектов, сделанных по этому принципу и понемногу в голове выстроился коварный план: сделать кросс-платформенную 2D игру на мобильных с OpenGL ES и на C#, а на десктопах с обычным OpenGL. Цели я добился не с первого раза и было с этим много проблем, но в результате очередной проект у меня работает без изменений бизнес-логики на iOS, Android, BlackBerry, Windows XP/7, Mac OS X, Linux, ReactOS, Windows 8, Windows Phone 8.1. Материала набралось на много статей, но в этот раз я расскажу именно о поддержке Windows Runtime.



OpenTK




Можно много спорить на счет удобства OpenGL именно для 2D, до хрипоты в горле убеждать себя, что для полноценной игры необходимы шейдеры и многопроходный рендеринг, а заодно и находить подтверждения, что устаревший OpenGL ES 1.1 часто реализован именно на уровне эмуляции через шейдеры. Это я оставлю для Дон Кихотов и теоретиков. Меня же волновало, что это самый простой способ написать единожды код 2D отрисовки и запускать его на разных платформах, причем не используя монструозные Unity, MonoGame и другие движки.

На iOS и Android под Xamarin все прошло гладко, работа с GL делается через библиотеку OpenTK с неймспейсом OpenGL.Graphics.GL11, константы и методы на обеих платформах одинаковы. На десктопах я решил использовать OpenTK.Graphics.OpenGL, т.е. обычный десктопный OpenGL с C# оберткой. Там в принципе нет glDrawTexfOES, но без проблем можно сделать замену для него и рисовать два треугольника через GL_TRIANGLE_STIP/GL_TRIANGLES и glDrawElements — по сравнению с мобильными, производительности хватает с лихвой и VBO тут не нужны.

Пример враппера с GL_TRIANGLES


private static readonly int[] s_textureCropOesTiv = new int[4];
private static readonly short[] s_indexValues = new short[] { 0, 1, 2, 1, 2, 3 };
private static readonly float[] s_vertexValues = new float[] { -0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f };

public void glDrawTexfOES(float x, float y, float z, float w, float h)
{
glPushMatrix();
glLoadIdentity();

glTranslatef(w / 2.0f + x, h / 2.0f + y, 0.0f);

glScalef(w, -h, 1.0f);

int[] tiv = s_textureCropOesTiv; // NOTE: clip rectangle, should be set before call

int[] texW = new int[1];
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, texW);
int[] texH = new int[1];
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, texH);

float[] texCoordValues = new float[8];

float left = 1.0f - (tiv[0] + tiv[2]) / (float)texW[0];
float bottom = 1.0f - tiv[1] / (float)texH[0];
float right = 1.0f - tiv[0] / (float)texW[0];
float top = 1.0f - (tiv[1] + tiv[3]) / (float)texH[0];

texCoordValues[0] = right;
texCoordValues[2] = left;
texCoordValues[4] = right;
texCoordValues[6] = left;

texCoordValues[1] = bottom;
texCoordValues[3] = bottom;
texCoordValues[5] = top;
texCoordValues[7] = top;

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, s_vertexValues);
glTexCoordPointer(2, GL_FLOAT, 0, texCoordValues);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, s_indexValues);

glPopMatrix();
}




Учтите, что копипастить себе этот код не стоит — он не будет работать там, где нет констант GL_TEXTURE_WIDTH/GL_TEXTURE_HEIGHT. Заодно переменная s_textureCropOesTiv должна быть заполнена до вызова, а сам код не выполняет переворот вьюпорта по оси ординат.


XAML




Некоторое количество магии понадобилось, чтобы проект запускался на актуальных версиях Mono, .Net 2.0-4.5, Wine, а заодно и под ReactOS, но в целом кроме зоопарка с текстурами особых проблем тут не было. А вот проблемы начались на Windows 8 и Windows Phone, где OpenGL отсутствует в принципе. С начала я пробовал решить это малой кровью, буквально дописав свою версию glDrawTexfOES, которая бы внутри вызывала что-то специфичное для этих систем. В ходе экспериментов я использовал XAML элемент Canvas, а в нем рисовал Rectangle, у которого в Brush использовалась нужная трансформация для отображения только части текстуры.

Код трансформации в XAML


TransformGroup group = new TransformGroup();

ScaleTransform scale = new ScaleTransform();
scale.ScaleX = (double)texture.PixelWidth / (double)clipRect.Width;
scale.ScaleY = (double)texture.PixelHeight / (double)clipRect.Height;
group.Children.Add(scale);

TranslateTransform translate = new TranslateTransform();
translate.X = -scale.ScaleX * (double)clipRect.X / (double)texture.PixelWidth;
translate.Y = -scale.ScaleY * (double)clipRect.Y / (double)texture.PixelHeight;
group.Children.Add(translate);

imageBrush.RelativeTransform = group;




clipRect — прямоугольник с параметрами обрезки, аналог s_textureCropOesTiv из примера выше

texture — BitmapSource с самой текстурой




Этот метод кажется странным, но надо помнить, что XAML зачастую hardware accelerated и довольно быстр. Я портировал с таким подходомнесколько мобильных OpenGL ES игр на Windows 8 и работают они приемлемо, только нет возможности изменять цвет текстур, как в GL через glColor. Т.е. в принципе в XAML разрешается менять прозрачность элемента, но никак нельзя менять его Color Tint. Например, если у вас используются белые шрифты и потом раскрашиваются в разные цвета, то с этим подоходом они так и останутся белыми.

В целом, вариант с XAML достаточно сомнителен и не совсем соответствовал изначальному плану, да и без цветовой дифференциации штанов модуляции, потому когда игра была на 80% готова и уже работала на мобильных и стационарном .Net/Mono, я начал искать более приемлемые варианты для Windows 8. Много было слухов и восторгов вокруг порта библиотеки Angle, но на тот момент она была уж очень сырая и без поддержки C#. Напрямую из C# работать с DirectX оказалось тоже не возможно, а сама Microsoft предлагает разработчику несколько «простых» путей: переделать весь C# код на C++, использовать стороннюю библиотеку SharpDX (C# биндинг над DirectX), либо перейти на MonoGame. Библиотека MonoGame это наследник XNA, использующий ту же SharpDX для вывода графики на Windows 8, она довольно неплоха, но довольно специфична и переходить на нее в моем проекте было поздновато. SharpDX выглядел не менее монструозным, ведь тянет за собой все существующие возможности DirectX, хотя и довольно близок к тому, что мне было надо. Я уже начал проводить с ним серьезные беседы с паяльником и мануалом, когда наткнулся на проект gl2dx.


GL2DX




Библиотека эта была выложена юзером average на CodePlex несколько лет назад и больше не обновлялась. Это С++ библиотека, которая объявляет такие же функции, как в OpenGL, а внутри транслирует их в вызовы D3D11. К библиотеке шел пример на C++/CX, который создавал XAML страницу с SwapChainBackgroundPanel и инициализировал ее через D3D11CreateDevice для работы с С++ частью. Проект был бы хорош, если бы хоть немного вышел из стадии прототипа. Технически, в нем работает всего несколько процентов OpenGL методов, а в остальных стоят ассерты. С другой стороны, она справляется с выводом 2D текстур, трансформацией и простейшей геометрией. На этом этапе я взялся за библиотеку и довел ее до состояния продукта, который подключается к C# проекту как Visual Studio Extension и позволяет писать подобный код:

Код


GL.Enable(All.ColorMaterial);
GL.Enable(All.Texture2D);
GL.Color4(1.0f, 1.0f, 1.0f, 1.0f);

GL.TexParameter(All.Texture2D, All.TextureCropRectOes, new int[] { 0, 0, 1024, 1024 });
GL.BindTexture(All.Texture2D, m_textureId1);
GL.DrawTex(0, - (m_width - m_height) / 2, 0, m_width, m_width);

for (int i = 0; i < 10; i++)
{
if (i % 2 == 0)
{
GL.BindTexture(All.Texture2D, m_textureId2);
GL.TexParameter(All.Texture2D, All.TextureCropRectOes, new int[] { 0, 0, 256, 256 });
}
else
{
GL.BindTexture(All.Texture2D, m_textureId2);
GL.TexParameter(All.Texture2D, All.TextureCropRectOes, new int[] { 256, 0, 256, 256 });
}

int aqPadding = 20;
int fishSize = 128;
int aqWidth = (int)m_width - aqPadding * 2 - fishSize;

float x = (Environment.TickCount / (i + 10)) % aqWidth;
float alpha = 1.0f;
if (x < fishSize)
alpha = x / fishSize;
else
if (x > aqWidth - fishSize)
alpha = (aqWidth - x - fishSize) / 128.0f;

GL.Color4(1.0f, 1.0f, 1.0f, alpha);
GL.DrawTex(x + aqPadding, m_height / 20 * (i + 5), 0, fishSize, fishSize);
}




P.S. Код в формате вызовов OpenTK, что немного сбивает с толку тех, что привык писать glColor4f вместо GL.Color4.


Сие поделие получило от меня гордое название MetroGL.

MetroGL




Пример на C++/CX трансформировался в библиотеку на этом же птичьем современном языке, оброс большим количеством дополнительных функций, а C++ получила реализацию многих OpenGL методов, блендинги, оптимизацию внутренного VertexBuilder, загрузку произвольных изображений и DDS текстур, а главное — точную имитацию glDrawTexfOES, дающую 1в1 такую же картинку, как на OpenGL ES, а заодно соединяющую последовательные операции с одной текстурой в единый DrawCall. Кое-что пришлось доводить напильником, сам код местами грязноват (как до меня, так и после), а для создания VSIX расширения надо пересобирать проект вручную под каждую архитектуру (x86, x64, ARM) и лишь потом билдить VSIX проект. Главное, что если у вас есть OpenGL ES 1.* код с 2D интерфейсом или не сложным 3D, то с этой библиотекой его можно использовать прямо из C#, не думая о внутренностях, С++ коде, D3D11 контекстах и других гадостяхрадостях. Заодно сделан пример с рыбками справа и кодом из под ката. Конечно, если код у вас на OpenGL 2.0+ с шейдерами и экстеншенами, то ни о каком портировании речи и не будет.

Другой неприятный момент в том, что у меня нет настроения и желания доводить библиотеку до уровня 50-100% совместимости с OpenGL, а значит под ваши конкретные задачи ее придется затачивать своими силами. Благо, весь код выложен на github и я пока никуда не исчезаю и буду рад коммитам или вообще желающим взвалить на себя этот груз. Библиотека собирается под Windows 8.0 и Windows Phone 8.1, для VSIX может понадобиться не-Express версия Visual Studio.

Эпилог




Ну и в конце-концов немного об играх. Проект свой я на 100% закончил и именно комбинация C# и OpenGL дала возможность сделать высокоуровневый код вообще не изменяемым — это библиотека без единого дефайна, не использующая каких-либо системных вызовов. Затем идет код среднего уровня: рисование через OpenGL в 2D, с вращением, трансформацией и цветовой модуляцией, тут немного код отличается на разных платформах — разные текстуры, по-разному хранятся данные. Низкоуровневая часть уже для каждой платформы разная, это создание окна, инициализация контекста, вывод звука. В любом случае, девять платформ, перечисленные в начале статьи, реально работают, и пусть C# в связке с OpenGL пока нельзя использовать в вебе или на Firefox OS, но все-равно разве это не отблеск кроссплатформенного будущего, господа?



This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Вычислительная техника в Deutsches Museum

Deutsches Museum — самый большой музей техники в Европе. В нем существуют практически все разделы современной техники и, в частности, история развития вычислительной техники. Я хочу представить несколько фотографий, которые могут быть интересны широкому кругу читателей.

Данная экспозиция начинается с огромного числа различных арифмометров и механических вычислительных машин, в частности, логарифмических линеек:


image


Там же представлена знаменитая Энигма:


image


Техника развивается дальше и появляются перфокарты (я с подобными устройствами уже работал):


image


Немногие знают, что первый электронный компьютер был создан в Германии:


image


Модель Zuse 4:


image


Еще несколько ламповых компьютеров:


image


image


image


Уже ближе к нашим дням:


image


image


Знаменитый IBM360:


image


image


Cray 1:


image


Вот из таких компонентов был сделан Cray 1:


image


Видно огромное число соединительных проводов:


image


Ба, да это-же топология интегральной микросхемы, автоматизацией создания которых я занимался многие годы:


image


Эволюция полупроводниковых пластин:


image


Накопители информации из разных времен:


image


Конечно, это только малая часть экспозиции, из которой я постарался выложить наиболее интересные вещи. На этом я пока заканчиваю, если сообществу будет интересно, можно будет рассказать про разделы, посвященные авиации и освоению космоса.


This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Почему вам НЕ стоит использовать AngularJs

Много времени прошло с момента появления AngularJs (в масштабах веб-технологий конечно). Сейчас в интернетах есть огромное количество постов восхваляющих этот фреймворк до небес, что это манна небесная не иначе, а критики не так уж и много как он того заслуживает. Сразу хочу сказать, что фреймворк я знаю хорошо, даже больше чем мне хотелось бы его знать, я программировал на нем в течении 2 лет. И для следующего проекта я его точно не выберу. Так что же не так с ним? Тут нет однозначного ответа, слишком много разных недостатков, которые создают такой облик фреймворку. Если одним словом – непродуманная архитектура.

Распространенная практика в мире ангуляра — решать проблемы, которые сам себе же и создал. Хотя на самом деле этой проблемы можно было бы и избежать, если хорошо спроектировать архитектуру. И ЭТОТ ПАТТЕРН ЕСТЬ ПРАКТИЧЕСКИ В КАЖДОМ АСПЕКТЕ ФРЕЙМВОРКА. Под катом я приведу много конкретных примеров, так что устраивайтесь поудобнее.



Двусторонний дата-биндинг




Существует фундаментальное правило, что явное лучше неявного. Все эти watcher'ы это неявный вызов обработчиков событий. В реальности события происходят при клике по элементу, а не при изменении данных, поэтому когда вы пишите на ангулярке вам необходимо думать следующим образом: «ага, тут кликнули по кнопке и изменилась модель, теперь нужно слушать изменения на этой модели и когда она меняется вызывается хэндлер», а не «кликнули на кнопку, вызвался хэндлер», ДВУСТОРОННИЙ БИНДИНГ — ЭТО НЕ ТО КАК ПРОИСХОДИТ ОБРАБОТКА СОБЫТИЙ В ПРИНЦИПЕ. На малых масштабах это не так заметно, но когда начинаешь писать что-то побольше Hello World, то отсутствие такой последовательности очень сильно мешает. И к тому же это усложняет дебагинг, подробнее об это в главе про дебаггинг.

Еще двусторонний биндинг означает, что изменив что-либо в своем приложении, это тригерит сотни функций, которые наблюдают за изменениями. И это чудовищно медленная операция, особенно все становится плохо на мобильных платформах. И это фундаментальная часть фреймворка. Ангуляр даже накладывает ограничения на то насколько богатый UI можно писать. И что самое интересное, это не какое-то эфемерное и далекое ограничение в которое вы никогда не упретесь. Это всего лишь 2000 биндингов, и если вы разрабатываете более-менее большое приложение, ТО ВЫ ТОЧНО УПРЕТЕСЬ В ЭТО ОГРАНИЧЕНИЕ. И тут вам придется драться с фреймворком. Ангуляр вводит возможность одностороннего дата-биндинга, что бы избежать проблем с производительностью. Создаем себе проблему и решаем ее костылем (непродуманная-архитектура#1).


Тут есть еще один момент, иногда все-таки двух сторонний дата-биндинг нужен, но UI все равно тормозит. Например при первой загрузке пользователь видит {{ выражения в скобочках }}. Хм… так это ж не баг, это фича! Нужно ввести директиву, которая будет прятать UI, что бы пользователь не видел мерцания, и не мешал фреймворку решать его несуществующие проблемы. И для этого вводится директива ngCloak, которая собственно этим и занимается. Опять создаем себе проблемы и решаем костылями (непродуманная-архитектура#2).


И если у фреймворка появляются такие проблемы с масштабируемостью, не значит ли это, что что-то на фундаментальном уровне не так? Лаконичные и продуманные технологии, как правило масштабируются очень хорошо.






Dependency Injection




Следующий пример того, как ангуляр сначала ставит грабли, а потом заставляет вас плясать с бубном, что бы их обойти — это Dependency Injection. В ангуляре переменные внедряются по имени аргумента:

function MyController($scope, $window) {
// ...
}




Здесь ангуляр вызывает у функции .toString(), берет названия аргументов и потом ищет их в списке со всеми существующими зависимостями. И проблема тут в том что, ЭТО ПЕРЕСТАЕТ РАБОТАТЬ ПРИ МИНИФИКАЦИИ КОДА.

Когда вы минифицируете свой код, то он перестает работать, потому что переменные инжектятся по имени. Вам либо нужно использовать такой синтаксис:



someModule.controller('MyController', ['$scope', 'dep1', 'dep2', function($scope, dep1, dep2) {
}]);




или такой

MyController.$inject = ['$scope', '$window'];




и в том и в том случае синтаксис совершенно уродливый. Для того, что бы решить эту проблему существуют специальные плагины, которые сделают из вашего кода пригодный для минифицирования код: ng-min и ng-annotate (непродуманная-архитектура#3). Существует три способа указать зависимости (совершенно не понятно зачем нужно было столько способов сделать одно и то же), один из которых не работает и требует костылей, а остальные уродливые. Примечательно, что документация начинается со способа, который не работает.

Следующая важная часть — это то, как зависимости объявляются. Прежде чем внедрять зависимость ее нужно как-то объявить. Как это можно было сделать, если вы психически здоровый человек:



injector.register(name, factoryFn);



Где name — это название зависимости, и factoryFn — функция, которая будет инициализировать зависимость. Вот и все. Буквально в одном предложении уместили очень лаконичную идею. Теперь смотрим на то что предлагает ангуляр http://docs.angularjs.org/guide/providers. Там вводятся 5 новых сущностей: provider, service, factory, value, constant (непродуманная-архитектура#4). И каждая из них чем-то отличается друг от друга, но по сути это все одно и то же. Но самое главное, что все они могут быть легко заменены одним методом, который я привел выше. Но это слишком просто и не интересно, уж лучше давайте заставим людей мучится.

И еще на засыпку, любая сущность которая инжектится называется «сервис» и один из типов сервиса, называется «сервис». И еще у них есть концепция фильтров и один объект из этой концепции называется… как, как вы думаете он называется (барабанная дробь) — ФИЛЬТР! ЭТО ГЕНИАЛЬНО!!! Это тоже самое что назвать своего ребенка «ребенок».






Дебаггинг




Дебаггинг сам по себе сложный, но этого мало, нужно это усложнить! Ангуляр питается вашей болью и страданьями!

ОШИБКИ В БИНДИНГАХ ВООБЩЕ НЕ ВЫЛЕТАЮТ, например в вот этом коде:


{{ phone }}







если user не определен, то никакой ошибки не будет (непродуманная-архитектура#5). Ангуляр молчит как партизан. Более того вы не можете поставить брейкпойнт внутри {{ такого идиотского выражения }}, потому что это не JavaScript.

Ошибки, которые произошли в JavaScript'е ловятся внутренним ангуляровским перехватчиком, и ВОСПРИНИМАЮТСЯ БРАУЗЕРОМ КАК ПОЙМАННЫЕ ОШИБКИ (все что произошло в ангуляре, остается в ангуляре). Из-за этого приходитья ставить в хроме флаг «Pause on caught exeptions» (что бы дебаггер останавливался на всех ошибках, а не только на непойманных (обычно интересуют именно непойманные ошибки, которые выкидываются в консоль)), поэтому приходится в дебаггере проходить по всем внутренним пойманным исключениям ангулярки пока она инициализируется (непродуманная-архитектура#6) и только потом вы попадаете именно в ваше исключение. И тут-то вы увидите вот такой стактрейс:



Ошибка вылетает из digest цикла и это означает, ЧТО ОНА МОГЛА БЫТЬ ВЫЗВАНА ИЗМЕНЕНИЕМ ЛЮБОЙ ПЕРЕМЕННОЙ ВО ВСЕМ ПРИЛОЖЕНИИ. Вы хрен когда проследите в дебаггере откуда растут ноги у ошибок. (непродуманная-архитектура#7)






Наследование скопов




Это без сомнения самая распространенная ошибка с которой сталкивался абсолютно каждый разработчик на angular. Например если вы напишите вот такой код

{{ phone }}











то при нажатии на кнопку переменная phone меняется не будет, в то время как в этом коде
{{ phone.value }}











все работает корректно, и номер телефона меняется при нажатии на кнопку. Либо например вот этот код, который даже опытных разработчиков поставит может поставить в тупик http://jsfiddle.net/1op3L9yo/. Даже введен новый синтаксис для объявления переменных в контроллере через this, который решает эту проблему. (непродуманная-архитектура#8)

Я не буду объяснять почему так происходит, на эту тему столько статей написано в интернете. И что самое интересное — этой проблемы можно было бы легко избежать просто УБРАВ ВОЗМОЖНОСТЬ НАСЛЕДОВАНИЯ СКОПОВ. Это был бы правильный дизайн. К тому же когда вы используете переменные из родительского скопа, это становится крайне сложно тестировать, странно, что фреймворк, который ставит одной из своих самых сильных сторон легкость тестирования, вводит такую логику.






Директивы




Мы подошли к самому интересному, директивы — это святая святых ангуляра. Им воспевают песни и хвалят все, кому не лень. Но я буду прагматичным, вот полный синтаксис объявления директивы:

var myModule = angular.module(...);

myModule.directive('directiveName', function factory(injectables) {
var directiveDefinitionObject = {
priority: 0,
template: '



', // or // function(tElement, tAttrs) { ... },
// or
// templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... },
transclude: false,
restrict: 'A',
templateNamespace: 'html',
scope: false,
controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },
controllerAs: 'stringAlias',
require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],
compile: function compile(tElement, tAttrs, transclude) {
return {
pre: function preLink(scope, iElement, iAttrs, controller) { ... },
post: function postLink(scope, iElement, iAttrs, controller) { ... }
}
// or
// return function postLink( ... ) { ... }
},
// or
// link: {
// pre: function preLink(scope, iElement, iAttrs, controller) { ... },
// post: function postLink(scope, iElement, iAttrs, controller) { ... }
// }
// or
// link: function postLink( ... ) { ... }
};
return directiveDefinitionObject;
});




Что бы понять этот синтаксис и зачем это нужно, надо действительно заморочиться. Вместо того, чтобы описывать ЧТО нужно сделать, вы больше заморачиваетесь на том КАК это сделать. И что самое обидное — ЭТА СЛОЖНОСТЬ НЕ НЕСЕТ НИКАКОЙ ПОЛЬЗЫ. (непродуманная-архитектура#9)

Далее, чтобы интегрировать какой-то код в мир ангуляра, например какой-нибудь jQuery плагинчик, вам нужно обернуть его обязательно в директиву. Потому что это было бы слишком просто, если бы разработчики могли сразу использовать готовые решения!


Далее, в директивах есть controller, compile, link функции, которые делают примерно тоже самое, но хрен пойми почему из них не сделать одну единственную функцию. И плюс ко всему имеется приоритет на директивах, в итоге какой код из какого метода (compile, link, controller) в какой последовательности применяется, если на элементе указано несколько директив, да еще какой-нибудь трансклюд вообще хрен пойми. (непродуманная-архитектура#10)






Проблемы с людьми




Во первых из-за того, что фрейворк чрезмерно сложный, мало разработчиков его понимают на действительно хорошем уровне и найти таких людей сложно. Во вторых серверные разработчики вообще не будут понимать, что творится на front-end'е и не смогут читать код. А это очень большой недостаток, создается черный ящик, в котором может разобраться только один человек в команде, и если этот человек уйдет, то никто не сможет его заменить. Это было бы нормально, если бы разработка на front-end'е действительно бы требовала таких сложных инструментов, но нет, она сложная потому что сложности создаются целенаправленно.





Невозможность серверной шаблонизации




Если вы попытаетесь использовать серверную шаблонизацию, например что бы ускорить прорисовку страницы, либо что бы поисковики индексировали (либо и то и другое), то вас постигнет разочарование. Т.к. серверная шаблонизация добавляет логики в HTML и AngularJs тоже пишет логику в HTML, то не происходит четкого разделения ответственности и как результат очень запутанный спагетти-код. Ангуляр просто не предполагает того, что разработчики захотят ускорить загрузку страницы, либо захотят индексацию поисковиками, он не создан для этого. (непродуманная-архитектура#11)





Важные вещи россыпью





  • Ужасная документация. Приходится дополнительно гуглить много информации.

  • До сих пор отсутствуют директивы для Drag and Drop событий (на момент написания этой статьи). Само по себе это не очень большая проблема, но это сигнализирует о продуманности продукта и внимании к деталям.

  • Когда вы пишите на ангуляре вы помещаете логику в ваш HTML. ng-repeat, ng-show, ng-class, ng-model, ng-init, ng-click, ng-switch, ng-if — что это как не помещение логики в представление. И самое главное — это невозможно тестировать юнит-тестами (непродуманная-архитектура#12).

  • Гугл не использует AngularJs для своих основных продуктов (gmail, google+). И это вызывает подозрения, если это такой хороший фрейворк и они сами его создали, что тогда сами и не используют? Хотя например изобретенный в фейсбуке ReactJs они используют в facebook.com и в инстаграмме.

  • Гугл может передумать и закрыть этот проект. Все мы знаем как гугл любит закрывать даже очень популярные проекты.






НЕ ИСПОЛЬЗУЙТЕ АНГУЛЯР. Вместо ангуляра лучше использовать React (предпочтительно) либо jQuery (для тех кто боится использовать реакт по какой-то причине). Я не знаю почему ангуляр популярный, но это точно не потому что это хороший фреймворк. Надеюсь мой опыт поможет кому-нибудь принять правильное решение при выборе стека технологий для следующего проекта.


This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Дайджест интересных материалов о создании контента, маркетинге и Growth Hacking #7


сегодня в 12:58





659


17






Похожие публикации



Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.


This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


[Перевод] Как колл-центры используют бихевиоральную экономику, чтобы оказывать влияние на клиентов


Когда в следующий раз будете дозваниваться в колл-центр, прислушайтесь внимательнее к тому, что говорит ваш собеседник. Велика вероятность того, что вас несколько раз назовут по имени, проявят сочувствие, возможно, извинятся. Приятно думать, что представитель компании действительно волнуется за вас – однако, девушка из колл-центра, вероятнее всего, просто следует написанному сценарию. Как показало наше исследование, использование подобной техники – не всегда удачное решение. В недавней статье для HBR под заголовком "Перестаньте пытаться угодить клиентам", мы рассматривали вопрос того, как клиентский сервис влияет на верность бренду, включая роль управления эмоциональной стороной взаимодействия с пользователями. Ниже приводится несколько дополнительных инсайтов на эту деликатную тему.


Когда речь заходит о коммуникации между представителем колл-центра и клиентом, большинство компаний все еще не может избавиться от подхода, в центре которого лежит выполнение сотрудником обязательно набора действий из некоторого списка. Сначала стандартное приветствие… сверьтесь о списком… три раза повторите имя клиента… еще раз сверьтесь со списком… покажите ему, что вам важна его проблема… еще проверка… спросите, удалось ли полностью решить проблему… сверьтесь еще, и еще, и еще раз.


Большинство компаний скажут вам, что в этом вопросе важно быть последовательным. Но, давайте признаем, что эта последовательность взращивает общение «на автомате», которое не влечет у клиента ощущение, что ему все удалось сделать без труда и не привязывает его к компании.


Мы видели, как компании уходят от этого «единого для всех» подхода и начинают относиться к обучению сотрудников колл-центра более креативно: просят их выбирать из разных вариантов ответа и, в некоторых случаях, использовать подходы, основанные на положениях бихевиоральной экономики, чтобы в корне изменить то, как клиент воспринимает взаимодействие с компанией.


Возьмите, к примеру, кейс Orsam Sylvania, пример, который мы разбирали в предыдущей статье. В этой компании сотрудников учат избегать слов с негативной коннотацией (например, «нельзя», «невозможно») и фраз, которые не позволяют продуктивно продолжать общение (вроде фразы «это наше дело»), в наиболее стандартных форматах сервисного взаимодействия. Это позволило им добиться снижения показателя Customer Effort Score (CES, показатель усилий клиента, чем меньше должен клиент прикладывать усилий к решению проблемы, тем этот показатель ниже и тем выше верность бренду со стороны потребителя) на 18,5% в сравнении со средним значением по индустрии.



Не так давно мы провели серию экспериментов над двумя разными группами потребителей, чтобы лучше понять влияние выбора слов на взаимодействие с клиентом:


В одном эксперименте сотруднику компании нужно было авторизовать банковский аккаунт клиента прежде, чем тот мог получить возможность осуществить перевод средств. Когда сотрудник просто говорил: «Вы не сможете перевести средства, пока не выполните действия по авторизации аккаунта...», клиенты оценивали его работу существенно ниже, чем когда специалист колл-центра строил фразу так: «Позвольте мне помочь вам авторизовать ваш аккаунт...». При том, что смысл фразы отличается ненамного, клиенты оценили последний вариант, как на 82% более качественный и потребовавший на 73% меньше усилий от них самих.


В другом эксперименте клиентам говорили, что им нужно привезти их новые велосипеды в сертифицированный центр ремонта. Качество работы специалиста, который просто констатировал: «Вам лучше привезти велосипед в центр по ремонту» было оценено намного ниже, чем работа сотрудника, который отмечал, что он «передаст отзыв в отдел сборки», «проверит по базе, можно ли обойтись мелким ремонтом» и в итоге «порекомендовал привезти велосипед в ремонтный центр». Последний вариант посчитали на 67% более качественным и потребовавшим от клиента на 77% меньше усилий.


Такой подход выходит за рамки традиционных навыков общения с клиентами. Он основывается на внимании к выбору языковых конструкций, которое позволяет максимально эффективно формулировать фразы. Это не просто сочувствие – это точно рассчитанное и предупредительное поведение. Мы называем это активным формированием пользовательского опыта.


Мы наблюдали и другие подходы к формированию пользовательского опыта, помимо простого подбора слов. Например, компания LoyaltyOne (также упомянутая в статье) практикует подход под названием «альтернативное позиционирование». Этот подход основан на получении и изучении базовой информации о клиенте в процессе взаимодействия и использовании этой информации для изменения в лучшую сторону отношения клиента к тем опциям, которые ему предлагает сотрудник. Внутреннее исследование компании показало, что по мнению клиентов качество обслуживания с использованием этой практики возросло на 15%.


В альтернативном позиционировании нет ничего революционного – по сути, продавцы демонстрировали характеристики продукта в выгодном для конкретного клиента свете с тех самых пор, как начала вестись торговля. Но использование этого метода в сервисных сценариях выглядит довольно инновационно и немногие готовы использовать такой подход.


Наряду с этим, мы видели, как подобные техники могут превратиться в сомнительные практики, этичность которых можно поставить под вопрос. Представители одной авиакомпании (которую мы не будем называть) недавно признались нам, что «поймали» некоторых из своих лучших специалистов поддержки на использовании похожих техник для избежания скандалов с клиентами из-за отмененных рейсов.


Представьте, например, что ваш рейс на 11 утра отменен, а вам завтра утром надо быть в другом городе. Но на вечерний рейс остаются свободные места. Там, где большинство специалистов говорят: «Я могу забронировать для вас билеты на 9 вечера», другие, прекрасно зная, что девятичасовой рейс открыт для бронирования, но желая манипулировать реакцией клиента, могут сказать: «Хорошо, я могу забронировать места на завтрашний рейс на 7 утра, но дайте-ка мне посмотреть, смогу ли я найти места на рейс пораньше, по нему вылет будет в 9 вечера сегодня». Эта техника формирования пользовательского опыта называется «эффект якоря». Менее приемлемая опция создает ментальный якорь, делая альтернативу более привлекательной. Вместо того, чтобы переживать, что 11-часовой рейс отменен, вы, вероятнее всего, порадуетесь, что специалист забронировал для вас место на вечерний рейс.


С точки зрения этики, у компаний, как правило, не возникают трудности с принятием идеи заменить негативные фразы на нейтральные или попросить сотрудников демонстрировать больше активного содействия клиенту. Но не заходят ли те, кто использует «эффект якоря» для формирования положительного пользовательского опыта, слишком уж далеко? В наших экспериментах мы протестировали похожие подходы, и они, безусловно, срабатывали, но по нашему мнению, это та сфера, в которой очень легко перейти грань этичности.


This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


CAD для разработки снежинок



Привет всем.

Да да, это CAD, для разработки снежинок, написанный мной за пару дней.

Предисловие.




Вырезая на днях очередную снежинку я задумался. Очень уж неудобно вырезать снежинку в слепую, разворачивать её, и убеждаться, что сделал не то что хотел.

Сначала я стал прибегать к карандашу. Сворачиваем снежинку, рисуем, вырезаем. Но мое воображение продолжало играть со мной злые шутки, я разворачивал и видел очередного уродца.

Почему бы не разработать CAD, чтобы поставить точку в этой ужасной несправедливости?

В статье не будет никакого процесса разработки и программирования. В ней я поделюсь с вами получившейся программой, и расскажу как ей пользоваться. Под катом много картинок.

Забрать сборку по win можно тут: http://sourceforge.net/projects/snowflaker/

Там же исходный код в GIT. Сборки под linux пока нет, но программа написана на fpc, и должна собираться и работать под linux-ом.


О программе




В программе мы проектируем контур, по которому будем вырезать, и отправляем на печать. Получаем распечатанный лист, складываем, вырезаем по контуру.

Поскольку не у всех есть принтер — изображение для печати можно предварительно растеризовать в png. Чтобы потом распечатать снежинок, прийти домой, сложить и вырезать.

Основы работы




Теперь к самой программе. Так как во многих случаях проще показать — дальше будет много картинок.

Итак интерфейс у неё следующий:



В рабочей области 2 линии — это границы листа после сворачивания. Тут мы можем таскать область правой кнопкой мыши, и зумить колесом:



Чтобы создать первый контур — выбираем инструмент линия, и левой кнопкой мыши рисуем ломаную. Как только решили что нам хватит — правой кнопкой выключаем инструмент.



hint: взять инструмент линия так же можно двойным щелчком на пустой области или на любой вершине.

Но пока у нас прямые линии. Давайте изогнем их (хватаем за линию или за специальные контрольные точки, и тащим):



Надо что-то куда-то передвинуть? Выделяем группу вершин, тащим их, или вообще удаляем клавишей Del:



hint: удалять любые примитивы (линии, вершины, заливку) можно щелчком правой кнопкой мыши по примитиву

Удалили лишнего? Не беда. Делаем двойной щелчок на линии, и получаем дополнительную вершину:



Работали в Paint-e? Там есть инструмент заливка. Можно обвести определенную область, потом капнуть в центр и залить. Берем заливку, капаем в снежинку, и видим в области просмотра наше чудо:



Важно! Заливаемый контур должен быть замкнут. Вот что будет, если разомкнуть контур:



Работает 1 в 1 как заливка в паинте.

Заливка не влияет на изображение при печати. Это только для предпросмотра.

Сохранение, открытие файла я разжевывать не буду. С печатью все просто, жмем кнопку печати, выбираем принтер, печатаем.

Хочу лишь обратить внимание на пункт сохранения снежинки для печати в PNG формате. Он вот тут:


Работаем с результатом печати




После печати у вас будет примерно вот такая картинка:



Поскольку тут много больших фото, то
как все это сложить смотрим под спойлером

Правила проектирования




Чтобы не возникло казусов: «Я вырезал снежинку, а она у меня рассыпалась» я хочу ознакомить всех с простыми правилами грамотного проектирования.

Снежинка состоит из линий разреза. Для снежинки есть верхняя линия разреза, которая обязательно должна пересекать обе стороны:



Дальше могут быть внутренние вырезы. Из обязательное условие — пересекать только одну сторону:



Ну и наконец у самой последней, нижней линии, вырезающей центр — могут быть пересечения с обоих сторон:



Если вы хотите вырезать не снежинку, а шаблон (например для нанесения на стекло), то у вас в распоряжении есть только одна верхняя линия. Никаких внутренних вырезов.

В заключение




Я думаю я опоздал с софтом, и снежинки у большинства уже нарезаны. Однако если это не так — я буду рад, если программа поможет вам сделать что-то замечательное. Так же буду рад, если найдете баги ;)

Всем новогоднего настроения, хороших праздников и удачи в будущем году.

Спасибо за внимание!

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.