diff --git a/plugins/CoreHome/CoreHome.php b/plugins/CoreHome/CoreHome.php
index 5b023b9cb387d2383d0ceb4836a8a0cb3f5c62c8..61f23990e7a92582dc4b6e2bc9638ab95a287a7e 100644
--- a/plugins/CoreHome/CoreHome.php
+++ b/plugins/CoreHome/CoreHome.php
@@ -118,6 +118,7 @@ class CoreHome extends \Piwik\Plugin
         $jsFiles[] = "plugins/CoreHome/javascripts/color_manager.js";
         $jsFiles[] = "plugins/CoreHome/javascripts/notification.js";
         $jsFiles[] = "plugins/CoreHome/javascripts/notification_parser.js";
+        $jsFiles[] = "plugins/CoreHome/javascripts/numberFormatter.js";
 
         $jsFiles[] = "plugins/CoreHome/angularjs/piwikApp.config.js";
 
diff --git a/plugins/CoreHome/javascripts/numberFormatter.js b/plugins/CoreHome/javascripts/numberFormatter.js
new file mode 100644
index 0000000000000000000000000000000000000000..2d3bcc172b3f2bac4f1921a3175f9f50d02301eb
--- /dev/null
+++ b/plugins/CoreHome/javascripts/numberFormatter.js
@@ -0,0 +1,143 @@
+/*!
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+/**
+ *  Number Formatter for formatting numbers, percent and currencies values
+ *
+ * @type {object}
+ */
+var NumberFormatter = (function () {
+
+    var minimumFractionDigits = 0;
+    var maximumFractionDigits = 2;
+
+    /**
+     * Formats the given numeric value with the given pattern
+     *
+     * @param value
+     * @param pattern
+     * @returns {string}
+     */
+    function format(value, pattern) {
+
+        if (!$.isNumeric(value)) {
+            return value;
+        }
+        pattern = pattern || piwik.numbers.patternNumber;
+
+        var patterns = pattern.split(';');
+        if (patterns.length == 1) {
+            // No explicit negative pattern was provided, construct it.
+            patterns.push('-' + patterns[0])
+        }
+
+        // Ensure that the value is positive and has the right number of digits.
+        var negative = value < 0;
+        pattern = negative ? patterns[1] : patterns[0];
+
+        var usesGrouping = (pattern.indexOf(',') != -1);
+        // if pattern has number groups, parse them.
+        if (usesGrouping) {
+            var primaryGroupMatches = pattern.match(/#+0/);
+            var primaryGroupSize = primaryGroupMatches[0].length;
+            var secondaryGroupSize = primaryGroupMatches[0].length;
+            var numberGroups = pattern.split(',');
+            // check for distinct secondary group size.
+            if (numberGroups.length > 2) {
+                secondaryGroupSize = numberGroups[1].length;
+            }
+        }
+
+        var signMultiplier = negative ? '-1' : '1';
+        value = value * signMultiplier;
+        // Split the number into major and minor digits.
+        var valueParts = value.toString().split('.');
+        var majorDigits = valueParts[0];
+        // Account for maximumFractionDigits = 0, where the number won't
+        // have a decimal point, and $valueParts[1] won't be set.
+        minorDigits = valueParts[1] || '';
+        if (usesGrouping) {
+            // Reverse the major digits, since they are grouped from the right.
+            majorDigits = majorDigits.split('').reverse();
+            // Group the major digits.
+            var groups = [];
+            groups.push(majorDigits.splice(0, primaryGroupSize).reverse().join(''));
+            while (majorDigits.length) {
+                groups.push(majorDigits.splice(0, secondaryGroupSize).reverse().join(''));
+            }
+            // Reverse the groups and the digits inside of them.
+            groups = groups.reverse();
+            // Reconstruct the major digits.
+            majorDigits = groups.join(',');
+        }
+        if (minimumFractionDigits < maximumFractionDigits) {
+            // Strip any trailing zeroes.
+            var minorDigits = minorDigits.replace(/0+$/,'');
+            if (minorDigits.length < minimumFractionDigits) {
+                // Now there are too few digits, re-add trailing zeroes
+                // until the desired length is reached.
+                var neededZeroes = minimumFractionDigits - minorDigits.length;
+                minorDigits += (new Array(neededZeroes+1)).join('0');
+            }
+        }
+        // Assemble the final number and insert it into the pattern.
+        value = minorDigits ? majorDigits + '.' + minorDigits : majorDigits;
+        value = pattern.replace(/#(?:[\.,]#+)*0(?:[,\.][0#]+)*/, value);
+        // Localize the number.
+        return replaceSymbols(value);
+    }
+
+    /**
+     * Replaces the placeholders with real symbols
+     *
+     * @param value
+     * @returns {string}
+     */
+    function replaceSymbols(value) {
+        var replacements = {
+            '.': piwik.numbers.symbolDecimal,
+            ',': piwik.numbers.symbolGroup,
+            '+': piwik.numbers.symbolPlus,
+            '-': piwik.numbers.symbolMinus,
+            '%': piwik.numbers.symbolPercent
+        };
+
+        var newValue = '';
+        var valueParts = value.split('');
+
+        $.each(valueParts, function(index, value) {
+            $.each(replacements, function(char, replacement) {
+                if (value.indexOf(char) != -1) {
+                    value = value.replace(char, replacement);
+                    return false;
+                }
+            });
+            newValue += value;
+        });
+
+        return newValue;
+    }
+
+    /**
+     * Public available methods
+     */
+    return {
+
+        formatNumber: function (value) {
+            return format(value, piwik.numbers.patternNumber);
+        },
+
+        formatPercent: function (value) {
+            return format(value, piwik.numbers.patternPercent);
+        },
+
+        formatCurrency: function (value, currency) {
+            var formatted = format(value, piwik.numbers.patternCurrency);
+            return formatted.replace('¤', currency);
+        }
+    }
+})();
diff --git a/plugins/CoreVisualizations/javascripts/jqplot.js b/plugins/CoreVisualizations/javascripts/jqplot.js
index fac656f5ae33fd9188835c8136cdbfb97fa4bb54..6e5d2135d1e731f467d6a1ddfc448d800a78aecd 100644
--- a/plugins/CoreVisualizations/javascripts/jqplot.js
+++ b/plugins/CoreVisualizations/javascripts/jqplot.js
@@ -749,106 +749,15 @@ RowEvolutionSeriesToggle.prototype.beforeReplot = function () {
 
 // ------------------------------------------------------------
 //  PIWIK NUMBERFORMATTER PLUGIN FOR JQPLOT
-//  Handle number formats for piwik...
 // ------------------------------------------------------------
 (function($){
 
-    function replaceSymbols(value) {
-        var replacements = {
-            '.': piwik.numbers.symbolDecimal,
-            ',': piwik.numbers.symbolGroup,
-            '+': piwik.numbers.symbolPlus,
-            '-': piwik.numbers.symbolMinus,
-            '%': piwik.numbers.symbolPercent
-        };
-
-        var newValue = '';
-        var valueParts = value.split('');
-
-        $.each(valueParts, function(index, value) {
-            $.each(replacements, function(char, replacement) {
-                if (value.indexOf(char) != -1) {
-                    value = value.replace(char, replacement);
-                    return false;
-                }
-            });
-            newValue += value;
-        });
-
-        return newValue;
-    }
-
-    var minimumFractionDigits = 0;
-    var maximumFractionDigits = 2;
-
-    $.jqplot.NumberFormatter = function (format, value, pattern) {
+    $.jqplot.NumberFormatter = function (format, value) {
 
         if (!$.isNumeric(value)) {
             return format.replace(/%s/, value);
         }
-        pattern = pattern || piwik.numbers.patternNumber;
-
-        var patterns = pattern.split(';');
-        if (patterns.length == 1) {
-            // No explicit negative pattern was provided, construct it.
-            patterns.push('-' + patterns[0])
-        }
-
-        // Ensure that the value is positive and has the right number of digits.
-        var negative = value < 0;
-        pattern = negative ? patterns[1] : patterns[0];
-
-        var usesGrouping = (pattern.indexOf(',') != -1);
-        // if pattern has number groups, parse them.
-        if (usesGrouping) {
-            var primaryGroupMatches = pattern.match(/#+0/);
-            var primaryGroupSize = primaryGroupMatches[0].length;
-            var secondaryGroupSize = primaryGroupMatches[0].length;
-            var numberGroups = pattern.split(',');
-            // check for distinct secondary group size.
-            if (numberGroups.length > 2) {
-                secondaryGroupSize = numberGroups[1].length;
-            }
-        }
-
-        var signMultiplier = negative ? '-1' : '1';
-        value = value * signMultiplier;
-        // Split the number into major and minor digits.
-        var valueParts = value.toString().split('.');
-        var majorDigits = valueParts[0];
-        // Account for maximumFractionDigits = 0, where the number won't
-        // have a decimal point, and $valueParts[1] won't be set.
-        minorDigits = valueParts[1] || '';
-        if (usesGrouping) {
-            // Reverse the major digits, since they are grouped from the right.
-            majorDigits = majorDigits.split('').reverse();
-            // Group the major digits.
-            var groups = [];
-            groups.push(majorDigits.splice(0, primaryGroupSize).reverse().join(''));
-            while (majorDigits.length) {
-                groups.push(majorDigits.splice(0, secondaryGroupSize).reverse().join(''));
-            }
-            // Reverse the groups and the digits inside of them.
-            groups = groups.reverse();
-            // Reconstruct the major digits.
-            majorDigits = groups.join(',');
-        }
-        if (minimumFractionDigits < maximumFractionDigits) {
-            // Strip any trailing zeroes.
-            var minorDigits = minorDigits.replace(/0+$/,'');
-            if (minorDigits.length < minimumFractionDigits) {
-                // Now there are too few digits, re-add trailing zeroes
-                // until the desired length is reached.
-                var neededZeroes = minimumFractionDigits - minorDigits.length;
-                minorDigits += (new Array(neededZeroes+1)).join('0');
-            }
-        }
-        // Assemble the final number and insert it into the pattern.
-        value = minorDigits ? majorDigits + '.' + minorDigits : majorDigits;
-        value = pattern.replace(/#(?:[\.,]#+)*0(?:[,\.][0#]+)*/, value);
-        // Localize the number.
-        value = replaceSymbols(value);
-        return format.replace(/%s/, value);
+        return format.replace(/%s/, NumberFormatter.formatNumber(value));
     }
 
 })(jQuery);
diff --git a/plugins/CoreVisualizations/javascripts/jqplotBarGraph.js b/plugins/CoreVisualizations/javascripts/jqplotBarGraph.js
index 70598be192b66f0fc9338d5edd2c35865df171ae..cd21308f739b35e7c983db7e404cd4d7bbd2c681 100644
--- a/plugins/CoreVisualizations/javascripts/jqplotBarGraph.js
+++ b/plugins/CoreVisualizations/javascripts/jqplotBarGraph.js
@@ -62,7 +62,7 @@
             var percentage = '';
             if (typeof this.tooltip.percentages != 'undefined') {
                 percentage = this.tooltip.percentages[seriesIndex][valueIndex];
-                percentage = ' (' + $.jqplot.NumberFormatter('%s', percentage, piwik.numbers.patternPercent) + ')';
+                percentage = ' (' + NumberFormatter.formatPercent(percentage) + ')';
             }
 
             var label = this.jqplotParams.axes.xaxis.labels[valueIndex];
diff --git a/plugins/CoreVisualizations/javascripts/jqplotPieGraph.js b/plugins/CoreVisualizations/javascripts/jqplotPieGraph.js
index 3c9d6c730f9b9dcb5c612c8e201bbc090912f95d..7169e32af4ff1b75ce486fcb8fff709a964e5db8 100644
--- a/plugins/CoreVisualizations/javascripts/jqplotPieGraph.js
+++ b/plugins/CoreVisualizations/javascripts/jqplotPieGraph.js
@@ -67,7 +67,7 @@
 
             var label = this.data[0][valueIndex][0];
 
-            var text = '<strong>' + $.jqplot.NumberFormatter('%s', percentage, piwik.numbers.patternPercent) + '</strong> (' + value + ' ' + series + ')';
+            var text = '<strong>' + NumberFormatter.formatPercent(percentage) + '</strong> (' + value + ' ' + series + ')';
             $(element).tooltip({
                 track:   true,
                 items:   '*',
diff --git a/plugins/Morpheus/templates/_jsGlobalVariables.twig b/plugins/Morpheus/templates/_jsGlobalVariables.twig
index 9602890c16870bd5253ae54fc4af782bbf1aac3c..9acb9bebbb3c0bd100a5f43ab5691c0c5e0db0c4 100644
--- a/plugins/Morpheus/templates/_jsGlobalVariables.twig
+++ b/plugins/Morpheus/templates/_jsGlobalVariables.twig
@@ -7,6 +7,7 @@
     piwik.numbers = {
         patternNumber: "{{ 'Intl_NumberFormatNumber'|translate }}",
         patternPercent: "{{ 'Intl_NumberFormatPercent'|translate }}",
+        patternCurrency: "{{ 'Intl_NumberFormatCurrency'|translate }}",
         symbolPlus: "{{ 'Intl_NumberSymbolPlus'|translate }}",
         symbolMinus: "{{ 'Intl_NumberSymbolMinus'|translate }}",
         symbolPercent: "{{ 'Intl_NumberSymbolPercent'|translate }}",