d3 / javascript фильтр данных в соответствии с вводом - PullRequest
0 голосов
/ 31 августа 2018

Извините, если мой вопрос, может быть, очень простой, но я научился сам, и трудно продолжать, не зная основ в javascript

Чтобы сделать мой вопрос простым, скажем, у меня есть данные, которые выглядят следующим образом:

country, value1, value2, 
US, 100, 50,
UK, 30, 20,
Germany, 40, 30,
France, 20, 10

Я хотел бы сделать выпадающий список, где значения1 и значение2 являются опциями. Таким образом, когда пользователь выбирает параметр value1 в раскрывающемся списке, появляется визуализация только для value1.

Итак, я написал псевдокод, как показано ниже, фильтруя данные по входным данным.

function update() {
var selected = menu.property("value");
data.filter((d) => return d3.keys(d[0]) === selected; )}

Доза это звучит хорошо? или есть что починить?

Кроме того, после фильтрации данных мне понадобятся дополнительные манипуляции с данными. Поэтому мне нужно указание страны, а также значения1 или значения2. Кто-нибудь знает, как сохранить приписывание страны при фильтрации?

Спасибо,

1 Ответ

0 голосов
/ 31 августа 2018

Строго говоря, вам не нужно фильтровать, вы можете просто выбрать, какое свойство данных вы хотите визуализировать:

Во-первых, давайте создадим меню выбора на основе имеющихся у вас столбцов, d3.csv создаст массив, который выглядит следующим образом:

var data = [
  {"country":"US", "value1": 100, "value2": 50},
  {"country":"UK", "value1": 30, "value2": 20},
  {"country":"Germany", "value1": 40, "value2": 30},
  {"country":"France", "value1": 20, "value2": 10}
];

Теперь мы можем получить столбцы, если с помощью d3.csv мы можем получить доступ к столбцам с помощью data.columns. Поскольку мы не хотим указывать страну в качестве опции, а только значения, мы можем выделить ее с помощью data.columns.slice(1). Я просто использую объект javascript в своих фрагментах, поэтому я использую d3.keys(data[0]).slice(1) для достижения того же эффекта .

Теперь мы можем создать раскрывающийся список в зависимости от того, сколько значений мы имеем в нашем наборе данных с помощью:

// Create a select element
var select = d3.select("body")
  .append("select")
  .on("change", function() {
     // Log value it is changed to:
     console.log(this.value);
  })

// Add an initial option:
select.append("option")
  .html("Select Value:")

// Add the columns as options:
var options = select.selectAll(null)
  .data(values)
  .enter()
  .append("option")
  .text(function(d) { return d; });

Что дает нам это:

var data = [
  {"country":"US", "value1": 100, "value2": 50},
  {"country":"UK", "value1": 30, "value2": 20},
  {"country":"Germany", "value1": 40, "value2": 30},
  {"country":"France", "value1": 20, "value2": 10}
];

// Get the columns. 
var values = d3.keys(data[0])
  .slice(1);

// Create a select element
var select = d3.select("body")
  .append("select")
  .on("change", function() {
     console.log(this.value);
  })

// Add an initial option:
select.append("option")
  .html("Select Value:")

// Add the options:
var options = select.selectAll(null)
  .data(values)
  .enter()
  .append("option")
  .text(function(d) { return d; });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

Теперь мы можем использовать эту функцию при изменении для передачи имени свойства в функцию обновления ( либо в качестве параметра, либо, как я делаю ниже, используя тот факт, что функция обратного вызова this элемент, событие которого вызвано ). Эта функция обновления примет это свойство и использует его для изменения визуализации:

Например:

select.on("change", update)

function update() {
   var property = this.value; // this is the element.

   // .... scale modification eg: scale.domain(d3.extent(data, function(d) { return d[property]; }))
   // .... enter/update/exit cycle       

   // Use property to shape visualization, eg:
   updateSelection.attr("property", function(d) { return scale(d[property]); })

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

Ниже я создал простую визуализацию, изменяя раскрывающийся список, обновляет график (просто без изменения масштаба, хотя, чтобы приспособить выбор начальной опции (которая не представляет свойство данных) I ' мы использовали d[property] || 0 при масштабировании значений, что изящно удаляет визуализацию).

var data = [
  {"country":"US", "value1": 100, "value2": 50},
  {"country":"UK", "value1": 30, "value2": 20},
  {"country":"Germany", "value1": 40, "value2": 30},
  {"country":"France", "value1": 20, "value2": 10}
];

// Get the columns. 
var values = d3.keys(data[0])
  .slice(1);

// Create a select element
var select = d3.select("body")
  .append("select")
  .on("change", update)

// Add an initial option:
select.append("option")
  .html("Select Value:")

// Add the options:
var options = select.selectAll(null)
  .data(values)
  .enter()
  .append("option")
  .text(function(d) { return d; });
  

// Create an SVG
var svg = d3.select("body")
  .append("svg")
  .attr("width", 500)
  .attr("height", 400);
  
// Spice it up with some scales:
var x = d3.scaleBand()
  .domain(data.map(function(d) { return d.country; }))
  .range([0,500])
  
var y = d3.scaleLinear()
  .domain([0,100])
  .range([150,0])
  
// Specify an Update function to create and update visualization elements: 
function update() {
  var value = this.value;
  var bars = svg.selectAll("rect")
    .data(data);
    
  bars.enter().append("rect")
    .attr("x", function(d) { return x(d.country); })
    .attr("width", x.bandwidth())
    .attr("y", 150)
    .attr("height",0)
    .merge(bars)    
    .transition()
    .attr("height", function(d) { return 150 - y(d[value] || 0); })
    .attr("y", function(d) { return y(d[value] || 0); });

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...