From b34ce82eb62bd5f3d401853c381d9490fc1da44f Mon Sep 17 00:00:00 2001 From: Juan Pablo Alperin Date: Thu, 19 Jul 2018 20:20:38 -0700 Subject: [PATCH 1/4] implement HTML version of miniViz --- paperbuzzviz.js | 180 ++++++++++++++++-------------------------------- 1 file changed, 60 insertions(+), 120 deletions(-) diff --git a/paperbuzzviz.js b/paperbuzzviz.js index 54bf982..fb6995c 100755 --- a/paperbuzzviz.js +++ b/paperbuzzviz.js @@ -25,49 +25,36 @@ function PaperbuzzViz(options) { var graphheight = options.graphheight; var graphwidth = options.graphwidth; + var published_date = options.published_date || false; + var data = options.paperbuzzStatsJson; - //console.log(data); - + + + if (published_date) { + // accept the published date passed in, if there was one + // Will choose pub date based on online pub, print pub, or issued. If no month or day defaults to 01 - if (data.metadata['published-online']) { - var year = data.metadata["published-online"]["date-parts"][0][0]; - if (data.metadata["published-online"]["date-parts"][0][1]) { - var month = data.metadata["published-online"]["date-parts"][0][1]; - } else {var month = 01; - } - if (data.metadata["published-online"]["date-parts"][0][2]) { - var day = data.metadata["published-online"]["date-parts"][0][2]; - } else {var day = 01; - } - var published_date = year+"-"+month+"-"+day; + } else if (data.metadata['published-online']) { + published_date = data.metadata["published-online"]["date-parts"][0]; } else if (data.metadata['published-print']) { - var year = data.metadata["published-print"]["date-parts"][0][0]; - if (data.metadata["published-print"]["date-parts"][0][1]) { - var month = data.metadata["published-print"]["date-parts"][0][1]; - } else {var month = 01; - } - if (data.metadata["published-print"]["date-parts"][0][2]) { - var day = data.metadata["published-print"]["date-parts"][0][2]; - } else {var day = 01; - } - var published_date = year+"-"+month+"-"+day; + published_date = data.metadata["published-print"]["date-parts"][0]; + } else if (published_date = data.metadata["issued"]) { + published_date = data.metadata["issued"]["date-parts"][0]; } else { - var year = data.metadata["issued"]["date-parts"][0][0]; - if (data.metadata["issued"]["date-parts"][0][1]) { - var month = data.metadata["issued"]["date-parts"][0][1]; - } else {var month = 01; - } - if (data.metadata["issued"]["date-parts"][0][2]) { - var day = data.metadata["issued"]["date-parts"][0][2]; - } else {var day = 01; - } - var published_date = year+"-"+month+"-"+day; + published_date = [1969, 1, 1]; // TODO: Better handling if no date is found } - - // extract publication date - var pub_date = parseDate(published_date); - //console.log(pub_date); + // Fill in the month and day with 1 if they are empty + if (published_date.length == 1) { + published_date.push(1) + } + if (published_date.length == 2) { + published_date.push(1) + } + + // extract publication date + var pub_date = parseDate(published_date.join('-')); + var vizDiv; // Get the Div where the viz should go (default to one with ID "paperbuzz') @@ -85,86 +72,12 @@ function PaperbuzzViz(options) { sources = data.altmetrics_sources - if (showMini) { - - //vizDiv.select("#loading").remove(); - - var miniViz = d3.select("body").append("svg") - .attr('height', "100%") - .attr("width", "100%"); - //console.log(sources); - miniViz.selectAll("rect") - .data(sources) - .enter().append("rect") - .attr("fill", "#CECCCC") - .attr("height", "90") - .attr("width", "100%") - .attr("x", "0") - .attr("y", "0"); - - miniViz.append("text") - .attr("x", "10") - .attr("y", "20") - .attr("class", "miniViz-title") - .html('' + data.metadata.title + ''); - - var total = 0; - for (i = 0; i < data.altmetrics_sources.length; i++) { - total += data.altmetrics_sources[i].events_count; - } - - function calculateYears(pub_date) { - var years = (new Date()).getFullYear() - pub_date.getFullYear(); - return Math.ceil(years); - } - - miniViz.append("text") - .attr("x", "10") - .attr("y", "70") - .attr("class", "miniViz-total") - .text(total); - - miniViz.append("text") - .attr("x", "100") - .attr("y", "50") - .attr("class", "miniViz-text") - .text('Online mentions over'); - - miniViz.append("text") - .attr("x", "100") - .attr("y", "70") - .attr("class", "miniViz-text") - .text(calculateYears(pub_date) + ' year(s)'); - - - var total = 0; - for (i = 0; i < data.altmetrics_sources.length; i++) { - console.log(i); - var x = 230 + (i*40); - var y = 33; - - miniViz.append("foreignObject") - .attr("class", "miniViz-count") - .attr("id", "miniViz-count-" + data.altmetrics_sources[i].source_id) - .attr("x", x) - .attr("y", y) - .html('' + " "); - - miniViz.append("text") - .attr("x", x) - .attr("y", 70) - .attr("class", "miniViz-text") - .text(data.altmetrics_sources[i].events_count); - } - - - } - /** * Initialize the visualization. * NB: needs to be accessible from the outside for initialization */ this.initViz = function() { + vizDiv.select("#loading").remove(); if (showTitle) { @@ -176,20 +89,47 @@ function PaperbuzzViz(options) { vizDiv.append("br"); - - // loop through sources - sources.forEach(function(source) { - metricsFound_ = true; - addSourceRow(vizDiv, source); - }); - - if (!metricsFound_) { + if (sources.length > 0) { + if (showMini) { + addMiniViz(vizDiv, sources); + } else { + // loop through sources + sources.forEach(function(source) { + // metricsFound_ = true; + addSourceRow(vizDiv, source); + }); + } + metricsFound_ = true; + } else { vizDiv.append("p") .attr("class", "muted") .text("No metrics found."); } }; + var addMiniViz = function(vizDiv, sources) { + + miniDiv = vizDiv.append('div') + .attr('id', 'paperbuzz-mini'); + + miniDiv.append('span') + .attr('class', 'miniViz-total') + + var total = 0; + sources.forEach(function(source) { + miniDiv.append('span') + .append('i') + .attr('class', 'icon-' + source.source_id) + .append('span') + .attr('class', 'miniViz-count') + .text(source.events_count); + total += source.events_count + }); + + miniDiv.selectAll('.miniViz-total') + .text(total); + } + /** * Build each article level statistics source. * @param {Object} canvas d3 element From b125b01d6d8516e58eda7d6b7ae97731bdf64d09 Mon Sep 17 00:00:00 2001 From: Juan Pablo Alperin Date: Thu, 19 Jul 2018 21:46:20 -0700 Subject: [PATCH 2/4] namespaced css classes --- css/paperbuzzviz.css | 145 +++++++++++++++++++------------------------ index.html | 19 ++++-- paperbuzzviz.js | 27 ++++---- 3 files changed, 92 insertions(+), 99 deletions(-) diff --git a/css/paperbuzzviz.css b/css/paperbuzzviz.css index 1fd4a87..ee5b9dd 100755 --- a/css/paperbuzzviz.css +++ b/css/paperbuzzviz.css @@ -1,4 +1,4 @@ -.title { +.paperbuzz-title { font-size: 1.5em; color: #789aa1; text-decoration: underline; @@ -8,23 +8,19 @@ font-size: 11px; } -.axis line, -.axis path { +.paperbuzz-axis line, +.paperbuzz-axis path { fill: none; stroke: black; stroke-width: 1; shape-rendering: crispEdges; } -.barsForTooltip { - fill: ffffff; - fill-opacity: 0; -} -.bar.main{ +.paperbuzz-bar.main{ fill: #789aa1; } -.bar.alt{ +.paperbuzz-bar.alt{ fill: #304345; } @@ -109,12 +105,7 @@ vertical-align: middle; } -#built-with { - float: right; - font-size: .75em; -} - -.paperbuzzTooltip { +.paperbuzz-tooltip { line-height: 1; font: 10px sans-serif; padding: 4px; @@ -125,7 +116,7 @@ } /* Creates a small triangle extender for the tooltip */ -.paperbuzzTooltip:after { +.paperbuzz-tooltip:after { box-sizing: border-box; display: inline; font-size: 10px; @@ -138,14 +129,14 @@ } /* Style northward tooltips differently */ -.paperbuzzTooltip.n:after { +.paperbuzz-tooltip.n:after { margin: -1px 0 0 0; top: 100%; left: 0; } /* Paperbuzz mini */ -.paperbuzz-mini-label { +#paperbuzz-mini { width: 250px; float: left; margin-top: .5em; @@ -158,7 +149,30 @@ -webkit-border-radius: 5px; border-radius: 5px; color: #28292b; - + clear: both; +} + +.paperbuzz-mini-total { + font-size: 3em; + color: #011a1f; + float: left; +} + +.paperbuzz-mini-source { + color: #011a1f; + float: left; + padding: .4em; +} +.paperbuzz-mini-source > i{ + padding-top: .4em; + padding-bottom: .em; + font-size: 1.15em; + vertical-align: middle; + +} + +.paperbuzz-mini-count { + margin-left: .2em; } /* Font icon css */ @@ -171,10 +185,10 @@ url('../fonts/icomoon.svg?846v#icomoon') format('svg'); font-weight: normal; font-style: normal; - } +} - [class^="icon-"], [class*=" icon-"] { +[class^="icon-"], [class*=" icon-"] { /* use !important to prevent issues with browser extensions that change fonts */ font-family: 'icomoon' !important; speak: none; @@ -183,82 +197,53 @@ font-variant: normal; text-transform: none; line-height: 1; - + /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - } +} - .icon-crossref:before { +.icon-crossref:before { content: "\e90c"; - } - .icon-datacite:before { +} +.icon-datacite:before { content: "\e90b"; - } - .icon-f1000:before { +} +.icon-f1000:before { content: "\e90a"; - } - .icon-hypothesis:before { +} +.icon-hypothesis:before { content: "\e909"; - } - .icon-cambia-lens:before { +} +.icon-cambia-lens:before { content: "\e907"; - } - .icon-stackexchange:before { +} +.icon-stackexchange:before { content: "\e908"; color: #1e5397; - } - .icon-reddit-links:before { +} +.icon-reddit-links:before { content: "\eac6"; - } - .icon-web:before { +} +.icon-web:before { content: "\e903"; - } - .icon-wikipedia:before { +} +.icon-wikipedia:before { content: "\e906"; - } - .icon-newsfeed:before { +} +.icon-newsfeed:before { content: "\e905"; - } - .icon-facebook:before { +} +.icon-facebook:before { content: "\e904"; - } - .icon-reddit:before { +} +.icon-reddit:before { content: "\e902"; - } - .icon-wordpressdotcom:before { +} +.icon-wordpressdotcom:before { content: "\e901"; - } - .icon-twitter:before { +} +.icon-twitter:before { content: "\e900"; - } - - /* miniViz */ - .miniViz-title { - font-size: .9em; - color: #011a1f; - text-decoration: underline; - } - - .miniViz-title:hover { - cursor: pointer; - } - - .miniViz-total { - font-size: 3em; - color: #011a1f; - } - - .miniViz-text { - font-size: .75em; - color: #011a1f; - } - - .miniViz-count { - font-size: 1.15em; - /*padding-bottom: 0.4em; - padding-top: 0.4em; - font-weight: bold; - vertical-align: middle;*/ - } +} \ No newline at end of file diff --git a/index.html b/index.html index 870f683..b55b81a 100755 --- a/index.html +++ b/index.html @@ -16,6 +16,13 @@ width: 800px; font-family: arial } + + #built-with { + clear: both; + float: right; + font-size: .75em; + } + @@ -40,16 +47,16 @@

Paperbuzz Visualizations

graphheight: 150, graphwidth: 300, showTitle: true, - showMini: true, + showMini: false, } var paperbuzzviz = undefined; - //var doi = '10.1080/23800127.2017.1283122'; - //var doi = '10.15252/embj.201695429'; - //var doi = '10.1016/j.quaint.2011.07.044'; - //var doi = '10.4236/sn.2017.62007'; - //var doi = '10.2190/EC.43.3.f' + // var doi = '10.1080/23800127.2017.1283122'; + // var doi = '10.15252/embj.201695429'; + // var doi = '10.1016/j.quaint.2011.07.044'; + // var doi = '10.4236/sn.2017.62007'; + // var doi = '10.2190/EC.43.3.f' var doi = '10.1038/nature.2017.22163'; d3.json('https://api.paperbuzz.org/v0/doi/' + doi, function(data) { options.paperbuzzStatsJson = data diff --git a/paperbuzzviz.js b/paperbuzzviz.js index fb6995c..37b8cfd 100755 --- a/paperbuzzviz.js +++ b/paperbuzzviz.js @@ -83,7 +83,7 @@ function PaperbuzzViz(options) { if (showTitle) { vizDiv.append("a") .attr('href', 'http://dx.doi.org/' + data.doi) - .attr("class", "title") + .attr("class", "paperbuzz-title") .text(data.metadata.title); } @@ -102,7 +102,7 @@ function PaperbuzzViz(options) { metricsFound_ = true; } else { vizDiv.append("p") - .attr("class", "muted") + .attr("class", "paperbuzz-muted") .text("No metrics found."); } }; @@ -113,20 +113,21 @@ function PaperbuzzViz(options) { .attr('id', 'paperbuzz-mini'); miniDiv.append('span') - .attr('class', 'miniViz-total') + .attr('class', 'paperbuzz-mini-total') var total = 0; sources.forEach(function(source) { - miniDiv.append('span') + miniDiv.append('div') + .attr('class', 'paperbuzz-mini-source') .append('i') .attr('class', 'icon-' + source.source_id) .append('span') - .attr('class', 'miniViz-count') + .attr('class', 'paperbuzz-mini-count') .text(source.events_count); total += source.events_count }); - miniDiv.selectAll('.miniViz-total') + miniDiv.selectAll('.paperbuzz-mini-total') .text(total); } @@ -447,15 +448,15 @@ function PaperbuzzViz(options) { viz.bars = viz.svg.append("g"); viz.svg.append("g") - .attr("class", "x axis") + .attr("class", "x paperbuzz-axis") .attr("transform", "translate(0," + (viz.height - 1) + ")"); viz.svg.append("g") - .attr("class", "y axis"); + .attr("class", "y paperbuzz-axis"); viz.tip = d3.tip() - .attr('class', 'paperbuzzTooltip') + .attr('class', 'paperbuzz-tooltip') .html(function(d) { return 'Count: ' + d.count + "
" + 'Date: ' + d.date; }); viz.tip.offset([-10, 0]); // make room for the little triangle viz.svg.call(viz.tip); @@ -523,12 +524,12 @@ function PaperbuzzViz(options) { // TODO: these transitions could use a little work var barWidth = Math.max((viz.width/(timeInterval.range(pub_date, end_date).length + 1)) - 2, 1); - var bars = viz.bars.selectAll(".bar") + var bars = viz.bars.selectAll(".paperbuzz-bar") .data(level_data, function(d) { return getDate(level, d); }); bars .enter().append("rect") - .attr("class", function(d) { return "bar " + viz.z((level == 'day' ? d3.timeWeek(getDate(level, d)) : d.year)); }) + .attr("class", function(d) { return "paperbuzz-bar " + viz.z((level == 'day' ? d3.timeWeek(getDate(level, d)) : d.year)); }) .attr("x", function(d) { return viz.x(getDate(level, d)) + 2; }) // padding of 2, 1 each .attr("y", function(d) { return viz.y(d.count) } ) .attr("width", barWidth) @@ -541,7 +542,7 @@ function PaperbuzzViz(options) { .remove(); viz.svg - .select(".x.axis") + .select(".x.paperbuzz-axis") .call((xAxis) .tickFormat(d3.timeFormat(xFormat))) .selectAll("text") @@ -553,7 +554,7 @@ function PaperbuzzViz(options) { viz.svg .transition().duration(1000) - .select(".y.axis") + .select(".y.paperbuzz-axis") .call(yAxis); } From 3968bf35d08f0f79d3545cf520f94b344658410c Mon Sep 17 00:00:00 2001 From: Juan Pablo Alperin Date: Thu, 19 Jul 2018 22:11:05 -0700 Subject: [PATCH 3/4] fixed bar colouring --- paperbuzzviz.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/paperbuzzviz.js b/paperbuzzviz.js index 37b8cfd..2f16d12 100755 --- a/paperbuzzviz.js +++ b/paperbuzzviz.js @@ -529,7 +529,10 @@ function PaperbuzzViz(options) { bars .enter().append("rect") - .attr("class", function(d) { return "paperbuzz-bar " + viz.z((level == 'day' ? d3.timeWeek(getDate(level, d)) : d.year)); }) + .attr("class", function(d) { + var bartype = (level == 'day' ? d3.timeWeek(getDate(level, d)) : getDate(level, d).getFullYear()); + return "paperbuzz-bar " + viz.z(bartype); + }) .attr("x", function(d) { return viz.x(getDate(level, d)) + 2; }) // padding of 2, 1 each .attr("y", function(d) { return viz.y(d.count) } ) .attr("width", barWidth) From b02bc355bfc79bf57cc9c0fda4034fb1e52864f9 Mon Sep 17 00:00:00 2001 From: Juan Pablo Alperin Date: Thu, 19 Jul 2018 23:00:07 -0700 Subject: [PATCH 4/4] tweaks to time controls on axis --- css/paperbuzzviz.css | 6 +++--- paperbuzzviz.js | 26 ++++++++++---------------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/css/paperbuzzviz.css b/css/paperbuzzviz.css index ee5b9dd..00e98e8 100755 --- a/css/paperbuzzviz.css +++ b/css/paperbuzzviz.css @@ -88,15 +88,15 @@ .paperbuzz-control.active { text-decoration: none; - color: grey; + color: black; } -.paperbuzz-control.disabled { +/*.paperbuzz-control.disabled { cursor: default; text-decoration: none; color: grey; } - +*/ .paperbuzz-control:hover { background-color: transparent; } diff --git a/paperbuzzviz.js b/paperbuzzviz.js index 2f16d12..7573c78 100755 --- a/paperbuzzviz.js +++ b/paperbuzzviz.js @@ -11,28 +11,23 @@ function PaperbuzzViz(options) { $ = options.jQuery || $; // Init basic options - var baseUrl = options.baseUrl; - var hasIcon = options.hasIcon; - var sources = []; - var eventcount = []; - var eventdate = []; - var eventsource =[]; var minItems_ = options.minItemsToShowGraph; var showTitle = options.showTitle; var showMini = options.showMini; + var formatNumber_ = d3.format(",d"); var parseDate = d3.timeParse('%Y-%m-%d'); + var graphheight = options.graphheight; var graphwidth = options.graphwidth; - var published_date = options.published_date || false; - var data = options.paperbuzzStatsJson; + var sources = data.altmetrics_sources; + var published_date = options.published_date || false; if (published_date) { - // accept the published date passed in, if there was one - + // accept published date provided // Will choose pub date based on online pub, print pub, or issued. If no month or day defaults to 01 } else if (data.metadata['published-online']) { published_date = data.metadata["published-online"]["date-parts"][0]; @@ -69,8 +64,7 @@ function PaperbuzzViz(options) { // to track if any metrics have been found var metricsFound_; - - sources = data.altmetrics_sources + /** * Initialize the visualization. @@ -90,7 +84,7 @@ function PaperbuzzViz(options) { vizDiv.append("br"); if (sources.length > 0) { - if (showMini) { + if (showMini || !hasSVG_) { addMiniViz(vizDiv, sources); } else { // loop through sources @@ -269,7 +263,7 @@ function PaperbuzzViz(options) { $levelControlsDiv.append("a") .attr("href", "javascript:void(0)") .classed("paperbuzz-control", true) - .classed("disabled", !showDaily) + // .classed("disabled", !showDaily) .classed("active", (level == 'day')) .text("daily (first 30)") .on("click", function() { @@ -287,7 +281,7 @@ function PaperbuzzViz(options) { $levelControlsDiv.append("a") .attr("href", "javascript:void(0)") .classed("paperbuzz-control", true) - .classed("disabled", !showMonthly || !showYearly) + // .classed("disabled", !showMonthly || !showYearly) .classed("active", (level == 'month')) .text("monthly") .on("click", function() { if (showMonthly && !$(this).hasClass('active')) { @@ -306,7 +300,7 @@ function PaperbuzzViz(options) { $levelControlsDiv.append("a") .attr("href", "javascript:void(0)") .classed("paperbuzz-control", true) - .classed("disabled", !showYearly || !showMonthly) + // .classed("disabled", !showYearly || !showMonthly) .classed("active", (level == 'year')) .text("yearly") .on("click", function() {