From 942602564d67c4b0980e374f1593f79f06d8a329 Mon Sep 17 00:00:00 2001 From: betsy Date: Tue, 6 Oct 2020 11:21:52 +1000 Subject: [PATCH 01/10] Bring in line with code on RankFlow website --- vis.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vis.js b/vis.js index cd82fd5..499f01b 100644 --- a/vis.js +++ b/vis.js @@ -54,7 +54,7 @@ function startVis(_valname,_w,_h) { calculateFactors(_valname); - _barspacing = Math.round((c_width - (_slicecount * _barwidth)) / (_slicecount - 1)) - _rightspacing; + _barspacing = Math.round((c_width - _rightspacing) / _slicecount); _slices = new Object; _lines = new Object; From e7edd3c445724b672d51809a7908602226c9cb9e Mon Sep 17 00:00:00 2001 From: betsy Date: Tue, 6 Oct 2020 15:12:27 +1000 Subject: [PATCH 02/10] Parsing of three columns works on index page --- index.html | 68 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/index.html b/index.html index 2b7a104..57e650b 100644 --- a/index.html +++ b/index.html @@ -40,17 +40,33 @@ var _h = $("#vis_height").val(); var _labels = {}; - var _valname = "uservariable"; - var _it = 2; - - var _rbo_p = parseFloat($("#vis_alpha").val()); - - var _tmpelements = _rows[1].split("\t") - _singlerow = (isNaN(parseInt(_tmpelements[1]))) ? true:false; - if(_singlerow == true) { + + var _values = 0; + var _tmpelements = _rows[1].split("\t"); + + if (isNaN(parseInt(_tmpelements[1]))) { + _values = 0; _makelog = false; - _it = 1; + } else if (isNaN(parseInt(_tmpelements[2]))) { + _values = 1; + } else { + _values = 2; } + + var _it = _values + 1; + + var _valnames = []; + if (_values > 0) { + var _tmpelements = _rows[0].split("\t") + if (_values >= 1) { + _valnames [0] = _tmpelements[1]; + } + if (_values >= 2) { + _valnames [1] = _tmpelements[2]; + } + } + + var _rbo_p = parseFloat($("#vis_alpha").val()); // HTML table output @@ -70,25 +86,41 @@ _labels[j] = _elements[j]; _html += '' + _elements[j] + ''; - if(!_singlerow) { + if(_values > 0) { _html += '' + _elements[j+1] + ''; } + if(_values > 1) { + _html += '' + _elements[j+2] + ''; + } } else { var _tmp = {}; - var _tmpvalue = ($("#vis_ranksize").is(":checked")) ? _rows.length-i:1; - _tmp[_valname] = (_singlerow) ? _tmpvalue:parseInt(_elements[j+1]); - if(_makelog == true) { - var _newvalname = "log(uservariable)"; - _tmp[_newvalname] = Math.round(Math.log(parseInt(_elements[j+1])) * 10); + if (_values == 0) { + _tmp["value"] = ($("#vis_ranksize").is(":checked")) ? _rows.length-i:1; } + if (_values > 0) { + _tmp[_valnames[0]] = parseInt(_elements[j+1]); + if (_makelog == true) { + _tmp["log("+ _valnames[0] + ")"] = Math.round(Math.log(parseInt(_elements[j+1])) * 10); + } + } + if (_values > 1) { + _tmp[_valnames[1]] = parseInt(_elements[j+2]); + if (_makelog == true) { + _tmp["log("+ _valnames[1] + ")"] = Math.round(Math.log(parseInt(_elements[j+2])) * 10); + } + } + _data[_labels[j]][_elements[j]] = _tmp; _html += '' + _elements[j] + ''; - if(!_singlerow) { + if(_values > 0) { _html += '' + _elements[j+1] + ''; } + if(_values > 1) { + _html += '' + _elements[j+2] + ''; + } } } @@ -154,7 +186,7 @@ _rbdout += ''; $("#vis_rbd").html(_rbdout); - var _startval = (_makelog) ? _newvalname:_valname; + var _startval = (_makelog) ? "log("+ _valnames[0] + ")":_valnames[0]; startVis(_startval,_w,_h); } @@ -240,7 +272,7 @@

RankFlow

the logarithm checkbox for better display.

You can either use data that is merely a collection of ranked items (tab separated single columns, example) - or combinations of items and a value (tab separated list of two columns, example).

+ or combinations of items and one or two values (tab separated list of two or three columns, example).

This tool also calculates the Rank-Biased Distance (RBD) metric to quantify changes from one slice to the next. The higher the RBD value, the more change. The "RBD p" parameter (value is between 0.01 and 0.99) below allows to determine how "top-weighed" the calculation should be. With a small p, changes at the top of the lists are weighed more strongly, with p approaching 1 all changes are treated the same. Calculations are based on William Webber, Alistair Moffat, and Justin Zobel (2010) From 594c542b9802bff349ec470b86366cd2b0af2c97 Mon Sep 17 00:00:00 2001 From: betsy Date: Mon, 12 Oct 2020 12:28:32 +1000 Subject: [PATCH 03/10] Allow third column to be used for colours --- index.html | 2 +- vis.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index 57e650b..bbe8a2c 100644 --- a/index.html +++ b/index.html @@ -187,7 +187,7 @@ $("#vis_rbd").html(_rbdout); var _startval = (_makelog) ? "log("+ _valnames[0] + ")":_valnames[0]; - startVis(_startval,_w,_h); + startVis(_startval, _valnames[1],_w,_h); } diff --git a/vis.js b/vis.js index 499f01b..f7cd33a 100644 --- a/vis.js +++ b/vis.js @@ -1,4 +1,4 @@ -function startVis(_valname,_w,_h) { +function startVis(_sizevaluename, _colourvaluename,_w,_h) { // variables to modify c_width = parseInt(_w); @@ -18,8 +18,8 @@ function startVis(_valname,_w,_h) { // do not modify _topalign = false; - _colorMetric = _valname; - _mainVar = _valname; + _colorMetric = _colourvaluename; + _mainVar = _sizevaluename; _slicecount = 0; _bottomspacing = 5; _topspacing = 15; @@ -47,12 +47,12 @@ function startVis(_valname,_w,_h) { } - createInterface(_valname); + createInterface(_mainVar); _pf = 0; // pixelfactor _cf = 0; // colorfactor - calculateFactors(_valname); + calculateFactors(_mainVar); _barspacing = Math.round((c_width - _rightspacing) / _slicecount); From 8f31f92981bd0bf6404e5bbdb882364a018b2fc0 Mon Sep 17 00:00:00 2001 From: Boyd Nguyen Date: Tue, 15 Nov 2022 12:59:47 +1000 Subject: [PATCH 04/10] add custom colour coding --- index.html | 286 ++++++++++-------- vis.js | 842 ++++++++++++++++++++++++++++------------------------- 2 files changed, 609 insertions(+), 519 deletions(-) diff --git a/index.html b/index.html index bbe8a2c..47e89ee 100644 --- a/index.html +++ b/index.html @@ -3,47 +3,55 @@ - + RankFlow - + - + - + - + - + - + @@ -270,14 +311,14 @@

RankFlow

This is a visualization tool that allows for analyzing changes in ranked and (if desired) valued lists over time. To try it out, download this file and paste the first 15 row or so (including the first row) from Excel into the textarea below. This file contains the top ranked videos on YouTube for the query "syria" on five consecutive days, as well as the viewcount for each video. Use the logarithm checkbox for better display.

- +

You can either use data that is merely a collection of ranked items (tab separated single columns, example) or combinations of items and one or two values (tab separated list of two or three columns, example).

- +

This tool also calculates the Rank-Biased Distance (RBD) metric to quantify changes from one slice to the next. The higher the RBD value, the more change. The "RBD p" parameter (value is between 0.01 and 0.99) below allows to determine how "top-weighed" the calculation should be. With a small p, changes at the top of the lists are weighed more strongly, with p approaching 1 all changes are treated the same. Calculations are based on William Webber, Alistair Moffat, and Justin Zobel (2010) "A similarity measure for indefinite rankings." ACM Transactions on Information Systems 28(4), 20. (ACM library / preprint)

- +

The source code of this tool is available here.

@@ -289,23 +330,20 @@

RankFlow

RBD p:

- +

- +

- +

- +

- +

- - - \ No newline at end of file diff --git a/vis.js b/vis.js index f7cd33a..15d9554 100644 --- a/vis.js +++ b/vis.js @@ -1,25 +1,25 @@ -function startVis(_sizevaluename, _colourvaluename,_w,_h) { +function startVis(_sizevaluename, _colourvaluename, _w, _h) { // variables to modify c_width = parseInt(_w); c_height = parseInt(_h); - + _barwidth = 12; _lineopacity = 0.35; _linedist = 0; _heightfactor = 2; _heightpadding = 5; _minblockheight = 3; - + _constrokecol = "#fff"; _constrokewidth = "1px"; _blostrokecolor = "#000"; _blostrokewidth = "1px"; - + // do not modify _topalign = false; _colorMetric = _colourvaluename; - _mainVar = _sizevaluename; + _mainVar = _sizevaluename; _slicecount = 0; _bottomspacing = 5; _topspacing = 15; @@ -32,452 +32,504 @@ function startVis(_sizevaluename, _colourvaluename,_w,_h) { _highestel = 0; _lowestel = 100000000000000000000000000; _labels = false; - + $("#visualization").html(""); - $("#visualization").css("width",(c_width + 30) + "px"); + $("#visualization").css("width", (c_width + 30) + "px"); $("#visualization").css("visibility", "visible"); $("#vis_interface").css("visibility", "visible"); $("#vis_svg").css("visibility", "visible"); - + _slicecounter = 0; - for(var _slice in _data) { - _slicecounter++; - _rowcounter = 0; - for(var _word in _data[_slice]) { _rowcounter++; } + for (var _slice in _data) { + _slicecounter++; + _rowcounter = 0; + for (var _word in _data[_slice]) { + _rowcounter++; + } } - - + + createInterface(_mainVar); - - _pf = 0; // pixelfactor - _cf = 0; // colorfactor - + + _pf = 0; // pixelfactor + _cf = 0; // colorfactor + calculateFactors(_mainVar); - - _barspacing = Math.round((c_width - _rightspacing) / _slicecount); - - _slices = new Object; + + _barspacing = Math.round((c_width - _rightspacing) / _slicecount); + + _slices = new Object; _lines = new Object; _linescon = new Object; _connectors = new Object; _labels = new Object; - + _sortdata = _data; - + r = null; - + createCanvas(); drawvis(_sortdata); colorcode(_colorMetric); -} - - -function createInterface(_valname) { - + } + + + function createInterface(_valname) { + // finding the highest bar and ordering the words in each slice by their value - for(var _slice in _data) { - _slicecount++; - _barheights[_slice] = 0; - _dataarray[_slice] = new Array; - for(var _word in _data[_slice]) { - _barheights[_slice] += _data[_slice][_word][_valname]; - var _tmphash = new Array(_word, _data[_slice][_word]); - //console.log(_tmphash); - _dataarray[_slice].push(_tmphash); - _highestel = (_data[_slice][_word][_valname] > _highestel ) ? _data[_slice][_word][_valname]:_highestel; - _lowestel = (_data[_slice][_word][_valname] < _lowestel) ? _data[_slice][_word][_valname]:_lowestel; - } - - _highest = (_barheights[_slice] > _highest ) ? _barheights[_slice]:_highest; - _lowest = (_barheights[_slice] < _lowest) ? _barheights[_slice]:_lowest; - - _dataarray[_slice].sort(function(a,b) { - return b[1][_valname] - a[1][_valname]; - }); - - _dataSortSize[_slice] = new Object; // clear old object and write new - for(var _key in _dataarray[_slice]) { - - _dataSortSize[_slice][_dataarray[_slice][_key][0]] = new Object; - - for(var _metric in _dataarray[_slice][_key][1]) { - _dataSortSize[_slice][_dataarray[_slice][_key][0]][_metric] = _dataarray[_slice][_key][1][_metric]; - } - } + for (var _slice in _data) { + _slicecount++; + _barheights[_slice] = 0; + _dataarray[_slice] = new Array; + for (var _word in _data[_slice]) { + _barheights[_slice] += _data[_slice][_word][_valname]; + var _tmphash = new Array(_word, _data[_slice][_word]); + //console.log(_tmphash); + _dataarray[_slice].push(_tmphash); + _highestel = (_data[_slice][_word][_valname] > _highestel) ? _data[_slice][_word][_valname] : _highestel; + _lowestel = (_data[_slice][_word][_valname] < _lowestel) ? _data[_slice][_word][_valname] : _lowestel; + } + + _highest = (_barheights[_slice] > _highest) ? _barheights[_slice] : _highest; + _lowest = (_barheights[_slice] < _lowest) ? _barheights[_slice] : _lowest; + + _dataarray[_slice].sort(function (a, b) { + return b[1][_valname] - a[1][_valname]; + }); + + _dataSortSize[_slice] = new Object; // clear old object and write new + for (var _key in _dataarray[_slice]) { + + _dataSortSize[_slice][_dataarray[_slice][_key][0]] = new Object; + + for (var _metric in _dataarray[_slice][_key][1]) { + _dataSortSize[_slice][_dataarray[_slice][_key][0]][_metric] = _dataarray[_slice][_key][1][_metric]; + } + } } - - + + var _ihtml = 'Color coding: ' + + ' show labels '; + + if (!_singlerow) { + _ihtml += ' sort by value' + + ' align on top'; } - - _ihtml += ''+ - ' show labels '; - - if(!_singlerow) { - _ihtml += ' sort by value'+ - ' align on top'; } - + $("#vis_interface").html(_ihtml); -} - - -function calculateFactors(_valname) { - + } + + + function calculateFactors(_valname) { + // calculating the pixelfactor, colorfactor and normalizing data _pf = (c_height - _bottomspacing - _topspacing - (_heightpadding * _rowcounter)) / _highest; _cf = (_highestel * _pf) / 200; - for(var _slice in _data) { - _barheights[_slice] = 0; - for(var _word in _data[_slice]) { - _data[_slice][_word]["height"] = Math.round(_data[_slice][_word][_valname] * _pf); - if(_data[_slice][_word]["height"] < _minblockheight) { _data[_slice][_word]["height"] = _minblockheight; } - _dataSortSize[_slice][_word]["height"] = Math.round(_dataSortSize[_slice][_word][_valname] * _pf); - if(_dataSortSize[_slice][_word]["height"] < _minblockheight) { _dataSortSize[_slice][_word]["height"] = _minblockheight;} - _barheights[_slice] += _data[_slice][_word]["height"] + _heightpadding; - if((_barheights[_slice] + _bottomspacing + _topspacing) > c_height) { c_height = _barheights[_slice] + _bottomspacing + _topspacing; } - } + for (var _slice in _data) { + _barheights[_slice] = 0; + for (var _word in _data[_slice]) { + _data[_slice][_word]["height"] = Math.round(_data[_slice][_word][_valname] * _pf); + if (_data[_slice][_word]["height"] < _minblockheight) { + _data[_slice][_word]["height"] = _minblockheight; + } + _dataSortSize[_slice][_word]["height"] = Math.round(_dataSortSize[_slice][_word][_valname] * _pf); + if (_dataSortSize[_slice][_word]["height"] < _minblockheight) { + _dataSortSize[_slice][_word]["height"] = _minblockheight; + } + _barheights[_slice] += _data[_slice][_word]["height"] + _heightpadding; + if ((_barheights[_slice] + _bottomspacing + _topspacing) > c_height) { + c_height = _barheights[_slice] + _bottomspacing + _topspacing; + } + } } console.log(c_height); -} - - -function createCanvas() { + } + + + function createCanvas() { _leftspacing = (_highest.toString().length * 8) + 5; - + r = Raphael(document.getElementById("visualization"), c_width + 30, c_height); - r.path("M" + a(_leftspacing - 5) + " " + a(c_height) + "L" + a(_leftspacing - 5) + " " + a(0)).attr({stroke: "#000"}); - - r.canvas.onclick = function() { - for(var _line in _lines) { - for(var i = 0; i < _lines[_line].length; i++) { - _lines[_line][i].color(_lines[_line][i].concol); - //console.log(_lines[_line][i].concol); - if(_lines[_line][i].label) { - _lines[_line][i].labelon = false; - _lines[_line][i].label.remove(); - } - } - } + r.path("M" + a(_leftspacing - 5) + " " + a(c_height) + "L" + a(_leftspacing - 5) + " " + a(0)).attr({ + stroke: "#000" + }); + + r.canvas.onclick = function () { + for (var _line in _lines) { + for (var i = 0; i < _lines[_line].length; i++) { + _lines[_line][i].color(_lines[_line][i].concol); + //console.log(_lines[_line][i].concol); + if (_lines[_line][i].label) { + _lines[_line][i].labelon = false; + _lines[_line][i].label.remove(); + } + } + } } - - var _bottomLabel = r.text(_leftspacing-10,(c_height - 9),"0").attr("text-anchor","end"); - var _topLabel = r.text(_leftspacing-10,20,_highest).attr("text-anchor","end"); -} - - -function drawvis(_data) { - + + var _bottomLabel = r.text(_leftspacing - 10, (c_height - 9), "0").attr("text-anchor", "end"); + var _topLabel = r.text(_leftspacing - 10, 20, _highest).attr("text-anchor", "end"); + } + + + function drawvis(_data) { + + console.log(_data) + var i = 0; var _wordlisthtml = ""; - + _lines = new Object; - - for(var _slice in _data) { - - if(typeof(_slices[_slice]) == "undefined") { - _slices[_slice] = new Object; - } - - var j = 0; - var _pos = 0; - - if(typeof(_labels[_slice]) == "undefined") { - _labels[_slice] = r.text(_leftspacing + _barspacing * i,5,_slice).attr("text-anchor","start"); - } - - /* - var _tmpkeys = Object.keys(_data[_slice]); - if(_top == true) { - console.log(_tmpkeys); - //_tmpkeys.reverse(); - console.log(_tmpkeys); - } - */ - - for(var _block in _data[_slice]) { - - if(_topalign == true) { - var tmp_y = _pos + _topspacing + (_heightpadding * j); - } else { - var tmp_y = c_height - _bottomspacing - _barheights[_slice] + (_heightpadding * j) + _pos; - } - - if(typeof(_slices[_slice][_block]) == "undefined") { - _slices[_slice][_block] = new block(_slice,_leftspacing + _barspacing * i,tmp_y,_data[_slice][_block],_block); - _slices[_slice][_block].draw(); - } else { - _slices[_slice][_block].move(tmp_y); - } - - - _pos += _data[_slice][_block]["height"]; - j++; - - if(typeof(_lines[_block]) == "undefined") { - _lines[_block] = new Array(); - } - - _lines[_block].push(_slices[_slice][_block]); - } - - i++; + + for (var _slice in _data) { + + if (typeof (_slices[_slice]) == "undefined") { + _slices[_slice] = new Object; + } + + var j = 0; + var _pos = 0; + + if (typeof (_labels[_slice]) == "undefined") { + _labels[_slice] = r.text(_leftspacing + _barspacing * i, 5, _slice).attr("text-anchor", "start"); + } + + /* + var _tmpkeys = Object.keys(_data[_slice]); + if(_top == true) { + console.log(_tmpkeys); + //_tmpkeys.reverse(); + console.log(_tmpkeys); + } + */ + + for (var _block in _data[_slice]) { + + if (_topalign == true) { + var tmp_y = _pos + _topspacing + (_heightpadding * j); + } else { + var tmp_y = c_height - _bottomspacing - _barheights[_slice] + (_heightpadding * j) + _pos; + } + + if (typeof (_slices[_slice][_block]) == "undefined") { + _slices[_slice][_block] = new block(_slice, _leftspacing + _barspacing * i, tmp_y, _data[_slice][_block], _block); + _slices[_slice][_block].draw(); + } else { + _slices[_slice][_block].move(tmp_y); + } + + + _pos += _data[_slice][_block]["height"]; + j++; + + if (typeof (_lines[_block]) == "undefined") { + _lines[_block] = new Array(); + } + + _lines[_block].push(_slices[_slice][_block]); + } + + i++; } - + $("#wordlist").html(_wordlisthtml); - + //console.log(_lines); - - for(var _word in _lines) { - - if(typeof(_linescon[_word]) == "undefined") { - _linescon[_word] = new Array; - } - - for(var i = 1; i < _lines[_word].length; i++) { - if(typeof(_linescon[_word][i - 1]) == "undefined") { - _linescon[_word][i - 1] = new connector(_lines[_word][i],_lines[_word][i-1]); - _linescon[_word][i - 1].draw(); - } else { - _linescon[_word][i - 1].move(); - } - } + + for (var _word in _lines) { + + if (typeof (_linescon[_word]) == "undefined") { + _linescon[_word] = new Array; + } + + for (var i = 1; i < _lines[_word].length; i++) { + if (typeof (_linescon[_word][i - 1]) == "undefined") { + _linescon[_word][i - 1] = new connector(_lines[_word][i], _lines[_word][i - 1]); + _linescon[_word][i - 1].draw(); + } else { + _linescon[_word][i - 1].move(); + } + } } -} - - -function colorcode(_sel) { - + } + + + function colorcode(_sel) { + _colorMetric = _sel; - + console.log(_sel); - + var _tmphighest = 0; var _tmplowest = 10000000000000000; - - for(var _slice in _data) { - for(var _word in _data[_slice]) { - var _tmphighest = (parseInt(_data[_slice][_word][_colorMetric]) > _tmphighest) ? _data[_slice][_word][_colorMetric]:_tmphighest; - var _tmplowest = (parseInt(_data[_slice][_word][_colorMetric]) < _tmplowest) ? _data[_slice][_word][_colorMetric]:_tmplowest; - } - } - - //console.log(_tmplowest + " / " + _tmphighest); - - var _cf = _tmphighest / 100; - - for(var _line in _lines) { - for(var i = 0; i < _lines[_line].length; i++) { - - var _tmpcol = "rgb(" + (Math.round(_lines[_line][i].values[_colorMetric] / _cf * 2)) + "," + (Math.round(200 - (_lines[_line][i].values[_colorMetric] / _cf * 2))) + "," + (Math.round(255 - (_lines[_line][i].values[_colorMetric] / _cf * 2))) + ")"; - - //console.log(_lines[_line][i].values[_colorMetric] + " " + _tmpcol); - _lines[_line][i].concol = _tmpcol; - _lines[_line][i].color(_tmpcol); - } - } - - for(var _word in _linescon) { - for(var _con in _linescon[_word]) { - _linescon[_word][_con].color(); - } + + if (_colorMetric == "colour") { + + tmp_colour = new Object; + + for (var _slide in _data) { + for (var _entity in _data[_slide]) { + tmp_colour[_entity] = _data[_slide][_entity]["colour"]; + } + + } + + for (var _line in _lines) { + for (var i = 0; i < _lines[_line].length; i++) { + _lines[_line][i].concol = tmp_colour[_line]; + _lines[_line][i].color(tmp_colour[_line]); + } + } + + } else { + for (var _slice in _data) { + for (var _word in _data[_slice]) { + var _tmphighest = (parseInt(_data[_slice][_word][_colorMetric]) > _tmphighest) ? _data[_slice][_word][_colorMetric] : _tmphighest; + var _tmplowest = (parseInt(_data[_slice][_word][_colorMetric]) < _tmplowest) ? _data[_slice][_word][_colorMetric] : _tmplowest; + } + } + + //console.log(_tmplowest + " / " + _tmphighest); + var _cf = _tmphighest / 100; + + for (var _line in _lines) { + for (var i = 0; i < _lines[_line].length; i++) { + + var _tmpcol = "rgb(" + (Math.round(_lines[_line][i].values[_colorMetric] / _cf * 2)) + "," + (Math.round(200 - (_lines[_line][i].values[_colorMetric] / _cf * 2))) + "," + (Math.round(255 - (_lines[_line][i].values[_colorMetric] / _cf * 2))) + ")"; + + //console.log(_lines[_line][i].values[_colorMetric] + " " + _tmpcol); + _lines[_line][i].concol = _tmpcol; + _lines[_line][i].color(_tmpcol); + } + } + + for (var _word in _linescon) { + for (var _con in _linescon[_word]) { + _linescon[_word][_con].color(); + } + } } -} - - -function block(_slice,_x,_y,_values,_label) { - - var _this = this; - + } + + + function block(_slice, _x, _y, _values, _label) { + + var _this = this; + this.slice = _slice; this.labelID = _label; - this.labelText = (_limitlabel) ? _label.substr(0,25) + " (" + _values["uservariable"] + ")":_label + " (" + _values["uservariable"] + ")"; - this.values = _values; - this.x = _x; - this.y = _y; - this.width = _barwidth; - this.height = _values["height"]; + this.labelText = (_limitlabel) ? _label.substr(0, 25) + " (" + _values["uservariable"] + ")" : _label + " (" + _values["uservariable"] + ")"; + this.values = _values; + this.x = _x; + this.y = _y; + this.width = _barwidth; + this.height = _values["height"]; this.concol = "#000"; this.labelon = false; - - // console.log("concol:" + this.concol + " " + this.height); - - this.draw = function() { - - this.rect = r.rect(a(this.x), a(this.y), this.width, this.height).attr({ - "fill":this.concol,"stroke":_blostrokecolor,"stroke-width":_blostrokewidth - }); - - _this.rect.node.onclick = function() { - _tmp = _this.labelID.replace(/\"/g,"\\\""); - window.setTimeout('_lines["' + _tmp + '"][0].highlight()',50); - } - } - - this.move = function(_to) { - this.y = _to; - if(this.labelon == true) {this.label.remove();} - this.rect.animate({y:a(_to)},_anispeed, "<",function() { - if(_this.labelon == true) {_this.showLabel()}; - }); + + // console.log("concol:" + this.concol + " " + this.height); + + this.draw = function () { + + this.rect = r.rect(a(this.x), a(this.y), this.width, this.height).attr({ + "fill": this.concol, + "stroke": _blostrokecolor, + "stroke-width": _blostrokewidth + }); + + _this.rect.node.onclick = function () { + _tmp = _this.labelID.replace(/\"/g, "\\\""); + window.setTimeout('_lines["' + _tmp + '"][0].highlight()', 50); + } } - - this.highlight = function() { - for(var i = 0; i < _lines[this.labelID].length; i++) { - _lines[this.labelID][i].color("#000"); - _lines[this.labelID][i].labelon = true; - _lines[this.labelID][i].label = r.text(a(_lines[this.labelID][i].x) + _barwidth + _linedist, a(_lines[this.labelID][i].y + (_lines[this.labelID][i].height / 2)), _lines[this.labelID][i].labelText).attr("text-anchor","start"); - - } - //this.labelon = true; - //this.label = r.text(a(this.x) + _barwidth + _linedist, a(this.y + (this.height / 2)), this.labelText).attr("text-anchor","start"); - } - - this.color = function(_col) { - - _this.rect.attr({ - fill:_col - }); - } - - this.showLabel = function() { - this.labelon = true; - this.label = r.text(a(this.x) + _barwidth + _linedist + 2, a(this.y + (this.height / 2)), this.labelText).attr("text-anchor","start"); - } - - this.hideLabel = function() { - if(this.label) { - this.labelon = false; - this.label.remove(); - } - } -} - - -function connector(_obj1,_obj2) { - + + this.move = function (_to) { + this.y = _to; + if (this.labelon == true) { + this.label.remove(); + } + this.rect.animate({ + y: a(_to) + }, _anispeed, "<", function () { + if (_this.labelon == true) { + _this.showLabel() + }; + }); + } + + this.highlight = function () { + for (var i = 0; i < _lines[this.labelID].length; i++) { + _lines[this.labelID][i].color("#000"); + _lines[this.labelID][i].labelon = true; + _lines[this.labelID][i].label = r.text(a(_lines[this.labelID][i].x) + _barwidth + _linedist, a(_lines[this.labelID][i].y + (_lines[this.labelID][i].height / 2)), _lines[this.labelID][i].labelText).attr("text-anchor", "start"); + + } + //this.labelon = true; + //this.label = r.text(a(this.x) + _barwidth + _linedist, a(this.y + (this.height / 2)), this.labelText).attr("text-anchor","start"); + } + + this.color = function (_col) { + + _this.rect.attr({ + fill: _col + }); + } + + this.showLabel = function () { + this.labelon = true; + this.label = r.text(a(this.x) + _barwidth + _linedist + 2, a(this.y + (this.height / 2)), this.labelText).attr("text-anchor", "start"); + } + + this.hideLabel = function () { + if (this.label) { + this.labelon = false; + this.label.remove(); + } + } + } + + + function connector(_obj1, _obj2) { + var _this = this; - + this.obj1 = _obj1; this.obj2 = _obj2; - - this.draw = function() { - - this.calcpoly(); - - this.line = r.path(this.poly).attr({ - "stroke":_constrokecol,"stroke-width":_constrokewidth - }); - - this.line.toBack(); + + this.draw = function () { + + this.calcpoly(); + + this.line = r.path(this.poly).attr({ + "stroke": _constrokecol, + "stroke-width": _constrokewidth + }); + + this.line.toBack(); } - - this.color = function() { - - _this.line.attr({ - fill: "0-" + _this.obj2.concol + "-" + _this.obj1.concol - }); - - _this.line.node.style.opacity = _lineopacity; + + this.color = function () { + + _this.line.attr({ + fill: "0-" + _this.obj2.concol + "-" + _this.obj1.concol + }); + + _this.line.node.style.opacity = _lineopacity; } - - this.calcpoly = function() { - - //console.log(this.obj1.x + " " + this.obj2.x); - - if(this.obj1.x < this.obj2.x) { - var from_x = a(this.obj1.x + this.obj1.width); - var to_x = a(this.obj2.x); - } else { - var from_x = a(this.obj1.x - _linedist); - var to_x = a(this.obj2.x + this.obj2.width + _linedist); - } - - var from_y = this.obj1.y + (this.obj1.height / 2); - var to_y = this.obj2.y + (this.obj2.height / 2); - - - //console.log("f:" + from_x + "|t:" + to_x + "|f-t:" + ((from_x - to_x) / 2)); - _tmpdist = from_y - to_y; - _widthfactor = _tmpdist / (_barspacing * 5); - - // var v_path1 = "M10 10L10 90L90 90L90 10L10 10"; - this.poly = "M" + from_x + " " + (from_y + (this.obj1.height / _heightfactor)) + - "Q" + (to_x + ((from_x - to_x) / 4 * 3)) + " " + (from_y + (this.obj1.height / _heightfactor)) + " " + (to_x + ((from_x - to_x) / 2) - _widthfactor) + " " + (to_y + ((from_y - to_y) / 2) + (((this.obj1.height + this.obj2.height) / 2) / _heightfactor)) + " T" + to_x + " " + (to_y + (this.obj2.height / _heightfactor)) + - //"L" + to_x + " " + (to_y + (this.obj2.height / _heightfactor)) + - "L" + to_x + " " + (to_y - (this.obj2.height / _heightfactor)) + - "Q" + (to_x + ((from_x - to_x) / 4)) + " " + (to_y - (this.obj2.height / _heightfactor)) + " " + (to_x + ((from_x - to_x) / 2) + _widthfactor) + " " + (to_y + ((from_y - to_y) / 2) - (((this.obj1.height + this.obj2.height) / 2) / _heightfactor)) + " T" + from_x + " " + (from_y - (this.obj1.height / _heightfactor)) + - //"L" + from_x + " " + (from_y - (this.obj1.height / _heightfactor)) + - "L"+ from_x + " " + (from_y + (this.obj1.height / _heightfactor)); + + this.calcpoly = function () { + + //console.log(this.obj1.x + " " + this.obj2.x); + + if (this.obj1.x < this.obj2.x) { + var from_x = a(this.obj1.x + this.obj1.width); + var to_x = a(this.obj2.x); + } else { + var from_x = a(this.obj1.x - _linedist); + var to_x = a(this.obj2.x + this.obj2.width + _linedist); + } + + var from_y = this.obj1.y + (this.obj1.height / 2); + var to_y = this.obj2.y + (this.obj2.height / 2); + + + //console.log("f:" + from_x + "|t:" + to_x + "|f-t:" + ((from_x - to_x) / 2)); + _tmpdist = from_y - to_y; + _widthfactor = _tmpdist / (_barspacing * 5); + + // var v_path1 = "M10 10L10 90L90 90L90 10L10 10"; + this.poly = "M" + from_x + " " + (from_y + (this.obj1.height / _heightfactor)) + + "Q" + (to_x + ((from_x - to_x) / 4 * 3)) + " " + (from_y + (this.obj1.height / _heightfactor)) + " " + (to_x + ((from_x - to_x) / 2) - _widthfactor) + " " + (to_y + ((from_y - to_y) / 2) + (((this.obj1.height + this.obj2.height) / 2) / _heightfactor)) + " T" + to_x + " " + (to_y + (this.obj2.height / _heightfactor)) + + //"L" + to_x + " " + (to_y + (this.obj2.height / _heightfactor)) + + "L" + to_x + " " + (to_y - (this.obj2.height / _heightfactor)) + + "Q" + (to_x + ((from_x - to_x) / 4)) + " " + (to_y - (this.obj2.height / _heightfactor)) + " " + (to_x + ((from_x - to_x) / 2) + _widthfactor) + " " + (to_y + ((from_y - to_y) / 2) - (((this.obj1.height + this.obj2.height) / 2) / _heightfactor)) + " T" + from_x + " " + (from_y - (this.obj1.height / _heightfactor)) + + //"L" + from_x + " " + (from_y - (this.obj1.height / _heightfactor)) + + "L" + from_x + " " + (from_y + (this.obj1.height / _heightfactor)); } - - this.move = function() { - - this.calcpoly(); - - this.line.animate({path:this.poly},_anispeed,"<"); + + this.move = function () { + + this.calcpoly(); + + this.line.animate({ + path: this.poly + }, _anispeed, "<"); } -} - - -function a(_v) { - return _v + 0.5; -} - - -function changeInterface(_what,_action) { - - if(_what == 'labels') { - for(var _line in _lines) { - for(var i = 0; i < _lines[_line].length; i++) { - if(_action == true) { - if( _lines[_line][i].labelon == false) { _lines[_line][i].showLabel(); } - } else { - _lines[_line][i].hideLabel(); - } - } - } - } - - if(_what == "sorting") { - _anispeed = 700; - if(_action == true) { - _sortdata = _dataSortSize; - } else { - _sortdata = _data; - } - drawvis(_sortdata); - } - - if(_what == "valign") { - _anispeed = 400; - if(_action == true) { - _topalign = true; - } else { - _topalign = false; - } - drawvis(_sortdata); - } -} - - -function encode_as_img_and_link() { - $("svg").attr({ version: '1.1' , xmlns:"http://www.w3.org/2000/svg"}); - var svg = $("#visualization").html(); - svg = svg.replace(/fill="url\('.+?#/g,"fill=\"url('#"); - var file = new Blob([svg], { type: 'image/svg+xml' }); - var fileURL = URL.createObjectURL(file); - $("#svgdown").html($(`download`)); -} + } + + + function a(_v) { + return _v + 0.5; + } + + + function changeInterface(_what, _action) { + + if (_what == 'labels') { + for (var _line in _lines) { + for (var i = 0; i < _lines[_line].length; i++) { + if (_action == true) { + if (_lines[_line][i].labelon == false) { + _lines[_line][i].showLabel(); + } + } else { + _lines[_line][i].hideLabel(); + } + } + } + } + + if (_what == "sorting") { + _anispeed = 700; + if (_action == true) { + _sortdata = _dataSortSize; + } else { + _sortdata = _data; + } + drawvis(_sortdata); + } + + if (_what == "valign") { + _anispeed = 400; + if (_action == true) { + _topalign = true; + } else { + _topalign = false; + } + drawvis(_sortdata); + } + } + + + function encode_as_img_and_link() { + $("svg").attr({ + version: '1.1', + xmlns: "http://www.w3.org/2000/svg" + }); + var svg = $("#visualization").html(); + svg = svg.replace(/fill="url\('.+?#/g, "fill=\"url('#"); + var file = new Blob([svg], { + type: 'image/svg+xml' + }); + var fileURL = URL.createObjectURL(file); + $("#svgdown").html($(`download`)); + } \ No newline at end of file From 84d6c153bc80ae4087f6282b3ac6d25be113bb3f Mon Sep 17 00:00:00 2001 From: Boyd Nguyen Date: Tue, 15 Nov 2022 14:59:41 +1000 Subject: [PATCH 05/10] code formatting --- vis.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/vis.js b/vis.js index 15d9554..c35ed67 100644 --- a/vis.js +++ b/vis.js @@ -109,7 +109,7 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { } - var _ihtml = 'Color coding: "; var _exit = false; dance: @@ -160,7 +160,7 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { } } } - console.log(c_height); + // console.log(c_height); } @@ -193,7 +193,7 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { function drawvis(_data) { - console.log(_data) + // console.log(_data) var i = 0; var _wordlisthtml = ""; @@ -277,7 +277,7 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { _colorMetric = _sel; - console.log(_sel); + // console.log(_sel); var _tmphighest = 0; var _tmplowest = 10000000000000000; @@ -314,7 +314,13 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { for (var _line in _lines) { for (var i = 0; i < _lines[_line].length; i++) { - var _tmpcol = "rgb(" + (Math.round(_lines[_line][i].values[_colorMetric] / _cf * 2)) + "," + (Math.round(200 - (_lines[_line][i].values[_colorMetric] / _cf * 2))) + "," + (Math.round(255 - (_lines[_line][i].values[_colorMetric] / _cf * 2))) + ")"; + var _tmpcol = "rgb(" + + (Math.round(_lines[_line][i].values[_colorMetric] / _cf * 2)) + + "," + + (Math.round(200 - (_lines[_line][i].values[_colorMetric] / _cf * 2))) + + "," + + (Math.round(255 - (_lines[_line][i].values[_colorMetric] / _cf * 2))) + + ")"; //console.log(_lines[_line][i].values[_colorMetric] + " " + _tmpcol); _lines[_line][i].concol = _tmpcol; From 9f745a608db4f2a6558052288fd6b51dcd0b141a Mon Sep 17 00:00:00 2001 From: Boyd Nguyen Date: Tue, 15 Nov 2022 16:04:52 +1000 Subject: [PATCH 06/10] change default color coding --- index.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/index.html b/index.html index 47e89ee..a907505 100644 --- a/index.html +++ b/index.html @@ -76,8 +76,6 @@ } } - - var _rbo_p = parseFloat($("#vis_alpha").val()); @@ -225,7 +223,7 @@ var _startval = (_makelog) ? "log(" + _valnames[0] + ")" : _valnames[0]; - startVis(_startval, _valnames[1], _w, _h); + startVis(_startval, _valnames[0], _w, _h); } From ea071c8da8740279afc8057f49275169f73e6a3c Mon Sep 17 00:00:00 2001 From: Boyd Nguyen Date: Tue, 15 Nov 2022 17:10:53 +1000 Subject: [PATCH 07/10] change path colour --- index.html | 10 +--------- vis.js | 30 ++++++++++++++++++++---------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/index.html b/index.html index a907505..451fd7b 100644 --- a/index.html +++ b/index.html @@ -36,9 +36,6 @@ _rows = _raw.split("\n"); - console.log("Rows:" + _rows); - console.log(_rows.length); - var _w = $("#vis_width").val(); var _h = $("#vis_height").val(); @@ -47,11 +44,6 @@ var _values = 0; var _tmpelements = _rows[1].split("\t"); - console.log("tmpelement: " + _tmpelements) - console.log("tmpelement[0]" + _tmpelements[0]) - console.log("tmpelement[1]" + _tmpelements[1]) - console.log("tmpelement[2]" + _tmpelements[2]) - if (isNaN(parseInt(_tmpelements[1]))) { _values = 0; _makelog = false; @@ -223,7 +215,7 @@ var _startval = (_makelog) ? "log(" + _valnames[0] + ")" : _valnames[0]; - startVis(_startval, _valnames[0], _w, _h); + startVis(_startval, _valnames[1], _w, _h); } diff --git a/vis.js b/vis.js index c35ed67..2ba817d 100644 --- a/vis.js +++ b/vis.js @@ -15,6 +15,8 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { _constrokewidth = "1px"; _blostrokecolor = "#000"; _blostrokewidth = "1px"; + + _custom_colour = true; // do not modify _topalign = false; @@ -283,7 +285,8 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { var _tmplowest = 10000000000000000; if (_colorMetric == "colour") { - + + _custom_colour = true; tmp_colour = new Object; for (var _slide in _data) { @@ -301,6 +304,7 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { } } else { + _custom_colour = false; for (var _slice in _data) { for (var _word in _data[_slice]) { var _tmphighest = (parseInt(_data[_slice][_word][_colorMetric]) > _tmphighest) ? _data[_slice][_word][_colorMetric] : _tmphighest; @@ -327,12 +331,12 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { _lines[_line][i].color(_tmpcol); } } - - for (var _word in _linescon) { - for (var _con in _linescon[_word]) { - _linescon[_word][_con].color(); - } - } + } + + for (var _word in _linescon) { + for (var _con in _linescon[_word]) { + _linescon[_word][_con].color(); + } } } @@ -435,9 +439,15 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { this.color = function () { - _this.line.attr({ - fill: "0-" + _this.obj2.concol + "-" + _this.obj1.concol - }); + if (_custom_colour == true) { + console.log("Custom colour: ON"); + _this.line.attr({fill: _this.obj1.concol}); + } + + else { + console.log("Custom colour: OFF"); + _this.line.attr({fill: "0-" + _this.obj2.concol + "-" + _this.obj1.concol}); + } _this.line.node.style.opacity = _lineopacity; } From 92ca52061722e3a1f72e6898aef2585c65ef3217 Mon Sep 17 00:00:00 2001 From: Boyd Nguyen Date: Wed, 16 Nov 2022 10:19:40 +1000 Subject: [PATCH 08/10] remove console log --- index.html | 2 +- vis.js | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/index.html b/index.html index 451fd7b..5a26196 100644 --- a/index.html +++ b/index.html @@ -187,7 +187,7 @@ i + 1], _rbo_p)) * 1000) / 1000); } - console.log(_rbds); + // console.log(_rbds); // RBD table output diff --git a/vis.js b/vis.js index 2ba817d..18b68c3 100644 --- a/vis.js +++ b/vis.js @@ -86,7 +86,6 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { for (var _word in _data[_slice]) { _barheights[_slice] += _data[_slice][_word][_valname]; var _tmphash = new Array(_word, _data[_slice][_word]); - //console.log(_tmphash); _dataarray[_slice].push(_tmphash); _highestel = (_data[_slice][_word][_valname] > _highestel) ? _data[_slice][_word][_valname] : _highestel; _lowestel = (_data[_slice][_word][_valname] < _lowestel) ? _data[_slice][_word][_valname] : _lowestel; @@ -195,8 +194,6 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { function drawvis(_data) { - // console.log(_data) - var i = 0; var _wordlisthtml = ""; @@ -255,8 +252,6 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { $("#wordlist").html(_wordlisthtml); - //console.log(_lines); - for (var _word in _lines) { if (typeof (_linescon[_word]) == "undefined") { @@ -279,8 +274,6 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { _colorMetric = _sel; - // console.log(_sel); - var _tmphighest = 0; var _tmplowest = 10000000000000000; From ca679b1e89b68ac9bc93d66e5417568bc34db8b3 Mon Sep 17 00:00:00 2001 From: Boyd Nguyen Date: Mon, 21 Nov 2022 15:48:32 +1000 Subject: [PATCH 09/10] matching colour column name by regex --- vis.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vis.js b/vis.js index 18b68c3..63e4b65 100644 --- a/vis.js +++ b/vis.js @@ -276,8 +276,8 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { var _tmphighest = 0; var _tmplowest = 10000000000000000; - - if (_colorMetric == "colour") { + + if (/colour/i.test(_colorMetric)) { _custom_colour = true; tmp_colour = new Object; From 53db0950d4fd00e827997553bc9b37f707eb238d Mon Sep 17 00:00:00 2001 From: Boyd Nguyen Date: Mon, 21 Nov 2022 16:02:11 +1000 Subject: [PATCH 10/10] account for casing of 'Colour' column name --- vis.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vis.js b/vis.js index 63e4b65..6d9fbbc 100644 --- a/vis.js +++ b/vis.js @@ -276,7 +276,7 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { var _tmphighest = 0; var _tmplowest = 10000000000000000; - + if (/colour/i.test(_colorMetric)) { _custom_colour = true; @@ -284,7 +284,7 @@ function startVis(_sizevaluename, _colourvaluename, _w, _h) { for (var _slide in _data) { for (var _entity in _data[_slide]) { - tmp_colour[_entity] = _data[_slide][_entity]["colour"]; + tmp_colour[_entity] = _data[_slide][_entity]["colour"] || _data[_slide][_entity]["Colour"]; } }