clientjs/packages/dashboard-components/src/pages/charts.jsx
author ymh <ymh.work@gmail.com>
Thu, 20 Sep 2018 18:45:04 +0200
changeset 15 799d0e9aa1dd
parent 0 5f4fcbc80b37
permissions -rw-r--r--
Added tag 0.2.0 for changeset 521d1a8c7150

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);