过去几年我在MySQL数据库中拥有大量数据。每个行都有一个Timestamp列。这就是我想用于图表中的x轴。
我想要做的是将这些日期分解为逻辑组,并使用正确的日期和与该时间段关联的汇总数据向用户显示图表。用户将能够动态选择日期范围。
我喜欢的是类似的东西:例如,当用户选择今天(或一天的框架)时,我希望软件将数据分解为2小时12个数据集的块(我只有12个空间)。但是,如果他们选择2天,我想将其分成12个相等的部分。如果他们选择15天,3年等,我仍然希望脚本将数据分解为12个(同时汇总行的数据)。
以下是我希望以某种方式动态实现的结果示例。我可以使用MySQL,PHP和Javascript。以下格式只是表示它可以是数组,对象,任何东西:
这是我在数据库中的数据,例如:
id | value | date |
-----------------------------------------
1 | 12 | 2017-01-23 00:13:12 |
2 | 54 | 2017-01-23 08:33:23 |
3 | 45 | 2017-01-23 09:01:57 |
4 | 94 | 2017-01-22 05:17:15 |
5 | 67 | 2017-01-22 10:12:44 |
6 | 3 | 2017-01-22 22:56:54 |
7 | 44 | 2017-01-22 23:27:55 |
8 | 19 | 2017-01-21 15:02:23 |
9 | 8 | 2017-01-21 00:14:54 |
这是我在将数据发送到我的图表之前想要的:
id | value | date |
-----------------------------------------
1 | 12 | 2017-01-23 06:00:00 |
2 | 99 | 2017-01-23 12:00:00 |
3 | 0 | 2017-01-23 18:00:00 |
4 | 0 | 2017-01-23 23:59:59 |
5 | 94 | 2017-01-22 06:00:00 |
6 | 67 | 2017-01-22 12:00:00 |
7 | 0 | 2017-01-22 18:00:00 |
8 | 47 | 2017-01-21 23:59:59 |
9 | 8 | 2017-01-21 06:00:00 |
10 | 0 | 2017-01-21 12:00:00 |
11 | 19 | 2017-01-21 18:00:00 |
12 | 0 | 2017-01-21 23:59:59 |
同样,日期范围并不重要,脚本应自动将其分成12个相等的部分。
知道怎么做到这一点?我在互联网上看到了很多这类图表,必须有一种简单的方法 - 不仅仅是手动编码条件。
答案 0 :(得分:2)
您可以在SQL,PHP和JavaScript中执行此操作。选择实际上是个人偏好的问题。我将在这里给出一个PHP函数来执行它:
function group_data($data, $count) {
usort($data, function ($a, $b) {
return strcmp($a["date"], $b["date"]);
});
$result = [];
$first = new DateTime($data[0]["date"]);
$first->setTime(0, 0); // First group always starts at midnight
$last = new DateTime($data[count($data)-1]["date"]);
// Group size is always an integer number of hours:
$hours = ceil(($first->diff($last)->days + 1) * 24 / $count);
$group_interval = new DateInterval("PT{$hours}H");
while ($count--) { // for each group
$first->add($group_interval); // Increment the date with the fixed group size
$date = $first->format('Y-m-d H:i:s');
// Accumulate the values in the data that precede this date/time:
$value = 0;
while (current($data) && current($data)["date"] < $date) {
$value += current($data)["value"];
next($data); // Move to the next record
}
// Append this group to the result
$result[] = ["id" => count($result)+1, "value" => $value, "date" => $date];
}
return $result;
}
以下是如何使用它的示例。我假设您已经从数据库中选择了数据到关联数组中:
$data = [
["id" => 1, "value" => 12, "date" => "2017-01-23 00:13:12"],
["id" => 2, "value" => 54, "date" => "2017-01-23 08:33:23"],
["id" => 3, "value" => 45, "date" => "2017-01-23 09:01:57"],
["id" => 4, "value" => 94, "date" => "2017-01-22 05:17:15"],
["id" => 5, "value" => 67, "date" => "2017-01-22 10:12:44"],
["id" => 6, "value" => 3, "date" => "2017-01-22 22:56:54"],
["id" => 7, "value" => 44, "date" => "2017-01-22 23:27:55"],
["id" => 8, "value" => 19, "date" => "2017-01-21 15:02:23"],
["id" => 9, "value" => 8, "date" => "2017-01-21 00:14:54"],
];
// Use the function to divide the data into 12 equally sized groups
$result = group_data($data, 12);
运行上面的示例后,$result
变量将包含以下数据:
[
["id" => 1, "value" => 8, "date" => "2017-01-21 06:00:00"],
["id" => 2, "value" => 0, "date" => "2017-01-21 12:00:00"],
["id" => 3, "value" => 19, "date" => "2017-01-21 18:00:00"],
["id" => 4, "value" => 0, "date" => "2017-01-22 00:00:00"],
["id" => 5, "value" => 94, "date" => "2017-01-22 06:00:00"],
["id" => 6, "value" => 67, "date" => "2017-01-22 12:00:00"],
["id" => 7, "value" => 0, "date" => "2017-01-22 18:00:00"],
["id" => 8, "value" => 47, "date" => "2017-01-23 00:00:00"],
["id" => 9, "value" => 12, "date" => "2017-01-23 06:00:00"],
["id" => 10, "value" => 99, "date" => "2017-01-23 12:00:00"],
["id" => 11, "value" => 0, "date" => "2017-01-23 18:00:00"],
["id" => 12, "value" => 0, "date" => "2017-01-24 00:00:00"],
]
答案 1 :(得分:1)
听起来你只需要创建整个数据集的数组
喜欢:
SQL
SELECT * FROM your table
WHERE (date BETWEEN date1 AND date2);
//send data set where you want it
商业逻辑
Array = [...dataset];
function (Array) {
let length= Array.length;
let sectionLength = Math.floor(length / 12);
for ( let i =0; i < length; i++) {
// create bins
if ( i < sectionLength){
//code to summarize array goes here or create new array
}
if ( i >= sectionLength && i < (section length * 2 )) {
// 2nd bin
}
......等等必须解决余数情况,因为它可以在0到12个案例之间排除,因此bin分布将是不同的
`function(array1,array2,array3 ......等{
foreach(论证){
显示器(参数) }` 这只是伪代码,但希望你能得到这个想法