如何为点刻度实现反转功能? [英] How can I implement an invert function for a point scale?

查看:108
本文介绍了如何为点刻度实现反转功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to add a tooltip for my dual line chart graph.

然而,我使用scalePoint来绘制我的图表,而不是使用timeScale或scaleLinear。

However, instead of using timeScale or scaleLinear, I used scalePoint to graph my chart.

我试图达到以下效果:
https://bl.ocks.org/mbostock/3902569

I am trying to achieve the following effect: 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' ]);
}));

这是我的鼠标悬停功能,

Here is my mouseover function,

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,因此显然没有反转函数来映射坐标我的数据。我只检索数组中的第一个元素,它是唯一一个无论鼠标位置如何都要显示的元素。

Since I am using scalePoint, there is obviously no invert function to map the coordinates to my data. and I am only retrieving the first element in the array and it is the only one that is being display regardless of the position of the mouse.

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

So my question is, how can I implement the invert functionality here while still using scalePoint?

谢谢:)

推荐答案

你是对的,没有反转。但是你可以创建自己的函数来获得给定x位置的相应域:

You are right, there is no invert for a point scale. But you can create your own function to get the corresponding domain of a given x position:

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 鼠标位置。

First, we get the x mouse position.

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

然后,根据您的比例范围和域名...

Then, based on your scale's range and domain...

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>

这篇关于如何为点刻度实现反转功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆