From fc2e6f4062fe3be7342007dec24b2c09ac95b549 Mon Sep 17 00:00:00 2001 From: A Date: Mon, 15 Jan 2018 11:28:41 +0100 Subject: [PATCH] Improves sorting of metric's labels. When selecting the time of metric's points only the time was selected, not the date. The issue with this is mainly in the view "Last 12 hours". Example: It's 11:10 am and I choose the "Last 12 hours" view, the metrics points will be from 23:00 yesterday to 11:00 am today. When giving all these datas and labels to ChartJS, it sorts the points by label from lower to highter. It means 23:00 (from yesterday) will be after the datas of today, it doesn't have sense. To fix it, I've added in the repositories the date in addition to the time. So it's no longer 11:00 that is selected but 2018-01-15 11:00. I've updated the Metric vue in order to cut the label when displaying so it doesn't change the displaying. Because there are metric views that are based on date but not time, there is a condition in the Metric vue to cut the string only if the time is present. Related to CachetHQ/Cachet#2848 --- app/Repositories/Metric/MetricRepository.php | 10 +++++----- app/Repositories/Metric/MySqlRepository.php | 4 ++-- app/Repositories/Metric/PgSqlRepository.php | 4 ++-- app/Repositories/Metric/SqliteRepository.php | 4 ++-- .../assets/js/components/status-page/Metric.vue | 15 ++++++++++++++- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/app/Repositories/Metric/MetricRepository.php b/app/Repositories/Metric/MetricRepository.php index c5bc69bd..3fc7054f 100644 --- a/app/Repositories/Metric/MetricRepository.php +++ b/app/Repositories/Metric/MetricRepository.php @@ -60,7 +60,7 @@ class MetricRepository public function listPointsLastHour(Metric $metric) { $dateTime = $this->dates->make(); - $pointKey = $dateTime->format('H:i'); + $pointKey = $dateTime->format('Y-m-d H:i'); $points = $this->repository->getPointsSinceMinutes($metric, 60)->pluck('value', 'key')->take(60); for ($i = 0; $i <= 60; $i++) { @@ -68,7 +68,7 @@ class MetricRepository $points->put($pointKey, $metric->default_value); } - $pointKey = $dateTime->sub(new DateInterval('PT1M'))->format('H:i'); + $pointKey = $dateTime->sub(new DateInterval('PT1M'))->format('Y-m-d H:i'); } return $points->sortBy(function ($point, $key) { @@ -87,7 +87,7 @@ class MetricRepository public function listPointsToday(Metric $metric, $hours = 12) { $dateTime = $this->dates->make(); - $pointKey = $dateTime->format('H:00'); + $pointKey = $dateTime->format('Y-m-d H:00'); $points = $this->repository->getPointsSinceHour($metric, $hours)->pluck('value', 'key'); for ($i = 0; $i <= $hours; $i++) { @@ -95,9 +95,9 @@ class MetricRepository $points->put($pointKey, $metric->default_value); } - $pointKey = $dateTime->sub(new DateInterval('PT1H'))->format('H:00'); - } + $pointKey = $dateTime->sub(new DateInterval('PT1H'))->format('Y-m-d H:00'); + } return $points->sortBy(function ($point, $key) { return $key; }); diff --git a/app/Repositories/Metric/MySqlRepository.php b/app/Repositories/Metric/MySqlRepository.php index 567da504..8b5488af 100644 --- a/app/Repositories/Metric/MySqlRepository.php +++ b/app/Repositories/Metric/MySqlRepository.php @@ -33,7 +33,7 @@ class MySqlRepository extends AbstractMetricRepository implements MetricInterfac { $queryType = $this->getQueryType($metric); - $points = DB::select("SELECT DATE_FORMAT({$this->getMetricPointsTable()}.`created_at`, '%H:%i') AS `key`, {$queryType} " . + $points = DB::select("SELECT DATE_FORMAT({$this->getMetricPointsTable()}.`created_at`, '%Y-%m-%d %H:%i') AS `key`, {$queryType} " . "FROM {$this->getMetricsTable()} INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id " . "WHERE {$this->getMetricsTable()}.id = :metricId " . "AND {$this->getMetricPointsTable()}.`created_at` >= DATE_SUB(NOW(), INTERVAL :minutes MINUTE) " . @@ -57,7 +57,7 @@ class MySqlRepository extends AbstractMetricRepository implements MetricInterfac public function getPointsSinceHour(Metric $metric, $hour) { $queryType = $this->getQueryType($metric); - $points = DB::select("SELECT DATE_FORMAT({$this->getMetricPointsTable()}.`created_at`, '%H:00') AS `key`, {$queryType} " . + $points = DB::select("SELECT DATE_FORMAT({$this->getMetricPointsTable()}.`created_at`, '%Y-%m-%d %H:00') AS `key`, {$queryType} " . "FROM {$this->getMetricsTable()} INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id " . "WHERE {$this->getMetricsTable()}.id = :metricId " . "AND {$this->getMetricPointsTable()}.`created_at` >= DATE_SUB(NOW(), INTERVAL :hour HOUR) " . diff --git a/app/Repositories/Metric/PgSqlRepository.php b/app/Repositories/Metric/PgSqlRepository.php index 6ffdff53..f79ac4af 100644 --- a/app/Repositories/Metric/PgSqlRepository.php +++ b/app/Repositories/Metric/PgSqlRepository.php @@ -33,7 +33,7 @@ class PgSqlRepository extends AbstractMetricRepository implements MetricInterfac public function getPointsSinceMinutes(Metric $metric, $minutes) { $queryType = $this->getQueryType($metric); - $points = DB::select("SELECT to_char({$this->getMetricPointsTable()}.created_at, 'HH24:MI') AS key, {$queryType} " . + $points = DB::select("SELECT to_char({$this->getMetricPointsTable()}.created_at, 'YYYY-MM-DD HH24:MI') AS key, {$queryType} " . "FROM {$this->getMetricsTable()} INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id " . "WHERE {$this->getMetricsTable()}.id = :metricId " . "AND {$this->getMetricPointsTable()}.created_at >= (NOW() - INTERVAL '{$minutes}' MINUTE) " . @@ -57,7 +57,7 @@ class PgSqlRepository extends AbstractMetricRepository implements MetricInterfac public function getPointsSinceHour(Metric $metric, $hour) { $queryType = $this->getQueryType($metric); - $points = DB::select("SELECT to_char({$this->getMetricPointsTable()}.created_at, 'HH24:00') AS key, {$queryType} " . + $points = DB::select("SELECT to_char({$this->getMetricPointsTable()}.created_at, 'YYYY-MM-DD HH24:00') AS key, {$queryType} " . "FROM {$this->getMetricsTable()} INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id " . "WHERE {$this->getMetricsTable()}.id = :metricId " . "AND {$this->getMetricPointsTable()}.created_at >= (NOW() - INTERVAL '{$hour}' HOUR) " . diff --git a/app/Repositories/Metric/SqliteRepository.php b/app/Repositories/Metric/SqliteRepository.php index 951da5e8..0eb15f0e 100644 --- a/app/Repositories/Metric/SqliteRepository.php +++ b/app/Repositories/Metric/SqliteRepository.php @@ -33,7 +33,7 @@ class SqliteRepository extends AbstractMetricRepository implements MetricInterfa public function getPointsSinceMinutes(Metric $metric, $minutes) { $queryType = $this->getQueryType($metric); - $points = DB::select("SELECT strftime('%H:%M', {$this->getMetricPointsTable()}.`created_at`) AS `key`, {$queryType} " . + $points = DB::select("SELECT strftime('%Y-%m-%d %H:%M', {$this->getMetricPointsTable()}.`created_at`) AS `key`, {$queryType} " . "FROM {$this->getMetricsTable()} " . "INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id " . "WHERE {$this->getMetricsTable()}.id = :metricId " . @@ -58,7 +58,7 @@ class SqliteRepository extends AbstractMetricRepository implements MetricInterfa public function getPointsSinceHour(Metric $metric, $hour) { $queryType = $this->getQueryType($metric); - $points = DB::select("SELECT strftime('%H:00', {$this->getMetricPointsTable()}.`created_at`) AS `key`, {$queryType} " . + $points = DB::select("SELECT strftime('%Y-%m-%d %H:00', {$this->getMetricPointsTable()}.`created_at`) AS `key`, {$queryType} " . "FROM {$this->getMetricsTable()} INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id " . "WHERE {$this->getMetricsTable()}.id = :metricId " . "AND {$this->getMetricPointsTable()}.`created_at` >= datetime('now', '-{$hour} hours') " . diff --git a/resources/assets/js/components/status-page/Metric.vue b/resources/assets/js/components/status-page/Metric.vue index 61fff42a..91cbdc58 100644 --- a/resources/assets/js/components/status-page/Metric.vue +++ b/resources/assets/js/components/status-page/Metric.vue @@ -118,10 +118,23 @@ module.exports = { } //Used in tooltip callback where this.metric is not the same. var metric = this.metric; + /* + * Datetimes are used as keys instead of just time in order to + * improve ordering of labels in "Last 12 hours", so we cut the + * labels. + * This cutting is done only if there is an hour in the string, so + * if the view by day is set it doesn't fail. + */ + var data_keys = _.keys(this.data); + if (0 < data_keys.length && data_keys[0].length > 10) { + for (var i = 0; i < data_keys.length; i++) { + data_keys[i] = data_keys[i].substr(11); + } + } this.chart = new Chart(this.context, { type: 'line', data: { - labels: _.keys(this.data), + labels: data_keys, datasets: [{ data: _.values(this.data), // backgroundColor: "{{ $theme_metrics }}",