|
66 | 66 | border: 1px solid #CCC; |
67 | 67 | border-radius: 4px; |
68 | 68 | } |
| 69 | + .chart rect { |
| 70 | + fill: #337ab7; |
| 71 | + } |
| 72 | + |
| 73 | + .chart text { |
| 74 | + fill: black; |
| 75 | + font: 12px sans-serif; |
| 76 | + text-anchor: end; |
| 77 | + } |
| 78 | + |
| 79 | + .axis path, |
| 80 | + .axis line { |
| 81 | + fill: none; |
| 82 | + stroke: #000; |
| 83 | + shape-rendering: crispEdges; |
| 84 | + } |
| 85 | + .chart {width: 100%;} |
| 86 | + |
69 | 87 | </style> |
70 | 88 | </head> |
71 | 89 | <body> |
|
74 | 92 | <nav class="navbar navbar-default"> |
75 | 93 | <div class="container-fluid"> |
76 | 94 | <div class="navbar-header"> |
77 | | - <span class="navbar-brand icon-primary"><a href="https://github.com/nexB/scancode-toolkit/">ScanCode</a> scan results for: scancode-toolkit2/scancode-toolkit/samples/</span> |
| 95 | + <span class="navbar-brand icon-primary"><a href="https://github.com/nexB/scancode-toolkit/">ScanCode</a> scan results for: {{ scanned_path }}</span> |
78 | 96 | </div> |
79 | 97 | <ul class="nav navbar-nav navbar-right"> |
80 | 98 | <li><a href="http://www.nexb.com">Made by nexB</a></li> |
|
94 | 112 | <div id="tree" style="overflow-x:scroll; overflow-y:auto;"></div> |
95 | 113 | </div> |
96 | 114 |
|
97 | | - <div class="col-md-8"> |
98 | | - <ul class="nav nav-tabs"> |
99 | | - <li id="tab1" class="active"><a data-toggle="tab" href="#">License & Copyright Information</a></li> |
100 | | - <li id="tab2"><a data-toggle="tab" href="#">File Information</a></li> |
101 | | - <li id="tab3"><a data-toggle="tab" href="#">Package Information</a></li> |
102 | | - </ul> |
103 | | - |
104 | | - <table id="data_table" class="data_table display table-wrap" cellspacing="0" width="100%"> |
105 | | - </table> |
| 115 | + <div id="tabbar" class="col-md-8"> |
| 116 | + <ul class="nav nav-tabs"> |
| 117 | + <li id="tab4" class="active"><a data-toggle="tab" href="#chart">License Summary</a></li> |
| 118 | + <li id="tab1"><a data-toggle="tab" href="#">License & Copyright Information</a></li> |
| 119 | + <li id="tab2"><a data-toggle="tab" href="#">File Information</a></li> |
| 120 | + <li id="tab3"><a data-toggle="tab" href="#">Package Information</a></li> |
| 121 | + </ul> |
| 122 | + <div id="summary"> |
| 123 | + <svg class="chart"></svg> |
| 124 | + </div> |
| 125 | + <div id="details"> |
| 126 | + <table id="data_table" class="data_table display table-wrap" cellspacing="0" width="100%"></table> |
| 127 | + </div> |
106 | 128 | </div> |
107 | 129 | </div> |
108 | 130 | </div> |
|
119 | 141 | <script src="{{ assets_dir }}/bootstrap.min.js"></script> |
120 | 142 | <script src="{{ assets_dir }}/jstree.min.js"></script> |
121 | 143 | <script src="{{ assets_dir }}/jquery.dataTables.min.js"></script> |
| 144 | + <script src="{{ assets_dir }}/d3.min.js" charset="utf-8"></script> |
| 145 | + <script src="{{ assets_dir }}/chart.js"></script> |
122 | 146 | <script type="text/javascript" src="{{ assets_dir }}/data.json"></script> |
123 | 147 | <script type="text/javascript"> |
124 | 148 | var icon_file = "glyphicon glyphicon-file"; |
|
128 | 152 | var file_color_empty = "icon-empty"; |
129 | 153 | var dir_color = "icon-primary"; |
130 | 154 | var dir_color_empty = "icon-empty"; |
| 155 | + var currNodeData; |
131 | 156 |
|
132 | 157 | genIconClass = function(isLeaf, isOpen, isEmpty){ |
133 | 158 | icon = isLeaf ? icon_file : (isOpen ? icon_dir_open : icon_dir_close); |
|
146 | 171 | renderTable(dtData); |
147 | 172 |
|
148 | 173 | $( "#tab1" ).click(function() { |
| 174 | + $('#details').show(); |
| 175 | + $('#summary').hide(); |
149 | 176 | table = $('#data_table').DataTable(); |
150 | 177 | table.clear(); |
151 | 178 | table.columns( '.tab1' ).visible( true ); |
152 | 179 | table.columns( '.tab2' ).visible( false ); |
153 | 180 | table.columns( '.tab3' ).visible( false ); |
| 181 | + table.columns( '.tab4' ).visible( false ); |
154 | 182 | table.rows.add(dtData); |
155 | 183 | table.draw(); |
156 | 184 | }); |
157 | 185 | $( "#tab2" ).click(function() { |
| 186 | + $('#details').show(); |
| 187 | + $('#summary').hide(); |
158 | 188 | table = $('#data_table').DataTable(); |
159 | 189 | table.clear(); |
160 | 190 | table.columns( '.tab1' ).visible( false ); |
161 | 191 | table.columns( '.tab2' ).visible( true ); |
162 | 192 | table.columns( '.tab3' ).visible( false ); |
| 193 | + table.columns( '.tab4' ).visible( false ); |
163 | 194 | table.rows.add(dtData2); |
164 | 195 | table.draw(); |
165 | 196 | }); |
166 | 197 | $( "#tab3" ).click(function() { |
| 198 | + $('#details').show(); |
| 199 | + $('#summary').hide(); |
167 | 200 | table = $('#data_table').DataTable(); |
168 | 201 | table.clear(); |
169 | 202 | table.columns( '.tab1' ).visible( false ); |
170 | 203 | table.columns( '.tab2' ).visible( false ); |
171 | 204 | table.columns( '.tab3' ).visible( true ); |
| 205 | + table.columns( '.tab4' ).visible( false ); |
172 | 206 | table.rows.add(dtData3); |
173 | 207 | table.draw(); |
174 | 208 | }); |
| 209 | + $( "#tab4" ).click(function() { |
| 210 | + $('#details').hide(); |
| 211 | + $('#summary').show(); |
| 212 | + resetChart(currNodeData); |
| 213 | + }); |
175 | 214 |
|
176 | | - // TODO: Optimize way to get table to redraw with correct widths |
177 | | - table = $('#data_table').DataTable(); |
178 | | - table.columns( '.tab1' ).visible( false ); |
179 | | - table.columns( '.tab2' ).visible( false ); |
180 | | - table.columns( '.tab3' ).visible( false ); |
181 | | - table.clear(); |
182 | | - table.columns( '.tab1' ).visible( true ); |
183 | | - table.rows.add(dtData); |
184 | | - table.draw(); |
| 215 | + $("#details").hide(); |
185 | 216 | }); |
186 | | - |
187 | 217 | // Returns a row in the format expected by jstree |
188 | | - getJSTreeData = function(parent, id, text, icon_class){ |
| 218 | + function getJSTreeData(parent, id, text, icon_class){ |
189 | 219 | return { |
190 | 220 | "id": id, |
191 | 221 | "parent": parent == "" ? '#' : parent, |
|
197 | 227 | }; |
198 | 228 |
|
199 | 229 | // Return license and copyright data in table format |
200 | | - toDataTableFormat = function(jsonData){ |
| 230 | + function toDataTableFormat(jsonData){ |
201 | 231 | return $.map(jsonData, function(x){ |
202 | 232 | // Add all license columns here |
203 | 233 | licenseData = []; |
|
351 | 381 |
|
352 | 382 | // Renders json data to jsTree format |
353 | 383 | toJSTreeFormat = function(jsonData){ |
| 384 | + // Sort data by location to ensure files are seen before directories |
| 385 | + jsonData.sort(function (a, b) { |
| 386 | + return a.location.localeCompare( b.location ); |
| 387 | + }).reverse(); |
354 | 388 | // Keeps track of IDs |
355 | 389 | var uniqueIDs = {}; |
356 | 390 |
|
|
413 | 447 | } |
414 | 448 | } |
415 | 449 | }) |
416 | | - .on("select_node.jstree", function(e, data) { |
| 450 | + .on("select_node.jstree", function(e, nodeData) { |
417 | 451 | // Redraw data table (forces custom filter to rerun) |
418 | 452 | // TODO: Figure out the tab and only update that table instead of all |
419 | 453 | table = $('#data_table').DataTable(); |
420 | 454 | table.draw(); |
| 455 | + onNodeSelected(nodeData); |
421 | 456 | }) |
422 | 457 | .on('open_node.jstree', function(e, data) { |
423 | 458 | data.instance.set_icon(data.node, genIconClass(false, true, "")); |
|
427 | 462 | }); |
428 | 463 | }; |
429 | 464 |
|
| 465 | + function onNodeSelected(nodeData){ |
| 466 | + currNodeData = nodeData; |
| 467 | + resetChart(currNodeData); |
| 468 | + } |
| 469 | + |
| 470 | + function resetChart(nodeData) { |
| 471 | + barChart.remove(); |
| 472 | + barChart = new BarChart(filteredData(nodeData), chartOptions, '.chart'); |
| 473 | + } |
| 474 | + |
| 475 | + // filter the data |
| 476 | + function filteredData(nodeData){ |
| 477 | + if (typeof nodeData == 'undefined') { |
| 478 | + return formatChartData(data); |
| 479 | + } |
| 480 | + return formatChartData($.map(data, function(item){ |
| 481 | + var pattern = '^' + nodeData.selected[0]; |
| 482 | + pattern += nodeData.node.children.length > 0 ? '/' : ''; |
| 483 | + if (item.location.match(pattern)){ |
| 484 | + return item; |
| 485 | + } else { |
| 486 | + return; |
| 487 | + } |
| 488 | + })); |
| 489 | + } |
| 490 | + |
430 | 491 | // Render the DataTable by specifying Copyright and License |
431 | 492 | renderTable = function(data) { |
432 | 493 | return $('#data_table').DataTable( { |
|
518 | 579 |
|
519 | 580 | $('#button').click(function(){ $('#data_table').toggleClass('ellipsis'); }) |
520 | 581 | </script> |
| 582 | + <script> |
| 583 | + function formatChartData(data) { |
| 584 | + |
| 585 | + var NO_LICENSES = [{short_name: 'No License Found'}] |
| 586 | + // Get license short name and if no license set it to No License Found |
| 587 | + var shortNames = $.map(data, function(item){ |
| 588 | + licenses = item.licenses.length > 0 ? item.licenses : NO_LICENSES; |
| 589 | + return $.map(licenses, function(license) { |
| 590 | + return license.short_name; |
| 591 | + }); |
| 592 | + }); |
| 593 | + |
| 594 | + // Sum the total number of times the license appears |
| 595 | + var count = {}; |
| 596 | + $.each(shortNames, function(i, name){ |
| 597 | + count[name] = count[name] + 1 || 1; |
| 598 | + }); |
| 599 | + |
| 600 | + // Transform license count into array of objects with license name & count |
| 601 | + var chartData = $.map(count, function(val, key) { |
| 602 | + return { |
| 603 | + name: key, |
| 604 | + val: val |
| 605 | + }; |
| 606 | + }); |
| 607 | + |
| 608 | + // Sorts the data highest value to lowest value |
| 609 | + chartData.sort(function(a,b){ |
| 610 | + if (a.val == b.val) { |
| 611 | + return a.name.localeCompare(b.name); |
| 612 | + } else { |
| 613 | + return a.val > b.val ? -1 : 1; |
| 614 | + } |
| 615 | + }); |
| 616 | + return chartData; |
| 617 | + } |
| 618 | + var chartData = formatChartData(data); |
| 619 | + |
| 620 | + // Options for the bar chart |
| 621 | + var chartOptions = { |
| 622 | + name: "License Summary", |
| 623 | + margin: 30, |
| 624 | + barHeight: 25, |
| 625 | + xAxisName: "License Count", |
| 626 | + yAxisName: "License Name" |
| 627 | + }; |
| 628 | + |
| 629 | + // Create and display the bar chart |
| 630 | + barChart = new BarChart(chartData, chartOptions, '.chart'); |
| 631 | + |
| 632 | + $(window).on('resize', barChart.draw); |
| 633 | + </script> |
521 | 634 | </body> |
522 | 635 | </html> |
0 commit comments