Skip to content
Snippets Groups Projects
DataTableCondensate.vue 9.58 KiB
Newer Older
<template>
    <div class="mainContent">
        <table :id=id class="table table-striped table-bordered table-hover" width="100%"></table>
    </div>
</template>

<script>
  const _ = require('lodash');
  const $ = window.jQuery = require('jquery');
  require('./js/datatable');

  let table;

  function getRatingValue(data) {
HongKee Moon's avatar
HongKee Moon committed
    return _.max(_.values(data));
  }

  function getRating(data) {
HongKee Moon's avatar
HongKee Moon committed
    const rating = _.max(_.values(data));
    const r = ['<div style="white-space: nowrap;">']
    for (let i = 0; i < 5; i++) {
      if (i < rating) {
        r.push('<span class="fa fa-star checked"/>')
      } else {
        r.push('<span class="fa fa-star"/>')
      }
    }

    r.push('</div>')
    return r;
  }

  export default {
    name: 'data-table',
    props: ['id', 'data', 'category'],
    data() {
      return {
      };
    },
    methods: {
      moveDetailPage(id) {
        const url = `/condensate/${id}`
        // eslint-disable-next-line
        // console.log(url)
        window.open(url)
      },
      createTable(id, data) {
        const vm = this;

        _.forEach(data, (d) => {
          d.DT_RowID = `${d.unique_name}`;
        });

        const columns = [
          {
            title: 'Name',
            data: 'name',
            fnCreatedCell: (nTd, sData, oData) => {
              $(nTd).html(`<a href="" class="detail-link"> ${oData.name}</a>`);
HongKee Moon's avatar
HongKee Moon committed
            title: 'Proteins',
            data: 'proteins',
HongKee Moon's avatar
HongKee Moon committed
            fnCreatedCell: (nTd, sData, oData) => {
              // console.log(sData)
              if(sData) {
                $(nTd).html(sData.length > 4 ? sData.splice(0, 4).join(', ') + ' ...' : sData.join(', '));
              }
            }
          },
          {
            title: 'No. Proteins',
            render: function ( data, type, row, meta ) {
              return row.proteins.length;
            }
          // {
          //   title: 'Biomolecular/Synthetic',
          //   data: 'is_experimental',
          //   render: function ( data, type, row, meta ) {
          //     return data ? 'Synthetic' : 'Biomolecular';
          //   }
          // },
          // {
          //   title: 'Localization',
          //   render: function ( data, type, row, meta ) {
          //     return '(placeholder)';
          //   }
          // },
HongKee Moon's avatar
HongKee Moon committed
          {
            title: 'Evidence Stars',
            data: 'protein_confidence_score',
            render: function ( data, type, row, meta ) {
              return getRatingValue(data);
            },
            fnCreatedCell: (nTd, sData, oData) => {
              // console.log(sData)
              if(sData) {
                $(nTd).html(getRating(sData).join('\n'));
              }
            }
          },
          {
            title: 'Species',
            data: 'species_name',
            render: function ( data, type, row, meta ) {
HongKee Moon's avatar
HongKee Moon committed
              if (data) {
                return data + ' (' + row.species_tax_id + ')';
              } else {
                return 'Chimeras';
              }
            }
          },
        ];

        const nTableOptions = {
          columns,
          aaSorting: [[ 0, 'asc' ]],
          paging: true,
          searching: true,
          info: true,
          data,
          pageLength: 100,
HongKee Moon's avatar
HongKee Moon committed
          order: [[2, 'desc']], // order: [[0, 'asc']],
          bDestroy: true, // Add this property to new setting,
          oLanguage: {
            sSearch: "Filter ",
          dom: '<"row"<"col-sm-8"f><"#download.col-sm-4">><"row"t><"row"<"col-sm-4"i><"col-sm-8"p>>',
          // dom: '<"row"<"col-sm-4"l><"col-sm-6"f><"#download.col-sm-2">><"row"t><"row"<"col-sm-4"i><"col-sm-8"p>>'
        };

        const tableId = `#${id}`;
        if (table) {
          table.destroy();
          $(tableId).empty();
        }

        table = $(tableId).DataTable(nTableOptions);

        $("#download").html('<div style="text-align: right;"><div class="dropdown">\n' +
          '  <button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">\n' +
          '    Download\n' +
          '  </button>\n' +
          '  <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">\n' +
          '    <a class="dropdown-item" href="#" ref="csv">CSV</a>\n' +
          '    <a class="dropdown-item" href="#" ref="tsv">TSV</a>\n' +
          '    <a class="dropdown-item" href="#" ref="json">JSON</a>\n' +
          '  </div>\n' +
          '</div></div>');

        const tableBody = `${tableId} tbody`;

        $(tableBody).on('click', 'tr td a.detail-link', (e) => {
          e.preventDefault()
          const tr = $(e.target).parent().parent();
          const row = table.row(tr);
HongKee Moon's avatar
HongKee Moon committed
          // console.log(row.data())
          vm.moveDetailPage(row.data().canonical_id);
        });

        $('#download').on('click', 'a.dropdown-item', (e) => {
          e.preventDefault()
          switch ($(e.target).text()) {
            case 'CSV':
              vm.downloadCsv(); break;
            case 'TSV':
              vm.downloadTsv(); break;
            case 'JSON':
              vm.downloadJson(); break;
          }
        });
      },
      downloadCsv() {
        const vm = this;
        let exports = [];

        let header = ['Name', 'Canonical ID', 'Biomolecular/Synthetic', 'Species Name', 'Species Tax Id', 'Proteins'];
        exports.push(header.join(', '));

        _.forEach(vm.data, item => {
          let proteins = [];
          _.each(item.proteins, (i) => {
            proteins.push(`${i}`)
          exports.push([`"${item.name}"`, `"${item.canonical_id}"`, `"${item.is_experimental ? 'Syntehtic' : 'Biomolecular'}"`, `"${item.species_name}"`, item.species_tax_id,`"${proteins.join('\t')}"`].join(','));
        })

        let blob = new Blob([exports.join('\n')], {type: 'text/csv'})

        let contentDisposition = 'Content-Disposition: attachment; filename="download-data.csv"'
        let filename = contentDisposition.split('filename=')[1]
        filename = filename.replace(/"/g, '')

        let link = vm.$refs.download
        link.href = window.URL.createObjectURL(blob)
        link.download = filename
        link.click()
      },
      downloadTsv() {
        const vm = this;
        let exports = [];

        let header = ['Name', 'Canonical ID', 'Biomolecular/Synthetic', 'Species Name', 'Species Tax Id', 'Proteins'];
        exports.push(header.join(', '));

        _.forEach(vm.data, item => {
          let proteins = [];
          _.each(item.proteins, (i) => {
            proteins.push(`${i}`)
HongKee Moon's avatar
HongKee Moon committed
          exports.push([item.name, item.canonical_id, item.is_experimental ? 'Synthetic' : 'Biomolecular', item.species_name, item.species_tax_id, proteins.join(', ')].join('\t'));
        })

        let blob = new Blob([exports.join('\n')], {type: 'text/tsv'})

        let contentDisposition = 'Content-Disposition: attachment; filename="download-data.tsv"'
        let filename = contentDisposition.split('filename=')[1]
        filename = filename.replace(/"/g, '')

        let link = vm.$refs.download
        link.href = window.URL.createObjectURL(blob)
        link.download = filename
        link.click()
      },
      downloadJson() {
        const vm = this;
        let blob = new Blob([JSON.stringify(vm.data, null, 2)], {type: 'application/json'})

        let contentDisposition = 'Content-Disposition: attachment; filename="download-data.json"'
        let filename = contentDisposition.split('filename=')[1]
        filename = filename.replace(/"/g, '')

        let link = vm.$refs.download
        link.href = window.URL.createObjectURL(blob)
        link.download = filename
        link.click()
      },
    },
    mounted() {
      const vm = this;
      vm.createTable(vm.id, vm.data);
    },
  };
</script>

<style>
    .mainContent {
      padding: 20px;
    }

    .checked {
      color: orange;
    }
    .no-padding {
      padding: 0;
      font-size: large;
      width: 330px;
    }

    td.pheno-title {
      text-align: center;
    }
    td.pheno {
      width: 33%;
      border-top: none;
      border-bottom: none;
      text-align: center;
      vertical-align: middle;
      font-size: small;
      word-wrap: break-spaces;
    }

    td.pheno-item {
      width: 33%;
      text-align: center;
      border-width: 0 1px;
      word-wrap: break-word;
    }

    .table thead td.pheno {
      border-width: 0 1px;
    }

    table.dataTable.row-border > tbody > tr:first-child > th,
    table.dataTable.row-border > tbody > tr:first-child > td,
    table.dataTable.display > tbody > tr:first-child > th,
    table.dataTable.display > tbody > tr:first-child > td {
      border-top: none;
    }

    table.dataTable.row-border > tbody > tr > th,
    table.dataTable.row-border > tbody > tr > td,
    table.dataTable.display > tbody > tr > th,
    table.dataTable.display > tbody > tr > td {
      border-top: 1px solid #ddd;
    }

    table.dataTable > tbody > tr {
      background-color: #ffffff;
    }

    table.dataTable.row-border > tbody > tr:hover,
    table.dataTable.display > tbody > tr:hover {
      background-color: #f6f6f6;
    .detail-link {
      color: #0065b9;
      font-weight: bold;
    }

    .dropdown-item {
      font-size: 1.2rem;
    }

    select.form-control {
      font-size: 12px;
      padding: 3px 12px;
      font-size: 1.2rem;
    }

    a mark {
        color: #0065b9;
        padding: 0;
        text-decoration: underline;
        font-style: oblique;
    }
</style>