Изменение загруженных данных с помощью D3

1

Я создал документ с использованием D3, где график изменяется в зависимости от того, что пользователь выбирает, и он работает, однако есть проблема с данными.

zivotni_broj;Datum;Kolicina_Vece;Kolicina_Jutro;fat;pro;lac;cels;sol;vlasnik
AA 110137783;3.6.2003 0:00:00;0,00;2100,00;5,21;3,70;4,44;,00;;00000001
AA 110137793;3.6.2003 0:00:00;0,00;1600,00;3,80;2,84;4,51;,00;;00000001
...

Как вы можете видеть, это в формате DSV, однако данные с именем "sol" никогда не записываются. Я спросил источник данных, и они сказали, что это означает, что он равен нулю, но D3 не распознает его как нуль, и график не может быть нарисован.

Данные успешно загружаются, и я получаю массив объектов, и я знаю, как изменить несуществующее значение "sol" на значение "0,00" с помощью цикла Javascript, но поскольку я делаю презентацию на D3, я хочу сделать так: с возможностями D3, как я могу. Я не хочу менять данные, так как хочу показать, что D3 может работать с почти любыми данными, без необходимости менять файл данных, чтобы он работал.

Поэтому мой вопрос заключается в том, имеет ли D3 возможность циклического преобразования данных и изменения его без необходимости изменения исходного файла данных?

Теги:
d3.js

3 ответа

2
Лучший ответ

В качестве варианта ответа Gerardo вы можете использовать функцию преобразования строк, которая предоставляется в качестве необязательного второго аргумента для dsv.parse (строка, [строка]). Поскольку вы попросили витрину D3, это может быть самым близким к решению для всех D3.

var dsv = 
'zivotni_broj;Datum;Kolicina_Vece;Kolicina_Jutro;fat;pro;lac;cels;sol;vlasnik
AA 110137783;3.6.2003 0:00:00;0,00;2100,00;5,21;3,70;4,44;,00;;00000001
AA 110137793;3.6.2003 0:00:00;0,00;1600,00;3,80;2,84;4,51;,00;;00000001';
    
var parse = d3.dsvFormat(";").parse;
var data = parse(dsv, d => {   // Here the row conversion function is specified
  d.sol = "0,00";              // as an anonymous fat arrow function filling in
  return d;                    // the empty column sol.
});
console.log(data);
<script src="https://d3js.org/d3.v4.js"></script>

Обратите внимание, что это делает именно то, что вы просили, т.е. заполните d.sol "0,00", не более, не менее. Тем не менее, вы не ограничены этим, вы могли бы сделать еще много вещей, таких как преобразование строк в числа, фильтрацию или уплотнение свойств, введение новых свойств и многое другое. Вы даже можете вернуть совершенно другой объект или массив, построенный с нуля.

  • 0
    Я закончил тем, что проверил, являются ли данные "" и превратил их в "0,00" в функции экстента, так как в любом случае они в основном циклически перебирают данные и работают. Графики, которые рисует документ, редко имеют более 40-50 узлов, поэтому скорость не является проблемой. Я также попробовал ваш путь, и он отлично работает, поскольку я также могу конвертировать дату в лучший формат и конвертировать другие данные в плавающее, таким образом немного очистив мой код. Тем не менее, документы загружаются немного медленнее в начале, но я вижу, в чем смысл, если я показываю большие объемы данных одновременно.
2

Когда D3 анализирует DSV как ваш, где некоторые заголовки не имеют соответствующего значения, он просто создает свойство, значение которого является пустой строкой.

Посмотрите здесь (bar пуст):

var format = d3.dsvFormat(";")
var dsv = format.parse(d3.select("#dsv").text());

console.log(dsv)
pre {
  display: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<pre id="dsv">foo;bar;baz
12;;4
21;;5
17;;9</pre>

Поэтому, чтобы создать нули, это просто вопрос цикла массива:

var format = d3.dsvFormat(";")
var dsv = format.parse(d3.select("#dsv").text());
dsv.forEach(function(d) {
  for (var key in d) {
    if (!d[key]) {
      d[key] = 0
    }
  }
})

console.log(dsv)
pre {
  display: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<pre id="dsv">foo;bar;baz
12;;4
21;;5
17;;9</pre>

EDIT: для более идиоматического D3-ориентированного ответа, как предлагается в комментариях, здесь приведена демонстрационная функция с использованием функции row:

var format = d3.dsvFormat(";")
var dsv = format.parse(d3.select("#dsv").text(), function(d, i, columns) {
  for (var i = 0; i < columns.length; i++) {
    if (!d[columns[i]]) {
      d[columns[i]] = 0
    }
  }
  return d;
})

console.log(dsv)
pre {
  display: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<pre id="dsv">foo;bar;baz
12;;4
21;;5
17;;9</pre>
  • 0
    PS: имейте в виду, что ноль здесь - это действительное число, а не строка, как другие значения.
  • 0
    * «он просто создает свойство, значение которого является пустым массивом» * - не изучив его, я все еще почти уверен, что он создает нулевое значение, а не пустой массив, верно? Что касается цикла, я являюсь поклонником функций преобразования строк, которые также дают ему больше касания D3, как и просил OP.
Показать ещё 5 комментариев
0

Я предполагаю, что вы более или менее ссылаетесь на ярлык? Если это так, используйте пустую опцию внутри объекта данных. Смотрите, если это трюк для вас.

empty: { label: { text: "0,00" }   }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню