簡體   English   中英

D3 scale.invert()不是x的返回日期

[英]D3 scale.invert() isn't returning date for x

我正在嘗試使用方法獲取最接近的y值,對於當前鼠標位置的x值。

我的數據集如下所示:

linedata = [{amount:100,date:'2015-11-2'},
            {amount:-1000,date:'2015-11-3'},
            {amount:5000,date:'2015-11-4'}
            ...
           ]

我有一個繪制scale.invert()好的折線圖,我只是在玩scale.invert()和bisect如何工作。 我創建了一個bisect函數:

var bisectDate = d3.bisector(function(d) { return d.date; }).left;

然后,進一步向下,在繪制圖形之后,有一個矩形我放在繪制圖形的區域上

graph.append("rect")
         .attr("class", "overlay")
         .attr("width", w)
         .attr("height", h)
         .on("mouseover", function() { focus.style("display", null); })
         .on("mouseout", function() { focus.style("display", "none"); })
         .on("mousemove", mousemove);

然后mousemove()函數定義如下:

function mousemove() {
    var xPosition = xScale.invert(d3.mouse(this)[0]), //<-- give me the date at the x mouse position
        closestElement = bisectDate(linedata, xPosition, 1), //<-- use the bisector to search the array for the closest point to the left and find that point given our mouse position
        d0 = linedata[closestElement - 1]
        d1 = linedata[closestElement],
        d = xPosition - d0.date > d1.date - xPosition ? d1 : d0;
    focus.attr("transform", "translate(" + xScale(+line_dateFormat.parse(d.date)) + "," + yScale(d.amount) + ")");
    focus.select("text").text(d.amount);
};

我遇到的問題是, mouseover()函數中的這一行:

var xPosition = xScale.invert(d3.mouse(this)[0])

沒有返回日期,它返回一個數字,如矩形的像素寬度。 下一行,bisect,無法將此數字與日期進行比較,因此最終總是為1。

我期待xPosition是這樣的日期:

Sat Jul 19 2014 09:32:43 GMT+1000 (AEST)
Sat Jul 19 2014 07:28:21 GMT+1000 (AEST)
Sat Jul 19 2014 05:24:00 GMT+1000 (AEST)
Sat Jul 19 2014 03:50:43 GMT+1000 (AEST)
Fri Jul 18 2014 22:39:49 GMT+1000 (AEST)
Fri Jul 18 2014 14:53:27 GMT+1000 (AEST)

或者像這樣:

1446382800000
1446382800000
1446382800000
1446382800000

但我得到的東西是這樣的:

531.190359375
472.78146093749996
408.8622890625
358.1677734375
333.92257031249994

顯然,我做錯了,但我不明白原因的基本原理。 任何人都可以向我解釋為什么我得到數字而不是日期?

使用Nithin CV Poyyil方法建議確定實際數據的輸出,為了解決這個問題,我不得不做兩件事。

1 - 在我的后端應用程序中,將日期從“2015-11-02”之類的字符串轉換為以毫秒為單位的紀元時間,然后再將其發送到d3.js使用的視圖。 這使得它更容易使用,可能應該從現在開始一直這樣做,直到永遠。

2 - 我在javascript很糟糕,不明白范圍。 所以我把所有必需的功能集中(並復制)到鼠標懸停功能中,如下所示:

function mousemove() {
    var xScale = d3.time.scale()
    .domain([d3.min(linedata, function(d) { return d.date; }), d3.max(linedata, function(d) { return d.date; })])
    .range([0, w + 170] );

    var yScale = d3.scale.linear()
    .domain([amount_min, amount_max])
    .range([h, 0])
    .nice();

    var bisectDate = d3.bisector(function(d) { return d.date; }).left;
    var dateFormat = d3.time.format('%d. %b')

    var xPosition = xScale.invert(d3.mouse(this)[0]),//xScale.invert(d3.mouse(this)[0]), //<-- give me the date at the x mouse position
        closestElement = bisectDate(linedata, xPosition, 1), //<-- use the bisector to search the array for the closest point to the left and find that point given our mouse position
        d0 = linedata[closestElement - 1],
        d1 = linedata[closestElement],
        d = xPosition - d0.date > d1.date - xPosition ? d1 : d0;

    focus.attr("transform", "translate(" + xScale(d.date) + "," + yScale(d.amount) + ")");
    focus.select("text").text("Amount: " + d.amount + " Date: " + d.date);
};

不是“正確”的方式,但我得到了我想要的結果,這對我來說更重要。 謝謝您的幫助!

希望這可以幫到你,

使用d3.time標度檢查xScale函數是否正確寫入。

通過傳遞給定范圍內的任何日期值來測試xScale函數。 eg : xScale(new Date("01-01-1998")) ,結果必須介於給定的范圍值之間。

xScale.invert(0 or 1)結果的測試返回值必須是您給定域中的日期值。

根據您提供的bostock鏈接,下面給出的代碼對我來說工作正常,

var width=500;
var xAxisScale = d3.time.scale().range([0, width]);
xAxisScale.domain([new Date("01-01-2014"),new Date("01-01-2015")]);
var rangeValue=xAxisScale(new Date("01-05-2014"))
var dateDomainValue=xAxisScale.invert(15);
console.log(rangeValue,dateDomainValue);

var mousemove=function(d){
 var xPosition = xAxisScale.invert(d3.mouse(this)[0])
 console.log("mousemove:",xPosition)
};

d3.selectAll("svg").append("rect")
         .attr("class", "overlay")
         .attr("width", 200)
         .attr("height", 300)
         .style("fill","gray")
         .on("mouseover", function() { console.log("mouseover") })
         .on("mouseout", function() { console.log("mouseout"); })
         .on("mousemove", mousemove);

HTML:

  <svg width="500" height="500"></svg>

輸出:

mouseover
mousemove: Sun Jan 05 2014 09:07:12 GMT+0530 (India Standard Time)
mousemove: Sun May 25 2014 12:57:36 GMT+0530 (India Standard Time)
mousemove: Wed May 21 2014 03:50:24 GMT+0530 (India Standard Time)
mouseout

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM