fix(webui): surface allows rudimentary rescaling
ci/woodpecker/push/woodpecker Pipeline failed
Details
ci/woodpecker/push/woodpecker Pipeline failed
Details
parent
f03523681b
commit
49085a2f04
|
@ -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>
|
||||
|
||||
|
|
Loading…
Reference in New Issue