#javascript #d3.js
#javascript #d3.js
Вопрос:
Я создаю простую линейную диаграмму D3, и у меня возникли проблемы с созданием всплывающей подсказки с d3.bisector()
функцией. Я ищу, чтобы она переходила к осям Y и X для каждого значения. Функция bisector отлично работает для предоставления мне значения xData, соответствующего координатам мыши, но я продолжаю получать некоторые очень странные результаты для yData. Я подозреваю, что проблема заключается в нисходящем характере массива yData. Есть ли способ настроить bisector()
функцию для обработки нисходящих массивов? Я ищу решение, которое работало бы с любым набором данных.
//define the domain and range for the chart
var xScale = d3.scaleLinear().domain([0,10]).range([0, width]);
var yScale = d3.scaleLinear().domain([0,10]).range([height,0]);
//data for the line
var xData = [0,1,2,3,4,5,6,7,8,9,10];
var yData = [10,9,8,7,6,5,4,3,2,1,0];
//set up the bisector function
var bisectData= d3.bisector(function(d){return d}).left;
// get the x and y position of the cursor and put it into the Xscale/yScale function to get the correct X and Y values from the corresponding coordinates
var x0 = xScale.invert(d3.mouse(this)[0])
var y0 = yScale.invert(d3.mouse(this)[1])
//round the values to the nearest integer to match the original data
var x0 = Math.round(x0);
var y0 = Math.round(y0);
//get the correct index value of the relevant data array
var xIndex= bisectData(xData,x0,1);
//get the actual value from the original array using the correct index
//this work fine
var x1 = xData[xIndex];
//this does not
var yIndex= bisectData(yData,y0,1);
var y1 = yData[yIndex];
Ответ №1:
В документации по d3.bisector()
вы уже все рассмотрели (выделено мной):
Используйте компаратор, а не средство доступа, если вы хотите, чтобы значения сортировались в порядке, отличном от естественного, например, по убыванию, а не по возрастанию.
Сигнатура этого метода позволяет вам передавать функцию сравнения, которая вызывается со значением поиска, переданным в качестве второго аргумента. Таким образом, вы можете иметь биссектрису для массива в порядке убывания следующим образом:
d3.bisector((d, x) => x - d).left
// ^--- Search value
Взгляните на следующую рабочую демонстрацию:
const yData = [10,9,8,7,6,5,4,3,2,1,0];
const descBisector = d3.bisector((d, x) => x - d).left;
const yIndex = descBisector(yData, 2);
console.log(yIndex);
<script src="https://d3js.org/d3.v5.js"></script>