折れ線グラフ雛形
tableタグで折れ線グラフを実現するもの。
グラフを増やす時は、tableタグ部分コピペする。
グラフの設定は、主にCSS変数を変える事である程度可能。
後は、ソースコードを直接変更する。
jsは、svgのx軸の表示位置を調整・設定、及び、svgとhtmlの座標を合致させるもの。
<style>
/* グラフtable */
.ogt-tb {border-collapse: collapse; font-size: small;}
/* 縦軸ラベル */
.ogt-tb .ogt-tr {padding: 1px; text-align: center; vertical-align: middle; writing-mode: vertical-rl; }
/* 縦軸目盛 */
.ogt-tb .ogt-tm {
height: var(--ogt-hei);
border-right: 1px solid black;
text-align: right;
vertical-align: top; /* 上端合わせにして目盛の間隔を調整 */
padding-right: 5px;
}
/* グラフ描画エリア */
.ogt-tb .graph-area {
position: relative;
width: calc( var(--ogt-mas) * var(--ogt-komoku) + var(--ogt-ofs) );
height: var(--ogt-hei);
background-color: var(--ogt-bco);
background-image: linear-gradient(gray 1px, transparent 1px);
background-size: 100% var(--ogt-mem); /* 縦軸補助線 */
border-bottom: 1px solid black;
border-right: 1px solid black;
padding: 0;
}
.ogt-tb .graph-area::after {
background-image: linear-gradient(to right, gray 1px, transparent 1px);
background-repeat: repeat-x;
background-size: var(--ogt-mas) 100%; /* 横軸補助線 */
content: "";
height: 100%;
left: var(--ogt-ofs);
position: absolute;
top: 0;
width: 100%;
}
/* SVGの設定 */
.ogt-tb svg {width:100%; height:100%; display:block;}
/* 折れ線のスタイル */
.ogt-tb .line {fill: none; stroke-width: 2;}
/* 点(プロット)のスタイル */
.ogt-tb .dot {}
/* 横軸ラベル */
.ogt-tb .ogt-yr{text-align: center; padding-top: 5px;}
/* 横軸目盛り */
.ogt-tb .ogt-ym{width: calc(var(--ogt-mas) * var(--ogt-komoku) + var(--ogt-ofs));position:relative;height:3em; top:0px;}
/*横軸ラベル文字のspan*/
.ogt-tb .ogt-ka{
position: absolute;
transform: translateX(-50%); /* 文字の真ん中を基準点にする*/
text-align: center;
white-space: nowrap;
left:calc( var(--ogt-mas) * var(--data-kan) + var(--ogt-ofs) );
}
/*文字の上に線を出す*/
.ogt-tb .ogt-ka::after {
content: "";
position: absolute;
top: -8px;/* 文字の何px上に線を出すか */
left: 50%;/* 文字の中央から */
width: 1px;/* 線の太さ */
height: 10px;/* 線の長さ */
background: black;/* 線の色gray */
}
/*縦書き-spanに加える*/
.ogt-tb .ogt-ymt{text-align: center; vertical-align: middle; writing-mode: vertical-rl;}
</style>
<table class="ogt-tb" style="--ogt-hei: 300px; --ogt-mem:25%; --ogt-bco:bisque; --ogt-str:blue; --ogt-kan:6; --ogt-ofs:0px; --ogt-mas:80px; --ogt-komoku:6;" border="0">
<tbody>
<tr>
<!-- 縦軸ラベル -->
<td class="ogt-tr">縦軸コメント</td>
<!-- 縦軸目盛 -->
<td class="ogt-tm">
<div style="height: var(--ogt-mem);">100</div>
<div style="height: var(--ogt-mem);">75</div>
<div style="height: var(--ogt-mem);">50</div>
<div style="height: var(--ogt-mem);">25</div>
<div>0</div>
</td>
<!-- グラフ本体 (SVG) -->
<td class="graph-area">
<svg viewBox="0 0 500 300" preserveAspectRatio="none">
<!--
points属性の解説: x,y_ の順で指定
x: 左からの距離 (0〜500)--ogt-mas * --ogt-komoku + --ogt-ofs 毎にjsでとるので記入は適当
y: 上からの距離 (0〜300) ※0が100%、300が0%に相当
-->
<polyline class="line" style="stroke: var(--ogt-str);" points="
0,250
1,200
2,220
3,100
4,120
5,50
"/>
<!--<line x1="20" y1="10" x2="600" y2="280" style="stroke:blue ;stroke-width:1;stroke-dasharray="2 2" />-->
<!-- 各ポイントに丸を表示する場合 F12→座標が表示されるので手入力 いらなければ削除 -->
<circle class="dot" cx="0" cy="250" r="4" style="fill: var(--ogt-str);" /><text x="4" y="240">20</text>
<circle class="dot" cx="1" cy="200" r="4" style="fill: var(--ogt-str);" />
<circle class="dot" cx="2" cy="220" r="4" style="fill: var(--ogt-str);" />
<circle class="dot" cx="3" cy="100" r="4" style="fill: var(--ogt-str);" />
<circle class="dot" cx="4" cy="120" r="4" style="fill: var(--ogt-str);" />
<circle class="dot" cx="5" cy="50" r="4" style="fill: var(--ogt-str);" />
</svg>
</td>
</tr>
<!-- 横軸目盛 数は--ogt-komokuの数値に合わせる-->
<tr class="ogt-yr">
<td></td>
<td></td>
<td class="ogt-ym">
<span class="ogt-ka" style="--data-kan:0;"></span>
<span class="ogt-ka" style="--data-kan:1;">a</span>
<span class="ogt-ka" style="--data-kan:2;">b</span>
<span class="ogt-ka" style="--data-kan:3;">c</span>
<span class="ogt-ka" style="--data-kan:4;">d</span>
<span class="ogt-ka" style="--data-kan:5;">e</span>
<br>横軸コメント
</td>
</tr>
</tbody>
</table>
<script>
const ogttbs = document.querySelectorAll('.ogt-tb');
ogttbs.forEach(ogtTb => {
const style = getComputedStyle(ogtTb);
// CSS変数から値を取得
const offset = parseFloat(style.getPropertyValue('--ogt-ofs')) || 0;
const mas = parseFloat(style.getPropertyValue('--ogt-mas')) || 0;
const komoku = parseFloat(style.getPropertyValue('--ogt-komoku')) || 0;
const totalWidth = mas * komoku + offset;
// 1. そのテーブル内の SVG の表示範囲を修正
const svg = ogtTb.querySelector('svg');
if (svg) {svg.setAttribute('viewBox', `0 0 ${totalWidth} 300`);}
// 2. そのテーブル内の polyline (折れ線) の座標修正
const lines = ogtTb.querySelectorAll('.line');
lines.forEach(line => {
console.log("****");
const pointsAttr = line.getAttribute('points').trim();
if (!pointsAttr) return;
const coords = pointsAttr.split(/[\s,]+/).filter(v => v !== "");
const newPoints = [];
for (let i = 0; i < coords.length; i += 2) {
const index = i / 2;
const x = (index * mas) + offset;
const y = coords[i + 1];
newPoints.push(`${x},${y}`);
console.log("x=",x," y=",y);
}
line.setAttribute('points', newPoints.join(' '));
});
// 3. そのテーブル内の circle (点) の座標修正
const dots = ogtTb.querySelectorAll('.dot');
dots.forEach((dot, i) => {
const j = i % komoku;
dot.setAttribute('cx', (j * mas) + offset);
});
});
</script>
0 件のコメント:
コメントを投稿