gpt4 book ai didi

javascript - 放大水平条形图中的画笔

转载 作者:行者123 更新时间:2023-11-30 20:24:06 25 4
gpt4 key购买 nike

在我下面的代码中,我已经设法使画笔与缩放事件一致移动,但我现在无法在使用画笔时尝试使条形图正确缩放。

我的 brushed 函数基于 this回答但无法将逻辑转换为我自己的代码。

我收到错误:无法读取未定义的属性“转换”,我不知道为什么。

这是我所有的代码:

const data = [
{month: "jan", value: 12},
{month: "feb", value: 25},
{month: "mar", value: 10},
{month: "apr", value: 15}
];

var svg = d3.select("svg"),
margin = {top: 10, right: 35, bottom: 10, left: 35},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;

var g = svg.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");

// === Bar ===

var x = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)]).nice()
.range([margin.left * 2, width])

var y = d3.scaleBand()
.domain(data.map(d => d.month))
.range([height, 0])
.padding(0.1)

var yAxis = g => g
.attr("transform", `translate(${margin.left * 2},0)`)
.call(d3.axisLeft(y).tickSizeOuter(0))

g.append("g").selectAll(".bar")
.data(data).enter().append("rect")
.attr("fill", "steelblue")
.attr("class", "bar")
.attr("x", x(0))
.attr("y", d => y(d.month))
.attr("width", d => x(d.value) - x(0))
.attr("height", y.bandwidth());

g.append("g")
.attr("class", "y-axis")
.call(yAxis);

// === Brush ===

var xB = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.range([0, margin.left]);

var yB = d3.scaleBand()
.domain(data.map(d => d.month))
.range([height, 0])
.padding(0.1);

var brush = d3.brushY()
.extent([[0, 0],[margin.left, height]])
.on("start brush", brushed);

var yAxisB = g => g
.call(d3.axisLeft(yB).tickSizeOuter(0))

g.append("g")
.attr("class", "brush")
.call(brush)
.call(brush.move, yB.range().reverse())

g.append("g").selectAll(".brushBar")
.data(data).enter().append("rect")
.attr("fill", "steelblue")
.attr("class", "brushBar")
.attr("x", xB(0))
.attr("y", d => yB(d.month))
.attr("width", d => xB(d.value) - xB(0))
.attr("height", yB.bandwidth());

g.append("g")
.call(yAxisB);

// === Brush & Zoom ===

var bExtent = [[0, 0], [width, height]]

var zoom = d3.zoom()
.scaleExtent([1, 2])
.translateExtent(bExtent)
.extent(bExtent)
.on("zoom", zoomed)

g.append("rect")
.attr("class", "zoom")
.attr("width", width)
.attr("height", height)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(zoom);

function zoomed() {

if (d3.event.sourceEvent &&
d3.event.sourceEvent.type === "brush") return;

var t = d3.event.transform;

y.range([height, 0]
.map(d => d3.event.transform.applyY(d)));

g.selectAll(".bar")
.attr("y", d => y(d.month))
.attr("height", y.bandwidth());

g.selectAll(".y-axis").call(yAxis);

g.select(".brush").call(brush.move,
yB.range().reverse().map(t.invertY, t))
}

function brushed() {

if (d3.event.sourceEvent &&
d3.event.sourceEvent.type === "zoom") return;

var s = d3.event.selection,
nD = [];

yB.domain().forEach((d) => {
var pos = yB(d) + yB.bandwidth() / 2;
if (pos > s[0] && pos < s[1]){
nD.push(d);
}
});

y.domain(nD);

g.selectAll(".y-axis").call(yAxis);

g.selectAll(".bar")
.attr("y", d => y(d.month))
.attr("height", y.bandwidth());

//g.select(".zoom").call(zoom.transform, d3.zoomIdentity
// .scale(2)
// .translate(-s[0], 0));
}
.zoom {
cursor: move;
fill: none;
pointer-events: all;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg width="540" height="120"></svg>

最佳答案

首先,我没有收到您描述的错误。

您的代码段中的问题似乎是刷出的条形图堆积在 SVG 的顶部。这是因为您正在更改 y scale 的域,因此一些条获得 undefined对于 y(d.month) .因此,它们并没有很好地从 View 中消失,而是简单地绘制在 0 处。在y位置。

最好的替代方法是重新考虑所有画笔/缩放代码。然而,对于代码中的最小更改,一个快速而肮脏的解决方案是简单地转动具有 undefined 的栏。对于 y位置透明:

.style("opacity", d => y(d.month) ? 1 : 0)

此外,制作 pointer-events: none;对于画笔中的栏,这会带来更好的用户体验:

.attr("pointer-events", "none")

这是您的代码,其中包含这些更改:

const data = [{
month: "jan",
value: 12
},
{
month: "feb",
value: 25
},
{
month: "mar",
value: 10
},
{
month: "apr",
value: 15
}
];

var svg = d3.select("svg"),
margin = {
top: 10,
right: 35,
bottom: 10,
left: 35
},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;

var g = svg.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");

// === Bar ===

var x = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)]).nice()
.range([margin.left * 2, width])

var y = d3.scaleBand()
.domain(data.map(d => d.month))
.range([height, 0])
.padding(0.1)

var yAxis = g => g
.attr("transform", `translate(${margin.left * 2},0)`)
.call(d3.axisLeft(y).tickSizeOuter(0))

g.append("g").selectAll(".bar")
.data(data).enter().append("rect")
.attr("fill", "steelblue")
.attr("class", "bar")
.attr("x", x(0))
.attr("y", d => y(d.month))
.attr("width", d => x(d.value) - x(0))
.attr("height", y.bandwidth());

g.append("g")
.attr("class", "y-axis")
.call(yAxis);

// === Brush ===

var xB = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.range([0, margin.left]);

var yB = d3.scaleBand()
.domain(data.map(d => d.month))
.range([height, 0])
.padding(0.1);

var brush = d3.brushY()
.extent([
[0, 0],
[margin.left, height]
])
.on("start brush", brushed);

var yAxisB = g => g
.call(d3.axisLeft(yB).tickSizeOuter(0))

g.append("g")
.attr("class", "brush")
.call(brush)
.call(brush.move, yB.range().reverse())

g.append("g").selectAll(".brushBar")
.data(data).enter().append("rect")
.attr("fill", "steelblue")
.attr("class", "brushBar")
.attr("pointer-events", "none")
.attr("x", xB(0))
.attr("y", d => yB(d.month))
.attr("width", d => xB(d.value) - xB(0))
.attr("height", yB.bandwidth());

g.append("g")
.call(yAxisB);

// === Brush & Zoom ===

var bExtent = [
[0, 0],
[width, height]
]

var zoom = d3.zoom()
.scaleExtent([1, 2])
.translateExtent(bExtent)
.extent(bExtent)
.on("zoom", zoomed)

g.append("rect")
.attr("class", "zoom")
.attr("width", width)
.attr("height", height)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(zoom);

function zoomed() {

if (d3.event.sourceEvent &&
d3.event.sourceEvent.type === "brush") return;

var t = d3.event.transform;

y.range([height, 0]
.map(d => d3.event.transform.applyY(d)));

g.selectAll(".bar")
.attr("y", d => y(d.month))
.attr("height", y.bandwidth());

g.selectAll(".y-axis").call(yAxis);

g.select(".brush").call(brush.move,
yB.range().reverse().map(t.invertY, t))
}

function brushed() {

if (d3.event.sourceEvent &&
d3.event.sourceEvent.type === "zoom") return;

var s = d3.event.selection,
nD = [];

yB.domain().forEach((d) => {
var pos = yB(d) + yB.bandwidth() / 2;
if (pos > s[0] && pos < s[1]) {
nD.push(d);
}
});

y.domain(nD);

g.selectAll(".y-axis").call(yAxis);

g.selectAll(".bar")
.attr("y", d => y(d.month))
.style("opacity", d => y(d.month) ? 1 : 0)
.attr("height", y.bandwidth());

//g.select(".zoom").call(zoom.transform, d3.zoomIdentity
// .scale(2)
// .translate(-s[0], 0));
}
.zoom {
cursor: move;
fill: none;
pointer-events: all;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg width="540" height="120"></svg>

关于javascript - 放大水平条形图中的画笔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51113417/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com