Result
非依存のvanillaなコードで動作します
データを元にグラフをcanvasで生成し、挿入します。データは配列で管理します
javascript
/** * データとclass */ let stonks = document.querySelectorAll(".stonk"); data = [ [ 420, 700, 500, 480, 460, 490, 390, 420, 550, 340, 320, 240, 180, 160, 200, 40, 0 ], [1, 3, 2, 3, 1, 2, 3], [13, 30, 12, 3, 51, 20, 31] ]; /*グラフのスタイル*/ const options = { lineWidth: 2, color: "#E3342F" }; /** * Class */ class Stonk { constructor(wrapper, data, settings = {}) { const defaults = { width: 80, color: "#000000", lineWidth: 1 }; this.settings = Object.assign(defaults, settings); this.wrapper = wrapper; this.data = data; this.normalData = []; this.canvas = null; this.ctx = null; this.dimes = { w: 0, h: 0 }; } draw() { this._buildCanvas(); this._normalizeData(this.data); this._drawData(); } _drawData() { let ctx = this.ctx; let { w, h } = this.dimes; w = w - this.settings.lineWidth / 2; h = h - this.settings.lineWidth / 2; let nd = this.normalData; let step = w / (this.data.length - 1); let tick = this.settings.lineWidth / 2; ctx.strokeStyle = this.settings.color; ctx.lineWidth = this.settings.lineWidth; ctx.beginPath(); ctx.moveTo(tick, h - nd[0]); for (var i = 1; i <= nd.length - 1; i++) { tick += step; ctx.lineTo(tick, h - nd[i]); } ctx.stroke(); } _buildCanvas() { let canvas = document.createElement("canvas"); let absoluteDimes; // canvasのグラフをinlineにして挿入する this.wrapper.style.cssText += ` position: relative; display: inline-block; line-height: 1; height: 0.9em; `; // 高さを一時的に設定して、境界を計算できるようにする canvas.style.height = "100%"; canvas.style.width = `${this.settings.width}px`; // ドキュメントに追加して、境界を返す this.canvas = canvas; this.ctx = this.canvas.getContext("2d"); this.wrapper.appendChild(this.canvas); absoluteDimes = this.canvas.getBoundingClientRect(); const { width: w, height: h } = absoluteDimes; this.dimes = { w, h: Math.floor(h) }; // 属性を設定 this.canvas.setAttribute("height", this.dimes.h); this.canvas.setAttribute("width", this.dimes.w); // 属性を削除する this.canvas.removeAttribute("style"); } // ユーティリティ _normalizeData(array) { let min = Math.min(...array); let max = Math.max(...array); this.data.forEach((v) => { let percentage = this._scaleBetween(v, 0, 100, min, max); let h = (this.dimes.h - this.settings.lineWidth) * (percentage / 100); this.normalData.push(h); }); } _scaleBetween(unscaledNum, minAllowed, maxAllowed, min, max) { return ( ((maxAllowed - minAllowed) * (unscaledNum - min)) / (max - min) + minAllowed ); } } /** * Mount */ stonks.forEach((s, idx) => { let stonk = new Stonk(s, data[idx], options).draw(); });
html
<p>文章内の任意の場所に<span class="stonk"></span>このように折れ線グラフを挿入する事が出来ます。折れ線グラフのデータは多次元配列で管理され、<span class="stonk"></span>指定のclassを付与した要素の順に割り当てられます。</p>