-2

我正在使用 D3 中的力图创建数据驱动的显示。

我通过 ajax 从服务器数据中提供节点和链接。

D3 Force Layout 模型中有一个函数允许您通过函数设置链接距离。我想将此函数存储在数据库中,或者至少让它们在服务器端生成。

这是一个简单的例子。

        force
            .gravity(json_data.gravity || 0.15)
            .charge(-150 + json_data.nodes.length)
            .nodes(json_data.nodes)
            .links(json_data.links)
            .linkDistance(function (link, index) {
                if (index % 2)
                    return 30;
                return 50;
            })
            .start();

对于charge 和linkDistance 等字段,我真的很希望在服务器端完成繁重的工作。

实现这一目标的“最佳”方式是什么?我知道 Eval 可能能够解决一些问题,但是,大多数帖子都说避免它..

想法?

编辑:

这就是我要存储的

"function (link, index) { if (index % 2) return 30; return 50;"

"function (link, index) { if (index % 3 ==1) return 30; if (index % 3==2) return 40; return 50;"

这是我拿它的地方。

服务器端 :

    public JsonGraphDTO(int Id, UnitRepository repository) {
        gravity = 0.15;
        linkDistance = "return 40;";
        ...

客户端处理:

        var fn = new Function('lnk','index',json_data.linkDistance);
        force
            .gravity(json_data.gravity || 0.15)
            .charge(-150 + json_data.nodes.length)
            .nodes(json_data.nodes)
            .links(json_data.links)
            .linkDistance(fn)
            .start();
4

1 回答 1

0

您希望能够链接到不同的功能,命名它们。

function linkDistance1 (link, index) { if (index % 2) return 30; return 50; }
function linkDistance2 (link, index) { if (index % 3 ==1) return 30; if (index % 3==2) return 40; return 50; }

并参考它们

    force
        .gravity(json_data.gravity || 0.15)
        .charge(-150 + json_data.nodes.length)
        .nodes(json_data.nodes)
        .links(json_data.links)
        .linkDistance(linkDistance1)
        .start();

您可以将其作为数组进行

var linkDistanceFunctions = [
    function (link, index) { if (index % 2) return 30; return 50; },
    function (link, index) { if (index % 3 ==1) return 30; if (index % 3==2) return 40; return 50; }
];

或作为一个对象

var linkDistanceFunctions = {
    "foo" : function (link, index) { if (index % 2) return 30; return 50; },
    "bar" : function (link, index) { if (index % 3 ==1) return 30; if (index % 3==2) return 40; return 50; }
};

你说你想动态加载它们,所以通过脚本标签加载它们。

window["myCallBack"] = function(myArrayOfFunctions){
    console.log(myArrayOfFunctions);
};
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'myServerSidePage.php?callback=myCallBack';
head.appendChild(script);

在服务器上,您将通过回调返回函数

myCallBack([
    function (link, index) { if (index % 2) return 30; return 50; },
    function (link, index) { if (index % 3 ==1) return 30; if (index % 3==2) return 40; return 50; }
]);

我使用了一个数组,如果你愿意,你可以发回一个对象或一个函数。

于 2012-11-28T22:14:03.273 回答