CSS властивості
ГлавнаяCanvasПрактика: Створення діаграм Canvas

Практика: Створення діаграм Canvas

272

Вихідники всіх проектів цієї книги можна знайти тут.

Зверніть увагу, що у цьому розділі ми завантажуватимемо код безпосередньо з локального жорсткого диска, а не через веб-сервер. Можливо, потрібно вимкнути безпеку в Chrome на час розробки. Якщо у Chrome виникли проблеми із завантаженням зображень або інших файлів безпосередньо з диска, спробуйте додати деякі прапори безпеки в командному рядку.

На Mac OS X це буде так:

/Applications /Google\ Chrome.app/Contents/MacOS/Google\ Chrome--allow-file-access-from-files--disable-web-security

На Linux:

chromium-browser--disable-web-security

У Windows:

chrome.exe--disable-web-security

Крім того, ви можете завантажити сторінки через локальний веб-сервер.

У цьому розділі ми відобразимо деякі дані шляхом малювання гістограми. Це покаже вам основи малювання ліній, фігур і тексту, потім ми зробимо кругову діаграму з градієнтом. ньому:

<html>
<body> <canvas width="500" height="500" id="canvas"></canvas> <script> var data=[16, 68, 20, 30, 54];
</script>
</body>
</html>

Сторінка вище містить елементи <canvas> та <script>. Елемент <canvas> є прямокутником на екрані, в якому відбуватиметься малювання. width та height визначають, наскільки він буде великий. <canvas> це блоковий елемент схожий на <div>, так що ви можете стилізувати його або позиціонувати так само, як і все інше на сторінці.

Змінна data у скрипті зберігає набір точок даних, які ми відобразимо в гістограмі.

Тепер отримаємо вказівник на полотно та заллємо фон сірим кольором. Додайте це в скрипт після змінної data.

<code data-language="javascript">//отримуємо вказівник на полотно var canvas=document.getElementById( 'canvas'); //Отримуємо покажчик на контекст малювання var c=canvas.getContext('2d'); //малюємо c.fillStyle="gray"; c.fillRect(0,0,500,500);

Додаємо дані

Тепер ви можете намалювати деякі дані. Зробіть це пробігаючись у циклі за масивом data. Для кожної точки даних заливаємо прямокутник, координата x якого визначається індексом масиву, а висота — його значенням. ; for(var i=0; i<data.length; i++) { var dp=data[i]; c.fillRect(25 + i*100, 30, 50, dp*5); }

Завантажте цю сторінку у вашому браузері. Повинно виглядати приблизно так:

Проста гістограма

Проста гістограма

Перша проблема полягає в тому, що стовпці йдуть зверху вниз замість знизу вгору. Пам'ятайте, що вісь містить 0 вгорі і збільшується коли ви йдете вниз. Щоб стовпці йшли знизу вгору, змінимо значення y на розраховане як висота полотна (500) мінус висота стовпця (dp*5), а потім додатково віднімемо 30, щоб підігнати по висоті.

<code data-language="javascript">//малюємо дані c.fillStyle="blue"; for(var i=0; i<data.length; i++) { var dp=data[i]; c.fillRect(25 + i*100, 500-dp*5 — 30, 50, dp*5); }

Тепер це виглядає так:

Фіксована орієнтація

Фіксована орієнтація

Осьові лінії та мітки

Тепер додамо осі через обведення лінії, яка починається зверху, рухається вниз і вправо.

<code data-language="javascript">//малюємо осьові лінії c.fillStyle="black"; c.lineWidth=2.0; c.beginPath(); c.moveTo(30,10); c.lineTo(30,460); c.lineTo(490,460); c.stroke();

Тепер додамо значення мітки та засічки зліва.

<code data-language="javascript">//малюємо текст і вертикальні лінії c .fillStyle="black"; for(var i=0; i<6; i++) { c.fillText((5-i)*20 + "",4, i*80+60); c.beginPath(); c.moveTo(25,i*80+60); c.lineTo(30,i*80+60); c.stroke(); }

І, нарешті, додамо мітки знизу для перших п'яти місяців року.

<code data-language="javascript">var labels=["JAN" ,"FEB","MAR","APR","MAY"]; //виводимо текст for(var i=0; i<5; i++) { c.fillText(labels[i], 50+ i*100, 475); }

Результат виглядає таким чином:

Діаграма з осьовим лініям та мітками

Діаграма з осьовим лініям та мітками

Не погано, але є кілька правок, які нам треба внести. Давайте змінимо колір фону на білий, щоб це було не так нудно, потім трохи налаштуємо положення стовпців, щоб вони насправді починалися з нуля.

c.fillStyle="white"; c.fillRect(0,0,500,500); //малюємо дані c.fillStyle="blue"; for(var i=0; i<data.length; i++) { var dp=data[i]; c.fillRect(40 + i*100, 460-dp*5, 50, dp*5); }

Тепер остаточно діаграма виглядає таким чином:

Красива гістограма

Красива гістограма

Кругова діаграма

Тепер візьмемо ті ж дані і намалюємо кругову діаграму. Код дуже схожий.

Створіть новий документ під назвою piechart.html з таким вмістом:

<html>
<body> <canvas width="500" height="500" id="canvas"></canvas> <script> //ініціалізація набору даних var data=[100, 68, 20, 30, 100]; var canvas=document.getElementById('canvas'); var c=canvas.getContext('2d'); //малюємо тло c.fillStyle="white"; c.fillRect(0,0,500,500);
</script>
</body>
</html>

Тепер додайте список кольорів (один для кожної точки даних) і обчислимо сумарне значення всіх даних.

<code data-language="javascript">//список кольорів var colors=[ "orange", "green", "blue", "yellow", "teal"]; //Обчислюємо суму всіх даних var total=0; for(var i=0; i<data.length; i++) { total +=data[i]; }

Малювання справжніх секторів здається складним, але насправді це досить легко. Кожен сектор починається у центрі кола (250,250), потім малюється дуга від попереднього кута до нового кута. Кут є дані конвертовані в радіани. Попередня кут — це кут від попередньої ітерації циклу (починаючи з 0). Дуга з центром 250,250 має радіус 100. Потім проводимо лінію назад в центр, заливаємо і обводимо фігуру. for(var i=0; i<data.length; i++) { //частка, представлена сегментом var fraction=data[i]/total; //Обчислюємо початковий кут var angle=prevAngle + fraction * Math.PI * 2; //Малюємо сегмент c.fillStyle=colors [i]; //Створюємо контур c.beginPath(); c.moveTo(250,250); c.arc(250,250, 100, prevAngle, angle, false); c.lineTo(250,250); //заливаємо його c.fill(); //обводимо його c.strokeStyle="black"; c.stroke(); //оновлюємо для наступної ітерації циклу prevAngle=angle; }

Остаточно додамо текст нижче графіка. Для центрування тексту необхідно спочатку розрахувати ширину тексту:

<code data-language="javascript">//малюємо текст центром c.fillStyle="black"; c.font="24pt sans-serif"; var text="Sales Data from 2025"; var metrics=c.measureText(text); c.fillText(text, 250-metrics.width/2, 400); 

І ось як це виглядає:

Кругова діаграма

Додаємо градієнт

Щоб діаграма виглядала трохи привабливіше, ви можете залити кожен сегмент радіальним градієнтом, на зразок цього:

<code data-language="javascript">//малюємо сегмент //c.fillStyle=colors[i]; //заливаємо радіальним градієнтом var grad=c.createRadialGradient( 250,250, 10, 250,250, 100); grad.addColorStop(0,"white"); grad.addColorStop(1,colors[i]); c.fillStyle=grad;

Градієнтна заливка сегмента йде від білого в центрі до кольору на краю і додає трохи глибини діаграмі. Це має виглядати так:

Кругова діаграма

Щоб зробити ці діаграми кориснішими ви можете спробувати внести кілька покращень:

  • Додайте дані та змініть математику так, щоб гістограма містила всі 12 місяців даних.
  • Побудуйте лінійну діаграму, яка малює кожну точку даних у вигляді кола, потім намалюйте ламану лінію, що з'єднує всі круги.
  • Зробіть гістограму симпатичнішою за рахунок градієнтної заливки, закруглених кутів або чорних контурів.
  • Намалюйте мітку на кожному сегменті кругової діаграми.