From 6c070f81d4b9262f7f71b9954df0e82e54d39a5f Mon Sep 17 00:00:00 2001 From: fred Date: Thu, 21 Apr 2022 17:09:44 +0200 Subject: [PATCH] Add TagCloud Channels data to Homepage --- crowdbunker.sh | 2 + templates/homepage.html | 20 +++ templates/js/tagcloud.js | 264 ++++++++++++++++++++++++++++++++++ templates/styles/tagcloud.css | 40 ++++++ templates/tagcloud.html | 201 ++++++++++++++++++++++++++ tools/get_tagcloud_data.sh | 13 ++ 6 files changed, 540 insertions(+) create mode 100644 templates/js/tagcloud.js create mode 100644 templates/styles/tagcloud.css create mode 100644 templates/tagcloud.html create mode 100755 tools/get_tagcloud_data.sh diff --git a/crowdbunker.sh b/crowdbunker.sh index 61da4fe..aea0030 100755 --- a/crowdbunker.sh +++ b/crowdbunker.sh @@ -403,6 +403,8 @@ echo "########################################################################## sed -i "s~_VUID_~$INDEX/$VUID~g" ~/.zen/bunkerbox/homepage/index.html sed -i "s/_WHO_/$(date -u "+%Y-%m-%d#%H:%M:%S")@$IPFSNODEID/g " ~/.zen/bunkerbox/homepage/index.html sed -i "s~_TITLE_~$TITLE~g" ~/.zen/bunkerbox/homepage/index.html + TAGS=$(${MY_PATH}/tools/get_tagcloud_data.sh $IPNS) + sed -i "s~_TAGCLOUD_~$TAGS~g" ~/.zen/bunkerbox/homepage/index.html # Copy json's cp ~/.zen/bunkerbox/history.json ~/.zen/bunkerbox/homepage/history.json diff --git a/templates/homepage.html b/templates/homepage.html index 5c7dae9..4b2e42e 100644 --- a/templates/homepage.html +++ b/templates/homepage.html @@ -61,6 +61,8 @@
+
+

@@ -158,6 +160,24 @@ function testLatency(cb) { cb(avg); } } + +$(document).ready(function() { + let options = { + container: { + width: 630, + backgroundColor: '#fafaf8', + //fontFamily: '"Times New Roman", Times, serif', + }, + tag: { + format: '{tag.name}: {tag.weight}', + maxFontSize: 41, // max font size in pixels + minFontSize: 8, // min font size in pixels + textShadow: true // enable text shadow + }, + _TAGCLOUD_ + } + $('#channels').tagCloud(options); +}); diff --git a/templates/js/tagcloud.js b/templates/js/tagcloud.js new file mode 100644 index 0000000..6388e72 --- /dev/null +++ b/templates/js/tagcloud.js @@ -0,0 +1,264 @@ +/** + * Tag cloud plugin for jQuery, showing bigger tags in the center + * @version 1.2.0 + * @release 2021-04-07 + * @repository https://github.com/peterthoeny/jquery.tagcloud + * @author Peter Thoeny, https://twiki.org/ & https://github.com/peterthoeny + * @copyright 2021 Peter Thoeny, https://github.com/peterthoeny + * @license MIT, https://opensource.org/licenses/mit-license + */ +(function($) { + + 'use strict'; + + let debug = false; + + function debugLog(msg) { + if(debug) { + console.log('- tagCloud: ' + msg); + } + } + + function entityEncode(val) { + val = val.toString() + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(/'/g, ''') + .replace(//g, '>'); + return val; + } + + $.fn.tagCloud = function(options) { + let self = $(this); + let addLink = options && options.tag && options.tag.format ? false : true; + options = $.extend({}, $.fn.tagCloud.defaults, options); + if(options.debug != undefined) { + debug = options.debug; + } + debugLog('options: ' + JSON.stringify(options, null, '')); + let tagName = self.prop('tagName'); + if(tagName === 'UL') { + if(!options.data) { + options.data = []; + } + self.find('li').each(function(idx, elem) { + let weight = $(elem).data('weight'); + if(weight == undefined) { + weight = $(elem).find(':first-child').data('weight'); + } + let href = $(elem).find('a').attr('href') || ''; + let tag = $(elem).text() || '?'; + debugLog(weight +', '+href+', '+tag+', '+$(elem).html()); + if(options.data[idx]) { + if(weight != undefined) { + options.data[idx].weight = Number(weight); + } + if(href) { + options.data[idx].link = href; + } + options.data[idx].name = tag; + } else { + options.data.push({ name: tag, link: href, weight: Number(weight) }) + } + }); + self.hide(); + if(self.next().hasClass('jqTcContainer')) { + self.next().remove(); + } + self.after('
'); + self = self.next(); + } + let css = {}; + Object.keys(options.container).forEach(function(key) { + css[key] = (options[key] != undefined) ? options[key] : options.container[key]; + }); + self.addClass('jqTcContainer').css(css); + let containerWidth = options.container.width; + let minWeight = 1000000000000; + let maxWeight = -1000000000000; + let minFontSize = options.tag.minFontSize || $.fn.tagCloud.defaults.tag.minFontSize; + let maxFontSize = options.tag.maxFontSize || $.fn.tagCloud.defaults.tag.maxFontSize; + let format = options.tag.format || $.fn.tagCloud.defaults.tag.format; + let sum = 0; + debugLog('minFontSize: '+minFontSize+', maxFontSize: '+maxFontSize); + options.data.forEach(function(item) { + if(item.weight < minWeight) { + minWeight = item.weight; + } + if(item.weight > maxWeight) { + maxWeight = item.weight; + } + sum += item.weight; + }); + let a = (maxFontSize - minFontSize) / (maxWeight - minWeight); + let b = minFontSize - (minWeight * a); + debugLog('minWeight: '+minWeight+', maxWeight: '+maxWeight+', a: '+a+', b: '+b); + let tags = options.data.sort(function(a, b) { + if(a.weight > b.weight) { + return -1; + } else if(a.weight < b.weight) { + return 1; + } + return 0; + }).map(function(item, idx) { + let html = format + .replace(/\{tag\.name\}/g, item.name) + .replace(/\{tag\.link\}/g, item.link) + .replace(/\{tag\.weight(?:\.(\d))?\}/g, function(m, c1) { + let num = item.weight; + if(c1) { + let factor = 10 ** parseInt(c1); + num = Math.round(num * factor) / factor; + } + return num.toString(); + }) + .replace(/\{tag\.percent(?:\.(\d))?\}/g, function(m, c1) { + let num = 100 * item.weight / sum; + let factor = 1; + if(c1) { + factor = 10 ** parseInt(c1); + } + num = Math.round(num * factor) / factor; + return num.toString() + '%'; + }); + if(addLink && item.link) { + html = '' + html + ''; + } + let size = parseInt((a * item.weight + b) * 10, 10) / 10; + let attrs = [ + 'class="jqTcTag"', + 'data-name="' + entityEncode(item.name) + '"', + 'data-link="' + entityEncode(item.link || '') + '"', + 'data-weight="' + item.weight + '"', + 'data-size="' + size + '"' + ]; + let style = 'style="font-size: ' + size + 'px;'; + let bgColor = item.bgColor || item.backgroundColor || options.tag.backgroundColor || + $.fn.tagCloud.defaults.backgroundColors[idx] || $.fn.tagCloud.defaults.defaultTagBackgroundColor; + if(bgColor) { + style += ' background-color: ' + bgColor + ';'; + } + let color = item.color || options.tag.color || $.fn.tagCloud.defaults.defaultTagColor; + if(color != 'auto') { + style += ' color: ' + color + ';'; + } + bgColor + .replace(/^#(.)(.)(.)$/, '#$1$1$2$2$3$3') + .replace(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i, function(m, c1, c2, c3) { + let brightness = Math.round(( + (Number('0x' + c1) * 299) + + (Number('0x' + c2) * 587) + + (Number('0x' + c3) * 114) + ) / 1000); + if(brightness > 125) { + if(color === 'auto') { + style += ' color: black;'; + } + if(options.tag.textShadow) { + style += ' text-shadow: 0px 0px 2px #dddddd;'; + } + } else { + if(color === 'auto') { + style += ' color: white;'; + } + if(options.tag.textShadow) { + style += ' text-shadow: 0px 0px 2px #222222;'; + } + } + }); + style += '"'; + attrs.push(style); + if(item.tooltip) { + attrs.push('title="' + entityEncode(item.tooltip) + '"'); + } + html = '' + html + ''; + self.html(html); // set temporarily to get width and height + let tagElem = self.find('span'); + item.width = tagElem.outerWidth(); + item.height = tagElem.outerHeight(); + item.html = html; + item.ttLength = tagElem.length; + item.ttHtml = self.text(); + return item; + }); + debugLog('tags: ' + JSON.stringify(tags, null, ' ')) + let rows = []; + let cells = []; + let width = 0; + let addRight = true; + let addBottom = true; + let padding = 2 * 5 + 5; + let containerPadding = padding; + let tagMargin = 2 * 10 + 5; + let verticalAlign = 'middle'; + tags.forEach(function(item) { + if(width + item.width + tagMargin >= containerWidth - containerPadding) { + let rowHtml = '' + cells.join('') + ''; + if(addBottom) { + rows.push(rowHtml); + verticalAlign = 'bottom'; + } else { + rows.unshift(rowHtml); + verticalAlign = 'top'; + } + addBottom = !addBottom; + containerPadding += 1.5 * padding; + cells = []; + width = 0; + } + if(addRight) { + cells.push(item.html); + } else { + cells.unshift(item.html); + } + addRight = !addRight; + width = width + item.width + tagMargin; + }); + let rowHtml = '' + cells.join('') + ''; + if(addBottom) { + rows.push(rowHtml); + } else { + rows.unshift(rowHtml); + } + let html = '' + rows.join('') + '
'; + let tagStyle = {}; + Object.keys(options.tag).forEach(key => { + if(!/^(minFontSize|maxFontSize|format|color|textShadow|backgroundColor)$/.test(key)) { + tagStyle[key] = options.tag[key]; + } + }); + self.html(html).find('.jqTcTag').css(tagStyle); + }; + + $.fn.tagCloud.defaults = { + container: { + width: 500, + height: 'auto', + backgroundColor: '#f0f0f0', + color: '#666666', + padding: '10px 5px', + fontFamily: '"Helvetica Neue",Helvetica,Arial,sans-serif' + }, + tag: { + minFontSize: 10, // min font size in pixels + maxFontSize: 40, // max font size in pixels + format: '{tag.name}', // also '{tag.link}', '{tag.weight}', '{tag.percent}' + color: 'auto', // auto text color, black for light background, white for dark background + textShadow: false // text shadow, enable for better visibility + }, + backgroundColors: [ + '#db843d', '#92a8cd', '#a47d7c', '#058dc7', '#50b432', '#ed561b', '#24cbe5', '#64e572', + '#ff9655', '#d6cb54', '#6af9c4', '#b5ca92', '#2f7ed8', '#5c40de', '#8bbc21', '#910000', + '#1aadce', '#492970', '#f28f43', '#77a1e5', '#c42525', '#a6c96a', '#db843d', '#92a8cd', + '#a47d7c', '#058dc7', '#50b432', '#ed561b', '#24cbe5', '#64e572', '#ff9655', '#d6cb54', + '#6af9c4', '#b5ca92', '#2f7ed8', '#5c40de', '#8bbc21', '#910000', '#1aadce', '#492970', + '#f28f43', '#77a1e5', '#c42525', '#a6c96a', '#db843d', '#92a8cd', '#a47d7c', '#058dc7', + '#50b432', '#ed561b', '#24cbe5', '#64e572', '#ff9655', '#d6cb54', '#6af9c4', '#b5ca92', + '#2f7ed8', '#5c40de', '#8bbc21', '#910000', '#1aadce', '#492970', '#f28f43', '#77a1e5' + ], + defaultTagColor: 'auto', // black or white, based on background color + defaultTagBackgroundColor: '#ff9655' // default background color + }; + +})(jQuery); diff --git a/templates/styles/tagcloud.css b/templates/styles/tagcloud.css new file mode 100644 index 0000000..24113c0 --- /dev/null +++ b/templates/styles/tagcloud.css @@ -0,0 +1,40 @@ +/** + * Tag cloud plugin for jQuery, showing bigger tags in the center + * @version 1.2.0 + * @release 2021-04-07 + * @repository https://github.com/peterthoeny/jquery.tagcloud + * @author Peter Thoeny, https://twiki.org/ & https://github.com/peterthoeny + * @copyright 2021 Peter Thoeny, https://github.com/peterthoeny + * @license MIT, https://opensource.org/licenses/mit-license + */ + +.jqTcContainer { +} +.jqTcContainer table { + border-collapse: collapse; + width: 100%; +} +.jqTcContainer td { + padding: 0; + border: 0 none; + text-align: center; + white-space: nowrap; +} +.jqTcTag { + display: inline-block; + margin: 3px 7px; + padding: 3px 10px; + border-radius: 5px; +} +.jqTcTag:hover { + box-shadow: 0 0 5px 1px #aaa; +} +.jqTcTag a { + text-decoration: none; + color: inherit; +} +.jqTcTag a:hover { + text-decoration: underline; +} + +/* EOF */ diff --git a/templates/tagcloud.html b/templates/tagcloud.html new file mode 100644 index 0000000..5ef952f --- /dev/null +++ b/templates/tagcloud.html @@ -0,0 +1,201 @@ + + + + + Demo of jQuery Tag Cloud + + + + + + + +
+

Demo of jQuery Tag Cloud jquery.tagcloud

+

Tag cloud plugin for jQuery, showing bigger tags in the center.

+
+

Example 1: Use li HTML tags to define the tag cloud, and options for custom colors

+ +
+ Tag Cloud + + HTML + + JavaScript +
+ + + + + +
+
+

Example 2: Use an empty div HTML tag, and options to define the tag cloud

+ +
+ Tag Cloud + + HTML + + JavaScript +
+
+
+ + + +
+
+

Repository: + https://github.com/peterthoeny/jquery.tagcloud

+

Author: + https://github.com/peterthoeny

+
+
+ + diff --git a/tools/get_tagcloud_data.sh b/tools/get_tagcloud_data.sh new file mode 100755 index 0000000..42b4811 --- /dev/null +++ b/tools/get_tagcloud_data.sh @@ -0,0 +1,13 @@ +#!/bin/bash +[[ ! $1 ]] && echo "You must provide 'qo-op' IPNS key"&& exit 1 +# echo create data set to include into tagcloud +DATA="" + +for channel in $(ls ~/.zen/bunkerbox/channels); do + + howmuch=$(jq '.Videos | length' ~/.zen/bunkerbox/history.${channel}.json) + DATA="$DATA { name: '"${channel}"', link: '"/ipns/$1/tw/${channel}"', weight: "${howmuch}", tooltip: '"${channel}"' }," + +done + +echo 'data: [ '$DATA' ]'