作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在努力实现this影响。我能找到的最接近该效果的工作示例是笛卡尔失真效果,它似乎不适用于 D3 V4。我不太明白需要更改哪些所有行或如何更改以使此示例与 d3js 版本 4 兼容。
(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/
我是一名优秀的程序员,十分优秀!