Я создал документ с использованием 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 возможность циклического преобразования данных и изменения его без необходимости изменения исходного файла данных?
В качестве варианта ответа 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"
, не более, не менее. Тем не менее, вы не ограничены этим, вы могли бы сделать еще много вещей, таких как преобразование строк в числа, фильтрацию или уплотнение свойств, введение новых свойств и многое другое. Вы даже можете вернуть совершенно другой объект или массив, построенный с нуля.
Когда 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>
Я предполагаю, что вы более или менее ссылаетесь на ярлык? Если это так, используйте пустую опцию внутри объекта данных. Смотрите, если это трюк для вас.
empty: { label: { text: "0,00" } }