From 5e02b1ed2289809e7203c78e04b3b8bde345b69a Mon Sep 17 00:00:00 2001 From: Caleb Knoll Date: Sun, 11 Jul 2021 23:33:46 -0500 Subject: [PATCH 1/4] Use checkboxes for options instead of buttons --- public/css/style.css | 11 ++- public/index.html | 18 ++--- public/js/script.js | 179 +++++++++++++++++++++++-------------------- 3 files changed, 112 insertions(+), 96 deletions(-) diff --git a/public/css/style.css b/public/css/style.css index 5ce1b31..93a6e5c 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -17,7 +17,7 @@ html, body { overflow-y: auto; } #viz { - width: 400px; + width: 425px; border-right: 1px solid #696969; } #node { @@ -53,3 +53,12 @@ html, body { .tag { font: 12pt Arial; } + +.btn-group button { + float: left; +} + +.btn-group button.selected { + background-color: rgb(55, 126, 184); + color: white; +} \ No newline at end of file diff --git a/public/index.html b/public/index.html index 0fe19f8..6958d1a 100644 --- a/public/index.html +++ b/public/index.html @@ -8,16 +8,14 @@
- - - - - - - - - - + + + + + + + +
diff --git a/public/js/script.js b/public/js/script.js index 785eeff..20fb832 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -374,6 +374,9 @@ } document.getElementById('unAxis').addEventListener('click', function () { + Array.from(document.getElementsByTagName("button")).forEach(b => b.classList.remove('selected')) + document.getElementById('unAxis').classList.add('selected'); + x = null; y = null; yProp = null; @@ -394,6 +397,9 @@ document.getElementById('alphabetical').addEventListener('click', function() { + Array.from(document.getElementsByTagName("button")).forEach(b => b.classList.remove('selected')) + document.getElementById('alphabetical').classList.add('selected'); + yProp = 'yHash'; y = d3.scaleLinear() .domain([yHeights.min, yHeights.max]) @@ -422,6 +428,9 @@ document.getElementById('parentChild').addEventListener('click', function() { + Array.from(document.getElementsByTagName("button")).forEach(b => b.classList.remove('selected')) + document.getElementById('parentChild').classList.add('selected'); + yProp = 'yTime'; y = d3.scaleLinear() .domain([yHeights.min, yHeights.max]) @@ -446,102 +455,102 @@ showTags = false; // TODO: animate or re-show tags after simulation finishes }); - document.getElementById('color').addEventListener('click', function() { - - const colorScale = d3.scaleOrdinal() - .domain(nodeTypes) - .range(d3.schemeSet1); - - currentFill = d => colorScale(d.type); - currentLineFill = d => colorScale(d.target.type); - - svg.selectAll('.commit').data(commits) - .transition() - .duration(750) - .style('fill', currentFill); - - if (showLines) { - svg.selectAll('.arrowUp').data(arrowsUp) - .transition() - .duration(750) - .style('stroke', currentLineFill); - svg.selectAll('.arrowOver').data(arrowsOver) - .transition() - .duration(750) - .style('stroke', currentLineFill); - } + document.getElementById('color').addEventListener('change', function() { + + if(this.checked) { + const colorScale = d3.scaleOrdinal() + .domain(nodeTypes) + .range(d3.schemeSet1); + + currentFill = d => colorScale(d.type); + currentLineFill = d => colorScale(d.target.type); + + svg.selectAll('.commit').data(commits) + .transition() + .duration(750) + .style('fill', currentFill); + + if (showLines) { + svg.selectAll('.arrowUp').data(arrowsUp) + .transition() + .duration(750) + .style('stroke', currentLineFill); + svg.selectAll('.arrowOver').data(arrowsOver) + .transition() + .duration(750) + .style('stroke', currentLineFill); + } + + // build legend: https://www.d3-graph-gallery.com/graph/custom_legend.html + // Add one dot in the legend for each name. + var size = 15; + svg.selectAll('legend-dot') + .data(nodeTypes) + .enter() + .append('rect') // TODO: circle + .attr('class', 'legend-dot') + .attr('x', 10) + .attr('y', function(d, i){ return 40 + i*(size+5)}) + .attr('width', size) + .attr('height', size) + .style('fill', d => colorScale(d)); + + // Add one dot in the legend for each name. + svg.selectAll('legend-label') + .data(nodeTypes) + .enter() + .append('text') + .attr('class', 'legend-label') + .attr('x', 10 + size*1.2) + .attr('y', function(d, i){ return 40 + i*(size+5) + (size/2)}) + .style('fill', d => colorScale(d)) + .text(d => d) + .attr('text-anchor', 'left') + .style('alignment-baseline', 'middle'); + } else { - // build legend: https://www.d3-graph-gallery.com/graph/custom_legend.html - // Add one dot in the legend for each name. - var size = 15; - svg.selectAll('legend-dot') - .data(nodeTypes) - .enter() - .append('rect') // TODO: circle - .attr('class', 'legend-dot') - .attr('x', 10) - .attr('y', function(d, i){ return 40 + i*(size+5)}) - .attr('width', size) - .attr('height', size) - .style('fill', d => colorScale(d)); - - // Add one dot in the legend for each name. - svg.selectAll('legend-label') - .data(nodeTypes) - .enter() - .append('text') - .attr('class', 'legend-label') - .attr('x', 10 + size*1.2) - .attr('y', function(d, i){ return 40 + i*(size+5) + (size/2)}) - .style('fill', d => colorScale(d)) - .text(d => d) - .attr('text-anchor', 'left') - .style('alignment-baseline', 'middle'); - }); + currentFill = 'steelblue'; + currentLineFill = 'steelblue' + svg.selectAll('.commit').data(commits) + .transition() + .duration(750) + .style('fill', currentFill); + + if (showLines) { + svg.selectAll('.arrowUp').data(arrowsUp) + .transition() + .duration(750) + .style('stroke', currentLineFill); + svg.selectAll('.arrowOver').data(arrowsOver) + .transition() + .duration(750) + .style('stroke', currentLineFill); + } + + svg.selectAll('.legend-label').remove(); + svg.selectAll('.legend-dot').remove(); - document.getElementById('uncolor').addEventListener('click', function () { - - currentFill = 'steelblue'; - currentLineFill = 'steelblue' - svg.selectAll('.commit').data(commits) - .transition() - .duration(750) - .style('fill', currentFill); - - if (showLines) { - svg.selectAll('.arrowUp').data(arrowsUp) - .transition() - .duration(750) - .style('stroke', currentLineFill); - svg.selectAll('.arrowOver').data(arrowsOver) - .transition() - .duration(750) - .style('stroke', currentLineFill); } - - svg.selectAll('.legend-label').remove(); - svg.selectAll('.legend-dot').remove(); - }); - document.getElementById('lines').addEventListener('click', function () { - showLines = true; - // TODO: fade - }); - document.getElementById('unlines').addEventListener('click', function () { - showLines = false; + document.getElementById('lines').addEventListener('change', function () { // TODO: fade + if(this.checked) { + showLines = true; + } else { + showLines = false; + } }); - document.getElementById('tags').addEventListener('click', function () { - showTags = true; + document.getElementById('tags').addEventListener('change', function () { // TODO: fade + if(this.checked) { + showTags = true; + } else { + showTags = false; + } }); - document.getElementById('untags').addEventListener('click', function () { - showTags = false; - // TODO: fade - }); }()); From 04da119ff79c1419cc1ff102ccb562d4f72bddc7 Mon Sep 17 00:00:00 2001 From: Caleb Knoll Date: Sat, 7 Aug 2021 23:57:04 -0500 Subject: [PATCH 2/4] Add sessionStorage to ui preferences so the preferences remain on reload, but not on page close --- public/index.html | 2 +- public/js/script.js | 88 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/public/index.html b/public/index.html index 6958d1a..fd2806b 100644 --- a/public/index.html +++ b/public/index.html @@ -11,7 +11,7 @@ - + diff --git a/public/js/script.js b/public/js/script.js index 20fb832..d810840 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -231,8 +231,13 @@ .nodes(commits) .on('tick', updateDOM); - } + changeColorSetting(); + changeLinesSetting(); + changeTagsSetting(); + arrangeNodes(); + + } function handleMouseOver(d) { @@ -373,7 +378,26 @@ } + function arrangeNodes() { + switch(sessionStorage.getItem('arrange')){ + case 'alphabetical': + arrageNodesAlphabetical(); + break; + case 'parentChild': + arrangeNodesParentChild(); + break; + default: // 'unAxis' + arrageNodesUnAxis(); + break; + } + } + document.getElementById('unAxis').addEventListener('click', function () { + sessionStorage.setItem('arrange', 'unAxis'); + arrangeNodes(); + }); + + function arrageNodesUnAxis() { Array.from(document.getElementsByTagName("button")).forEach(b => b.classList.remove('selected')) document.getElementById('unAxis').classList.add('selected'); @@ -392,11 +416,14 @@ .restart(); svg.attr('height', window.innerHeight); - - }); + } document.getElementById('alphabetical').addEventListener('click', function() { + sessionStorage.setItem('arrange', 'alphabetical'); + arrangeNodes(); + }); + function arrageNodesAlphabetical(){ Array.from(document.getElementsByTagName("button")).forEach(b => b.classList.remove('selected')) document.getElementById('alphabetical').classList.add('selected'); @@ -424,10 +451,14 @@ showLines = false; showTags = false; // TODO: animate or re-show tags after simulation finishes - }); + } document.getElementById('parentChild').addEventListener('click', function() { + sessionStorage.setItem('arrange', 'parentChild'); + arrangeNodes(); + }); + function arrangeNodesParentChild(){ Array.from(document.getElementsByTagName("button")).forEach(b => b.classList.remove('selected')) document.getElementById('parentChild').classList.add('selected'); @@ -453,11 +484,22 @@ svg.attr('height', (commits.length*commitDistance)+100); showTags = false; // TODO: animate or re-show tags after simulation finishes - }); + } document.getElementById('color').addEventListener('change', function() { + // store empty string instead of the string false, which will eval to true when recalled + sessionStorage.setItem('color', this.checked ? this.checked : ''); + changeColorSetting(); + }); + + function changeColorSetting() { + var setting = sessionStorage.getItem('color'); + + // check the box in case we are loading from storage + // this will not trigger the change event + document.getElementById('color').checked = setting; - if(this.checked) { + if(setting) { const colorScale = d3.scaleOrdinal() .domain(nodeTypes) .range(d3.schemeSet1); @@ -531,26 +573,50 @@ svg.selectAll('.legend-dot').remove(); } + } + + document.getElementById('lines').addEventListener('change', function () { + // store empty string instead of the string false, which will eval to true when recalled + sessionStorage.setItem('lines', this.checked ? this.checked : ''); + changeLinesSetting() }); + function changeLinesSetting() { + + var setting = sessionStorage.getItem('lines'); + + // check the box in case we are loading from storage + // this will not trigger the change event + document.getElementById('lines').checked = setting; - document.getElementById('lines').addEventListener('change', function () { // TODO: fade - if(this.checked) { + if(setting) { showLines = true; } else { showLines = false; } - }); + } document.getElementById('tags').addEventListener('change', function () { + // store empty string instead of the string false, which will eval to true when recalled + sessionStorage.setItem('tags', this.checked ? this.checked : ''); + changeTagsSetting(); + }); + + function changeTagsSetting() { + var setting = sessionStorage.getItem('tags'); + + // check the box in case we are loading from storage + // this will not trigger the change event + document.getElementById('tags').checked = setting; + // TODO: fade - if(this.checked) { + if(setting) { showTags = true; } else { showTags = false; } - }); + } }()); From 019a0af623f7e94a145b322355a2d1f4dd051a35 Mon Sep 17 00:00:00 2001 From: Caleb Knoll Date: Sun, 8 Aug 2021 00:08:07 -0500 Subject: [PATCH 3/4] Remove resetting of tags and lines now that the setting is preserved on refresh --- public/js/script.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/public/js/script.js b/public/js/script.js index d810840..485415a 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -448,9 +448,6 @@ .restart(); svg.attr('height', (commits.length*commitDistance)+100); - - showLines = false; - showTags = false; // TODO: animate or re-show tags after simulation finishes } document.getElementById('parentChild').addEventListener('click', function() { @@ -482,8 +479,6 @@ .restart(); svg.attr('height', (commits.length*commitDistance)+100); - - showTags = false; // TODO: animate or re-show tags after simulation finishes } document.getElementById('color').addEventListener('change', function() { From 44b791c7ed1d20ae93f30226911b2b70fa7a0e6e Mon Sep 17 00:00:00 2001 From: Caleb Knoll Date: Sun, 8 Aug 2021 00:09:07 -0500 Subject: [PATCH 4/4] Remove obsolete comments, now that we have scrollbars --- public/js/script.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/public/js/script.js b/public/js/script.js index 485415a..e5fc9b3 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -431,8 +431,6 @@ y = d3.scaleLinear() .domain([yHeights.min, yHeights.max]) .range([margin.top+(commits.length*commitDistance), margin.top+50]); - // TODO: what if we have more than a page's worth? - //.range([height - margin.bottom, margin.top+50]); x = d3.scaleLinear() .domain([xWidths.min, xWidths.max]) @@ -463,8 +461,6 @@ y = d3.scaleLinear() .domain([yHeights.min, yHeights.max]) .range([margin.top+(commits.length*commitDistance), margin.top+50]); - // TODO: what if we have more than a page's worth? - //.range([height - margin.bottom, margin.top+50]); x = d3.scaleLinear() .domain([xWidths.min, xWidths.max])