Skip to content
Snippets Groups Projects
SpeciesChart.vue 3.25 KiB
<template>
  <div>
    <h3 class="text-center text-2xl font-bold">
      Proteins
    </h3>
    <div
      ref="proteinChart"
      class="chart"
    />
    <div
      id="legenddiv"
      class="legend"
    />

    <h3 class="text-center text-2xl font-bold">
      Condensates
    </h3>
    <div
      ref="condensateChart"
      class="chart"
    />
    <div
      id="legend-pie-div"
      class="legend"
    />
  </div>
</template>

<script>
// require modules
/* eslint-disable no-unused-vars */

const _ = require('lodash');
const am4core = require('@amcharts/amcharts4/core');
const am4charts = require('@amcharts/amcharts4/charts');
const am4themesAnimated = require('@amcharts/amcharts4/themes/animated').default;

am4core.useTheme(am4themesAnimated);

export default {
  name: "SpeciesChart",
  components: {
  },
  props: ["protein", "condensate"],
  data() {
    return {
    }
  },
  mounted() {
    am4core.options.autoDispose = true;
    this.drawProteinPieChart();
    this.drawCondensatePieChart();
  },
  methods: {
    drawPieChart(chartRef, legendDiv, data) {
      const chart = am4core.create(chartRef, am4charts.PieChart3D);
      chart.hiddenState.properties.opacity = 0; // this creates initial fade-in

      // console.log(series);
      const filter = 10;
      let d = _.filter(data, c => c.count > filter)

      let etcTotal = _.reduce(_.filter(data, c => c.count < filter), (sum, n) => sum + n.count, 0);
      chart.data = _.concat(d, {'_id': `ETC (≤ ${filter})`, 'total': etcTotal})
      // chart.data = _.orderBy(data, ['total'], ['desc']);

      const pieSeries = chart.series.push(new am4charts.PieSeries3D());
      pieSeries.dataFields.value = 'count';
      pieSeries.dataFields.category = '_id';

      // chart.innerRadius = am4core.percent(40);
      // Add a legend
      chart.legend = new am4charts.Legend();
      chart.legend.labels.template.text = '{category}:';
      chart.legend.valueLabels.template.text = '{value} ({value.percent.formatNumber("#.0")}%)';

      const legendContainer = am4core.create(legendDiv, am4core.Container);
      legendContainer.width = am4core.percent(100);
      legendContainer.height = am4core.percent(100);
      chart.legend.parent = legendContainer;

      function resizeLegend() {
        const el = document.getElementById(legendDiv);
        if (el) {
          // eslint-disable-next-line
          const newHeight = chart.legend.contentHeight + 'px';
          if (el.style.height !== newHeight) {
            el.style.height = newHeight;
            setTimeout(() => {
              chart.legend.labels.template.width = am4core.percent(100);
            }, 100);
          }
        }
      }

      chart.legend.events.on('sizechanged', resizeLegend);
      chart.legend.events.on('datavalidated', resizeLegend);
      chart.legend.labels.template.truncate = false;
    },
    drawProteinPieChart() {
      const vm = this;

      vm.drawPieChart(vm.$refs.proteinChart, 'legenddiv', vm.protein)
    },
    drawCondensatePieChart() {
      const vm = this;

      vm.drawPieChart(vm.$refs.condensateChart, 'legend-pie-div', vm.condensate)
    }
  }
}
</script>

<style scoped>
.mainContent {
  padding: 20px;
}
.chart {
  width: 100%;
  height: 500px;
}

.legend {
  width: 100%;
  border: 1px dotted #c99;
  margin: 1em 0;
}
</style>