Deno+TypeScript+ESMでD3.jsを書く
変更点
最新のECMAScriptの書き方に変えた
d3.attr()にnullを返すcallbackは渡せるが、undefinedを返すcallbackを渡せない ?? nullで変換しておく必要があった
importは段階的に絞り込んだ
とりあえずimport * as d3 from "https://esm.sh/d3@7.8.0";で試す
その後d3を削除
最後にmicrolibrariesに変えた
ShadowRootはCSS selectorで取得できないので、直接ShadowRootをd3.select()に渡す マウスポインタの座標計算ミスってる
そのうち直す
手動で型付けする必要がある
code:test.ts
/// <reference no-default-lib="true" />
/// <reference lib="esnext" />
/// <reference lib="dom" />
import {
scaleBand,
scaleLinear,
import {
axisBottom,
axisLeft,
interface Data {
name: string;
value: number;
}
const dataset: Data[] = [
{ name: "A", value: 5 },
{ name: "B", value: 6 },
{ name: "C", value: 8 },
{ name: "D", value: 1 },
{ name: "E", value: 2 },
{ name: "F", value: 6 },
{ name: "G", value: 8 },
{ name: "H", value: 6 },
{ name: "I", value: 10 },
{ name: "J", value: 9 },
];
const width = 600;
const height = 400;
// 描画領域を作成する
const root = document.createElement("div");
{
const app = document.createElement("div");
const shadowRoot = app.attachShadow({ mode: "open" });
const style = document.createElement("style");
style.textContent = `:host {
position: fixed;
bottom: 0;
left: 0;
border: 1px solid gray;
border-radius: 4px;
}
.tooltip {
position: absolute;
text-align: center;
width: auto;
height: auto;
padding: 5px;
font: 12px;
background: white;
-webkit-box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.8);
-moz-box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.8);
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.8);
visibility: hidden;
}
.bar:hover {
fill: Brown;
}`;
shadowRoot.appendChild(style);
shadowRoot.appendChild(root);
document.body.append(app);
}
// SVG領域を作成
const svg = select(root).append("svg").attr("width", width).attr(
"height",
height,
);
const padding = 30;
0.1,
).domain(dataset.map((d) => d.name));
const yScale = scaleLinear()
svg.append("g")
.attr("transform", translate(0, ${height - padding}))
.call(axisBottom(xScale));
svg.append("g")
.attr("transform", translate(${padding}, 0))
.call(axisLeft(yScale));
// 棒グラフを作る
const rects = svg.append("g")
.selectAll("rect")
// data binding
.data(dataset)
// dataの分だけ<rect>を作る
.enter().append("rect")
// 棒グラフのスタイル設定
.attr("x", (d) => (xScale(d.name) ?? null))
.attr("y", (d) => (yScale(d.value) ?? null))
.attr("width", xScale.bandwidth())
.attr("height", (d) => height - padding - yScale(d.value))
.attr("fill", "steelblue")
.attr("class", "bar");
// tooltipを作る
const tooltip = select(root).append("div").attr("class", "tooltip");
// ホバーでtooltipを表示する
rects.on(
"mouseover",
(_, d) =>
tooltip.style("visibility", "visible").html(
name : ${d.name}<br>value : ${d.value},
),
)
.on(
"mousemove",
(e) =>
tooltip.style("top", ${e.clientY - 20}px).style(
"left",
${e.clientX + 10}px,
),
)
.on("mouseout", () => tooltip.style("visibility", "hidden"));