gpt4 book ai didi

javascript - 如何为点比例尺实现反转功能?

转载 作者:数据小太阳 更新时间:2023-10-29 05:46:19 25 4
gpt4 key购买 nike

我正在尝试为我的双折线图添加工具提示。

但是,我没有使用 timeScale 或 scaleLinear,而是使用 scalePoint 来绘制我的图表。

我正在尝试实现以下效果: https://bl.ocks.org/mbostock/3902569

this.x  = d3.scalePoint().range([ this.margin.left, this.width - this.margin.right ]);
this.xAxis = d3.axisBottom(this.x);
this.x.domain(
this.dataArray.map(d => {
return this.format(d[ 'year' ]);
}));

这是我的鼠标悬停功能,

function mousemove() {
//d3.mouse(this)[ 0 ]
//x.invert

var x0 = d3.mouse(this)[ 0 ],
i = bisectDate(data, x0, 1),
d0 = data[ i - 1 ],
d1 = data[ i ],
d = x0 - d0.year > d1.year - x0 ? d1 : d0;

console.log(x0);
// focus.attr("transform", "translate(" + x(format(d.year)) + "," + y(d.housing_index_change) + ")");
// focus.select("text").text(d.housing_index_change);
}

由于我使用的是 scalePoint,因此显然没有将坐标映射到我的数据的反转函数。我只检索数组中的第一个元素,它是唯一显示的元素,无论鼠标的位置如何。

所以我的问题是,如何在仍然使用 scalePoint 的同时在这里实现反转功能?

谢谢你:)

最佳答案

你是对的,没有invert对于点尺度。但是您可以创建自己的函数来获取给定 x 位置的相应域:

function scalePointPosition() {
var xPos = d3.mouse(this)[0];
var domain = xScale.domain();
var range = xScale.range();
var rangePoints = d3.range(range[0], range[1], xScale.step())
var yPos = domain[d3.bisect(rangePoints, xPos) -1];
console.log(yPos);
}

一步一步的解释

首先,我们获取 x 鼠标位置。

var xPos = d3.mouse(this)[0];

然后,根据你的秤的量程和域...

var domain = xScale.domain(); 
var range = xScale.range();

...我们使用 d3.range 创建一个数组,其中包含点刻度中的所有步长:

var rangePoints = d3.range(range[0], range[1], xScale.step())

最后,我们使用bisect得到对应的域:

var yPos = domain[d3.bisect(rangePoints, xPos) -1];

检查此演示中的 console.log:

var data = [{
A: "groupA",
B: 10
}, {
A: "groupB",
B: 20
}, {
A: "groupC",
B: 30
}, {
A: "groupD",
B: 10
}, {
A: "groupE",
B: 17
}]

var width = 500,
height = 200;

var svg = d3.selectAll("body")
.append("svg")
.attr("width", width)
.attr("height", height);

var color = d3.scaleOrdinal(d3.schemeCategory10)
.domain(data.map(function(d) {
return d.A
}));

var xScale = d3.scalePoint()
.domain(data.map(function(d) {
return d.A
}))
.range([50, width - 50])
.padding(0.5);

var yScale = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.B
}) * 1.1])
.range([height - 50, 10]);

var circles = svg.selectAll(".circles")
.data(data)
.enter()
.append("circle")
.attr("r", 8)
.attr("cx", function(d) {
return xScale(d.A)
})
.attr("cy", function(d) {
return yScale(d.B)
})
.attr("fill", function(d) {
return color(d.A)
});

var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);

svg.append("g").attr("transform", "translate(0,150)")
.attr("class", "xAxis")
.call(xAxis);

svg.append("g")
.attr("transform", "translate(50,0)")
.attr("class", "yAxis")
.call(yAxis);

svg.append("rect")
.attr("opacity", 0)
.attr("x", 50)
.attr("width", width - 50)
.attr("height", height)
.on("mousemove", scalePointPosition);

function scalePointPosition() {
var xPos = d3.mouse(this)[0];
var domain = xScale.domain();
var range = xScale.range();
var rangePoints = d3.range(range[0], range[1], xScale.step())
var yPos = domain[d3.bisect(rangePoints, xPos) - 1];
console.log(yPos);
}
.as-console-wrapper { max-height: 20% !important;}
<script src="https://d3js.org/d3.v4.min.js"></script>

关于javascript - 如何为点比例尺实现反转功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40573630/

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