#javascript #d3.js #observable #contour
Вопрос:
Я пытаюсь преобразовать наблюдаемый блокнот из приведенной ниже ссылки в обычный Javascript.
https://observablehq.com/@d3/contours
Есть ли способ достичь этого
Комментарии:
1. На какой части ты застрял ?
Ответ №1:
Вот он:
const width = 600;
const height = 600;
const value = (x, y) => (1 (x y 1) ** 2 * (19 - 14 * x 3 * x ** 2 - 14 * y 6 * x * y 3 * y ** 2)) * (30 (2 * x - 3 * y) ** 2 * (18 - 32 * x 12 * x * x 48 * y - 36 * x * y 27 * y ** 2));
const x = d3.scaleLinear([-2, 2], [0, width 28])
const y = d3.scaleLinear([-2, 1], [height, 0])
const getGrid = () => {
const q = 4; // The level of detail, e.g., sample every 4 pixels in x and y.
const x0 = -q / 2, x1 = width 28 q;
const y0 = -q / 2, y1 = height q;
const n = Math.ceil((x1 - x0) / q);
const m = Math.ceil((y1 - y0) / q);
const grid = new Array(n * m);
for (let j = 0; j < m; j) {
for (let i = 0; i < n; i) {
grid[j * n i] = value(x.invert(i * q x0), y.invert(j * q y0));
}
}
grid.x = -q;
grid.y = -q;
grid.k = q;
grid.n = n;
grid.m = m;
return grid;
};
const grid = getGrid();
const chart = () => {
const svg = d3.select("svg")
.attr("viewBox", [0, 0, width 28, height]);
svg.append("g")
.attr("fill", "none")
.attr("stroke", "#fff")
.attr("stroke-opacity", 0.5)
.selectAll("path")
.data(contours)
.join("path")
.attr("fill", d => color(d.value))
.attr("d", d3.geoPath());
svg.append("g")
.call(xAxis);
svg.append("g")
.call(yAxis);
return svg.node();
}
const thresholds = d3.range(1, 20).map(i => Math.pow(2, i));
const color = d3.scaleSequentialLog(d3.extent(thresholds), d3.interpolateMagma);
const transform = ({type, value, coordinates}) => {
return {type, value, coordinates: coordinates.map(rings => {
return rings.map(points => {
return points.map(([x, y]) => ([
grid.x grid.k * x,
grid.y grid.k * y
]));
});
})};
}
const contours = d3.contours()
.size([grid.n, grid.m])
.thresholds(thresholds)
(grid)
.map(transform)
const xAxis = g => g
.attr("transform", `translate(0,${height})`)
.call(d3.axisTop(x).ticks(width / height * 10))
.call(g => g.select(".domain").remove())
.call(g => g.selectAll(".tick").filter(d => x.domain().includes(d)).remove())
const yAxis = g => g
.attr("transform", "translate(-1,0)")
.call(d3.axisRight(y))
.call(g => g.select(".domain").remove())
.call(g => g.selectAll(".tick").filter(d => y.domain().includes(d)).remove())
chart();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.6.2/d3.min.js"></script>
<svg width="300" height="300" />