From 0bd0dfd10d811bb1a83a0a809ae73cbd3563c846 Mon Sep 17 00:00:00 2001 From: mschor Date: Wed, 13 Oct 2021 17:57:14 -0400 Subject: [PATCH] Changes to bar charts and 'Start your search' section (issues: #87, #88, #89, #100, #102) --- css/dashboard.css | 94 +++++++++++++++++++++++- css/dcc-review.css | 24 ++++++ css/index.css | 66 +++++++++++++++++ css/pdashboard.css | 52 ++++++++++--- css/style.css | 2 +- dcc_review.html | 47 +++++++----- index.html | 109 +++++++++++++++++++--------- js/index.js | 20 ++++- js/pdashboard.js | 5 +- js/stacked-bar-graph.js | 157 +++++++++++++++++++++++----------------- pdashboard.html | 55 ++++++++------ udashboard.html | 105 +++++++++++++++------------ 12 files changed, 529 insertions(+), 207 deletions(-) diff --git a/css/dashboard.css b/css/dashboard.css index 5f749aa..92a11ac 100644 --- a/css/dashboard.css +++ b/css/dashboard.css @@ -1,5 +1,6 @@ .main { overflow-y: hidden; + display: block; } .data_content { @@ -12,6 +13,18 @@ margin: auto; } +#chart-container-1 { + display: inline-block; + width: 75%; + vertical-align: top; +} + +#chart-container-2 { + display: inline-block; + width: 75%; + vertical-align: top; +} + svg { width: 100%; height: 100%; @@ -27,18 +40,84 @@ svg { margin-bottom: 20px; } +#sbc1-container { + display: inline-block; + width: 75%; +} + +#sbc2-container { + display: inline-block; + width: 75%; +} + +#sbc1_container { + /* padding: 2%; */ + padding: 10px; + max-height: 200px; + overflow-y: scroll; + border: 0px; +} + +#sbc2_container { + /* padding: 2%; */ + padding: 10px; + max-height: 200px; + overflow-y: scroll; + border: 0px; +} + +#sbc1_container::-webkit-scrollbar { + -webkit-appearance: none; + width: 7px; +} + +#sbc2_container::-webkit-scrollbar { + -webkit-appearance: none; + width: 7px; +} + +#sbc1_container::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: rgba(0, 0, 0, .5); + box-shadow: 0 0 1px rgba(255, 255, 255, .5); +} + +#sbc2_container::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: rgba(0, 0, 0, .5); + box-shadow: 0 0 1px rgba(255, 255, 255, .5); +} + +#sbc1-group-by-container { + padding-bottom: 20px; +} + +#sbc2-group-by-container { + padding-bottom: 20px; +} + +#sbc1-group-by-and-legend-container { + width:24%; + display: inline-block; +} + +#sbc2-group-by-and-legend-container { + width:24%; + display: inline-block; +} + #sbc1-form-controls { margin: 0 auto; margin-bottom: 0px; position: relative; - width: 600px; + width: 800px; } #sbc2-form-controls { margin: 0 auto; margin-bottom: 0px; position: relative; - width: 600px; + width: 800px; } #dc1-form-controls { @@ -66,9 +145,18 @@ svg { flex-direction: row; flex-wrap: wrap; margin: auto; - width: 940px; + width: 1200px; +} + +.export-button { + bottom: 0; + position: absolute; + right: 0; + padding: 0px; + margin: 0px; } + div.thumbnail_chart { color: blue; cursor: pointer; diff --git a/css/dcc-review.css b/css/dcc-review.css index 7c48d89..e765654 100644 --- a/css/dcc-review.css +++ b/css/dcc-review.css @@ -2,6 +2,30 @@ body { } +#chart-container-1 { + display: inline-block; + width: 70%; + vertical-align: top; +} + +#review_bc1-group-by-container { + padding-bottom: 20px; + /* margin-top: -12px; */ +} + +#review_bc1-group-by-and-legend-container { + width:28%; + display: inline-block; + padding-left: 0px; +} + +#review_bc1_container { + padding: 10px; + max-height: 300px; + overflow-y: scroll; + border: 0px; +} + .top_content_section_right { display: flex; flex:0 0 200px; diff --git a/css/index.css b/css/index.css index c175c63..d7b55a2 100644 --- a/css/index.css +++ b/css/index.css @@ -61,6 +61,72 @@ main { font-size: 1.25rem; } +#browse-by-feature-container { + text-align: center; + display: flex; + justify-content: space-evenly; + max-width: 400px; + margin: 0 auto; + padding: 10px 0; +} + +#search-by-container { + text-align: center; + display: flex; + justify-content: space-between; + max-width: 400px; + margin: 0 auto; + padding: 20px 20px; +} + +#sbc1-group-by-and-legend-container { + width:24%; + display: inline-block; +} + +#sbc1-container { + display: inline-block; + width: 75%; + vertical-align: top; +} + +.export-button { + bottom: 0; + position: absolute; + right: 0; + padding: 0px; + margin: 0px; +} + +#sbc1_container { + /* padding: 2%; */ + padding: 10px; + max-height: 200px; + overflow-y: scroll; + border: 0px; + +} + +#sbc1-group-by-container { + padding-bottom: 20px; +} +/* #sbc1_container::-webkit-scrollbar { + -webkit-appearance: none; + width: 7px; +} + +#sbc1_container::-webkit-scrollbar-track { + background-color: blue; + width: 20px; +} */ + + +/* #sbc1_container::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: rgba(0, 0, 0, .5); + box-shadow: 0 0 1px rgba(255, 255, 255, .5); +} */ + #chart-container { height: 350px; margin: auto; diff --git a/css/pdashboard.css b/css/pdashboard.css index e76c6ca..eaa1bde 100644 --- a/css/pdashboard.css +++ b/css/pdashboard.css @@ -7,15 +7,51 @@ padding: 0rem; } -.svg_container { - flex: 5 1 85%; - border: 1px solid #cccccc; - margin-right: 20px; - padding: 0.5rem; + +#chart-container { + height: 350px; + margin: auto; +} + +#sbc1-controls input { + margin-left: 0rem; +} + +#sbc1-controls label { + margin-left: 1.2rem; } + +#chart-container-1 { + display: inline-block; + width: 60%; + vertical-align: top; +} + +#sbc1-group-by-container { + padding-bottom: 20px; + margin-top: -12px; +} + +#sbc1-group-by-and-legend-container { + width:20%; + display: inline-block; + padding-left: 8px; +} + +#sbc1_container { + /* padding: 2%; */ + padding: 10px; + max-height: 250px; + overflow-y: scroll; + border: 0px; +} + + + .checkboxes { - flex: 1 1 15%; + margin: 15px; + flex: 1 1 10%; border: 1px solid #cccccc; padding: 1rem 1rem 1rem 0rem; } @@ -44,10 +80,6 @@ svg { min-height: 350px; } -.checkboxes { - flex: 1 1 15%; -} - .button { margin: 0.5rem 0.5rem 1rem 0.5rem; } diff --git a/css/style.css b/css/style.css index f35a0fc..b2871d6 100644 --- a/css/style.css +++ b/css/style.css @@ -295,7 +295,7 @@ main { align-items: flex-start; flex-wrap: nowrap; margin: auto; - width: 940px; + max-width: 1100px; } .chart { diff --git a/dcc_review.html b/dcc_review.html index 365fc11..439c5ec 100644 --- a/dcc_review.html +++ b/dcc_review.html @@ -86,28 +86,33 @@

 

Data Snapshot

-

+
-
- -
+
+ +
+ +
+
+ + +
+
+
-
- - -
-
+
-
- - - - + +
+ +
+

+
diff --git a/index.html b/index.html index cbe4964..6879019 100644 --- a/index.html +++ b/index.html @@ -10,7 +10,8 @@ - + +
@@ -36,22 +37,52 @@

Find files, biosamples, or subjects from Common Fund data sets

Start your search

- +
Click to search by:
@@ -61,26 +92,31 @@

Example Data Views

Preview the data

-

+
- +
+
+
+ + +
+
+
+ +
-
-
- - -
+
-
- - - + - +
+ + +
+

+
+ +
diff --git a/js/index.js b/js/index.js index 2c0c586..c2ac772 100644 --- a/js/index.js +++ b/js/index.js @@ -116,6 +116,19 @@ function add_summary_data(catalog_id) { }); } +function add_counts(catalog_id) { + var summary_url = DASHBOARD_API_URL + '/dcc_info'; + + // counts for top-level entities + get_json_retry(summary_url, function(data) { + Object.keys(data).forEach(function(key) { + if (key.endsWith('_count')) { + $('#' + key).append(data[key].toLocaleString()); + } + }); + }); +} + // set/update Chaise URLs with the correct Chaise URL and de the catalog id function update_chaise_urls(catalog_id) { // "Search all Files" button @@ -152,8 +165,7 @@ $(document).ready(function() { // chart 1 - stacked bar graph register_dropdowns(catalog_id, 'sbc1'); - window.onload = function() { - update_chart(catalog_id, 'sbc1'); - window.addEventListener('resize', function() { window_resized(catalog_id, 'sbc1'); }); - }; + update_chart(catalog_id, 'sbc1'); + add_counts(catalog_id); + window.addEventListener('resize', function() { window_resized(catalog_id, 'sbc1'); }); }); diff --git a/js/pdashboard.js b/js/pdashboard.js index 9050eae..05acc71 100644 --- a/js/pdashboard.js +++ b/js/pdashboard.js @@ -241,7 +241,6 @@ $(document).ready(function() { register_dropdowns(catalog_id, 'sbc1'); update_favorites(); update_saved_queries(); - window.onload = function() { - window.addEventListener('resize', function() { window_resized(catalog_id, 'sbc1'); }); - }; + window.addEventListener('resize', function() { window_resized(catalog_id, 'sbc1'); }); + }); diff --git a/js/stacked-bar-graph.js b/js/stacked-bar-graph.js index 5e998b8..0a69396 100644 --- a/js/stacked-bar-graph.js +++ b/js/stacked-bar-graph.js @@ -129,13 +129,13 @@ function update_chart(catalog_id, chart_id) { const requestnum = ++REQUESTNUMS[chart_id]; var data_fn = function(data) { - // ignore out-of-sequence responses - if (requestnum == REQUESTNUMS[chart_id]) { - chart_data[chart_id] = data; - chart_data_urls[chart_id] = data_url; + // ignore out-of-sequence responses + if (requestnum == REQUESTNUMS[chart_id]) { + chart_data[chart_id] = data; + chart_data_urls[chart_id] = data_url; register_export_buttons(chart_id); draw_chart(chart_id, data, x_axis, y_axis); - } + } }; var fail_fn = function(jqXHR, status, error) { // ignore out-of-sequence responses @@ -250,12 +250,20 @@ function merge_groups(groups, max_groups, grouping1) { return new_groups; } +function getComputedLength() { + return function () { + let self = d3.select(this); + let textLength = self.node().getComputedTextLength(); + return textLength; + }; +} + function ellipsize(width, padding) { return function () { let self = d3.select(this); let textLength = self.node().getComputedTextLength(); let text = self.text(); - + while (textLength > (width - 2 * padding) && text.length > 0) { text = text.slice(0, -1); self.text(text + '...'); @@ -267,9 +275,9 @@ function ellipsize(width, padding) { // set the color palette var colorizer = d3.scaleOrdinal() .range([ - '#c0653d', '#f0593b', '#eb7e23', '#edb21e', '#f2cb2e', - '#d0c596', '#a28c33', '#96c93e', '#7da34a', '#80cbb3', - '#1bbcc0', '#138eae', '#76c8ed', '#aa8ec2', '#ef7e34' + '#c0653d', '#138eae', '#f2cb2e', '#96c93e', '#aa8ec2', + '#eb7e23', '#ffffff', '#edb21e', '#76c8ed', '#f0593b', + '#d0c596', '#80cbb3', '#7da34a', '#1bbcc0', '#a28c33' ]); function show_error(chart_id) { @@ -290,27 +298,37 @@ function add_tooltip(chart_id, svg) { let rect = tooltip.append('rect') .attr('width', 190) - .attr('height', 50) + .attr('height', 70) .attr('class', 'chart_tooltip_rect'); let text1 = tooltip.append('text') .attr('class', 'chart_tooltip_title') - .attr('id', chart_id + '-brick-category') + .attr('id', chart_id + '-x-category') .attr('x', 5) .attr('dy', '1.8em'); + text1.append('text').text('value here'); + + tooltip.append('text') + .attr('x', 5) + .attr('dy', '3.2em') + .attr('id', chart_id + '-z-category') + .attr('class', 'chart_tooltip_title'); tooltip.append('text') .attr('x', 5) - .attr('dy', '3.4em') - .attr('id', chart_id + '-brick-value') - .attr('class', 'chart_tooltip_value'); + .attr('dy', '4.6em') + .attr('id', chart_id + '-y-category') + .attr('class', 'chart_tooltip_title'); + // .attr('class', 'chart_tooltip_value'); + + } function draw_chart(svg_id, stacked_data, x_axis, y_axis) { $('#' + svg_id).empty(); update_chart_title(svg_id); - var x_axis_label_rot = 25; + var x_axis_label_rot = -35; var x_axis_label_dx = '-.8em'; var x_axis_label_dy = '.5em'; @@ -375,12 +393,6 @@ function draw_chart(svg_id, stacked_data, x_axis, y_axis) { }); stacked_data = new_stacked_data; - // apply group limits - if (MAX_GRAPH_GROUP1 != null) - stacked_data = merge_within_groups_local(stacked_data, MAX_GRAPH_GROUP2, x_axis); - if (MAX_GRAPH_GROUP2 != null) - stacked_data = merge_groups(stacked_data, MAX_GRAPH_GROUP1, x_axis); - // Can't assume that y-axis keys will be the same in each list element, // must take union across them all. stacked_data.forEach(d => { @@ -418,7 +430,7 @@ function draw_chart(svg_id, stacked_data, x_axis, y_axis) { const top_margin = 35; const bottom_margin = 80; var left_margin = 60; - var right_margin = 30; + var right_margin = 10; // svg_width determined by enclosing div const svg = d3.select('#' + svg_id); @@ -440,8 +452,8 @@ function draw_chart(svg_id, stacked_data, x_axis, y_axis) { if (svg_width < 400) { legend_width = 0; right_margin = 10; - x_axis_label_rot = 90; - x_axis_label_dx = '1em'; + x_axis_label_rot = -90; + x_axis_label_dx = '-1em'; x_axis_label_dy = '-0.5em'; d3.select('#' + svg_id + '-last_updated').style('display', 'none'); d3.select('#' + svg_id + '-form-row').style('flex-wrap', 'wrap'); @@ -450,7 +462,7 @@ function draw_chart(svg_id, stacked_data, x_axis, y_axis) { d3.select('#' + svg_id + '-form-row').style('flex-wrap', 'nowrap'); } - const width = svg_width - left_margin - right_margin - legend_width; + const width = svg_width - left_margin - right_margin; // - legend_width; const height = svg_height - top_margin - bottom_margin; svg.attr('height', svg_height); @@ -480,7 +492,8 @@ function draw_chart(svg_id, stacked_data, x_axis, y_axis) { var num_bars = stacked_data.length; function maxlen_fn(text, index) { // final bar has less space due to color key - return ((x_axis_label_rot != 90) && (index + 1 == num_bars)) ? 13 : 28; + // return ((x_axis_label_rot != 90) && (index + 1 == num_bars)) ? 13 : 28; + return (x_axis_label_rot != -90) ? 20 : 14; } var tlc = 0; @@ -501,6 +514,7 @@ function draw_chart(svg_id, stacked_data, x_axis, y_axis) { .attr('transform', `translate(0, ${height})`) .call(d3.axisBottom(xScale)) .selectAll('.tick text') + .style("text-anchor", "end") .call(trim_labels, maxlen_fn) .attr('dx', x_axis_label_dx) .attr('dy', x_axis_label_dy) @@ -562,30 +576,22 @@ function draw_chart(svg_id, stacked_data, x_axis, y_axis) { .attr('text-anchor', 'middle') .text(y_title); -// svg.append('image') -// .attr('x', svg_width - 125) -// .attr('y', 0) -// .attr('id', svg_id + '-export-button') -// .attr('height', 32) -// .attr('width', 125) -// .attr('xlink:href', './images/download_button.png') -// .on('click', function() { -// $('#export-modal').attr('name', svg_id + '-modal'); -// $('#export-modal').modal(); -// }) -// .append('title') -// .text('Export chart'); - // limit categories - var max_categories = 14; + // var max_categories = 14; add_tooltip(svg_id, svg); var tooltip = d3.select('#' + svg_id + '-tooltip'); var title_fn = function(d) { return d; }; var text_fn = function(d) { return d; }; - // add_legend(svg_id, width, chart, categories.slice(0,max_categories), tooltip, title_fn, text_fn, left_margin, 0); if (legend_width > 0) { - add_legend(svg_id, width, legend_width, chart, categories.slice(0, max_categories), null, title_fn, text_fn, left_margin, 0); + legend_height = categories.length * 20; + $('#' + svg_id + '_container').empty(); + var legendSVG = d3.select('#' + svg_id + '_container') + .append('svg') + .attr('height', legend_height) + .attr('width', '100%') + .attr('preserveAspectRatio', 'xMinYMin'); + add_legend(svg_id, 0, legend_width, legendSVG, categories, null, title_fn, text_fn, left_margin, 0); } groups.attr('fill', function(a, b) { return colorizer(b); }) @@ -613,7 +619,9 @@ function draw_chart(svg_id, stacked_data, x_axis, y_axis) { .on('mouseover', function() { tooltip.style('display', null); }) .on('mouseout', function() { tooltip.style('display', 'none'); }) .on('mousemove', function(d, e) { - var brick_name = d3.select(this.parentNode).datum().key; + var brick_num = d3.select(this.parentNode).datum(); + let series_idx = d3.select(this).datum()[2]; + var brick_name = brick_num.key; var brick_value = 0; let coords = d3.mouse(this); let xPosition = coords[0]; // distance from y-axis on chart @@ -626,10 +634,30 @@ function draw_chart(svg_id, stacked_data, x_axis, y_axis) { } else { brick_value = comma_formatter(d[1] - d[0]); } - - $('#' + svg_id + '-brick-value').text(brick_value); - let text = $('#' + svg_id + '-brick-category'); - text.append('tspan').text(brick_name).each(ellipsize(190, 5)); + var x_axis_selection = $('#' + svg_id + '-x-axis option:checked').val(); + var x_axis_val = stacked_data[series_idx][x_axis_selection]; + var y_axis_val = brick_value; + var group_val = brick_name; + var group_key = $('#' + svg_id + '-group-by option:checked').text(); + var x_axis_key = $('#' + svg_id + '-x-axis option:checked').text(); + var y_axis_key = $('#' + svg_id + '-y-axis option:checked').text(); + x_cat_text = $('#' + svg_id + '-x-category').text(x_axis_key + ": " + x_axis_val); + z_cat_text = $('#' + svg_id + '-z-category').text(group_key + ": " + group_val); + y_cat_text = $('#' + svg_id + '-y-category').text(y_axis_key + ": " + y_axis_val); + + x_cat_text.each( function() { + let self = d3.select(this); + let textLength = self.node().getComputedTextLength(); + }); + + let x_width = 0; + let y_width = 0; + let z_width = 0; + x_cat_text.each( function() { x_width = d3.select(this).node().getComputedTextLength();}); + y_cat_text.each( function() { y_width = d3.select(this).node().getComputedTextLength();}); + z_cat_text.each( function() { z_width = d3.select(this).node().getComputedTextLength();}); + tip_width = Math.max(x_width, y_width, z_width); + $('.chart_tooltip_rect').width(tip_width + 10); // Get the series index that we are hovering over so we can compute the // the x value to use (if we wish to lock it down). @@ -638,15 +666,15 @@ function draw_chart(svg_id, stacked_data, x_axis, y_axis) { // let tooltipX = seriesX; let tooltipX = xPosition + left_margin - (tooltip_width / 2); - let tooltipY = yPosition - 50; // Get the tooltip above the mouse position + let tooltipY = yPosition - 45; // Get the tooltip above the mouse position // Prevent the tooltip from starting from out-of-bounds if (tooltipX < 1) { tooltipX = 1; } - if (tooltipY < 1) { - tooltipY = 1; + if (tooltipY < -10) { + tooltipY = -10; } tooltip.attr('transform', 'translate(' + tooltipX + ',' + tooltipY + ')'); @@ -654,7 +682,7 @@ function draw_chart(svg_id, stacked_data, x_axis, y_axis) { } function add_legend(svg_id, chart_width, legend_width, chart, categories, tooltip, title_fn, text_fn, x_offset, y_offset, mouseover_fn, mouseout_fn) { - var top = -10; + var top = 0; // Create the legend var legend = chart.append('g').selectAll('.legend') @@ -666,16 +694,16 @@ function add_legend(svg_id, chart_width, legend_width, chart, categories, toolti return 'translate(0,' + (top + i * 20) + ')'; }) .on('mouseover', function(d, e) { - if (tooltip != null) tooltip.style('display', null); - if (mouseover_fn != null) mouseover_fn(d, e); + if (tooltip != null) tooltip.style('display', null); + if (mouseover_fn != null) mouseover_fn(d, e); }) .on('mouseout', function(d, e) { - if (tooltip != null) tooltip.style('display', 'none'); - if (mouseout_fn != null) mouseout_fn(d, e); + if (tooltip != null) tooltip.style('display', 'none'); + if (mouseout_fn != null) mouseout_fn(d, e); }) .on('mousemove', function(d, e) { - if (tooltip == null) return; - var tooltip_title = title_fn(d); + if (tooltip == null) return; + var tooltip_title = title_fn(d); var tooltip_text = text_fn(d); let coords = d3.mouse(this); @@ -683,13 +711,9 @@ function add_legend(svg_id, chart_width, legend_width, chart, categories, toolti let yPosition = coords[1]; // distance from top of chart let tooltip_width = $('.chart_tooltip_rect').width(); - $('#' + svg_id + '-brick-value').text(tooltip_text).each(ellipsize(190, 5)); - let text = $('#' + svg_id + '-brick-category'); - text.append('tspan').text(tooltip_title).each(ellipsize(190, 5)); - let tooltipX = xPosition + x_offset - tooltip_width; let tooltipY = yPosition + y_offset - 50; // Get the tooltip above the mouse position - tooltipY += (top + e * 20); + tooltipY += (top + e * 20); // Prevent the tooltip from starting from out-of-bounds if (tooltipX < 1) { @@ -704,18 +728,19 @@ function add_legend(svg_id, chart_width, legend_width, chart, categories, toolti }); legend.append('rect') - .attr('x', chart_width + 28) + // .attr('x', chart_width + 28) + .attr('x', chart_width) .attr('width', 18) .attr('height', 18) .attr('fill', function(d, i) { return colorizer(i); }); legend.append('text') - .attr('x', chart_width + 50) + .attr('x', chart_width + 25) .attr('y', 8) .attr('dy', '.35em') .attr('font-family', 'sans-serif') .style('font-size', '0.7rem') - .text(title_fn).each(ellipsize(legend_width - 15, 5)) + .text(title_fn) //.each(ellipsize(legend_width - 15, 5)) .append('title').text(title_fn); } diff --git a/pdashboard.html b/pdashboard.html index d5cb654..77b28d3 100644 --- a/pdashboard.html +++ b/pdashboard.html @@ -96,10 +96,27 @@

Common Fund Data Ecosystem

-
- +
+
- + +
+
+ + +
+
+
+ + + +

@@ -110,8 +127,17 @@

Common Fund Data Ecosystem

-
+
+
+ + +
-
- - -
-
- - -
+ +
diff --git a/udashboard.html b/udashboard.html index c5b6c7a..3983228 100644 --- a/udashboard.html +++ b/udashboard.html @@ -76,49 +76,57 @@

Dashboard

Chart 1

-

-

+

+
- + +
+ +
+
+ + +
+
+
+
-
-
- - -
+
- - +
-
- - + + - +
+ +
+

+
+
@@ -130,27 +138,30 @@

Dashboard

Chart 2

-

+ +
+
+ + +
+
+
+
-
+
-
- - -
-
- - + +
+ +
+

+