1

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

我想为用户提供选择出现在 Sankey 中的列的能力。例如,我希望 Sankey 显示页面、访问者、元素和国家/地区。数据中的结果还包括 Visitor_Link、Country、State 和 Browser。

下次运行时,用户可以选择一组不同的列(例如页面、访问者)。

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 });
        }
    }
});

依此类推来构建 sankey:

//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);

感谢您提供的任何见解。

4

0 回答 0