【发布时间】:2014-08-16 04:40:09
【问题描述】:
D3 已经有一堆symbols,但我想添加一个自定义的。这样我就可以在我的代码中调用d3.svg.symbol().type('custom')。
【问题讨论】:
标签: d3.js
D3 已经有一堆symbols,但我想添加一个自定义的。这样我就可以在我的代码中调用d3.svg.symbol().type('custom')。
【问题讨论】:
标签: d3.js
这不能直接完成,因为无法从 API 访问符号定义数组。
您可以在源代码HERE 中看到符号定义存储在名为d3_svg_symbols 的d3.map 中。此映射中唯一暴露给公共 API 的部分是键数组。这是通过调用地图的.keys() 方法HERE 来完成的。
d3.svg.symbolTypes = d3_svg_symbols.keys();
定义本身永远不会公开,因此您不能像希望的那样直接添加定义。
但是,您可以构建一个解决方法而没有太多困难。一种方法是创建自定义符号的地图,并基于现有的内置符号创建函数。例如:
// DEFINE A COUPLE OF CUSTOM SYMBOLS
var customSymbolTypes = d3.map({
'custom-symbol-1': function(size) {
// returns a path-data string
},
'custom-symbol-2': function(size) {
// returns a path-data string
}
});
// CREATE A CUSTOM SYMBOL FUNCTION MIRRORING THE BUILT-IN FUNCTIONALITY
d3.svg.customSymbol = function() {
var type,
size = 64; // SET DEFAULT SIZE
function symbol(d,i) {
// GET THE SYMBOL FROM THE CUSTOM MAP
return customSymbolTypes.get(type.call(this,d,i))(size.call(this,d,i));
}
// DEFINE GETTER/SETTER FUNCTIONS FOR SIZE AND TYPE
symbol.type = function(_) {
if (!arguments.length) return type;
type = d3.functor(_);
return symbol;
};
symbol.size = function(_) {
if (!arguments.length) return size;
size = d3.functor(_);
return symbol;
};
return symbol;
};
然后,您可以创建一个函数来检查一个符号是否在内置符号列表中,如果不是,则假设它是一个自定义符号:
function getSymbol(type, size) {
// SIZE DEFAULTS TO 64 IF NOT GIVEN
size = size || 64;
// IF TYPE IS ONE OF THE BUILT-IN TYPES, CALL THE BUILT-IN FUNCTION
if (d3.svg.symbolTypes.indexOf(type) !== -1) {
return d3.svg.symbol().type(type).size(size)();
}
// OTHERWISE, CALL THE CUSTOM SYMBOL FUNCTION
else {
return d3.svg.customSymbol().type(type).size(size)();
}
}
HERE 是此方法的实际演示。
我承认不得不像这样重新实现整个符号函数似乎有点疯狂。可能值得在 github 页面上提出功能请求,要求能够提供可以读入内置方法的符号定义的自定义映射。无论如何,我希望这对现在有所帮助。
【讨论】: