Javascript d3.js为sankey选择特定列

Javascript d3.js为sankey选择特定列,javascript,d3.js,sankey-diagram,Javascript,D3.js,Sankey Diagram,我可以过滤特定列上的数据,将29行压缩到9行,如下例所示;但是,是否有可能获取数据中的结果并排除列 我想向用户提供选择Sankey中显示哪些列的功能。例如,我希望Sankey显示页面、访问者、元素和国家。数据中的结果还包括访问者链接、国家、州和浏览器 下次运行时,用户可以选择一组不同的列,例如Page,Visitor function filter(arr, criteria) { return arr.filter(function (obj) { return Obj

我可以过滤特定列上的数据,将29行压缩到9行,如下例所示;但是,是否有可能获取数据中的结果并排除列

我想向用户提供选择Sankey中显示哪些列的功能。例如,我希望Sankey显示页面、访问者、元素和国家。数据中的结果还包括访问者链接、国家、州和浏览器

下次运行时,用户可以选择一组不同的列,例如Page,Visitor

function filter(arr, criteria) {
    return arr.filter(function (obj) {
        return Object.keys(criteria).every(function (c) {
            return obj[c] == criteria[c];
        });
    });
}

//filters object
var filters = {
    'Country': ['Canada', 'United States of America'],
    'Element': ['Page1_A0']
};

// these column are used in the filter and 
// are also the source, target relationships
// Source=Page and Target = Visitor
// Source=Visitor and Target = Element
// Source=Element and Target = Country
var mycolumns = ['Page', 'Visitor', 'Element', 'Country'];

// other columns in the data include: Visitor_Link, Country, State, Browser

d3.tsv(folder + file, function (error, data) {
    graph = { "nodes": [], "links": [] };
    // filter rows with a filter on one or more columns
    // example: 'Country': ['Canada'],
    data = data.filter(function (row) {
        // run through all the filters, returning a boolean as true
        // if mycolumns are found
        return mycolumns.reduce(function (pass, column) {
            return pass && (
                // pass if no filter is set
                !filters[column] ||
                // pass if the row's value is equal to the filter
                // (i.e. the filter is set to a string)
                row[column] === filters[column] ||
                // pass if the row's value is in an array of filter values
                filters[column].indexOf(row[column]) >= 0
            );                   
        }, true);
    })
我试过各种各样的东西;但是如果我能根据mycolumns数组中的字段来构建Sankey,那将是一个好的开始。我试过用这个来隔离这些列

var mappedArray = d3.entries(data[0]);
data.forEach(function (d, i) {
    for (var n = 0; n < mappedArray.length; n++) {
        if (!!mappedArray[n].value && !!mappedArray[n + 1].value) {
            var the_first_value = mappedArray[n].value;
            var the_second_value = mappedArray[n + 1].value;
            console.log(the_first_value + "," + the_second_value);
            graph.nodes.push({ "name": the_first_value });
            graph.nodes.push({ "name": the_second_value });
            graph.links.push({ "source": the_first_value,
                               "target": the_second_value, "value": 1 });
        }
    }
});
感谢您提供的任何见解

//this handy little function returns only the distinct / unique nodes
graph.nodes = d3.keys(
        d3.nest()
            .key(function (d) { return d.name; })
            .map(graph.nodes)
    );

// it appears d3 with force layout wants a numeric source and target
// so loop through each link replacing the text with its index from node
graph.links.forEach(function (d, i) {
    graph.links[i].source = graph.nodes.indexOf(graph.links[i].source);
    graph.links[i].target = graph.nodes.indexOf(graph.links[i].target);
});

// now loop through each nodes to make nodes an array of objects rather
// than an array of strings
graph.nodes.forEach(function (d, i) {
    graph.nodes[i] = { "name": d };
});

sankey
    .nodes(graph.nodes)
    .links(graph.links)
    .layout(32);