はじめに
円グラフや並び替え可能なリストというと、専用のJavaScriptライブラリを導入するイメージがあるかもしれません。しかし、モダンブラウザの標準機能だけで、追加ライブラリなしに実現できる場合があります。本記事では、円グラフを描くCSS conic-gradientと、要素の並び替えに使えるHTML5 Drag and Drop APIの2つを紹介します。
CSS conic-gradient:円グラフを描くグラデーション
conic-gradient()は、通常のグラデーション(linear-gradientが直線状、radial-gradientが中心から放射状)とは異なり、中心点を軸に回転する形で色が変化するグラデーション関数です。この性質を利用すると、色の帯を角度で区切るだけで円グラフのような表現が作れます。
.pie-chart {
width: 200px;
height: 200px;
border-radius: 50%;
background: conic-gradient(
#4CAF50 0deg 120deg, /* 0%〜33%: 緑 */
#FFC107 120deg 240deg, /* 33%〜67%: 黄色 */
#F44336 240deg 360deg /* 67%〜100%: 赤 */
);
}
border-radius: 50%と組み合わせて円形に切り抜くことで、円グラフとして表示されます。色の境界はパーセンテージでも指定できます。
.pie-chart {
background: conic-gradient(
#4CAF50 0% 40%,
#FFC107 40% 75%,
#F44336 75% 100%
);
}
用途と注意点
- 円グラフのほか、市松模様(チェッカーボード)やカラーホイールの表現にも使われる
-
background-colorのような単色を扱うプロパティには使えない(あくまでbackgroundやbackground-imageのような画像扱いのプロパティ専用) - グラフの値が動的に変わる場合は、JavaScriptから
style.backgroundのCSS文字列を書き換えることで対応できる(チャート専用ライブラリなしで、シンプルな円グラフ表示だけなら十分実現可能) - 繰り返しパターンを作りたい場合は
repeating-conic-gradient()という専用の関数も用意されている
HTML5 Drag and Drop API:ネイティブの並び替えUI
要素をドラッグして並び替える機能も、draggable属性とドラッグ関連イベントの組み合わせだけで、外部ライブラリなしに実装できます。
基本の仕組み
<ul id="list">
<li draggable="true" data-id="1">項目A</li>
<li draggable="true" data-id="2">項目B</li>
<li draggable="true" data-id="3">項目C</li>
</ul>
要素にdraggable="true"を指定するだけで、その要素はドラッグ可能になります(画像・リンク・選択されたテキストはデフォルトでドラッグ可能です)。
let draggedItem = null;
document.querySelectorAll('li').forEach(item => {
item.addEventListener('dragstart', (e) => {
draggedItem = item;
e.dataTransfer.effectAllowed = 'move';
});
item.addEventListener('dragover', (e) => {
e.preventDefault(); // dropを許可するために必須
});
item.addEventListener('drop', (e) => {
e.preventDefault();
if (draggedItem !== item) {
// ドラッグ元とドロップ先を入れ替える
const list = item.parentNode;
const draggedIndex = [...list.children].indexOf(draggedItem);
const targetIndex = [...list.children].indexOf(item);
if (draggedIndex < targetIndex) {
list.insertBefore(draggedItem, item.nextSibling);
} else {
list.insertBefore(draggedItem, item);
}
}
});
});
主なイベントの役割
| イベント | 発生タイミング |
|---|---|
dragstart |
ドラッグ操作が始まった時(ドラッグ元の要素で発生) |
dragover |
ドラッグ中の要素が、ドロップ先候補の上を通過している間、継続的に発生 |
drop |
ドロップ(マウスボタンを離す)が行われた時 |
dragend |
ドラッグ操作全体が終了した時(成功・キャンセル問わず) |
dragoverイベントでe.preventDefault()を呼ばないと、そもそもdropイベント自体が発火しない点は特に間違えやすいポイントです(ブラウザのデフォルト動作では、多くの要素はドロップ先として扱われないため)。
注意点
-
DataTransferオブジェクトを使うことで、ドラッグ中に任意のデータ(テキスト・URL等)を運ぶこともできる(e.dataTransfer.setData()) - モバイル(タッチ操作)では、HTML5 Drag and Drop APIは標準では動作しない。タッチ対応が必要な場合は、タッチイベント(
touchstart/touchmove/touchend)を別途実装するか、対応済みのライブラリを検討する必要がある - 並び替えの永続化(サーバーへの保存)は別途、並び替え後の順序をAPIに送信する実装が必要になる
まとめ
| 項目 | 内容 |
|---|---|
conic-gradient() |
中心点を軸に回転する形のグラデーション。円グラフ表現に応用できる |
| HTML5 Drag and Drop API |
draggable属性とドラッグ系イベント(dragstart/dragover/drop)の組み合わせでライブラリなしの並び替えUIを実装できる |
| 共通の利点 | どちらもモダンブラウザの標準機能のみで完結し、追加ライブラリの導入コストがかからない |
| 主な制約 | Drag and Drop APIはモバイルのタッチ操作に非対応(別途実装が必要) |