2013-03-01 123 views
2

我有其在从MySQL数据库这种格式使用PHP返回此JSON数组:返回平均值/平均,用于为选定值D3.js

[{"dateTimeTaken":"2013-02-28 05:04:16","reading":"10.7","parameterType":"Flouride"}, 
{"dateTimeTaken":"2013-02-28 05:04:21","reading":"10.5","parameterType":"Flouride"}, 
{"dateTimeTaken":"2013-02-28 05:04:26","reading":"15.1","parameterType":"pH"}, 
{"dateTimeTaken":"2013-02-28 05:04:31","reading":"4.4","parameterType":"Temperature"}... 

我有两个下拉列表 - 其中用户将选择)“parameterType”然后b)“月”。我想返回所选参数类型的选定月份内每天的平均值/平均值读数。

不知道我怎么能在D3做到这一点 - 但认为它可能是沿着线的东西:由参数类型

  • 过滤数据和月所选值
  • 回报意味着“读书”
  • 更新图表相应

不知道如果我完全没谱虽然 - 或者我可以怎么连实现这一目标?

UPDATE:

d3.select("#parameterType").on("change", function() { filterData(); }); 

    d3.select("#dateTimeTaken").on("change", function() { filterData(); }); 

    function filterData() 
    { 
     var selectedParameter = document.getElementById("parameterType").value; 
     var selectedMonth = document.getElementById("dateTimeTaken").value; 

     var selectedData = data.filter(function(d) 
     { 
      return d.parameterType == selectedParameter && 
        d.dateTimeTaken.getMonth() == (selectedMonth-1); 
     }); 

     console.log(selectedData);//RETURNING EMPTY ARRAY? 

     mean = d3.mean(selectedData,function(d) { return d.reading}) 

     //UPDATE GRAPH 
     x.domain(d3.extent(data, function(d) { return d.dateTimeTaken; })); 
     y.domain(d3.extent(data, function(d) { return d.reading; })); 

     svg.select("path.line") 
      .attr("d", line(data)); 

     svg.select(".x.axis") 
      .transition() 
      .duration(750) 
      .ease("linear") 
      .call(xAxis); 

     svg.select(".y.axis") 
      .transition() 
      .duration(750) 
      .ease("linear") 
      .call(yAxis); 
    } 
    }); 
    }); 

回答

4

你所寻找的是标准的JavaScript Array.filter方法:

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter

对于每一个 “重绘” 你可以创建一个过滤集:

var selectedData = data.filter(function(d) { 
    return d.parameterType == selectedParameter && 
      +d.dateTimeTaken.slice(5,7) == selectedMonth; 
    }) 

和平均可以通过把一个加号(+)在一个变量的变换为数值尝试的前面容易地计算

mean = d3.mean(selectedData,function(d) { return +d.reading}) 

请注意。

但是现在您可能会意识到使用字符串格式的日期非常不方便。你可以做任何过滤之前做一些预处理:

var dateFmt = d3.time.format("%Y-%m-%d %H:%M:%S"); 

data.forEach(function(d) { 
    d.reading = +d.reading; // convert to number 
    d.dateTimeTaken = dateFmt.parse(d.dateTimeTaken); // convert to javascript date 
}); 

这里我使用的d3.time.format功能将字符串转换成日期一个javascript日期(见https://github.com/mbostock/d3/wiki/Time-Formatting

在这种情况下,您的过滤器(见上文)会稍有不同:

var selectedData = data.filter(function(d) { 
    return d.parameterType == selectedParameter && 
      +d.dateTimeTaken.getMonth() == (selectedMonth-1); 
    }) 

请注意,由于得到月()十二月为0,一月11,我要一个。减去从selectedMonth得到一个适当的比较。

+1

感谢您的建议 - 出于某种原因,我无法工作selectedData正在返回一个空数组?请参阅上面的更新(先前在代码中完成的解析 - 未显示) – Newbie 2013-03-02 17:26:14

+1

如果您的过滤器返回一个空数组,则意味着不符合任何单个元素的条件。您应该检查进入过滤器的值并进行手动比较。字符串需要完全相同(包括大小写和空格)。 – zjonsson 2013-03-04 14:07:00

+0

谢谢 - 在我的查询中,我在下拉列表中选择月份名称作为显示目的 - 当更改为月份(它返回月份编号)完美工作时。将不得不在某个阶段改回月份名称 - 但当我来到它的时候会跨过那座桥:) – Newbie 2013-03-06 21:40:19