gpt4 book ai didi

javascript - 在 D3.js 插件中链接函数

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:59:14 24 4
gpt4 key购买 nike

我为 D3.js 编写了一个名为 d3-marcon 的插件实现 Mike Bostock's margin conventions .例如,不必写:

var margin = {top: 10, bottom: 10, left: 10, right: 10},
width = window.innerWidth - margin.left - margin.right,
height = window.innerHeight - margin.top - margin.bottom,
svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

你可以这样写:

var setup = d3.marcon({top: 10, bottom: 10, left: 10, right: 10, width: window.innerWidth, height: window.innerHeight}),
margin = setup.margin,
width = setup.width,
height = setup.height,
svg = setup.svg;

如您所见,它通过将选项对象传递给 marcon() 函数来工作。如果您未指定任何选项,则所有边距默认为 0,宽度默认为 900,高度默认为 600,并附加 svg 元素到 “正文”。因此,您只需一行代码 var setup = d3.marcon() 即可快速启动并运行,然后在您想要更改可视化时传递选项。

这很有用,但感觉还是不像真正的D3功能。真正的 D3 函数允许将函数链接在一起,而不是传递选项对象。因此,与 d3.marcon({element: ".viz"}) 不同,D3 代码看起来像 d3.marcon().element(".viz")

D3 代码还允许您将附加函数传递给链式函数(例如 d3.method().chainedFunction(function(d) { return d.value; })),因此您可以更新基于数据的对象的属性。

显然,我的插件没有做这些事情。我花了几个小时查看现有的 D3 模块,试图弄清楚它们是如何工作的,但我一无所获。谁能建议如何让我的代码像正确的 D3 模块一样工作?或者,如果做不到这一点,可以阅读一个很好的教程吗?

我链接到上面的存储库,但是 here it is again .和 here is a block展示它是如何工作的。

最佳答案

这是我的建议,基于 Nick Zhu 在他的书 Data Visualization with D3 4.x 中的方法。

基本上,我们创建一个带有对象的函数...

function marcon() {
var instance = {};
}

... 并分别设置每个方法:

instance.top = function(d) {
if (!arguments.length) return top;
top = d;
return instance;
};

最后,你用render()调用渲染部分:

marcon().top(10)
.left(10)
//etc...
.render();

这种方法的好处在于,正如您所要求的,它允许链接。例如,您可以像这样创建 SVG:

var mySvg = marcon();

mySvg.top(20)
.left(10)
.right(10)
.bottom(10)
.height(200)
.width(200)
.element("body")
.render();

这是一个演示:

function marcon() {
var instance = {};
var top = 10,
bottom = 0,
left = 0,
right = 0,
width = 900,
height = 600,
element = "body",
innerWidth, innerHeight, svg;

instance.top = function(d) {
if (!arguments.length) return top;
top = d;
return instance;
};

instance.left = function(d) {
if (!arguments.length) return left;
left = d;
return instance;
};

instance.right = function(d) {
if (!arguments.length) return right;
right = d;
return instance;
};

instance.bottom = function(d) {
if (!arguments.length) return bottom;
bottom = d;
return instance;
};

instance.width = function(d) {
if (!arguments.length) return width;
width = d;
return instance;
};

instance.height = function(d) {
if (!arguments.length) return height;
height = d;
return instance;
};

instance.element = function(d) {
if (!arguments.length) return element;
element = d;
return instance;
};

instance.innerWidth = function() {
return innerWidth;
};

instance.innerHeight = function() {
return innerHeight;
};

instance.svg = function() {
return svg;
};

instance.render = function() {
innerWidth = width - left - right;
innerHeight = height - top - bottom;
svg = d3.select(element)
.append("svg")
.attr("width", innerWidth + left + right)
.attr("height", innerHeight + top + bottom)
.append("g")
.attr("transform", "translate(" + left + ", " + top + ")");
}

return instance;
}

var mySvg = marcon();
mySvg.top(20)
.left(10)
.right(10)
.bottom(20)
.height(200)
.width(200)
.element(".testDiv")
.render();

var rect = mySvg.svg()
.append("rect")
.attr("width", mySvg.innerWidth())
.attr("height", mySvg.innerHeight())
.style("fill", "teal")
svg {
background-color: tan;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="testDiv"></div>

此外,它允许默认值。如果您不设置 setter,它将默认为指定的值。这里,如果我们不设置宽度,默认为900:

function marcon() {
var instance = {};
var top = 10,
bottom = 0,
left = 0,
right = 0,
width = 900,
height = 600,
element = "body",
innerWidth, innerHeight, svg;

instance.top = function(d) {
if (!arguments.length) return top;
top = d;
return instance;
};

instance.left = function(d) {
if (!arguments.length) return left;
left = d;
return instance;
};

instance.right = function(d) {
if (!arguments.length) return right;
right = d;
return instance;
};

instance.bottom = function(d) {
if (!arguments.length) return bottom;
bottom = d;
return instance;
};

instance.width = function(d) {
if (!arguments.length) return width;
width = d;
return instance;
};

instance.height = function(d) {
if (!arguments.length) return height;
height = d;
return instance;
};

instance.element = function(d) {
if (!arguments.length) return element;
element = d;
return instance;
};

instance.innerWidth = function() {
return innerWidth;
};

instance.innerHeight = function() {
return innerHeight;
};

instance.svg = function() {
return svg;
};

instance.render = function() {
innerWidth = width - left - right;
innerHeight = height - top - bottom;
svg = d3.select(element)
.append("svg")
.attr("width", innerWidth + left + right)
.attr("height", innerHeight + top + bottom)
.append("g")
.attr("transform", "translate(" + left + ", " + top + ")");
}

return instance;
}

var mySvg = marcon();
mySvg.top(20)
.left(10)
.right(10)
.bottom(20)
.height(200)
.element("body")
.render();

var rect = mySvg.svg()
.append("rect")
.attr("width", mySvg.innerWidth())
.attr("height", mySvg.innerHeight())
.style("fill", "teal")
svg {
background-color: tan;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="testDiv"></div>

最后,您可以使用 getter,例如:

marcon().top();

这给了你值(value)。这是一个演示,看看控制台:

function marcon() {
var instance = {};
var top = 10,
bottom = 0,
left = 0,
right = 0,
width = 900,
height = 600,
element = "body",
innerWidth, innerHeight, svg;

instance.top = function(d) {
if (!arguments.length) return top;
top = d;
return instance;
};

instance.left = function(d) {
if (!arguments.length) return left;
left = d;
return instance;
};

instance.right = function(d) {
if (!arguments.length) return right;
right = d;
return instance;
};

instance.bottom = function(d) {
if (!arguments.length) return bottom;
bottom = d;
return instance;
};

instance.width = function(d) {
if (!arguments.length) return width;
width = d;
return instance;
};

instance.height = function(d) {
if (!arguments.length) return height;
height = d;
return instance;
};

instance.element = function(d) {
if (!arguments.length) return element;
element = d;
return instance;
};

instance.innerWidth = function() {
return innerWidth;
};

instance.innerHeight = function() {
return innerHeight;
};

instance.svg = function() {
return svg;
};

instance.render = function() {
innerWidth = width - left - right;
innerHeight = height - top - bottom;
svg = d3.select(element)
.append("svg")
.attr("width", innerWidth + left + right)
.attr("height", innerHeight + top + bottom)
.append("g")
.attr("transform", "translate(" + left + ", " + top + ")");
}

return instance;
}

var mySvg = marcon();
mySvg.top(20)
.left(10)
.right(10)
.bottom(20)
.height(200)
.width(200)
.element("body")
.render();

var rect = mySvg.svg()
.append("rect")
.attr("width", mySvg.innerWidth())
.attr("height", mySvg.innerHeight())
.style("fill", "teal");

console.log("The height is " + mySvg.height())
svg {
background-color: tan;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="testDiv"></div>

关于javascript - 在 D3.js 插件中链接函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45266547/

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