d3-axisと同じことをpreactで実現する
code:sample.js
const { render, html } = htmPreact;
const { axisBottom, select, scaleLinear } = d3;
const tickSizeOuter = 6;
const tickSizeInner = 6;
const tickPadding = 3;
const offset = (window?.devicePixelRatio ?? 0) > 1 ? 0 : 0.5;
const Axis = ({ height, scale, orient, format }) => {
const isLR = orient === "left" || orient === "right";
const isTL = orient === "top" || orient === "left";
const k = isTL ? -1 : 1;
const dy = orient === "top" ? "0em" : orient === "bottom" ? "0.71em" : "0.32em";
format ??= (t) => t;
const range = scale.range();
const range0 = range0 + offset; const spacing = Math.max(tickSizeInner, 0) + tickPadding;
return html`<g
transform=${translate(0, ${height / 2})}
fill="none"
font-size="10"
font-familly="sans-serif"
text-anchor=${orient === "right" ? "start" : orient === "left" ? "end" : "middle"}
<path class="domain" stroke="currentColor" d=${
isLR
? (tickSizeOuter
? M${k * tickSizeOuter},${range0}H${offset}V${range1}H${k * tickSizeOuter}
: M${offset},${range0}V${range1})
: (tickSizeOuter
? M${range0},${k * tickSizeOuter}V${offset}H${range1}V${k * tickSizeOuter}
: M${range0},${offset}H${range1})
} />
scale.domain().map(...)だと境界値しか出力されないみたい
間も出力するにはどうしたらいい?
code:sample.js
${scale.domain().map(
(d) => html<g class="tick" opacity="1" transform=${translate(${scale(d) + offset},0)`}>
<line stroke="currentColor" ...${isLR ? ({ x2: k * tickSizeInner }) : ({ y2: k * tickSizeInner })} />
<text
fill="currentColor"
...${isLR ? ({ x: k * spacing }) : ({ y: k * spacing })}
dy=${dy}>${
format(d)
}</text>
</g>`
)}
</g>`;
};
code:sample.js
const padding = 20;
render(html`
<${Axis} height=${height} scale=${scale} orient="bottom" />
</svg>`, document.body);