gpt4 book ai didi

d3.js - 修改 D3js V4 的笛卡尔失真

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

我正在努力实现this影响。我能找到的最接近该效果的工作示例是笛卡尔失真效果,它似乎不适用于 D3 V4。我不太明白需要更改哪些所有行或如何更改以使此示例与 d3js 版本 4 兼容。

jsfiddle

    (function chart3() {
console.clear()
var width = 960,
height = 180,
xSteps = d3.range(10, width, 16),
ySteps = d3.range(10, height, 16);



var xFisheye = d3.fisheye.scale(d3.scale.identity).domain([0, width]).focus(360),
yFisheye = d3.scale.linear().domain([0, height]);

var svg = d3.select("#chart3").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(-.5,-.5)");

svg.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height);

var xLine = svg.selectAll(".x")
.data(xSteps)
.enter().append("line")
.attr("class", "x")
.attr("y2", height);

redraw();

svg.on("mousemove", function() {
var mouse = d3.mouse(this);

// HACK ( only for left-side )
xFisheye.focus(mouse[0] - 32); // HACK 1
yFisheye(mouse[1]);
if(mouse[0] > 26) // HACK 2
redraw();
});

function redraw() {
xLine.attr("x1", xFisheye).attr("x2", xFisheye);
}
})();

最佳答案

无论如何,我只是调整了 d3-fisheye 插件以与 d3 v4 一起使用。我还添加了可能有用的 fisheye.invert

import * as d3 from 'd3'

const fisheye = {
scale: function (scaleType) {
return d3FisheyeScale(scaleType(), 3, 0)
},
circular: function () {
let radius = 200
let distortion = 2
let k0
let k1
let focus = [0, 0]

function fisheye (d) {
let dx = d.x - focus[0]
let dy = d.y - focus[1]
let dd = Math.sqrt(dx * dx + dy * dy)
if (!dd || dd >= radius) return {x: d.x, y: d.y, z: dd >= radius ? 1 : 10}
let k = k0 * (1 - Math.exp(-dd * k1)) / dd * 0.75 + 0.25
return {x: focus[0] + dx * k, y: focus[1] + dy * k, z: Math.min(k, 10)}
}

function rescale () {
k0 = Math.exp(distortion)
k0 = k0 / (k0 - 1) * radius
k1 = distortion / radius
return fisheye
}

fisheye.radius = function (_) {
if (!arguments.length) return radius
radius = +_
return rescale()
}

fisheye.distortion = function (_) {
if (!arguments.length) return distortion
distortion = +_
return rescale()
}

fisheye.focus = function (_) {
if (!arguments.length) return focus
focus = _
return fisheye
}

return rescale()
}
}

function d3FisheyeScale (scale, d, a) {
function fisheye (_) {
let x = scale(_)
let left = x < a
let range = d3.extent(scale.range())
let min = range[0]
let max = range[1]
let m = left ? a - min : max - a
if (m === 0) m = max - min
return (left ? -1 : 1) * m * (d + 1) / (d + (m / Math.abs(x - a))) + a
}

fisheye.invert = function (xf) {
let left = xf < a
let range = d3.extent(scale.range())
let min = range[0]
let max = range[1]
let m = left ? a - min : max - a
if (m === 0) m = max - min
return scale.invert(a + m * (xf - a) / ((d + 1) * m - (left ? -1 : 1) * d * (xf - a)))
}

fisheye.distortion = function (_) {
if (!arguments.length) return d
d = +_
return fisheye
}

fisheye.focus = function (_) {
if (!arguments.length) return a
a = +_
return fisheye
}

fisheye.copy = function () {
return d3FisheyeScale(scale.copy(), d, a)
}

fisheye.nice = scale.nice
fisheye.ticks = scale.ticks
fisheye.tickFormat = scale.tickFormat

const rebind = function (target, source) {
let i = 1
const n = arguments.length
let method
while (++i < n) {
method = arguments[i]
target[method] = d3Rebind(target, source, source[method])
};
return target
}
function d3Rebind (target, source, method) {
return function () {
var value = method.apply(source, arguments)
return value === source ? target : value
}
}
return rebind(fisheye, scale, 'domain', 'range')
}

export default fisheye

现在使用它:

import fisheye from './fisheye'
import { scaleLinear, scalePow } from 'd3-scale'

const fisheyeLinearScale = fisheye.scale(scaleLinear)
const fisheyePowScale = fisheye.scale(scalePow().exponent(1.1).copy)

const myFisheyeScale = fisheyePowScale.domain(<domain>)
.range(<range>)
.focus(<mouseX>)
.distortion(<deformation>)

关于d3.js - 修改 D3js V4 的笛卡尔失真,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42694544/

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