fix(webui): surface allows rudimentary rescaling
ci/woodpecker/push/woodpecker Pipeline failed Details

feat/selector-improvements
Tomáš Mládek 2023-11-12 18:17:21 +01:00
parent f03523681b
commit 49085a2f04
1 changed files with 70 additions and 61 deletions

View File

@ -29,6 +29,7 @@
let loaded = false;
let viewHeight = 0;
let viewWidth = 0;
let rootEl: HTMLElement | undefined;
interface IPoint {
address: string;
@ -67,78 +68,85 @@
onMount(async () => {
const d3 = await import("d3");
const view = d3.select(".view");
function init() {
const view = d3.select(".view");
const svg = view.select("svg");
svg.selectAll("*").remove();
const svg = view.append("svg");
const xScale = d3
.scaleLinear()
.domain([0, viewWidth])
.range([0, viewWidth]);
const xScale = d3
.scaleLinear()
.domain([0, viewWidth])
.range([0, viewWidth]);
const xAxis = d3
.axisBottom(xScale)
.ticks(15)
.tickSize(viewHeight)
.tickPadding(5 - viewHeight);
const xAxis = d3
.axisBottom(xScale)
.ticks(15)
.tickSize(viewHeight)
.tickPadding(5 - viewHeight);
const yScale = d3
.scaleLinear()
.domain([0, viewHeight])
.range([viewHeight, 0]);
const yScale = d3
.scaleLinear()
.domain([0, viewHeight])
.range([viewHeight, 0]);
const yAxis = d3
.axisRight(yScale)
.ticks(viewHeight / (viewWidth / 15))
.tickSize(viewWidth)
.tickPadding(5 - viewWidth);
const yAxis = d3
.axisRight(yScale)
.ticks(viewHeight / (viewWidth / 15))
.tickSize(viewWidth)
.tickPadding(5 - viewWidth);
const gX = svg.append("g").attr("class", "axis axis--x").call(xAxis);
const gY = svg.append("g").attr("class", "axis axis--y").call(yAxis);
const gX = svg.append("g").attr("class", "axis axis--x").call(xAxis);
const gY = svg.append("g").attr("class", "axis axis--y").call(yAxis);
const zoom = d3
.zoom()
// .scaleExtent([1, 40])
// .translateExtent([
// [-100, -100],
// [width + 90, height + 100],
// ])
.on("zoom", zoomed);
const zoom = d3
.zoom()
// .scaleExtent([1, 40])
// .translateExtent([
// [-100, -100],
// [width + 90, height + 100],
// ])
.on("zoom", zoomed);
function zoomed({ transform }: { transform: ZoomTransform }) {
const points = d3.select(".content");
points.style(
"transform",
`translate(${transform.x}px, ${transform.y}px) scale(${transform.k})`,
);
const allPoints = d3.selectAll(".point");
allPoints.style("transform", `scale(${1 / transform.k})`);
function zoomed({ transform }: { transform: ZoomTransform }) {
const points = d3.select(".content");
points.style(
"transform",
`translate(${transform.x}px, ${transform.y}px) scale(${transform.k})`,
);
const allPoints = d3.selectAll(".point");
allPoints.style("transform", `scale(${1 / transform.k})`);
gX.call(xAxis.scale(transform.rescaleX(xScale)));
gY.call(yAxis.scale(transform.rescaleY(yScale)));
}
gX.call(xAxis.scale(transform.rescaleX(xScale)));
gY.call(yAxis.scale(transform.rescaleY(yScale)));
// function reset() {
// svg.transition().duration(750).call(zoom.transform, d3.zoomIdentity);
// }
view.on("mousemove", (ev: MouseEvent) => {
// not using offsetXY because `translate` transforms on .inner mess it up
const viewBBox = (view.node() as HTMLElement).getBoundingClientRect();
const [x, y] = d3
.zoomTransform(d3.select(".content").node() as HTMLElement)
.invert([ev.clientX - viewBBox.left, ev.clientY - viewBBox.top]);
currentX = xScale.invert(x);
currentY = yScale.invert(y);
});
d3.select(".view")
.call(zoom)
.on("dblclick.zoom", (_ev: MouseEvent) => {
selectorCoords = [currentX, currentY];
});
loaded = true;
}
// function reset() {
// svg.transition().duration(750).call(zoom.transform, d3.zoomIdentity);
// }
view.on("mousemove", (ev: MouseEvent) => {
// not using offsetXY because `translate` transforms on .inner mess it up
const viewBBox = (view.node() as HTMLElement).getBoundingClientRect();
const [x, y] = d3
.zoomTransform(d3.select(".content").node() as HTMLElement)
.invert([ev.clientX - viewBBox.left, ev.clientY - viewBBox.top]);
currentX = xScale.invert(x);
currentY = yScale.invert(y);
const resizeObserver = new ResizeObserver(() => {
init();
});
d3.select(".view")
.call(zoom)
.on("dblclick.zoom", (_ev: MouseEvent) => {
selectorCoords = [currentX, currentY];
});
loaded = true;
resizeObserver.observe(rootEl);
});
async function onSelectorInput(ev: CustomEvent<IValue>) {
@ -159,7 +167,7 @@
}
</script>
<div class="surface">
<div class="surface" bind:this={rootEl}>
<div class="header">
<div class="axis-selector">
X: <Selector type="attribute" bind:attribute={x} />
@ -242,6 +250,7 @@
</div>
{/each}
</div>
<svg />
</div>
</div>