FEATURE: adds a new chart report to track pageviews (#6913)

FEATURE: adds a new chart report to track pageviews (#6913)

diff --git a/app/assets/javascripts/admin/components/admin-report-stacked-chart.js.es6 b/app/assets/javascripts/admin/components/admin-report-stacked-chart.js.es6
new file mode 100644
index 0000000..dbc310b
--- /dev/null
+++ b/app/assets/javascripts/admin/components/admin-report-stacked-chart.js.es6
@@ -0,0 +1,127 @@
+import { number } from "discourse/lib/formatter";
+import loadScript from "discourse/lib/load-script";
+
+export default Ember.Component.extend({
+  classNames: ["admin-report-chart", "admin-report-stacked-chart"],
+
+  init() {
+    this._super(...arguments);
+
+    this.resizeHandler = () =>
+      Ember.run.debounce(this, this._scheduleChartRendering, 500);
+  },
+
+  didInsertElement() {
+    this._super(...arguments);
+
+    $(window).on("resize.chart", this.resizeHandler);
+  },
+
+  willDestroyElement() {
+    this._super(...arguments);
+
+    $(window).off("resize.chart", this.resizeHandler);
+
+    this._resetChart();
+  },
+
+  didReceiveAttrs() {
+    this._super(...arguments);
+
+    Ember.run.debounce(this, this._scheduleChartRendering, 100);
+  },
+
+  _scheduleChartRendering() {
+    Ember.run.schedule("afterRender", () => {
+      this._renderChart(this.get("model"), this.$(".chart-canvas"));
+    });
+  },
+
+  _renderChart(model, $chartCanvas) {
+    if (!$chartCanvas || !$chartCanvas.length) return;
+
+    const context = $chartCanvas[0].getContext("2d");
+
+    const chartData = Ember.makeArray(
+      model.get("chartData") || model.get("data")
+    );
+
+    const data = {
+      labels: chartData[0].data.map(cd => cd.x),
+      datasets: chartData.map(cd => {
+        return {
+          label: cd.req,
+          stack: "pageviews-stack",
+          data: cd.data.map(d => Math.round(parseFloat(d.y))),
+          backgroundColor: cd.color
+        };
+      })
+    };
+
+    loadScript("/javascripts/Chart.min.js").then(() => {
+      this._resetChart();
+      this._chart = new window.Chart(context, this._buildChartConfig(data));
+    });
+  },
+
+  _buildChartConfig(data) {
+    return {
+      type: "bar",
+      data,
+      responsive: true,
+      maintainAspectRatio: false,
+      options: {
+        hover: { mode: "index" },
+        tooltips: {
+          mode: "index",
+          intersect: false,
+          callbacks: {
+            title: tooltipItem =>
+              moment(tooltipItem[0].xLabel, "YYYY-MM-DD").format("LL")
+          }
+        },
+        legend: { display: false },
+        layout: {
+          padding: {
+            left: 0,
+            top: 0,
+            right: 0,
+            bottom: 0
+          }
+        },
+        scales: {
+          yAxes: [
+            {
+              stacked: true,
+              display: true,
+              ticks: {
+                userCallback: label => {
+                  if (Math.floor(label) === label) return label;
+                },
+                callback: label => number(label)
+              }
+            }
+          ],
+          xAxes: [
+            {
+              display: true,
+              gridLines: { display: false },
+              type: "time",
+              time: {
+                parser: "YYYY-MM-DD",
+                minUnit: "day"
+              }
+            }
+          ]
+        }
+      }
+    };
+  },
+
+  _resetChart() {
+    if (this._chart) {
+      this._chart.destroy();
+      this._chart = null;
+    }
+  }
+});
diff --git a/app/assets/javascripts/admin/components/admin-report.js.es6 b/app/assets/javascripts/admin/components/admin-report.js.es6
index 2fe345c..2f647f6 100644
--- a/app/assets/javascripts/admin/components/admin-report.js.es6
+++ b/app/assets/javascripts/admin/components/admin-report.js.es6
@@ -34,6 +34,7 @@ function collapseWeekly(data, average) {
     bucket = bucket || { x: data[i].x, y: 0 };
     bucket.y += data[i].y;
   }
+
   return aggregate;
 }
 
@@ -389,7 +390,19 @@ export default Ember.Component.extend({
   _loadReport(jsonReport) {
     Report.fillMissingDates(jsonReport, { filledField: "chartData" });
 
-    if (jsonReport.chartData && jsonReport.chartData.length > 40) {
+    if (jsonReport.chartData && jsonReport.modes[0] === "stacked_chart") {
+      jsonReport.chartData = jsonReport.chartData.map(chartData => {
+        if (chartData.length > 40) {
+          return {
+            data: collapseWeekly(chartData.data),
+            req: chartData.req,
+            color: chartData.color
+          };
+        } else {
+          return chartData;
+        }
+      });
+    } else if (jsonReport.chartData && jsonReport.chartData.length > 40) {
       jsonReport.chartData = collapseWeekly(
         jsonReport.chartData,
         jsonReport.average
diff --git a/app/assets/javascripts/admin/models/report.js.es6 b/app/assets/javascripts/admin/models/report.js.es6
index e5a7634..ae0205b 100644
--- a/app/assets/javascripts/admin/models/report.js.es6
+++ b/app/assets/javascripts/admin/models/report.js.es6
@@ -473,11 +473,26 @@ Report.reopenClass({
         .utc(report[endDate])
         .locale("en")
         .format("YYYY-MM-DD");
-      report[filledField] = fillMissingDates(
-        JSON.parse(JSON.stringify(report[dataField])),
-        startDateFormatted,
-        endDateFormatted
-      );
+
+      if (report.modes[0] === "stacked_chart") {
+        report[filledField] = report[dataField].map(rep => {
+          return {
+            req: rep.req,
+            color: rep.color,
+            data: fillMissingDates(
+              JSON.parse(JSON.stringify(rep.data)),
+              startDateFormatted,
+              endDateFormatted
+            )
+          };
+        });
+      } else {
+        report[filledField] = fillMissingDates(
+          JSON.parse(JSON.stringify(report[dataField])),
+          startDateFormatted,
+          endDateFormatted
+        );
+      }
     }
   },
 
diff --git a/app/assets/javascripts/admin/templates/components/admin-report-stacked-chart.hbs b/app/assets/javascripts/admin/templates/components/admin-report-stacked-chart.hbs
new file mode 100644
index 0000000..9c36cfa
--- /dev/null
+++ b/app/assets/javascripts/admin/templates/components/admin-report-stacked-chart.hbs
@@ -0,0 +1,3 @@
+<div class="chart-canvas-container">
+  <canvas class="chart-canvas" height="250"></canvas>
+</div>
diff --git a/app/assets/javascripts/admin/templates/dashboard_next_general.hbs b/app/assets/javascripts/admin/templates/dashboard_next_general.hbs
index 000fcf1..9921a92 100644
--- a/app/assets/javascripts/admin/templates/dashboard_next_general.hbs
+++ b/app/assets/javascripts/admin/templates/dashboard_next_general.hbs
@@ -15,6 +15,11 @@
       <div class="section-body">
         <div class="charts">
           {{admin-report
+            dataSourceName="consolidated_page_views"
+            forcedModes="stacked-chart"
+            filters=filters}}
+
+          {{admin-report
             dataSourceName="signups"
             showTrend=true
             forcedModes="chart"
diff --git a/app/assets/stylesheets/common/admin/admin_base.scss b/app/assets/stylesheets/common/admin/admin_base.scss
index f462ec2..17ccf65 100644
--- a/app/assets/stylesheets/common/admin/admin_base.scss
+++ b/app/assets/stylesheets/common/admin/admin_base.scss
@@ -998,6 +998,7 @@ table#user-badges {
 @import "common/admin/admin_report";
 @import "common/admin/admin_report_counters";
 @import "common/admin/admin_report_chart";
+@import "common/admin/admin_report_stacked_chart";
 @import "common/admin/admin_report_table";
 @import "common/admin/admin_report_inline_table";
 @import "common/admin/dashboard_previous";
diff --git a/app/assets/stylesheets/common/admin/admin_report_stacked_chart.scss b/app/assets/stylesheets/common/admin/admin_report_stacked_chart.scss
new file mode 100644
index 0000000..bbbd92c
--- /dev/null
+++ b/app/assets/stylesheets/common/admin/admin_report_stacked_chart.scss
@@ -0,0 +1,9 @@
+.admin-report-stacked-chart {
+  display: flex;
+  justify-content: space-between;
+
+  .chart-canvas-container {
+    flex: 5;

[... diff too long, it was truncated ...]

GitHub sha: b95165b8

1 Like

Fix random build error