Привет, мои друзья StackOverflow:Временные ряды анализа данных с использованием D3.js
Пришло время обратиться за помощью. Я несколько недель изучаю D3.js, и я начинаю чувствовать, что понимаю 10% (га, га, га). Я пытаюсь создать очень простой линейный граф. Я могу сделать это до тех пор, пока данные очень просты, но мой исходный источник данных имеет отметки времени UTC и реальные/десятичные числа, которые продолжают сбивать что-либо сверх простого.
Сырьевой источник данных выглядит следующим образом:
{ "Links": {}, "Items": [ { "Timestamp": "2016-07-12T22:21:10Z", "Value": 1055.6793212890625, "UnitsAbbreviation": "m3/h", "Good": true, "Questionable": false, "Substituted": false }, { "Timestamp": "2016-07-12T22:39:10Z", "Value": 989.00830078125, "UnitsAbbreviation": "m3/h", "Good": true, "Questionable": false, "Substituted": false } ], "UnitsAbbreviation": "m3/h" }
Использование JQuery и функции Javascript время форматирования Я могу собрать следующий упрощенный набор данных:
var dataset = [ {'theTime': '2016/07/12 15:58:40', 'theValue': 1123.07275390625}, {'theTime': '2016/07/12 16:21:10', 'theValue': 1055.6793212890625}, {'theTime': '2016/07/12 16:45:40', 'theValue': 962.4850463867188}, {'theTime': '2016/07/12 17:14:40', 'theValue': 831.2259521484375}, {'theTime': '2016/07/12 17:55:10', 'theValue': 625.3046875} ];
Вот мой код:
//~ Populate the 'dataset': var dataset = []; $.get(url, function(data){ var itemCount = data.Items.length; var commaCount = itemCount - 1; for(i=0; i < itemCount; i++){ if(i == commaCount){ dataset.push("{'theTime': '" + formattedDateTime(data.Items[i].Timestamp) + "', 'theValue': " + data.Items[i].Value + "}"); } else { dataset.push("{'theTime': '" + formattedDateTime(data.Items[i].Timestamp) + "', 'theValue': " + data.Items[i].Value + "},"); } } var margin = {top: 20, right: 20, bottom: 30, left: 50}; var width = 960 - margin.left - margin.right; var height = 500 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse; var x = d3.time.scale() .range([0, width]); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var line = d3.svg.line() .x(function(d) { return x(d.theTime); }) .y(function(d) { return y(d.theValue); }); var svg = d3.select("#myChart").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); dataset.forEach(function(d) { d.theTime = parseDate(d.theTime); d.theValue = +d.theValue; }); x.domain(d3.extent(data, function(d) { return d.theTime; })); y.domain(d3.extent(data, function(d) { return d.theValue;})); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("return time(ms)"); svg.append("path") .datum(dataset) .attr("class", "line") .attr("d", line); }); //~~~ Format The Date: function formattedDateTime(dateAndTime) { var d = new Date(dateAndTime); var numDate = d.getDate(); var numMonth = d.getMonth() + 1; var numYear = d.getFullYear(); var numHours = d.getHours(); var numMinutes = d.getMinutes(); var numSeconds = d.getSeconds(); numDate = (numDate < 10) ? "0" + numDate : numDate; numMonth = (numMonth < 10) ? "0" + numMonth : numMonth; numHours = (numHours < 10) ? "0" + numHours : numHours; numMinutes = (numMinutes < 10) ? "0" + numMinutes : numMinutes; numSeconds = (numSeconds < 10) ? "0" + numSeconds : numSeconds; return numYear + "/" + numMonth + "/" + numDate + " " + numHours + ":" + numMinutes + ":" + numSeconds; };
Первая ошибка возникает в функции 'dataset.forEach()', wh ich «Uncaught TypeError: Cannot read property 'length' of undefined
». Мое усилие там, чтобы проанализировать эти данные, проистекает из другой ошибки, которая возникает в точке «svg.append (« путь ») в коде, которая равна« Error: <path> attribute d: Expected number, "MNaN,NaNLNaN,NaNL…
».
Uggghhhh! (: -C). Если в аудитории есть любые наставники D3.js, пожалуйста, помогите мне определить, что я делаю неправильно, и как это исправить. Большое спасибо!
// ============= прилагаемая 01 ========================
I это работало! Yeee Haaaw!
Опубликуйте пересмотренный рабочий код ниже. Но для тех, кто следил за этим сообщением, я хотел объяснить, что я нашел.
Марк в связанном сообщении (Alternatives for using forEeach() loop while converting data for D3.js) предложил изменить dataset.push(), чтобы удалить все кавычки. Это дало мне объекты вместо строк. После некоторого устранения неполадок он, наконец, выглядел так, как ожидалось (полностью псих!), И спасибо Марку, ваши предложения сделали трюк.
Вот пересмотренный код:
//~ Populate the 'dataset': var dataset = []; $.get(url, function(data){ var itemCount = data.Items.length; var commaCount = itemCount - 1; for(i=0; i<itemCount; i++){ dataset.push({theTime: formattedDateTime(data.Items[i].Timestamp), theValue: data.Items[i].Value}); } var margin = {top: 20, right: 20, bottom: 30, left: 50}; var width = 960 - margin.left - margin.right; var height = 500 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y/%m/%d %H:%M:%S").parse; var x = d3.time.scale() .range([0, width]); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var line = d3.svg.line() .x(function(d) { return x(d.theTime); }) .y(function(d) { return y(d.theValue); }); var svg = d3.select("#myChart").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); dataset.forEach(function(d) { d.theTime = parseDate(d.theTime); d.theValue = parseFloat(d.theValue); }); x.domain(d3.extent(dataset, function(d) { return d.theTime; })); y.domain(d3.extent(dataset, function(d) { return d.theValue;})); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("M³/hr"); svg.append("path") .datum(dataset) .attr("class", "line") .attr("d", line); }); //~~~ Format The Date: function formattedDateTime(dateAndTime) { var d = new Date(dateAndTime); var numDate = d.getDate(); var numMonth = d.getMonth() + 1; var numYear = d.getFullYear(); var numHours = d.getHours(); var numMinutes = d.getMinutes(); var numSeconds = d.getSeconds(); numDate = (numDate < 10) ? "0" + numDate : numDate; numMonth = (numMonth < 10) ? "0" + numMonth : numMonth; numHours = (numHours < 10) ? "0" + numHours : numHours; numMinutes = (numMinutes < 10) ? "0" + numMinutes : numMinutes; numSeconds = (numSeconds < 10) ? "0" + numSeconds : numSeconds; return numYear + "/" + numMonth + "/" + numDate + " " + numHours + ":" + numMinutes + ":" + numSeconds; };
Привет @WebFixItMan, вы могли бы совместно использовать объект данных «dataSet» после выполнения цикла for в вершина. Я считаю, что основная причина обеих ошибок связана с выходом функции formattedDateTime. – Alex
Какая версия D3? –
Привет, Алекс и Херардо! Я считаю, что ответ Кирилла отвечает на вопрос Алекса. Для Херардо я использую ссылку CDN: \t '' – WebFixItMan