clientjs/packages/dashboard-components/src/pages/charts.jsx
changeset 0 5f4fcbc80b37
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/clientjs/packages/dashboard-components/src/pages/charts.jsx	Fri Sep 14 17:57:34 2018 +0200
@@ -0,0 +1,116 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+
+import _ from 'lodash';
+import { FormattedMessage } from 'react-intl';
+import { categoryColors } from '../utils';
+
+import RowChart from '../ui/RowChart';
+
+
+/**
+ * TODO: As a first implementation we have chosen to delagate the barchart DOM drawing to D3.
+ * This may not be the optimum solution. This may have to be rewrittten to use
+ * React for elementt creation and D3 as the visualisation kernel. This
+ */
+const ChartsPage = ({ chartsCounts }) => (
+  <div className="col col-12">
+    <div className="row">
+      <h3><FormattedMessage id="charts.metacategories_title" defaultMessage="Metacategories" /></h3>
+    </div>
+    <RowChart {...chartsCounts.metacategories} />
+
+    { (chartsCounts.actions.data.length > 0) && (
+      <div className="row chart-actions-row">
+        <h3><FormattedMessage id="charts.call_to_actions_title" defaultMessage="Call to actions" /></h3>
+      </div>
+    )}
+    { (chartsCounts.actions.data.length > 0) && <RowChart {...chartsCounts.actions} /> }
+
+    { (chartsCounts.categories.data.length > 0) && (
+      <div className="row chart-actions-row">
+        <h3><FormattedMessage id="charts.categories_title" defaultMessage="Categories" /></h3>
+      </div>
+    )}
+    { (chartsCounts.categories.data.length > 0) && <RowChart {...chartsCounts.categories} /> }
+
+  </div>
+);
+
+ChartsPage.propTypes = {
+  chartsCounts: PropTypes.object.isRequired,
+  metacategories: PropTypes.arrayOf(PropTypes.object).isRequired,
+  topics: PropTypes.arrayOf(PropTypes.string).isRequired,
+};
+
+export default connect(
+  (state, props) => {
+    const { topics, metacategories } = props;
+    const annotations = state.annotations.items;
+    const topicsList = topics.map(t => t.toLowerCase());
+    let tagsCount = _.reduce(
+      metacategories,
+      (res, m) => {
+        res[`cat:${m.tag}`] = {
+          id: m.id,
+          count: 0,
+          tag: m.tag,
+          color: categoryColors[m.id],
+        };
+        return res;
+      },
+      {},
+    );
+    tagsCount = _.reduce(
+      annotations,
+      (res, annot) => {
+        annot.tags.forEach((tg) => {
+          const t = tg.toLowerCase();
+          if (t.startsWith('cat:')) {
+            const s = t.substr(4);
+            if (!(t in res)) {
+              res[t] = {
+                id: s,
+                count: 0,
+                tag: s,
+                color: (categoryColors[s] || 'gray'),
+              };
+            }
+            res[t].count += 1;
+          } else if (t.startsWith('need:')) {
+            const s = t.substr(5);
+            if (!(t in res)) {
+              res[t] = {
+                id: s,
+                count: 0,
+                tag: s,
+                color: 'gray',
+              };
+            }
+            res[t].count += 1;
+          } else if (topicsList.includes(t)) {
+            if (!(t in res)) {
+              res[t] = {
+                id: t,
+                count: 0,
+                tag: t,
+                color: 'gray',
+              };
+            }
+            res[t].count += 1;
+          }
+        });
+        return res;
+      },
+      tagsCount,
+    );
+    return {
+      chartsCounts: {
+        metacategories: { data: _.reduce(tagsCount, (res, v, k) => (k.startsWith('cat:') ? [...res, v] : res), []), tagPrefix: 'cat:' },
+        actions: { data: _.reduce(tagsCount, (res, v, k) => (k.startsWith('need:') ? [...res, v] : res), []), tagPrefix: 'need:' },
+        categories: { data: _.reduce(tagsCount, (res, v, k) => (topicsList.includes(k.toLowerCase()) ? [...res, v] : res), []), tagPrefix: '' },
+      },
+    };
+  },
+)(ChartsPage);