diff --git a/README.md b/README.md index d29e713d047b54a1230828478d2dd0b5e10fed97..6fb2e3e8ee9b03cd1e8abfb2f480304654746abd 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with Moodle. If not, see <http://www.gnu.org/licenses/>. Please note that this plugin also contains files that are under the -- MIT License: namely index.js, jquery-3.2.1, textclipper.js. +- MIT License: namely index.js, jquery-3.2.1, textclipper.js, chart.js - Apache License, Version 2.0: namely pdf.js. Google Charts Api is used in download function to convert latex formulae to png: <https://chart.googleapis.com/chart>. diff --git a/controller.php b/controller.php index 900a3f9c6e780f54f953758ba926aa36426a8705..e39c140e39e6751b8b0d296d872a13714b308247 100644 --- a/controller.php +++ b/controller.php @@ -446,7 +446,7 @@ if ($action === 'statistic') { $strings = $stringman->load_component_strings('pdfannotator', 'en'); // Method gets the strings of the language files. $PAGE->requires->strings_for_js(array_keys($strings), 'pdfannotator'); // Method to use the language-strings in javascript. $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/locallib.js?ver=00002")); - $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/statistic.js")); + $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/statistic.js?ver=0001")); $myrenderer = $PAGE->get_renderer('mod_pdfannotator'); $capabilities = new stdClass(); $capabilities->viewquestions = has_capability('mod/pdfannotator:viewquestions', $context); diff --git a/locallib.php b/locallib.php index 9f582b3391dbb2282da58bb65cf6ec8ecd786c6a..86f70e9b72413b0f332de0b93a1ce199e8a70266 100644 --- a/locallib.php +++ b/locallib.php @@ -58,7 +58,7 @@ function pdfannotator_display_embed($pdfannotator, $cm, $course, $file, $page = $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/pdf.js")); $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/pdf_viewer.js")); $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/textclipper.js")); - $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/index.js?ver=00011")); + $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/index.js?ver=00012")); $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/locallib.js?ver=00002")); // Pass parameters from PHP to JavaScript. diff --git a/shared/statistic.js b/shared/statistic.js index 8d69dfe828d5a717a1419558abf6251911cdc842..d4b495c1cae5f38a6b2ed4249eac4b38868eedcf 100644 --- a/shared/statistic.js +++ b/shared/statistic.js @@ -7,58 +7,95 @@ // R: The first parameter has to be Y, because it is a default YUI-object (demanded by moodle). function setCharts(Y, names, otherquestions, myquestions, otheranswers, myanswers) { - Highcharts.setOptions({ - colors: ['rgb(0,84,159)', 'rgb(142,186,229)', 'rgb(87,171,39)', 'rgb(184,214,152)'] - }); - Highcharts.chart('chart_questions_answers', { - chart: { - type: 'column', - borderColor: 'black', - borderWidth: 1 - }, - title: { - text: M.util.get_string('chart_title', 'pdfannotator'), - }, - xAxis: { - categories: names + // On small screens set width depending on number of annotators. Otherwise the diagram is very small. + let width = Math.max(names.length * 25, 300); + width = names.length * 40; + if (window.innerWidth < width) { + document.getElementById('chart-container').style.width = width + "px"; + } + + var maxValue = calculateMax(otherquestions, myquestions, otheranswers, myanswers); + + var ctx = document.getElementById('myChart').getContext('2d'); + var myChart = new Chart(ctx, { + type: 'bar', + data: { + labels: names, + datasets: [{ + label: M.util.get_string('myquestions', 'pdfannotator'), + stack: 'questions', + data: myquestions, + backgroundColor: 'rgb(0,84,159)', + }, { + label: M.util.get_string('questions', 'pdfannotator') + ' ' + M.util.get_string('by_other_users', 'pdfannotator'), + stack: 'questions', + data: otherquestions, + backgroundColor: 'rgb(142,186,229)', + }, + { + label: M.util.get_string('myanswers', 'pdfannotator'), + stack: 'answers', + data: myanswers, + backgroundColor: 'rgb(87,171,39)', + }, + { + label: M.util.get_string('answers', 'pdfannotator') + ' ' + M.util.get_string('by_other_users', 'pdfannotator'), + stack: 'answers', + data: otheranswers, + backgroundColor: 'rgb(184,214,152)', + }] }, - yAxis: { - allowDecimals: false, + options: { + maintainAspectRatio: false, title: { - text: M.util.get_string('count', 'pdfannotator') + display: true, + text: M.util.get_string('chart_title', 'pdfannotator'), + fontSize: 20 }, - reversedStacks: false - }, - plotOptions: { - column: { - stacking: 'normal' + legend: { + display: true, + position: 'bottom' + }, + scales: { + + xAxes: [{ + stacked: true + }], + yAxes: [{ + ticks: { + beginAtZero: true, + precision: 0, + max: maxValue + 2 + } + }] + }, + tooltips: { + mode: 'x' + }, + layout: { + padding: { + left: 0, + right: 0, + top: 0, + bottom: 0 + } } - }, - tooltip: { - headerFormat: '<b>{point.key}</b><br/>', - pointFormat: '{series.name}: {point.y}<br/>' + M.util.get_string('total', 'pdfannotator') + ': {point.stackTotal}' - }, - legend: { - itemWidth: 225 - }, - series: [{ - name: M.util.get_string('myquestions', 'pdfannotator'), - data: myquestions, - stack: 'questions' - }, { - name: M.util.get_string('questions', 'pdfannotator') + ' ' + M.util.get_string('by_other_users', 'pdfannotator'), - data: otherquestions, - stack: 'questions' - }, { - name: M.util.get_string('myanswers', 'pdfannotator'), - data: myanswers, - stack: 'answers' - }, { - name: M.util.get_string('answers', 'pdfannotator') + ' ' + M.util.get_string('by_other_users', 'pdfannotator'), - data: otheranswers, - stack: 'answers' - }] + } }); } + +function calculateMax(otherquestions, myquestions, otheranswers, myanswers) { + let max = 0; + for (let i = 0; i < otherquestions.length; ++i) { + if (otherquestions[i] + myquestions[i] > max) { + max = otherquestions[i] + myquestions[i]; + } + if (otheranswers[i] + myanswers[i] > max) { + max = otheranswers[i] + myanswers[i]; + } + } + + return max; +} diff --git a/styles.css b/styles.css index b6ab92caa1e544ede584e77634f663916a66bbfa..276ed314a6a7ba8a0a3342a5152f0cc43911c8bb 100644 --- a/styles.css +++ b/styles.css @@ -424,11 +424,11 @@ body { } .path-mod-pdfannotator .chat-message.mark { - border: 3px solid red !important + border: 3px solid red !important; } .path-mod-pdfannotator .chat-message.correct { - border: 3px solid green !important + border: 3px solid green !important; } .path-mod-pdfannotator .chat-message:not(.questioncomment) { @@ -461,7 +461,7 @@ body { } .path-mod-pdfannotator .chat-message .time, -.path-mod-pdfannotator .chat-message .edited{ +.path-mod-pdfannotator .chat-message .edited { float: right; font-size: 11px; color: #777; @@ -495,7 +495,7 @@ body { width: 100%; } -.path-mod-pdfannotator :not(.questioncomment) > .chat-message-text p{ +.path-mod-pdfannotator :not(.questioncomment) > .chat-message-text p { margin-bottom: 0; } @@ -528,7 +528,7 @@ body { } /*AnkerToolbar*/ -.path-mod-pdfannotator .fixtool{ +.path-mod-pdfannotator .fixtool { position: fixed !important; overflow-x: auto; overflow-y: visible; @@ -536,7 +536,7 @@ body { right: unset !important; } -.path-mod-pdfannotator.fullscreenWrapper #region-main{ +.path-mod-pdfannotator.fullscreenWrapper #region-main { position: fixed ; top: 0px; left: 0px; @@ -560,7 +560,7 @@ body { visibility: hidden; } -.path-mod-pdfannotator.fullscreenWrapper #block-region-side-pre{ +.path-mod-pdfannotator.fullscreenWrapper #block-region-side-pre { display: none; visibility: hidden; } @@ -571,7 +571,7 @@ body { } .path-mod-pdfannotator.fullscreenWrapper .m-t-2.m-b-1, -.path-mod-pdfannotator.fullscreenWrapper .m-t-1.m-b-1{ +.path-mod-pdfannotator.fullscreenWrapper .m-t-1.m-b-1 { display: none; visibility: hidden; } @@ -631,19 +631,19 @@ table td, table th { padding: 9px 10px; text-align: left; } Mobile @media only screen and (max-width: 767px) { - table.flexible { margin-bottom: 0; } + table.flexible { margin-bottom: 0; } - .pinned { position: absolute; left: 0; top: 0; background: #fff; width: 35%; overflow: hidden; overflow-x: scroll; border-right: 1px solid #ccc; border-left: 1px solid #ccc; } - .pinned table { border-right: none; border-left: none; width: 100%; } - .pinned table th, .pinned table td { white-space: nowrap; } - .pinned td:last-child { border-bottom: 0; } + .pinned { position: absolute; left: 0; top: 0; background: #fff; width: 35%; overflow: hidden; overflow-x: scroll; border-right: 1px solid #ccc; border-left: 1px solid #ccc; } + .pinned table { border-right: none; border-left: none; width: 100%; } + .pinned table th, .pinned table td { white-space: nowrap; } + .pinned td:last-child { border-bottom: 0; } - div.table-wrapper { position: relative; margin-bottom: 20px; overflow: hidden; border-right: 1px solid #ccc; } - div.table-wrapper div.scrollable { margin-left: 35%; } - div.table-wrapper div.scrollable { overflow: scroll; overflow-y: hidden; } + div.table-wrapper { position: relative; margin-bottom: 20px; overflow: hidden; border-right: 1px solid #ccc; } + div.table-wrapper div.scrollable { margin-left: 35%; } + div.table-wrapper div.scrollable { overflow: scroll; overflow-y: hidden; } - table.flexible td, table.flexible th { position: relative; white-space: nowrap; overflow: hidden; } - table.flexible th:first-child, table.flexible td:first-child, table.flexible td:first-child, table.flexible.pinned td { display: none; } + table.flexible td, table.flexible th { position: relative; white-space: nowrap; overflow: hidden; } + table.flexible th:first-child, table.flexible td:first-child, table.flexible td:first-child, table.flexible.pinned td { display: none; } }*/ @@ -675,38 +675,37 @@ table td, table th { padding: 9px 10px; text-align: left; } }*/ @media only screen and (max-width: 414px) { - #mod-pdfannotator-questions th:nth-child(2), #mod-pdfannotator-questions td:nth-child(2), - #mod-pdfannotator-questions th:nth-child(3), #mod-pdfannotator-questions td:nth-child(3), - #mod-pdfannotator-questions th:nth-child(4), #mod-pdfannotator-questions td:nth-child(4), - #mod-pdfannotator-questions th:nth-child(5), #mod-pdfannotator-questions td:nth-child(5), - #mod-pdfannotator-questions th:nth-child(6), #mod-pdfannotator-questions td:nth-child(6), - #mod-pdfannotator-answers th:nth-child(2), #mod-pdfannotator-answers td:nth-child(2), - #mod-pdfannotator-answers th:nth-child(3), #mod-pdfannotator-answers td:nth-child(3), - #mod-pdfannotator-answers th:nth-child(5), #mod-pdfannotator-answers td:nth-child(5), - #mod-pdfannotator-answers th:nth-child(6), #mod-pdfannotator-answers td:nth-child(6), - #mod-pdfannotator-ownposts th:nth-child(2), #mod-pdfannotator-ownposts td:nth-child(2), - #mod-pdfannotator-ownposts th:nth-child(3), #mod-pdfannotator-ownposts td:nth-child(3), - #mod-pdfannotator-ownposts th:nth-child(4), #mod-pdfannotator-ownposts td:nth-child(4), - #mod-pdfannotator-reports th:nth-child(2), #mod-pdfannotator-reports td:nth-child(2), - #mod-pdfannotator-reports th:nth-child(3), #mod-pdfannotator-reports td:nth-child(3), - #mod-pdfannotator-reports th:nth-child(4), #mod-pdfannotator-reports td:nth-child(4), - #mod-pdfannotator-reports th:nth-child(5), #mod-pdfannotator-reports td:nth-child(5), - .path-mod-pdfannotator .text - { - display: none; - visibility: hidden; - } - .path-mod-pdfannotator #region-main-box { - padding-right: 0px; - padding-left: 0px; - /*overflow: visible;*/ - } - .path-mod-pdfannotator .text_to_html { - word-break: break-all; - } - .path-mod-pdfannotator #itemsperpagewrapper { - display: block; - } + #mod-pdfannotator-questions th:nth-child(2), #mod-pdfannotator-questions td:nth-child(2), + #mod-pdfannotator-questions th:nth-child(3), #mod-pdfannotator-questions td:nth-child(3), + #mod-pdfannotator-questions th:nth-child(4), #mod-pdfannotator-questions td:nth-child(4), + #mod-pdfannotator-questions th:nth-child(5), #mod-pdfannotator-questions td:nth-child(5), + #mod-pdfannotator-questions th:nth-child(6), #mod-pdfannotator-questions td:nth-child(6), + #mod-pdfannotator-answers th:nth-child(2), #mod-pdfannotator-answers td:nth-child(2), + #mod-pdfannotator-answers th:nth-child(3), #mod-pdfannotator-answers td:nth-child(3), + #mod-pdfannotator-answers th:nth-child(5), #mod-pdfannotator-answers td:nth-child(5), + #mod-pdfannotator-answers th:nth-child(6), #mod-pdfannotator-answers td:nth-child(6), + #mod-pdfannotator-ownposts th:nth-child(2), #mod-pdfannotator-ownposts td:nth-child(2), + #mod-pdfannotator-ownposts th:nth-child(3), #mod-pdfannotator-ownposts td:nth-child(3), + #mod-pdfannotator-ownposts th:nth-child(4), #mod-pdfannotator-ownposts td:nth-child(4), + #mod-pdfannotator-reports th:nth-child(2), #mod-pdfannotator-reports td:nth-child(2), + #mod-pdfannotator-reports th:nth-child(3), #mod-pdfannotator-reports td:nth-child(3), + #mod-pdfannotator-reports th:nth-child(4), #mod-pdfannotator-reports td:nth-child(4), + #mod-pdfannotator-reports th:nth-child(5), #mod-pdfannotator-reports td:nth-child(5), + .path-mod-pdfannotator .text { + display: none; + visibility: hidden; + } + .path-mod-pdfannotator #region-main-box { + padding-right: 0px; + padding-left: 0px; + /*overflow: visible;*/ + } + .path-mod-pdfannotator .text_to_html { + word-break: break-all; + } + .path-mod-pdfannotator #itemsperpagewrapper { + display: block; + } } .path-mod-pdfannotator nav.pagination:nth-of-type(1) { @@ -728,12 +727,12 @@ header, section, footer, aside, nav, main, article, figure { /* Dropdown Button */ .path-mod-pdfannotator .dropbtn { - background-color: #3498DB; - color: white; - padding: 16px; - font-size: 16px; - border: none; - cursor: pointer; + background-color: #3498DB; + color: white; + padding: 16px; + font-size: 16px; + border: none; + cursor: pointer; } /* For mobile phones: */ /* Only overview tables. Not table in reportform */ @@ -743,36 +742,36 @@ header, section, footer, aside, nav, main, article, figure { /* Dropdown button on hover & focus */ .path-mod-pdfannotator .dropbtn:hover, .path-mod-pdfannotator .dropbtn:focus { - background-color: #2980B9; + background-color: #2980B9; } /* The container <div> - needed to position the dropdown content */ .path-mod-pdfannotator .dropdown { - position: relative; - display: inline-block; + position: relative; + display: inline-block; } /* Dropdown Content (Hidden by Default) */ .path-mod-pdfannotator .dropdown-content { - display: none; - position: absolute; - background-color: #f1f1f1; - min-width: 160px; - box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); - z-index: 55; + display: none; + position: absolute; + background-color: #f1f1f1; + min-width: 160px; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + z-index: 55; } /* Links inside the dropdown */ .path-mod-pdfannotator .dropdown-content a { - color: black; - padding: 12px 16px; - text-decoration: none; - display: block; + color: black; + padding: 12px 16px; + text-decoration: none; + display: block; } /* Change color of dropdown links on hover */ .path-mod-pdfannotator .dropdown-content a:hover { - background-color: #ddd + background-color: #ddd; } .path-mod-pdfannotator .dropdown [type="button"] { @@ -781,11 +780,11 @@ header, section, footer, aside, nav, main, article, figure { /* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */ .path-mod-pdfannotator .show { - display:block; + display: block; } .path-mod-pdfannotator a.morelink { - text-decoration:none !important; + text-decoration: none !important; outline: none; } @@ -793,7 +792,7 @@ header, section, footer, aside, nav, main, article, figure { display: none; } -.path-mod-pdfannotator .annotator { +.path-mod-pdfannotator .annotator { text-decoration: none !important; } @@ -854,6 +853,10 @@ header, section, footer, aside, nav, main, article, figure { } @keyframes animatebottom { - from{ bottom:-100px; opacity:0 } - to{ bottom:0; opacity:1 } + from { bottom:-100px; opacity:0 } + to { bottom:0; opacity:1 } +} + +.path-mod-pdfannotator .pdfannotator-statistic #chart-container { + min-height: 500px; } diff --git a/templates/statistic.mustache b/templates/statistic.mustache index f4666b302ccf53944f6bd1567ae606d901cd6aee..8e33ee24253a33805660a728490d1b6b72c1f8f6 100644 --- a/templates/statistic.mustache +++ b/templates/statistic.mustache @@ -1,4 +1,4 @@ - <script src="https://code.highcharts.com/highcharts.js"></script> <!-- TODO replace with local version! --> +<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js" charset="utf-8"></script> <div class="pdfannotator-statistic"> @@ -27,6 +27,16 @@ </div> </div> + + <div class="row"> + <div class="col-md-12"> + + <div id="chart-container"> + <canvas id="myChart"></canvas> + </div> + + </div> + </div> </div> diff --git a/version.php b/version.php index b6199c02c926f3d9053d1ccabc876cf6e1a63ad8..3c7512f2e5d1f998ae19b00e2ff76be3fdb51ea6 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'mod_pdfannotator'; // Full name of the plugin (used for diagnostics). -$plugin->version = 2019070900; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2019100100; // The current module version (Date: YYYYMMDDXX). $plugin->release = 'PDF Annotator v1.1 release 1'; $plugin->requires = 2016112900; // Requires this Moodle version. $plugin->cron = 0; // Period for cron to check this module (secs).