UNPKG

hierarchic-heatmap-table-component

Version:

A visualisation tool for displaying rows in a hiearchic manner with heatmap capabilities

481 lines (399 loc) 18.8 kB
;(function(global) { 'use strict'; var HeatMapTable = function(argv) { return new HeatMapTable.init(argv); } HeatMapTable.prototype = { initHandlebars : function() { var self = this; //Share template for recursively generate children Handlebars.registerPartial('create-children', HBtemplates['templates/src/heatmap-tree.tmpl']); Handlebars.registerHelper('createRow', function(data) { var rowTemplate = HBtemplates['templates/src/heatmap-row.tmpl'] var iconHtml = null; var result = {}; result.rowLabel = data.rowLabel; result.linkURL = data.linkURL; result.linkLabel = data.linkLabel; if (data.children.length > 0 || (data.detailData && data.detailData.length > 0)) { result.iconHtml = '<span class="glyphicon glyphicon-plus"></span>'; } else { result.class = "heatmap-no-cursor"; result.iconHtml ='<span class="glyphicon glyphicon-record"></span>'; } return new Handlebars.SafeString(rowTemplate(result)); }); Handlebars.registerHelper('for', function(n, block) { var accum = ''; for(var i = 0; i < n; ++i) accum += block.fn(i); return accum; }); Handlebars.registerHelper('showValue', function(value, block) { var valueCssClass = ""; if (value.hasOwnProperty("value")) { valueCssClass = value['cssClass']; value = value.value; } var valueTemplate = HBtemplates['templates/src/heatmap-value.tmpl']; var circleTemplate = HBtemplates['templates/src/heatmap-circle.tmpl']; var result = {}; result.tip = value; result.columnWidth = self.columnWidth; result.valueCssClass = valueCssClass; if (self.valueToStyle[value]) { if (self.valueToStyle[value].cssClass) { result.circleColorClass = self.valueToStyle[value].cssClass; } else if (self.valueToStyle[value].color) { result.circleColorStyle = self.valueToStyle[value].color; } else if (self.valueToStyle[value].html) { result.valueStyle = self.valueToStyle[value].html; return new Handlebars.SafeString(valueTemplate(result)); } else { result.circleColorStyle = "black"; return new Handlebars.SafeString(valueTemplate(result)); } } else { return new Handlebars.SafeString(valueTemplate(result)); } result.valueStyle = circleTemplate(result); return new Handlebars.SafeString(valueTemplate(result)); }); Handlebars.registerHelper('addDetail', function(detailData) { return new Handlebars.SafeString(self.detailTemplate(detailData)); }); Handlebars.registerHelper('heatmapCreateHeader', function() { if (self.headerTemplate) { return new Handlebars.SafeString(self.headerTemplate(self.headerTemplateData)); } }); }, showHeatmapBody: function() { $(this.heatmapTable).find(".heatmap-body").remove(); if (this.heatmapBody) { $(this.heatmapTable).append(this.heatmapBody); } else { var template = HBtemplates['templates/src/heatmap-body.tmpl']; this.heatmapBody = template(); $(this.heatmapTable).append(this.heatmapBody); } }, showHeatmapSkeleton: function() { var template = HBtemplates['templates/src/heatmap-skeleton.tmpl']; var setting = {}; setting.isShowExportButton = this.isShowExportButton; $(this.heatmapTable).append(template(setting)); }, showHeatmapRows : function() { var self = this; this.showLoadingStatus(); $(this.heatmapTable).find(".heatmap-rows").empty() var heatmapRowsHTML = $('<ul class="tree heatmap-ul heatmap-rows"></ul>'); for (var i = 0; i < this.data.length; i++) { var row = this.createRow(this.data[i]); heatmapRowsHTML.append(row); } $(this.heatmapTable).find(".heatmap-body").append(heatmapRowsHTML); $(this.heatmapTable).find('.heatmap-rowLabel').click(function () { $(this).find(".glyphicon").toggleClass("glyphicon-plus glyphicon-minus") $(this).parent().parent().children('ul.tree').toggleClass("heatmap-closed heatmap-opened").toggle(300); }); this.hideLoadingStatus(); $('[data-toggle="tooltip"]').tooltip(); }, createRow: function(data) { if (data.html) return data.html; data.childrenHTML = []; if (data.children && data.children.length > 0) { for (var i = 0; i < data.children.length; i++) { var childreRowsHTML = new Handlebars.SafeString(this.createRow(data.children[i])); data.childrenHTML.push(childreRowsHTML); } } data.html = this.heatmapTreeTmpl(data); return data.html; }, initSearchBoxSource: function (data) { this.initSearchBoxSourceList(data); this.rowLabelList = []; for (var key in this.rowLabelDict) { this.rowLabelList.push(key); } var self = this; $.typeahead({ input: '.heatmap-filterByRowName-input', source: { data: this.rowLabelList }, callback: { onClick: function() { $(self.heatmapTable).find(".heatmap-filterByRowName-search").click(); } } }); }, initSearchBoxSourceList: function(data) { for (var i = 0; i < data.length; i++) { this.rowLabelDict[data[i].rowLabel.toLowerCase()] = true; if (data[i].children && data[i].children.length > 0) { this.initSearchBoxSourceList(data[i].children); } } }, expandByFilterString: function(root, filterString, isRoot) { var children = root.children("li"); var found = false; var rowLabel = root.parent().children(".heatmap-row").children(".heatmap-rowLabel").children(".rowLabel").text(); for (var i = 0; i < children.length; i++) { found |= this.expandByFilterString($(children[i]).children(".heatmap-closed"), filterString, false); } if (found && isRoot === false) { root.show() .toggleClass("heatmap-closed heatmap-opened") .parent().children(".heatmap-row").find(".glyphicon").toggleClass("glyphicon-plus glyphicon-minus"); } return found || rowLabel.toLowerCase().indexOf(filterString.toLowerCase()) !== -1 }, initClickEvent : function() { var self = this; //Add the click event of collapseAll button $(self.heatmapTable).find(".heatmap-collapseAll-btn").click(function() { self.showLoadingStatus(); $(self.heatmapTable).find(".heatmap-opened").each(function() { $(this).hide() .toggleClass("heatmap-opened heatmap-closed") .parent().children(".heatmap-row").find(".glyphicon").toggleClass("glyphicon-minus glyphicon-plus"); }); self.hideLoadingStatus(); }); //Add the click event of expandAll button $(self.heatmapTable).find(".heatmap-expandAll-btn").click(function() { self.showLoadingStatus(); $(self.heatmapTable).find(".heatmap-closed").each(function() { $(this).show() .toggleClass("heatmap-closed heatmap-opened") .parent().children(".heatmap-row").find(".glyphicon").toggleClass("glyphicon-plus glyphicon-minus"); }); self.hideLoadingStatus(); }) $(self.heatmapTable).find(".heatmap-reset-btn").click(function() { self.data = self.originData; self.resetHeatMap(); }); $(self.heatmapTable).find(".heatmap-filterByRowName-input").keydown(function(e) { if(e.keyCode==13){ $(self.heatmapTable).find(".heatmap-filterByRowName-search").click(); } }); $(self.heatmapTable).find(".heatmap-filterByRowName-input").keyup(function(e) { if ($(self.heatmapTable).find(".heatmap-filterByRowName-input").val() === "") { self.data = self.originData; self.showHeatmapBody(); self.showHeatmapRows(); } }); $(self.heatmapTable).find(".heatmap-filterByRowName-search").click(function() { var filterString = $(self.heatmapTable).find(".heatmap-filterByRowName-input").val(); if (filterString === "") return ; self.showLoadingStatus(); self.data = self.filterBySearch(self.originData, filterString); self.hideLoadingStatus(); self.showHeatmapBody(); self.showHeatmapRows(); self.expandByFilterString($(self.heatmapTable).find(".heatmap-rows"), filterString, true); if (self.data.length === 0) { $(self.heatmapTable).find(".heatmap-rows").append("<p>No result be found.</p>"); } }); if (self.isShowExportButton) { $(self.heatmapTable).find(".heatmap-export-btn").click(function() { self.download(); }); } $.fn.preBind = function (type, data, fn) { this.each(function () { var $this = $(this); $this.bind(type, data, fn); var currentBindings = $._data(this, 'events')[type]; if ($.isArray(currentBindings)) { currentBindings.unshift(currentBindings.pop()); } }); return this; }; //reset heatmap $(".typeahead__cancel-button").preBind("mousedown", function() { self.data = self.originData; self.resetHeatMap(); }) }, loadJSONData : function(data) { this.originData = data; this.data = this.originData; this.initSearchBoxSource(this.data); }, loadJSONDataFromURL : function(filePath) { var self = this; $.getJSON(filePath, function(data) { self.loadJSONData(data); }); this.initSearchBoxSource(this.data); }, initInitialState: function() { $(".heatmap-filterByRowName-input").text(""); }, clear: function() { $(this.heatmapTable).empty(); }, resetHeatMap: function() { this.clear(); this.showHeatmapSkeleton(); this.initInitialState(); // this.show(true); this.showHeatmapBody(); this.showHeatmapRows(); this.initSearchBoxSource(this.data); this.initClickEvent(); }, show : function() { this.showHeatmapBody(); this.showHeatmapRows(); this.initClickEvent(); if (this.data.length === 0) { this.showNoFoundInfo(); return; } $(this.heatmapTable).find(".heatmap-filterByRowName-search").click(); }, showNoFoundInfo: function() { $(this.heatmapTable).find(".heatmap-rows").append("<p>No result be found.</p>"); }, getValueToStyle: function(valuesSetting) { var valueToStyle = {} for (var i = 0; i < valuesSetting.length; i++) { valueToStyle[valuesSetting[i].value] = {}; if (valuesSetting[i].color) { valueToStyle[valuesSetting[i].value].color = valuesSetting[i].color; } else if (valuesSetting[i].cssClass) { valueToStyle[valuesSetting[i].value].cssClass = valuesSetting[i].cssClass; } else if (valuesSetting[i].html) { valueToStyle[valuesSetting[i].value].html = valuesSetting[i].html; } else { throw "The value" + values[j].value + "has no color or cssClass"; } } return valueToStyle }, filterBySearch: function(data, filterString) { var newDataList = []; for (var i = 0; i < data.length; i++) { var curNewData = {}; for (var key in data[i]) { curNewData[key] = data[i][key]; } curNewData.childrenHTML = null; curNewData.html = null; if (curNewData.rowLabel.toLowerCase().indexOf(filterString.toLowerCase()) !== -1) { newDataList.push(curNewData); } else if (data[i].children && data[i].children.length !== 0) { var newChildren = this.filterBySearch(data[i].children, filterString); if (newChildren.length !== 0) { curNewData.children = newChildren; } else { curNewData.children = []; } if (curNewData.children && curNewData.children.length !== 0) { newDataList.push(curNewData); } } } return newDataList; }, showLoadingStatus: function() { $(".heatmap-info").show(); }, hideLoadingStatus: function() { $(".heatmap-info").hide(); }, download: function() { var csvData = this.getHeaderCsvData(); csvData += this.getRowCsvData(this.data); this.downloadFile("data.csv", csvData); }, downloadFile: function(fileName, csvData) { var aLink = document.createElement('a'); var blob = new Blob([csvData]); var evt = document.createEvent("HTMLEvents"); evt.initEvent("click", false, false); aLink.download = fileName; aLink.href = URL.createObjectURL(blob); aLink.dispatchEvent(evt); }, getHeaderCsvData: function() { var headerData = ""; headerData += "rowLabel"; for (var i = 0; i < this.headerTemplateData.header.length; i++) { headerData += "," + this.headerTemplateData.header[i]; } headerData += "\n"; return headerData; }, getRowCsvData: function(data) { var csvData = ""; for (var i = 0; i < data.length; i++) { csvData += data[i].rowLabel; for (var j = 0; j < data[i].values.length; j++) { csvData += "," + data[i].values[j]; } csvData += "\n"; if (data[i].children && data[i].children.length > 0) { csvData += this.getRowCsvData(data[i].children); } } return csvData; }, hoverEvent: function() { }, activeHoverEvent: function() { } } HeatMapTable.init = function(argv) { this.heatmapTreeTmpl = HBtemplates['templates/src/heatmap-tree.tmpl']; this.heatmapRowsHTML = null; this.dataIndexToHtml = {}; this.rowLabelList = []; this.rowLabelDict = {}; this.originData = []; this.data = []; this.heatmapTable = $("#" + argv.tableID)[0]; if (argv.options) { this.detailTemplateSrc = argv.options.detailTemplateSrc || null; this.headerTemplateSrc = argv.options.headerTemplateSrc || null; this.detailTemplateID = argv.options.detailTemplateID || null; this.headerTemplateID = argv.options.headerTemplateID || null; this.headerTemplateData = argv.options.headerTemplateData || {header: [""]}; this.columnWidth = argv.options.columnWidth || "70px"; this.valueToStyle = this.getValueToStyle(argv.options.valuesSetting); this.isShowExportButton = argv.options.showExportButton || false; } this.initHandlebars(); this.showHeatmapSkeleton(); this.initInitialState(); if (this.detailTemplateID) { var source = $('#'+this.detailTemplateID).html(); this.detailTemplate = Handlebars.compile(source); } if (this.headerTemplateID) { var source = $('#'+this.headerTemplateID).html(); this.headerTemplate = Handlebars.compile(source); } if (this.detailTemplateSrc) { this.detailTemplate = Handlebars.compile(this.detailTemplateSrc); } if (this.headerTemplateSrc) { this.headerTemplate = Handlebars.compile(this.headerTemplateSrc); } } HeatMapTable.init.prototype = HeatMapTable.prototype; global.HeatMapTable = HeatMapTable; }(window));