Я надеюсь, что сейчас, в 2014 году, нет необходимости объяснять, почему это SVG благословение для разработчиков, которые хотят, чтобы их графики выглядят острыми на всех устройствах, особенно с их огромным разнообразием резолюций .
Но, как и любой другой технологии, SVG имеет свои ограничения.И в этой статье мы поговорим о том, как обойти некоторые из них .
Что Проблема
Почему вы даже не нужно, чтобы генерировать SVG на сервере?Технология полностью на стороне клиента, так что бы мотивировать, чтобы кто-переместить его оттуда
Прежде чем ответить на эти вопросы, давайте посмотрим на состояние industry.Когда мы говорим о “создании SVG” в настоящее время, мы имеем в виду “генерации SVG с JavaScript.” Текущее состояние браузере поддержку и библиотек делает создание сложных визуальных (даже с анимацией и взаимодействия с пользователем) нетривиальная задача: Просто выберите библиотеку,подходит ваша потребность .
И есть много, чтобы выбрать из, от общего назначения, таких как те, Raphaël.js __15 | | 1__14 | __19, Snap.svg __21 | | 2__14 и svg.js 3 в мириады мелких, а также, если вы заговоре и визуализации данных, gRaphaël 4 | __18 | Highcharts__14 5 и D3 6 .
Так прямо вопрос, как мы продолжаем генерировать SVG с JavaScript, а также положить результаты поколения на сервере?Вопрос в том, немного долго, но вот причины, почему мы должны на него ответить:
- Для позволяют пользователю скачать graphicЕсли мы не хотим, чтобы напугать пользователя с этим “неизвестным” формате, то мы должны преобразовать SVG в PNG или PDF .
- Чтобы включить графики для вставлен в emailМы все любим графики в наших электронных писем, и мы предпочитаем Retina-готовые те .
- Чтобы включить графический будет отображаться на другом websiteПодумайте API .
- Для улучшения performanceЛогика комплекс визуализации может легко повесить браузер для нескольких секунд.По генерации SVG на сервере, мы можем кэшировать результат, а затем доставить в кэше SVG, когда следующий пользователь хочет, .
Solutions
Просто Повторное вся логика на Server
Это решение можно, просто не практично.Большинство зрелых языках фоновых есть библиотеки для генерации SVG.Но мыразработчики.Мы не хотим, чтобы воссоздать ту же логику в два раза, потому что это приведет к ошибкам, проблемы интеграции и обременительной необходимости поддержки .
Простой Solution
Самый простой способ поставить сгенерированный SVG на сервере, это просто отправить сгенерированные данные с просьбой AJAX, когда это полная .
Ниже простой пример с Raphaël.js и JQuery.Давайте начнем с простого HTML как шаблонного:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.2/raphael-min.js"></script>
</head>
<body>
<div id="svg"></div>
</body>
</html>
Теперь добавьте наш код рисования на него:
$(function() {
var svgContainer = document.getElementById("svg");
var paper = Raphael(svgContainer, 640, 480);
paper
.rect(0, 0, 640, 480, 10)
.attr({
fill: '#fff',
stroke: 'none'
});
var circle = paper
.circle(320, 240, 60)
.attr({
fill: '#223fa3',
stroke: '#000',
'stroke-width': 80,
'stroke-opacity': 0.5
});
paper
.rect(circle.attr('cx') - 10, circle.attr('cy') - 10, 20, 20)
.attr({
fill: '#fff',
stroke: 'none'
});
$.post(
'/svg_catcher',
{ content: svgContainer.innerHTML }
);
});
На сервере, мы просто кэшировать результат и сохранить или обработать его, как нам хотели.Вот полученное изображение, в случае вам интересно:
8
В случае, если ваш браузер не поддерживает эту фотографию, here’ са PNG version 9 .
Этот метод является абсолютно подходит не только для Рафаэле, но и для любого SVG-генерации библиотеки.Я просто взял Рафаэль, потому что это популярно, боевые испытания решение, с API, что легко понять.Это резко упрощает создание и обработку изображений через JavaScript, а также поддерживает VML для старых браузеров, которые не поддерживают SVG .
Этот подход легко и просто, но она имеет много недостатков, слишком:
- Вам придется встраивать все внешние ресурсы (в основном изображения) после их загрузки;в противном случае, все преобразователи покажет белый заполнитель вместо первоисточник .
- Если SVG большая и сети пользователя не является надежным, то в результате файл может в конечном итоге недействительными.Мы могли бы проверить действия на стороне сервера, но это не поможет при следующем точки .
- Вредоносное вход проблема.Замена красивый красочный бизнес диаграмму с (SVG) изображения котенка легко.Технически, это было бы справедливо, но вы можете видеть, почему это было бы вредно .
Вы могли бы, конечно, взять этот подход, если вы доверяете своим пользователям (если это приложение интрасети, например).В противном случае, риск для безопасности может быть слишком большим .
PhantomJS
Для устранения вход пользователя из уравнения (или свести ее к минимуму, насколько это возможно), мы должны двигаться наш скрипт поколения к серверу.
Много сложного кода работает в браузере.Самый простой способ запустить ее на сервере, чтобы переместить браузер с сервером.Благодаря PhantomJS 10 , что является абсолютно выполнимо .
PhantomJS является реализация WebKit, что можно управлять с помощью JavaScript.Грубо говоря, это реальная — пока обезглавленное — браузеру, что означает, что веб-страницы никогда не оказывается .
Начните с установки PhantomJS в вашей системе, которая легко, следуя официальный documentation __12 | 11 .Затем мы изменим наш скрипт, чтобы заставить его работать с PhantomJS: Во-первых, создать index.html
с шаблонного кода для нашего генератора:
<!DOCTYPE html>
<html>
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.2/raphael-min.js"></script>
<meta charset="utf-8">
</head>
<body>
<div id="svg"></div>
</body>
</html>
Затем создайте generator.js
, который будет управлять PhantomJS:
var fs = require('fs');
var page = require('webpage').create();
var url = 'file://' + fs.absolute('./index.html');
var svgDrawer = function() {
var svgContainer = document.getElementById("svg");
var paper = Raphael(svgContainer, 640, 480);
paper
.rect(0, 0, 640, 480, 10)
.attr({
fill: '#fff',
stroke: 'none'
});
var circle = paper
.circle(320, 240, 60)
.attr({
fill: '#223fa3',
stroke: '#000',
'stroke-width': 80,
'stroke-opacity': 0.5
});
paper
.rect(circle.attr('cx') - 10, circle.attr('cy') - 10, 20, 20)
.attr({
fill: '#fff',
stroke: 'none'
});
return svgContainer.innerHTML;
};
page.open(url, function (status) {
console.log(page.evaluate(svgDrawer));
phantom.exit();
});
Сейчас она готова произвести SVG для нас:
phantomjs generator.js > result.svg
Итак, у нас есть генератор, который полностью работает на нашем сервере, без нашего написал много кода .
Можем ли мы сделать это лучше?Да
Запуск time phantomjs generator.js > result.svg
ушло около 0,2 секунды на моей машине .
0.14s user 0.03s system 74% cpu 0.232 total
Наиболее ресурсоемкой задачей было, конечно, мы должны сделать это для каждого запроса, который несколько неэффективно “браузера потепление.”.Мы можем предотвратить это, повернув наш сценарий PhantomJS из раствора «одного перспективе” к реальному серверу, который прислушивается к данным и отвечает SVG .
Давайте сделаем это.Мы не хотим, чтобы генерировать тот же SVG каждый раз, таким образом, мы также добавим динамическую поддержку нашей визуализации.Наша конечная документооборота будет выглядеть следующим образом:
- Запустите сервер, который будет слушать на специальный порт для наших запросов .
- Передать его просьбу с нашей полезной нагрузки данных для визуализации .
- Получить ответ с SVG, основанный на наших данных .
Для запуска сервера, мы будем использовать встроенный в module __52
Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров