Выберите данные из CSV перед загрузкой с помощью javascript (библиотека d3)

Я хочу выбрать некоторые данные из файла CSV, прежде чем загружать его с помощью javascript (с библиотекой d3).

Вот как я загружаю CSV:

d3.csv("data.csv", function(csv) {
    vis.datum(csv).call(chart);
        });

И это образец файла CSV:

Class,Age,Sex,Survived
First Class,Adult,Male,Survived
First Class,Adult,Male,Survived
First Class,Adult,Male,Survived
First Class,Adult,Male,Survived
First Class,Adult,Male,Survived
First Class,Adult,Female,Survived
First Class,Adult,Female,Survived
First Class,Adult,Female,Survived
Second Class,Adult,Male,Perished
Second Class,Adult,Male,Perished
Second Class,Adult,Male,Perished
Third Class,Adult,Male,Survived
Third Class,Adult,Male,Survived
Third Class,Adult,Male,Survived
Third Class,Adult,Male,Survived
Third Class,Adult,Male,Perished
Third Class,Adult,Male,Perished
Crew,Adult,Male,Perished
Crew,Adult,Male,Perished
Crew,Adult,Female,Survived
Crew,Adult,Female,Survived

Например, я хочу только выбрать строки Second Class и First Class, прежде чем загружать его с помощью d3.csv.

Я знаю, что могу просто удалить другие строки в CSV, но я хочу сделать функцию, чтобы пользователь мог выбирать, какие категории он хочет использовать. Надеюсь, это имеет смысл.

Ответы

Ответ 1

Быстрый ответ: используйте .filter(), чтобы выбрать нужные строки, например:

d3.csv("data.csv", function(csv) {
    csv = csv.filter(function(row) {
        return row['Class'] == 'Second Class' || row['Class'] == 'First Class';
    })
    vis.datum(csv).call(chart);
});

Это легко, если вы, кодер, выбираете фильтры. Однако, если вам нужно, чтобы это было выбрано путем взаимодействия с пользователем, вам нужно будет создать более сложную функцию. Предполагая, что вы сохранили пользовательские варианты в объекте с именем filters, с ключами, соответствующими вашим строкам, один из вариантов может выглядеть так:

// an example filters object
var filters = {
    'Class': ['First Class', 'Second Class'],
    'Sex': 'Female'
};

d3.csv("data.csv", function(csv) {
    csv = csv.filter(function(row) {
        // run through all the filters, returning a boolean
        return ['Class','Age','Sex','Survived'].reduce(function(pass, column) {
            return pass && (
                // pass if no filter is set
                !filters[column] ||
                    // pass if the row value is equal to the filter
                    // (i.e. the filter is set to a string)
                    row[column] === filters[column] ||
                    // pass if the row value is in an array of filter values
                    filters[column].indexOf(row[column]) >= 0
                );
        }, true);
    })
    console.log(csv.length, csv);
});

(Вам не нужно делать это с помощью .reduce(), но мне нравится, насколько он чист.)

Если, как это возможно, вы не хотите делать эту фильтрацию во время загрузки, а вместо этого динамически фильтруйте в зависимости от пользовательского ввода, вы все равно можете использовать функцию фильтра, но вы захотите сохранить csv где-то в памяти и фильтровать его "на лету", возможно, в функции update(), вызванной пользовательскими взаимодействиями.