Я надеюсь, что сейчас, в 2014 году, нет необходимости объяснять, почему SVG является благословением для разработчиков, которые хотят, чтобы их графики выглядят острыми на всех устройствах, особенно с их огромным разнообразием резолюций .
Но, как и любой другой технологии, SVG имеет свои ограничения.И в этой статье мы поговорим о том, как обойти некоторые из них .
Что Проблема
Почему бы вам даже не нужно генерировать SVG на сервере?Технология полностью на стороне клиента, так что бы мотивировать кто-нибудь, чтобы переместить его оттуда
Прежде чем ответить на эти вопросы, давайте посмотрим на состояние industry.Когда мы говорим о “создании SVG” в настоящее время, мы имеем в виду “генерации SVG с помощью JavaScript.” Текущее состояние браузере поддержку и библиотек делает создание сложных визуальных эффектов (даже с анимацией и взаимодействия с пользователем) нетривиальная задача: Просто выберите библиотеку, котораяподходит ваша потребность .
И есть много, чтобы выбрать из, от общего назначения из них, такие как Raphaël.js 1 , Snap.svg 2 и svg.js 3 в множества мелких, а также, если вы черчения и визуализации данных, gRaphaël 4 , Highcharts 5 и D3 6 .
Так прямо вопрос, как мы продолжаем генерировать SVG с JavaScript, а также положить результаты поколения на сервере?Вопрос в том, немного долго, но вот причины, почему мы должны на него ответить:
- Чтобы разрешить пользователю загрузить graphicЕсли мы не хотим, чтобы напугать пользователя с этим «неизвестного» формате, то мы должны преобразовать SVG в PNG или PDF .
- Чтобы включить графики для вставлен в emailМы все любим графики в наших электронных писем, и мы предпочитаем Retina-Ready те .
- Чтобы включить графику, который будет отображаться на другом 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 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 из раствора “одно-Run” к реальному серверу, который прислушивается к данным и отвечает SVG .
Давайте сделаем это.Мы не хотим, чтобы генерировать тот же SVG каждый раз, так что мы также добавим динамическую поддержку нашей визуализации.Наша конечная рабочий будет выглядеть следующим образом:
- Запустите сервер, который будет слушать на специальный порт для наших запросов .
- Передать его просьбу с нашим полезных данных для визуализации .
- Получите ответ с SVG на основе наших данных .
Для запуска сервера, мы будем использовать встроенный в module
Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров