gpt4 book ai didi

d3.js - d3fc - 使用最新版本 14 进行捕捉的十字准线

转载 作者:行者123 更新时间:2023-12-02 02:40:31 25 4
gpt4 key购买 nike

在以前版本的 d3fc 中,我的代码使用 fc.util.seriesPointSnapXOnly 捕捉十字准线。

这似乎在最新版本的 d3fc 中消失了(或者我可能在其中一个独立包中遗漏了它?)。

我正在使用 Canvas 实现 (annotationCanvasCrosshair),它似乎也缺少以前使用的“捕捉”功能:

fc.tool.crosshair()
.snap(fc.util.seriesPointSnapXOnly(line, series))

此外,“on”也不可用,所以我无法附加 trackingstart、trackingend 等事件。

我现在如何实现捕捉十字准线?组件的 Canvas 版本严重缺乏示例。有没有人有通过 Canvas 渲染在最新版本的 d3fc 中显示捕捉十字准线的示例?

这是我目前拥有的 https://codepen.io/parliament718/pen/xxbQGgp

最佳答案

我知道你在 d3fc github 上提出了这个问题,因此我假设你知道 util/snap.js is been deprecated .

由于此功能现在不受支持,似乎解决它的唯一可行方法是实现您自己的功能。

我拿了你的penoriginal snap.js code作为起点并应用 Simple Crosshair example 中概述的方法来自文档。

我最终不得不逐字添加缺少的函数及其依赖项(当然你可以重构并将其打包到一个单独的模块中):

function defined() {
var outerArguments = arguments;
return function(d, i) {
for (var c = 0, j = outerArguments.length; c < j; c++) {
if (outerArguments[c](d, i) == null) {
return false;
}
}
return true;
};
}

function minimum(data, accessor) {
return data.map(function(dataPoint, index) {
return [accessor(dataPoint, index), dataPoint, index];
}).reduce(function(accumulator, dataPoint) {
return accumulator[0] > dataPoint[0] ? dataPoint : accumulator;
}, [Number.MAX_VALUE, null, -1]);
}

function pointSnap(xScale, yScale, xValue, yValue, data, objectiveFunction) {
// a default function that computes the distance between two points
objectiveFunction = objectiveFunction || function(x, y, cx, cy) {
var dx = x - cx,
dy = y - cy;
return dx * dx + dy * dy;
};

return function(point) {
var filtered = data.filter(function(d, i) {
return defined(xValue, yValue)(d, i);
});

var nearest = minimum(filtered, function(d) {
return objectiveFunction(point.x, point.y, xScale(xValue(d)), yScale(yValue(d)));
})[1];

return [{
datum: nearest,
x: nearest ? xScale(xValue(nearest)) : point.x,
y: nearest ? yScale(yValue(nearest)) : point.y
}];
};
}

function seriesPointSnap(series, data, objectiveFunction) {
return function(point) {
var xScale = series.xScale(),
yScale = series.yScale(),
xValue = series.crossValue(),
yValue = (series.openValue).call(series);
return pointSnap(xScale, yScale, xValue, yValue, data, objectiveFunction)(point);
};
};

function seriesPointSnapXOnly(series, data) {
function objectiveFunction(x, y, cx, cy) {
var dx = x - cx;
return Math.abs(dx);
}
return seriesPointSnap(series, data, objectiveFunction);
}

工作最终结果可以在这里看到:https://codepen.io/timur_kh/pen/YzXXOOG .我基本上定义了两个系列并使用 pointer 组件更新第二个系列数据并触发重新渲染:

    const data = {
series: stream.take(50), // your candle stick chart
crosshair: [] // second series to hold the crosshair position
};
.............
const crosshair = fc.annotationCanvasCrosshair() // define your crosshair

const multichart = fc.seriesCanvasMulti()
.series([candlesticks, crosshair]) // we've got two series now
.mapping((data, index, series) => {
switch(series[index]) {
case candlesticks:
return data.series;
case crosshair:
return data.crosshair;
}
});
.............
function render() {
d3.select('#zoom-chart')
.datum(data)
.call(chart);
// add the pointer component to the plot-area, re-rendering each time the event fires.
var pointer = fc.pointer()
.on('point', (event) => {
data.crosshair = seriesPointSnapXOnly(candlesticks, data.series)(event[0]);// and when we update the crosshair position - we snap it to the other series using the old library code.
render();
});

d3.select('#zoom-chart .plot-area')
.call(pointer);
}

更新:功能可以像这样简化,我还更新了笔:

function minimum(data, accessor) {
return data.map(function(dataPoint, index) {
return [accessor(dataPoint, index), dataPoint, index];
}).reduce(function(accumulator, dataPoint) {
return accumulator[0] > dataPoint[0] ? dataPoint : accumulator;
}, [Number.MAX_VALUE, null, -1]);
}

function seriesPointSnapXOnly(series, data, point) {
if (point == undefined) return []; // short circuit if data point was empty
var xScale = series.xScale(),
xValue = series.crossValue();

var filtered = data.filter((d) => (xValue(d) != null));
var nearest = minimum(filtered, (d) => Math.abs(point.x - xScale(xValue(d))))[1];

return [{
x: xScale(xValue(nearest)),
y: point.y
}];
};

这远未完善,但我希望它传达了总体思路。

关于d3.js - d3fc - 使用最新版本 14 进行捕捉的十字准线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59832117/

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