diff --git a/Help/3 Analysis Modules/1 Basic Statistics.html b/Help/3 Analysis Modules/1 Basic Statistics.html
index 76766aa..e23a70a 100644
--- a/Help/3 Analysis Modules/1 Basic Statistics.html
+++ b/Help/3 Analysis Modules/1 Basic Statistics.html
@@ -1,7 +1,7 @@
-Basic Statistics
+Basic statistics
-Basic Statistics
+Basic statistics
Summary
-The Basic Statistics module generates some simple composition
+The Basic statistics module generates some simple composition
statistics for the file analysed.
@@ -21,8 +21,8 @@ Summary
File type: Says whether the file appeared to contain actual base calls or
colorspace data which had to be converted to base calls
Encoding: Says which ASCII encoding of quality values was found in this
-file.
- Total Sequences: A count of the total number of sequences processed.
+file.
+Total Sequences: A count of the total number of sequences processed.
There are two values reported, actual and estimated. At the moment these
will always be the same. In the future it may be possible to analyse just
a subset of sequences and estimate the total number, to speed up the analysis,
@@ -41,12 +41,12 @@ Summary
Warning
-Basic Statistics never raises a warning.
+Basic statistics never raises a warning.
Failure
-Basic Statistics never raises an error.
+Basic statistics never raises an error.
Common reasons for warnings
diff --git a/Help/3 Analysis Modules/10 Adapter Content.html b/Help/3 Analysis Modules/10 Adapter Content.html
index e5fa778..5cc5c3f 100644
--- a/Help/3 Analysis Modules/10 Adapter Content.html
+++ b/Help/3 Analysis Modules/10 Adapter Content.html
@@ -1,7 +1,7 @@
-Adapter Content
+Adapter content
-Adapter Content
+Adapter content
Summary
The Kmer Content module will do a generic analysis of all of the Kmers
diff --git a/Help/3 Analysis Modules/4 Per Base Sequence Content.html b/Help/3 Analysis Modules/4 Per Base Sequence Content.html
index bae1142..b4dd69b 100644
--- a/Help/3 Analysis Modules/4 Per Base Sequence Content.html
+++ b/Help/3 Analysis Modules/4 Per Base Sequence Content.html
@@ -59,7 +59,7 @@
Common reasons for warnings
Overrepresented sequences: If there is any evidence of overrepresented
sequences such as adapter dimers or rRNA in a sample then these sequences
-may bias the overall composition and their sequence will emerge from this plot.
+may bias the overall composition and their sequence will emerge from this plot.
Biased fragmentation: Any library which is generated based on the ligation
of random hexamers or through tagmentation should theoretically have good
diversity through the sequence, but experience has shown that these libraries
@@ -67,7 +67,7 @@ Common reasons for warnings
due to a biased selection of random primers, but doesn't represent any individually
biased sequences. Nearly all RNA-Seq libraries will fail this module because of
this bias, but this is not a problem which can be fixed by processing, and it
-doesn't seem to adversely affect the ablity to measure expression.
+doesn't seem to adversely affect the ablity to measure expression.
Biased composition libraries: Some libraries are inherently biased in their
sequence composition. The most obvious example would be a library which has been
treated with sodium bisulphite which will then have converted most of the cytosines
@@ -80,6 +80,7 @@ Common reasons for warnings
only sequences which do not match. Sudden deviations in composition at the end
of libraries which have undergone aggressive trimming are therefore likely to be
spurious.
+
diff --git a/Help/3 Analysis Modules/6 Per Base N Content.html b/Help/3 Analysis Modules/6 Per Base N Content.html
index 443a119..440b89a 100644
--- a/Help/3 Analysis Modules/6 Per Base N Content.html
+++ b/Help/3 Analysis Modules/6 Per Base N Content.html
@@ -13,7 +13,7 @@ Per Base N Content
Summary
If a sequencer is unable to make a base call with sufficient confidence
-then it will normally substitute an N rather than a conventional base]
+then it will normally substitute an N rather than a conventional base
call
diff --git a/Help/3 Analysis Modules/7 Sequence Length Distribution.html b/Help/3 Analysis Modules/7 Sequence Length Distribution.html
index 27bbbb9..eeca7a2 100644
--- a/Help/3 Analysis Modules/7 Sequence Length Distribution.html
+++ b/Help/3 Analysis Modules/7 Sequence Length Distribution.html
@@ -1,7 +1,7 @@
-Sequence Length Distribution
+Sequence length distribution
-Sequence Length Distribution
+Sequence length distribution
Summary
Some high throughput sequencers generate sequence fragments
diff --git a/README.md b/README.md
index ee8f15d..164c546 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,10 @@
-# FastQC
+
+
+
+
+
+
+
**A Quality Control application for FastQ files**
@@ -23,7 +29,8 @@ FastQC is an application which takes a FastQ file and runs a series of tests on
FastQC can be run either as an interactive graphical application which allows you to view results for multiple files in a single application. Alternatively you can run the program in a non interactive way (say as part of a pipeline) which will generate an HTML report for each file you process.
FastQC is a cross-platform application, written in java. In theory it should run on any platform which has a suitable java runtime environment.
-Having said that we've only tested in on Windows, MacOSX and Linux running the Oracle v1.6 to 1.8 JREs. Please let us know what happened if you try running it on other platforms / JREs. Please see the detailed instructions in the INSTALL.txt document to tell you how to get a suitable java version to run FastQC on your system.
+Having said that we've only tested in on Windows, MacOSX and Linux running the Oracle v1.6 to 1.8 JREs. Please let us know what happened if you try running it on other platforms / JREs.
+Please see the detailed instructions [in `INSTALL.md`](`INSTALL.md`) to tell you how to get a suitable java version to run FastQC on your system.
## Installation
@@ -31,8 +38,15 @@ Please see the [**project web page**](http://www.bioinformatics.babraham.ac.uk/p
## Contributions
-If you have any comments about FastQC we would like to hear them. You can either enter them into the github bug tracker at:
+If you have any comments about FastQC we would like to hear them.
+You can either create a [GitHub issue](https://github.com/s-andrews/FastQC/issues/) or send them directly to simon.andrews@babraham.ac.uk.
-https://github.com/s-andrews/FastQC/issues/
+FastQC was written by Simon Andrews, at the Babraham Institute, Cambridge, UK.
-..or send them directly to simon.andrews@babraham.ac.uk.
+https://www.bioinformatics.babraham.ac.uk/
+
+
+
+
+
+
diff --git a/Templates/Icons/error.png b/Templates/Icons/error.png
deleted file mode 100644
index edb1fd8..0000000
Binary files a/Templates/Icons/error.png and /dev/null differ
diff --git a/Templates/Icons/error.svg b/Templates/Icons/error.svg
new file mode 100644
index 0000000..e0adc44
--- /dev/null
+++ b/Templates/Icons/error.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/Templates/Icons/fastqc_icon.png b/Templates/Icons/fastqc_icon.png
deleted file mode 100644
index 348c93b..0000000
Binary files a/Templates/Icons/fastqc_icon.png and /dev/null differ
diff --git a/Templates/Icons/fastqc_icon.svg b/Templates/Icons/fastqc_icon.svg
new file mode 100644
index 0000000..618ccb4
--- /dev/null
+++ b/Templates/Icons/fastqc_icon.svg
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Templates/Icons/pass.svg b/Templates/Icons/pass.svg
new file mode 100644
index 0000000..39f109f
--- /dev/null
+++ b/Templates/Icons/pass.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/Templates/Icons/tick.png b/Templates/Icons/tick.png
deleted file mode 100644
index 9c6a456..0000000
Binary files a/Templates/Icons/tick.png and /dev/null differ
diff --git a/Templates/Icons/warning.png b/Templates/Icons/warning.png
deleted file mode 100644
index 34db221..0000000
Binary files a/Templates/Icons/warning.png and /dev/null differ
diff --git a/Templates/Icons/warning.svg b/Templates/Icons/warning.svg
new file mode 100644
index 0000000..3023ec0
--- /dev/null
+++ b/Templates/Icons/warning.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/Templates/fastqc.css b/Templates/fastqc.css
new file mode 100644
index 0000000..1d6cc43
--- /dev/null
+++ b/Templates/fastqc.css
@@ -0,0 +1,464 @@
+/* FastQC CSS Stylesheet */
+
+/* RESET AND BASE STYLES */
+
+* {
+ box-sizing: border-box;
+}
+html {
+ scroll-padding-top: 2rem;
+}
+body {
+ font-family: sans-serif;
+ color: #000;
+ background-color: #FFF;
+ border: 0;
+ margin: 0;
+ padding: 0;
+}
+
+img {
+ max-width: 100%;
+}
+
+p.plot {
+ margin: 1rem 0;
+}
+p.plot > svg {
+ max-width: 100%;
+ height: auto;
+ display: block;
+}
+
+p {
+ margin: 1rem 0;
+}
+
+a {
+ color: #000080;
+ transition: color 0.2s ease;
+}
+a:hover {
+ color: #800000;
+}
+
+
+/* LAYOUT COMPONENTS */
+
+.container {
+ display: flex;
+}
+
+.sidebar {
+ flex: 0 0 300px;
+ background-color: #F8F8F8;
+ border-right: 1px solid #CCC;
+ position: sticky;
+ top: 0;
+ height: 100vh;
+ overflow-y: auto;
+}
+
+.sidebar-header {
+ background-color: #EEE;
+ padding: 1rem;
+ border-bottom: 1px solid #CCC;
+}
+
+.sidebar-header a {
+ text-decoration: none;
+ color: #000;
+}
+
+.header-title {
+ margin: 0 0 0.5rem;
+}
+.header-title a {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.header-title svg {
+ height: 34px;
+ width: auto;
+}
+
+.header-filename {
+ font-size: 0.85rem;
+}
+
+.header-filename p {
+ margin: 0.25rem 0;
+}
+
+.main {
+ padding: 0 2rem;
+ overflow-x: auto;
+ width: 100%;
+}
+
+.module {
+ padding: 1rem 0 2rem;
+ overflow-x: auto;
+}
+
+.footer {
+ margin-top: 3rem;
+ padding: 1.5rem 0;
+ border-top: 1px solid #EEE;
+ font-size: 0.9rem;
+ color: #666;
+}
+
+/* NAVIGATION STYLES */
+
+.navigation {
+ padding: 1rem 0;
+}
+
+.navigation h2 {
+ margin: 0 0 1rem 1rem;
+ font-size: 1.1rem;
+}
+
+.navigation ul {
+ padding: 0;
+ margin: 0;
+ list-style-type: none;
+}
+.navigation li {
+ padding: 0;
+ border-bottom: 1px solid #DDD;
+}
+.navigation li:last-child {
+ border-bottom: none;
+}
+
+.navigation li a {
+ padding: 0.5rem 1rem;
+ transition: background-color 0.2s ease;
+ text-decoration: none;
+ color: #000;
+ font-size: 0.9rem;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+.navigation li a:hover {
+ background-color: #F0F0F0;
+}
+.navigation li span {
+ display: inline-block;
+ border: 2px solid;
+ border-radius: 0.2rem;
+ font-size: 0.7rem;
+ padding: 0.1rem 0.3rem;
+ text-align: center;
+ min-width: 3.5rem;
+ text-transform: uppercase;
+ font-weight: bold;
+}
+
+/* Status indicators */
+.sidebar-error {
+ background-color: #f0c6bc;
+ color: #862a13;
+ border-color: #862a13;
+}
+
+.sidebar-warning {
+ background-color: #e8d28f;
+ color: #8d6c08;
+ border-color: #8d6c08;
+}
+
+.sidebar-pass {
+ background-color: #afe0b7;
+ color: #2f6638;
+ border-color: #2f6638;
+}
+
+/* CONTENT STYLING */
+h1 {
+ font-size: 1.8rem;
+}
+
+h2 {
+ padding-bottom: 0.5rem;
+ margin-bottom: 1rem;
+ color: #800000;
+ border-bottom: 2px solid #800000;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+.module-title {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+table {
+ margin: 1rem 0;
+ border-collapse: collapse;
+ width: 100%;
+ min-width: 600px;
+}
+
+th {
+ text-align: center;
+ background-color: #000080;
+ color: #FFF;
+ padding: 0.75rem 0.5rem;
+ font-weight: bold;
+}
+
+td {
+ font-family: monospace;
+ background-color: #F5F5F5;
+ color: #000;
+ padding: 0.5rem;
+ border-bottom: 1px solid #DDD;
+}
+tr:nth-child(even) td {
+ background-color: #EEE;
+}
+
+/* Basic statistics table styling (first module) */
+.module:first-of-type table thead {
+ display: none;
+}
+.module:first-of-type table td {
+ font-family: sans-serif;
+ background-color: transparent;
+}
+.module:first-of-type table tbody td:first-child {
+ font-weight: bold;
+ color: #333;
+ text-align: right;
+ width: 12rem;
+}
+.module:first-of-type table tbody tr:last-child td {
+ border-bottom: none;
+}
+
+/* HELP TOGGLE FUNCTIONALITY */
+
+/* Hide the checkbox */
+.help-checkbox {
+ display: none;
+}
+
+/* Style the label as a button */
+.help-toggle {
+ background-color: #3498db;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ padding: 4px 8px;
+ font-size: 11px;
+ font-weight: normal;
+ cursor: pointer;
+ transition: background-color 0.3s ease;
+}
+
+.help-toggle:hover {
+ background-color: #2980b9;
+}
+
+/* Show/hide text logic */
+.help-hide, .help-checkbox:checked ~ h2 .help-toggle .help-show {
+ display: none;
+}
+
+.help-checkbox:checked ~ h2 .help-toggle .help-hide {
+ display: inline;
+}
+
+.help-box {
+ background-color: #f8f9fa;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ padding: 0 15px;
+ margin-bottom: 0;
+ font-size: 0.8rem;
+ line-height: 1.5;
+ max-height: 0;
+ overflow: hidden;
+ opacity: 0;
+ transition: max-height 0.3s ease-out, opacity 0.3s ease-out, padding 0.3s ease-out, margin 0.3s ease-out;
+}
+
+/* Show help box when checkbox is checked */
+.help-checkbox:checked ~ .help-box {
+ max-height: 1000px;
+ opacity: 1;
+ padding-top: 15px;
+ padding-bottom: 15px;
+ margin: 10px 0 20px 0;
+}
+
+.help-box h4 {
+ margin: 0.5rem 0 0;
+}
+.help-box h4:first-child {
+ margin-top: 0;
+}
+
+.help-box p {
+ margin: 0 0 10px;
+}
+
+.help-box ul {
+ margin: 0 0 10px;
+ padding-left: 20px;
+}
+
+/* RESPONSIVE DESIGN - SMALL SCREENS */
+
+.mobile-nav {
+ display: none;
+ background-color: #EEE;
+ padding: 0.75rem 1rem;
+ border-bottom: 1px solid #CCC;
+ align-items: center;
+ justify-content: space-between;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 1000;
+}
+
+.menu-toggle-input {
+ display: none;
+}
+
+.menu-toggle {
+ cursor: pointer;
+ padding: 0.25rem;
+ display: flex;
+ flex-direction: column;
+ gap: 3px;
+}
+
+.hamburger {
+ width: 20px;
+ height: 2px;
+ background-color: #333;
+ transition: all 0.3s ease;
+}
+
+.mobile-title {
+ font-size: 1rem;
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 0.25rem;
+ margin-right: 1rem;
+}
+.mobile-title svg {
+ height: 24px;
+ width: auto;
+}
+
+.mobile-title-app {
+ font-weight: bold;
+}
+
+.mobile-title-filename {
+ font-size: 0.9rem;
+ color: #666;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+@media (max-width: 768px) {
+ html {
+ scroll-padding-top: 60px;
+ }
+ .mobile-nav {
+ display: flex;
+ }
+
+ .container {
+ margin-top: 45px;
+ }
+ .main {
+ padding: 0 1rem;
+ }
+ .sidebar {
+ position: fixed;
+ top: 45px;
+ left: 0;
+ right: 0;
+ width: 100%;
+ height: calc(100vh - 45px);
+ transform: translateY(-100%);
+ transition: transform 0.3s ease;
+ z-index: 999;
+ border: none;
+ }
+ .sidebar-header {
+ display: none;
+ }
+
+ /* Show sidebar when menu is toggled - slide down from top */
+ .menu-toggle-input:checked ~ .container .sidebar {
+ transform: translateY(0);
+ }
+
+ /* Hamburger animation when menu is open */
+ .menu-toggle-input:checked ~ .mobile-nav .hamburger:nth-child(1) {
+ transform: rotate(45deg) translate(3px, 3px);
+ }
+ .menu-toggle-input:checked ~ .mobile-nav .hamburger:nth-child(2) {
+ opacity: 0;
+ }
+ .menu-toggle-input:checked ~ .mobile-nav .hamburger:nth-child(3) {
+ transform: rotate(-45deg) translate(4px, -4px);
+ }
+
+ table {
+ font-size: 0.85rem;
+ }
+
+ th, td {
+ padding: 0.5rem 0.25rem;
+ }
+}
+
+
+
+/* PRINT STYLES */
+
+@media print {
+ img,
+ p.plot > svg {
+ max-width: 100% !important;
+ page-break-inside: avoid;
+ }
+
+ h2, h3 {
+ page-break-after: avoid;
+ }
+
+ .sidebar-header {
+ background-color: #FFF;
+ }
+
+ .mobile-nav {
+ display: none !important;
+ }
+
+ .sidebar {
+ position: static !important;
+ transform: none !important;
+ width: auto !important;
+ }
+
+ .container {
+ flex-direction: column !important;
+ }
+}
diff --git a/Templates/fastqc2fo.xsl b/Templates/fastqc2fo.xsl
index 83f6817..6986387 100644
--- a/Templates/fastqc2fo.xsl
+++ b/Templates/fastqc2fo.xsl
@@ -48,9 +48,7 @@
-
-
-
+
diff --git a/Templates/header_template.html b/Templates/header_template.html
deleted file mode 100644
index 7ffb43b..0000000
--- a/Templates/header_template.html
+++ /dev/null
@@ -1,186 +0,0 @@
-
- @media screen {
- div.summary {
- width: 18em;
- position:fixed;
- top: 3em;
- margin:1em 0 0 1em;
- }
-
- div.main {
- display:block;
- position:absolute;
- overflow:auto;
- height:auto;
- width:auto;
- top:4.5em;
- bottom:2.3em;
- left:18em;
- right:0;
- border-left: 1px solid #CCC;
- padding:0 0 0 1em;
- background-color: white;
- z-index:1;
- }
-
- div.header {
- background-color: #EEE;
- border:0;
- margin:0;
- padding: 0.5em;
- font-size: 200%;
- font-weight: bold;
- position:fixed;
- width:100%;
- top:0;
- left:0;
- z-index:2;
- }
-
- div.footer {
- background-color: #EEE;
- border:0;
- margin:0;
- padding:0.5em;
- height: 1.3em;
- overflow:hidden;
- font-size: 100%;
- font-weight: bold;
- position:fixed;
- bottom:0;
- width:100%;
- z-index:2;
- }
-
- img.indented {
- margin-left: 3em;
- }
- }
-
- @media print {
- img {
- max-width:100% !important;
- page-break-inside: avoid;
- }
- h2, h3 {
- page-break-after: avoid;
- }
- div.header {
- background-color: #FFF;
- }
-
- }
-
- body {
- font-family: sans-serif;
- color: #000;
- background-color: #FFF;
- border: 0;
- margin: 0;
- padding: 0;
- }
-
- div.header {
- border:0;
- margin:0;
- padding: 0.5em;
- font-size: 200%;
- font-weight: bold;
- width:100%;
- }
-
- #header_title {
- display:inline-block;
- float:left;
- clear:left;
- }
- #header_filename {
- display:inline-block;
- float:right;
- clear:right;
- font-size: 50%;
- margin-right:2em;
- text-align: right;
- }
-
- div.header h3 {
- font-size: 50%;
- margin-bottom: 0;
- }
-
- div.summary ul {
- padding-left:0;
- list-style-type:none;
- }
-
- div.summary ul li img {
- margin-bottom:-0.5em;
- margin-top:0.5em;
- }
-
- div.main {
- background-color: white;
- }
-
- div.module {
- padding-bottom:1.5em;
- padding-top:1.5em;
- }
-
- div.footer {
- background-color: #EEE;
- border:0;
- margin:0;
- padding: 0.5em;
- font-size: 100%;
- font-weight: bold;
- width:100%;
- }
-
-
- a {
- color: #000080;
- }
-
- a:hover {
- color: #800000;
- }
-
- h2 {
- color: #800000;
- padding-bottom: 0;
- margin-bottom: 0;
- clear:left;
- }
-
- table {
- margin-left: 3em;
- text-align: center;
- }
-
- th {
- text-align: center;
- background-color: #000080;
- color: #FFF;
- padding: 0.4em;
- }
-
- td {
- font-family: monospace;
- text-align: left;
- background-color: #EEE;
- color: #000;
- padding: 0.4em;
- }
-
- img {
- padding-top: 0;
- margin-top: 0;
- border-top: 0;
- }
-
-
- p {
- padding-top: 0;
- margin-top: 0;
- }
diff --git a/Templates/module_wrapper.html b/Templates/module_wrapper.html
new file mode 100644
index 0000000..a44eeca
--- /dev/null
+++ b/Templates/module_wrapper.html
@@ -0,0 +1,16 @@
+
+
+
+
+ {{STATUS_ICON}}{{MODULE_NAME}}
+
+
+ show help
+ hide help
+
+
+
+{{HELP_CONTENT}}
+
+{{MODULE_CONTENT}}
+
diff --git a/Templates/report_template.html b/Templates/report_template.html
new file mode 100644
index 0000000..f45933e
--- /dev/null
+++ b/Templates/report_template.html
@@ -0,0 +1,61 @@
+
+
+
+ {{TITLE}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{FASTQC_ICON_SVG_MOBILE}}
+ FastQC:
+ {{FILENAME}}
+
+
+
+
+
+
+
+
+
+{{MODULE_CONTENT}}
+
+
+
+
+
+
diff --git a/Templates/sidebar_item.html b/Templates/sidebar_item.html
new file mode 100644
index 0000000..0f7b354
--- /dev/null
+++ b/Templates/sidebar_item.html
@@ -0,0 +1,5 @@
+
+
+ {{STATUS_TEXT}} {{MODULE_NAME}}
+
+
diff --git a/uk/ac/babraham/FastQC/Modules/AbstractQCModule.java b/uk/ac/babraham/FastQC/Modules/AbstractQCModule.java
index bb26b9a..c953dd2 100644
--- a/uk/ac/babraham/FastQC/Modules/AbstractQCModule.java
+++ b/uk/ac/babraham/FastQC/Modules/AbstractQCModule.java
@@ -42,21 +42,17 @@ public abstract class AbstractQCModule implements QCModule {
protected void simpleXhtmlReport(HTMLReportArchive report,String svgData, BufferedImage image, String alt) throws XMLStreamException {
XMLStreamWriter xhtml = report.xhtmlStream();
xhtml.writeStartElement("p");
- xhtml.writeEmptyElement("img");
- xhtml.writeAttribute("class", "indented");
+ xhtml.writeAttribute("class", "plot");
if (FastQCConfig.getInstance().svg_output) {
- xhtml.writeAttribute("src", ImageToBase64.svgImageToBase64(svgData));
+ String placeholder = report.registerInlineSvg(svgData);
+ xhtml.writeAttribute("aria-label", alt);
+ xhtml.writeComment(placeholder);
}
else {
+ xhtml.writeEmptyElement("img");
xhtml.writeAttribute("src", ImageToBase64.imageToBase64(image));
+ xhtml.writeAttribute("alt", alt);
}
- xhtml.writeAttribute("alt", alt);
-
-// if(svgData!=null){
-// xhtml.writeAttribute("width",String.valueOf(img.getWidth()));
-// xhtml.writeAttribute("height",String.valueOf(img.getHeight()));
-// }
-
xhtml.writeEndElement();//p
}
diff --git a/uk/ac/babraham/FastQC/Modules/AdapterContent.java b/uk/ac/babraham/FastQC/Modules/AdapterContent.java
index b5ffcfb..460b0f7 100644
--- a/uk/ac/babraham/FastQC/Modules/AdapterContent.java
+++ b/uk/ac/babraham/FastQC/Modules/AdapterContent.java
@@ -248,7 +248,7 @@ public String description() {
}
public String name() {
- return "Adapter Content";
+ return "Adapter content";
}
public boolean raisesError() {
diff --git a/uk/ac/babraham/FastQC/Modules/BasicStats.java b/uk/ac/babraham/FastQC/Modules/BasicStats.java
index bb06b9c..f58773a 100644
--- a/uk/ac/babraham/FastQC/Modules/BasicStats.java
+++ b/uk/ac/babraham/FastQC/Modules/BasicStats.java
@@ -82,7 +82,7 @@ public void reset () {
}
public String name() {
- return "Basic Statistics";
+ return "Basic statistics";
}
public void setFileName (String name) {
diff --git a/uk/ac/babraham/FastQC/Modules/DuplicationLevel.java b/uk/ac/babraham/FastQC/Modules/DuplicationLevel.java
index d9c4c2a..33353b1 100644
--- a/uk/ac/babraham/FastQC/Modules/DuplicationLevel.java
+++ b/uk/ac/babraham/FastQC/Modules/DuplicationLevel.java
@@ -237,7 +237,7 @@ public void makeReport(HTMLReportArchive report) throws IOException,XMLStreamExc
}
public String name() {
- return "Sequence Duplication Levels";
+ return "Sequence duplication levels";
}
public void processSequence(Sequence sequence) {
diff --git a/uk/ac/babraham/FastQC/Modules/SequenceLengthDistribution.java b/uk/ac/babraham/FastQC/Modules/SequenceLengthDistribution.java
index 728c56c..a08e3e3 100644
--- a/uk/ac/babraham/FastQC/Modules/SequenceLengthDistribution.java
+++ b/uk/ac/babraham/FastQC/Modules/SequenceLengthDistribution.java
@@ -188,7 +188,7 @@ public String description() {
}
public String name() {
- return "Sequence Length Distribution";
+ return "Sequence length distribution";
}
public boolean raisesError() {
diff --git a/uk/ac/babraham/FastQC/Report/HTMLReportArchive.java b/uk/ac/babraham/FastQC/Report/HTMLReportArchive.java
index 334eda5..e4eb067 100644
--- a/uk/ac/babraham/FastQC/Report/HTMLReportArchive.java
+++ b/uk/ac/babraham/FastQC/Report/HTMLReportArchive.java
@@ -19,7 +19,6 @@
*/
package uk.ac.babraham.FastQC.Report;
-import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -31,13 +30,18 @@
import java.io.StringReader;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
-import javax.imageio.ImageIO;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLOutputFactory;
@@ -55,9 +59,28 @@
import uk.ac.babraham.FastQC.FastQCApplication;
import uk.ac.babraham.FastQC.Modules.QCModule;
import uk.ac.babraham.FastQC.Sequence.SequenceFile;
-import uk.ac.babraham.FastQC.Utilities.ImageToBase64;
public class HTMLReportArchive {
+
+ private static final Pattern SVG_ID_PATTERN = Pattern.compile("id=\"([^\"]+)\"");
+ private static final Pattern SVG_URL_PATTERN = Pattern.compile("url\\(#([^)]+)\\)");
+ private static final Pattern SVG_XML_DECL = Pattern.compile("^\\s*<\\?xml[^>]*\\?>\\s*");
+ private static final Pattern SVG_DOCTYPE = Pattern.compile("^\\s*]*>\\s*");
+ private static final Pattern INLINE_SVG_PLACEHOLDER = Pattern.compile("");
+
+ private static final Pattern HTML_TAG = Pattern.compile("(?s)");
+ private static final Pattern HEAD_BLOCK = Pattern.compile("(?s).*?");
+ private static final Pattern BODY_OPEN = Pattern.compile("(?s)]*>");
+ private static final Pattern BODY_CLOSE = Pattern.compile("(?s).*?");
+ private static final Pattern IMG_IN_P = Pattern.compile("(?s)\\s* ]*>\\s*
");
+ private static final Pattern IMG_TAG = Pattern.compile("(?s) ]*>");
+ private static final Pattern EMPTY_P = Pattern.compile("(?s)\\s*
");
+ private static final Pattern H1_BLOCK = Pattern.compile("(?s)]*>.*? ");
+ private static final Pattern H2_OPEN = Pattern.compile("(?s)]*)>");
+ private static final Pattern H2_CLOSE = Pattern.compile("(?s) ");
+ private static final Pattern MULTI_BLANK = Pattern.compile("\\n\\s*\\n\\s*\\n");
+ private static final Pattern LEADING_WS = Pattern.compile("(?m)^\\s+");
+
private XMLStreamWriter xhtml=null;
private StringBuffer data = new StringBuffer();
private QCModule [] modules;
@@ -66,90 +89,58 @@ public class HTMLReportArchive {
private byte [] buffer = new byte[1024];
private File htmlFile;
private File zipFile;
+ private String htmlTemplate;
+ private Map helpFileMapping;
+ private Map templateCache = new HashMap();
+ private List inlineSvgs = new ArrayList();
public HTMLReportArchive (SequenceFile sequenceFile, QCModule [] modules, File htmlFile) throws IOException, XMLStreamException {
this.sequenceFile = sequenceFile;
this.modules = modules;
this.htmlFile = htmlFile;
this.zipFile = new File(htmlFile.getAbsoluteFile().toString().replaceAll("\\.html$", "")+".zip");
- StringWriter htmlStr = new StringWriter();
+
+ this.htmlTemplate = loadTemplate("/Templates/report_template.html");
+ this.helpFileMapping = initializeHelpFileMapping();
+
+ // Create a placeholder XMLStreamWriter (replaced per-module in generateModuleContent)
XMLOutputFactory xmlfactory = XMLOutputFactory.newInstance();
- this.xhtml= xmlfactory.createXMLStreamWriter(htmlStr);
-
-
+ this.xhtml= xmlfactory.createXMLStreamWriter(new StringWriter());
+
+
zip = new ZipOutputStream(new FileOutputStream(zipFile));
zip.putNextEntry(new ZipEntry(folderName()+"/"));
zip.putNextEntry(new ZipEntry(folderName()+"/Icons/"));
zip.putNextEntry(new ZipEntry(folderName()+"/Images/"));
- startDocument();
- for (int m=0;m>");
- data.append(modules[m].name());
- data.append("\t");
- if (modules[m].raisesError()) {
- data.append("fail");
- }
- else if (modules[m].raisesWarning()) {
- data.append("warn");
- }
- else {
- data.append("pass");
- }
- data.append("\n");
- xhtml.writeEndElement();
- modules[m].makeReport(this);
- data.append(">>END_MODULE\n");
-
- xhtml.writeEndElement();
- }
- closeDocument();
-
- zip.putNextEntry(new ZipEntry(folderName()+"/fastqc_report.html"));
+ data.append("##FastQC\t");
+ data.append(FastQCApplication.VERSION);
+ data.append("\n");
+
+ String moduleContent = generateModuleContent();
xhtml.flush();
xhtml.close();
- zip.write(htmlStr.toString().getBytes());
+
+ String finalHtml = generateHtmlFromTemplate(moduleContent);
+
+ zip.putNextEntry(new ZipEntry(folderName()+"/fastqc_report.html"));
+ zip.write(finalHtml.getBytes());
zip.closeEntry();
zip.putNextEntry(new ZipEntry(folderName()+"/fastqc_data.txt"));
zip.write(data.toString().getBytes());
zip.closeEntry();
-
+
+ String summaryText = generateSummaryText();
+ zip.putNextEntry(new ZipEntry(folderName()+"/summary.txt"));
+ zip.write(summaryText.getBytes());
+ zip.closeEntry();
+
//XSL-FO
try {
DocumentBuilderFactory domFactory=DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(false);
DocumentBuilder builder=domFactory.newDocumentBuilder();
- Document src=builder.parse(new InputSource( new StringReader(htmlStr.toString())));
+ Document src=builder.parse(new InputSource( new StringReader(finalHtml)));
InputStream rsrc=getClass().getResourceAsStream("/Templates/fastqc2fo.xsl");
if(rsrc!=null)
{
@@ -176,7 +167,7 @@ else if (modules[m].raisesWarning()) {
PrintWriter pr = new PrintWriter(new FileWriter(htmlFile));
- pr.print(htmlStr.toString());
+ pr.print(finalHtml);
pr.close();
@@ -238,175 +229,236 @@ public ZipOutputStream zipFile () {
return zip;
}
- private void startDocument () throws IOException,XMLStreamException
- {
-
- // Just put the fastQC version at the start of the text report
- data.append("##FastQC\t");
- data.append(FastQCApplication.VERSION);
- data.append("\n");
-
- // Add in the icon files for pass/fail/warn
- for(String icnName:new String[]{
- "fastqc_icon.png",
- "warning.png",
- "error.png",
- "tick.png"})
- {
- InputStream in =getClass().getResourceAsStream("/Templates/Icons/"+icnName);
- if(in==null) continue;
- zip.putNextEntry(new ZipEntry(folderName()+"/Icons/"+icnName));
- int len;
- while ((len = in.read(buffer)) > 0) {
- zip.write(buffer, 0, len);
- }
- in.close();
- zip.closeEntry();
+ public String registerInlineSvg(String svgData) {
+ int id = inlineSvgs.size();
+ inlineSvgs.add(prepareSvgForInline(svgData));
+ return "FASTQC_INLINE_SVG_" + id;
+ }
+
+ private static String prepareSvgForInline(String svg) {
+ svg = SVG_XML_DECL.matcher(svg).replaceFirst("");
+ svg = SVG_DOCTYPE.matcher(svg).replaceFirst("");
+ return svg.trim();
+ }
+
+ private String replaceInlineSvgPlaceholders(String content) {
+ Matcher m = INLINE_SVG_PLACEHOLDER.matcher(content);
+ if (!m.find()) return content;
+
+ StringBuffer sb = new StringBuffer(content.length());
+ m.reset();
+ while (m.find()) {
+ int id = Integer.parseInt(m.group(1));
+ String svg = inlineSvgs.get(id);
+ m.appendReplacement(sb, Matcher.quoteReplacement(svg));
+ }
+ m.appendTail(sb);
+ return sb.toString();
+ }
+
+ private String loadTemplate(String templatePath) throws IOException {
+ String cached = templateCache.get(templatePath);
+ if (cached != null) return cached;
+
+ InputStream templateStream = getClass().getResourceAsStream(templatePath);
+ StringWriter templateWriter = new StringWriter();
+ byte[] buffer = new byte[1024];
+ int nRead;
+ while ((nRead = templateStream.read(buffer)) != -1) {
+ templateWriter.write(new String(buffer, 0, nRead, "UTF-8"));
+ }
+ templateStream.close();
+ String result = templateWriter.toString();
+ templateCache.put(templatePath, result);
+ return result;
+ }
+
+ private String generateSummaryItems() throws IOException {
+ StringBuffer summaryItems = new StringBuffer();
+ String sidebarItemTemplate = loadTemplate("/Templates/sidebar_item.html");
+
+ for (int m=0;m");
- xhtml.writeStartElement("html");
- xhtml.writeStartElement("head");
-
- xhtml.writeStartElement("title");
- xhtml.writeCharacters(sequenceFile.name());
- xhtml.writeCharacters(" FastQC Report");
- xhtml.writeEndElement();//title
-
- InputStream rsrc=getClass().getResourceAsStream("/Templates/header_template.html");
- if(rsrc!=null)
- {
- xhtml.writeStartElement("style");
- xhtml.writeAttribute("type", "text/css");
-
- byte array[]=new byte[128];
- int nRead;
- while((nRead=rsrc.read(array))!=-1) { xhtml.writeCharacters(new String(array,0,nRead));}
- rsrc.close();
- xhtml.writeEndElement();//style
- }
+ String item = sidebarItemTemplate;
+ item = item.replace("{{MODULE_INDEX}}", String.valueOf(m));
+ item = item.replace("{{MODULE_NAME}}", modules[m].name());
-
-
-
- xhtml.writeEndElement();//head
-
- xhtml.writeStartElement("body");
-
- xhtml.writeStartElement("div");
- xhtml.writeAttribute("class", "header");
-
- xhtml.writeStartElement("div");
- xhtml.writeAttribute("id", "header_title");
-
- xhtml.writeEmptyElement("img");
- xhtml.writeAttribute("src", base64ForIcon("Icons/fastqc_icon.png"));
- xhtml.writeAttribute("alt", "FastQC");
- xhtml.writeCharacters("FastQC Report");
- xhtml.writeEndElement();//div
-
- xhtml.writeStartElement("div");
- xhtml.writeAttribute("id", "header_filename");
- xhtml.writeCharacters(df.format(new Date()));
- xhtml.writeEmptyElement("br");
- xhtml.writeCharacters(sequenceFile.name());
- xhtml.writeEndElement();//div
- xhtml.writeEndElement();//div
-
-
- xhtml.writeStartElement("div");
- xhtml.writeAttribute("class", "summary");
-
- xhtml.writeStartElement("h2");
- xhtml.writeCharacters("Summary");
- xhtml.writeEndElement();//h2
-
-
- xhtml.writeStartElement("ul");
-
+ if (modules[m].raisesError()) {
+ item = item.replace("{{STATUS_CLASS}}", "sidebar-error");
+ item = item.replace("{{STATUS_TEXT}}", "Error");
+ } else if (modules[m].raisesWarning()) {
+ item = item.replace("{{STATUS_CLASS}}", "sidebar-warning");
+ item = item.replace("{{STATUS_TEXT}}", "Warn");
+ } else {
+ item = item.replace("{{STATUS_CLASS}}", "sidebar-pass");
+ item = item.replace("{{STATUS_TEXT}}", "Pass");
+ }
+
+ summaryItems.append(item).append("\n");
+ }
+
+ return summaryItems.toString();
+ }
+
+ private String generateSummaryText() {
StringBuffer summaryText = new StringBuffer();
-
+
for (int m=0;m>");
+ data.append(modules[m].name());
+ data.append("\t");
+ if (modules[m].raisesError()) {
+ data.append("fail");
+ } else if (modules[m].raisesWarning()) {
+ data.append("warn");
+ } else {
+ data.append("pass");
+ }
+ data.append("\n");
+
+ modules[m].makeReport(this);
+ data.append(">>END_MODULE\n");
+
+ moduleXhtml.flush();
+ moduleXhtml.close();
+ } finally {
+ this.xhtml = originalXhtml;
+ }
+
+ String moduleBody = replaceInlineSvgPlaceholders(moduleBodyWriter.toString());
+
+ String moduleWrapper = moduleWrapperTemplate;
+ moduleWrapper = moduleWrapper.replace("{{MODULE_INDEX}}", String.valueOf(m));
+ moduleWrapper = moduleWrapper.replace("{{MODULE_NAME}}", modules[m].name());
+ moduleWrapper = moduleWrapper.replace("{{STATUS_ICON}}", getStatusIcon(modules[m]));
+ moduleWrapper = moduleWrapper.replace("{{HELP_CONTENT}}", extractHelpText(modules[m].name()));
+ moduleWrapper = moduleWrapper.replace("{{MODULE_CONTENT}}", moduleBody);
+
+ allModulesContent.append(moduleWrapper).append("\n");
}
+
+ return allModulesContent.toString();
}
-
- private void closeDocument () throws XMLStreamException
- {
- xhtml.writeEndElement();//div
- xhtml.writeStartElement("div");
- xhtml.writeAttribute("class", "footer");
- xhtml.writeCharacters("Produced by ");
- xhtml.writeStartElement("a");
- xhtml.writeAttribute("href", "http://www.bioinformatics.babraham.ac.uk/projects/fastqc/");
- xhtml.writeCharacters("FastQC");
- xhtml.writeEndElement();//a
- xhtml.writeCharacters(" (version "+FastQCApplication.VERSION+")");
- xhtml.writeEndElement();//div
-
- xhtml.writeEndElement();//body
- xhtml.writeEndElement();//html
+
+ private String generateHtmlFromTemplate(String moduleContent) throws IOException {
+ SimpleDateFormat df = new SimpleDateFormat("EEE d MMM yyyy");
+
+ String html = htmlTemplate;
+ html = html.replace("{{TITLE}}", sequenceFile.name() + " FastQC Report");
+ html = html.replace("{{DATE}}", df.format(new Date()));
+ html = html.replace("{{FILENAME}}", sequenceFile.name());
+ html = html.replace("{{VERSION}}", FastQCApplication.VERSION);
+ html = html.replace("{{FASTQC_ICON_SVG_MOBILE}}", getFastQCIconWithUniqueIds("mobile"));
+ html = html.replace("{{FASTQC_ICON_SVG_SIDEBAR}}", getFastQCIconWithUniqueIds("sidebar"));
+ html = html.replace("{{SUMMARY_ITEMS}}", generateSummaryItems());
+ html = html.replace("{{CSS_CONTENT}}", loadTemplate("/Templates/fastqc.css"));
+ html = html.replace("{{MODULE_CONTENT}}", moduleContent);
+
+ return html;
+ }
+
+ private Map initializeHelpFileMapping() {
+ Map mapping = new HashMap();
+ mapping.put("Basic statistics", "/Help/3 Analysis Modules/1 Basic Statistics.html");
+ mapping.put("Per base sequence quality", "/Help/3 Analysis Modules/2 Per Base Sequence Quality.html");
+ mapping.put("Per sequence quality scores", "/Help/3 Analysis Modules/3 Per Sequence Quality Scores.html");
+ mapping.put("Per base sequence content", "/Help/3 Analysis Modules/4 Per Base Sequence Content.html");
+ mapping.put("Per sequence GC content", "/Help/3 Analysis Modules/5 Per Sequence GC Content.html");
+ mapping.put("Per base N content", "/Help/3 Analysis Modules/6 Per Base N Content.html");
+ mapping.put("Sequence length distribution", "/Help/3 Analysis Modules/7 Sequence Length Distribution.html");
+ mapping.put("Sequence duplication levels", "/Help/3 Analysis Modules/8 Duplicate Sequences.html");
+ mapping.put("Overrepresented sequences", "/Help/3 Analysis Modules/9 Overrepresented Sequences.html");
+ mapping.put("Adapter content", "/Help/3 Analysis Modules/10 Adapter Content.html");
+ mapping.put("Kmer Content", "/Help/3 Analysis Modules/11 Kmer Content.html");
+ mapping.put("Per tile sequence quality", "/Help/3 Analysis Modules/12 Per Tile Sequence Quality.html");
+ return mapping;
+ }
+
+ private String extractHelpText(String moduleName) {
+ String helpFilePath = helpFileMapping.get(moduleName);
+ if (helpFilePath == null) {
+ return "Help documentation not available for this module.
";
}
-
-
-
-
+
+ try {
+ String helpHtml = loadTemplate(helpFilePath);
+ return convertHelpHtmlToText(helpHtml);
+ } catch (IOException e) {
+ return "Help documentation could not be loaded for this module.
";
+ }
+ }
+
+ private String convertHelpHtmlToText(String htmlContent) {
+ String content = HTML_TAG.matcher(htmlContent).replaceAll("");
+ content = HEAD_BLOCK.matcher(content).replaceAll("");
+ content = BODY_OPEN.matcher(content).replaceAll("");
+ content = BODY_CLOSE.matcher(content).replaceAll("");
+ content = IMG_IN_P.matcher(content).replaceAll("");
+ content = IMG_TAG.matcher(content).replaceAll("");
+ content = EMPTY_P.matcher(content).replaceAll("");
+ content = H1_BLOCK.matcher(content).replaceAll("");
+ content = H2_OPEN.matcher(content).replaceAll("");
+ content = H2_CLOSE.matcher(content).replaceAll(" ");
+ content = MULTI_BLANK.matcher(content).replaceAll("\n\n");
+ content = LEADING_WS.matcher(content).replaceAll("");
+ content = content.trim();
+
+ return content;
+ }
+
}
diff --git a/uk/ac/babraham/FastQC/Report/stylesheet.txt b/uk/ac/babraham/FastQC/Report/stylesheet.txt
deleted file mode 100644
index f52e99e..0000000
--- a/uk/ac/babraham/FastQC/Report/stylesheet.txt
+++ /dev/null
@@ -1,55 +0,0 @@
- body {
- font-family: sans-serif;
- color: #000000;
- background-color: #FFFFFF;
- }
-
- a {
- color: #000080;
- }
-
- a:hover {
- color: #800000;
- }
-
- h2 {
- color: #800000;
- padding-bottom: 0;
- margin-bottom: 0;
- padding-top: 2em;
- }
-
- table {
- margin-left: 3em;
- text-align: center;
- }
-
- th {
- text-align: center;
- background-color: #000080;
- color: #FFFFFF;
- padding: 0.4em;
- }
-
- td {
- font-family: monospace;
- text-align: left;
- background-color: #EEEEEE;
- color: #000000;
- padding: 0.4em;
- }
-
- img {
- padding-top: 0;
- margin-top: 0;
- border-top: 0;
- }
-
- img.indented {
- margin-left: 3em;
- }
-
- p {
- padding-top: 0;
- margin-top: 0;
- }
diff --git a/uk/ac/babraham/FastQC/Resources/babraham.svg b/uk/ac/babraham/FastQC/Resources/babraham.svg
new file mode 100644
index 0000000..882e504
--- /dev/null
+++ b/uk/ac/babraham/FastQC/Resources/babraham.svg
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uk/ac/babraham/FastQC/Resources/babraham_darkbg.svg b/uk/ac/babraham/FastQC/Resources/babraham_darkbg.svg
new file mode 100644
index 0000000..bf6602d
--- /dev/null
+++ b/uk/ac/babraham/FastQC/Resources/babraham_darkbg.svg
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uk/ac/babraham/FastQC/Resources/fastqc_icon.png b/uk/ac/babraham/FastQC/Resources/fastqc_icon.png
index 348c93b..fb7b2cb 100644
Binary files a/uk/ac/babraham/FastQC/Resources/fastqc_icon.png and b/uk/ac/babraham/FastQC/Resources/fastqc_icon.png differ
diff --git a/uk/ac/babraham/FastQC/Resources/fastqc_icon.svg b/uk/ac/babraham/FastQC/Resources/fastqc_icon.svg
index 04bf1d5..618ccb4 100644
--- a/uk/ac/babraham/FastQC/Resources/fastqc_icon.svg
+++ b/uk/ac/babraham/FastQC/Resources/fastqc_icon.svg
@@ -1,189 +1,47 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- image/svg+xml
-
-
-
-
-
-
- C
-
-
-
-
-
-
- Q
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uk/ac/babraham/FastQC/Resources/fastqc_icon_100.png b/uk/ac/babraham/FastQC/Resources/fastqc_icon_100.png
index 668c917..43e0a8e 100644
Binary files a/uk/ac/babraham/FastQC/Resources/fastqc_icon_100.png and b/uk/ac/babraham/FastQC/Resources/fastqc_icon_100.png differ
diff --git a/uk/ac/babraham/FastQC/Resources/fastqc_icon_hires.png b/uk/ac/babraham/FastQC/Resources/fastqc_icon_hires.png
new file mode 100644
index 0000000..a77b12e
Binary files /dev/null and b/uk/ac/babraham/FastQC/Resources/fastqc_icon_hires.png differ
diff --git a/uk/ac/babraham/FastQC/Resources/fastqc_logo.png b/uk/ac/babraham/FastQC/Resources/fastqc_logo.png
new file mode 100644
index 0000000..f66b429
Binary files /dev/null and b/uk/ac/babraham/FastQC/Resources/fastqc_logo.png differ
diff --git a/uk/ac/babraham/FastQC/Resources/fastqc_logo.svg b/uk/ac/babraham/FastQC/Resources/fastqc_logo.svg
new file mode 100644
index 0000000..75fa6ea
--- /dev/null
+++ b/uk/ac/babraham/FastQC/Resources/fastqc_logo.svg
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uk/ac/babraham/FastQC/Resources/fastqc_logo_darkbg.png b/uk/ac/babraham/FastQC/Resources/fastqc_logo_darkbg.png
new file mode 100644
index 0000000..79b3864
Binary files /dev/null and b/uk/ac/babraham/FastQC/Resources/fastqc_logo_darkbg.png differ
diff --git a/uk/ac/babraham/FastQC/Resources/fastqc_logo_darkbg.svg b/uk/ac/babraham/FastQC/Resources/fastqc_logo_darkbg.svg
new file mode 100644
index 0000000..0f1ecaf
--- /dev/null
+++ b/uk/ac/babraham/FastQC/Resources/fastqc_logo_darkbg.svg
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uk/ac/babraham/FastQC/Utilities/ImageSaver/SVGGenerator.java b/uk/ac/babraham/FastQC/Utilities/ImageSaver/SVGGenerator.java
index eec7360..989a57d 100644
--- a/uk/ac/babraham/FastQC/Utilities/ImageSaver/SVGGenerator.java
+++ b/uk/ac/babraham/FastQC/Utilities/ImageSaver/SVGGenerator.java
@@ -133,6 +133,10 @@ private SVGGenerator (StringBuffer sb, Component c) {
sb.append(c.getWidth());
sb.append("\" height=\"");
sb.append(c.getHeight());
+ sb.append("\" viewBox=\"0 0 ");
+ sb.append(c.getWidth());
+ sb.append(" ");
+ sb.append(c.getHeight());
sb.append("\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n");
sb.append("\n");
diff --git a/uk/ac/babraham/FastQC/Utilities/ImageToBase64.java b/uk/ac/babraham/FastQC/Utilities/ImageToBase64.java
index 63794f4..42f22e8 100644
--- a/uk/ac/babraham/FastQC/Utilities/ImageToBase64.java
+++ b/uk/ac/babraham/FastQC/Utilities/ImageToBase64.java
@@ -33,35 +33,17 @@ public class ImageToBase64 {
public static String imageToBase64 (BufferedImage b) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
OutputStream b64 = new Base64.OutputStream(os);
-
- try {
+
+ try {
ImageIO.write(b, "PNG", b64);
-
+
return("data:image/png;base64,"+os.toString("UTF-8"));
}
catch (IOException e) {
e.printStackTrace();
return "Failed";
}
-
- }
-
- public static String svgImageToBase64 (String svgdata) {
-
-
- // We've moved to using the Java.util Base64 encoder which means that
- // SVG output will only work on java v8+ but there was a bug in the
- // library we were using which caused the last character to get lost
- // some times so this is an easy fix and no one is using java