如何动态生成图表的日期/时间值?

时间:2018-01-05 22:03:18

标签: javascript php mysql charts

过去几年我在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个相等的部分。

知道怎么做到这一点?我在互联网上看到了很多这类图表,必须有一种简单的方法 - 不仅仅是手动编码条件。

2 个答案:

答案 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(论证){

显示器(参数)    }` 这只是伪代码,但希望你能得到这个想法