diff --git a/src/lib/loggers.js b/src/lib/loggers.js
index 3524ac2dd27..e6bb04224c9 100644
--- a/src/lib/loggers.js
+++ b/src/lib/loggers.js
@@ -12,6 +12,8 @@
var dfltConfig = require('../plot_api/plot_config').dfltConfig;
+var notifier = require('./notifier');
+
var loggers = module.exports = {};
/**
@@ -21,39 +23,63 @@ var loggers = module.exports = {};
*/
loggers.log = function() {
+ var i;
+
if(dfltConfig.logging > 1) {
var messages = ['LOG:'];
-
- for(var i = 0; i < arguments.length; i++) {
+ for(i = 0; i < arguments.length; i++) {
messages.push(arguments[i]);
}
-
apply(console.trace || console.log, messages);
}
+
+ if(dfltConfig.notifyOnLogging > 1) {
+ var lines = [];
+ for(i = 0; i < arguments.length; i++) {
+ lines.push(arguments[i]);
+ }
+ notifier(lines.join('
'), 'long');
+ }
};
loggers.warn = function() {
+ var i;
+
if(dfltConfig.logging > 0) {
var messages = ['WARN:'];
-
- for(var i = 0; i < arguments.length; i++) {
+ for(i = 0; i < arguments.length; i++) {
messages.push(arguments[i]);
}
-
apply(console.trace || console.log, messages);
}
+
+ if(dfltConfig.notifyOnLogging > 0) {
+ var lines = [];
+ for(i = 0; i < arguments.length; i++) {
+ lines.push(arguments[i]);
+ }
+ notifier(lines.join('
'), 'stick');
+ }
};
loggers.error = function() {
+ var i;
+
if(dfltConfig.logging > 0) {
var messages = ['ERROR:'];
-
- for(var i = 0; i < arguments.length; i++) {
+ for(i = 0; i < arguments.length; i++) {
messages.push(arguments[i]);
}
-
apply(console.error, messages);
}
+
+ if(dfltConfig.notifyOnLogging > 0) {
+ var lines = [];
+ for(i = 0; i < arguments.length; i++) {
+ lines.push(arguments[i]);
+ }
+ notifier(lines.join('
'), 'stick');
+ }
};
/*
diff --git a/src/lib/notifier.js b/src/lib/notifier.js
index 34d3fe47dfa..89b63ede164 100644
--- a/src/lib/notifier.js
+++ b/src/lib/notifier.js
@@ -70,11 +70,17 @@ module.exports = function(text, displayLength) {
p.append('span').text(lines[i]);
}
- note.transition()
- .duration(700)
- .style('opacity', 1)
- .transition()
- .delay(ts)
- .call(killNote);
+ if(displayLength === 'stick') {
+ note.transition()
+ .duration(350)
+ .style('opacity', 1);
+ } else {
+ note.transition()
+ .duration(700)
+ .style('opacity', 1)
+ .transition()
+ .delay(ts)
+ .call(killNote);
+ }
});
};
diff --git a/src/plot_api/plot_config.js b/src/plot_api/plot_config.js
index 2f2f750332b..87c3d8e4ad7 100644
--- a/src/plot_api/plot_config.js
+++ b/src/plot_api/plot_config.js
@@ -376,7 +376,9 @@ var configAttributes = {
},
logging: {
- valType: 'boolean',
+ valType: 'integer',
+ min: 0,
+ max: 2,
dflt: 1,
description: [
'Turn all console logging on or off (errors will be thrown)',
@@ -388,6 +390,21 @@ var configAttributes = {
].join(' ')
},
+ notifyOnLogging: {
+ valType: 'integer',
+ min: 0,
+ max: 2,
+ dflt: 0,
+ description: [
+ 'Set on-graph logging (notifier) level',
+ 'This should ONLY be set via Plotly.setPlotConfig',
+ 'Available levels:',
+ '0: no on-graph logs',
+ '1: warnings and errors, but not informational messages',
+ '2: verbose logs'
+ ].join(' ')
+ },
+
queueLength: {
valType: 'integer',
min: 0,
diff --git a/src/plots/mapbox/index.js b/src/plots/mapbox/index.js
index 9efcafca2a0..c9e93b61d6f 100644
--- a/src/plots/mapbox/index.js
+++ b/src/plots/mapbox/index.js
@@ -250,6 +250,7 @@ function findAccessToken(gd, mapboxIds) {
var msg = hasOneSetMapboxStyle ?
constants.noAccessTokenErrorMsg :
constants.missingStyleErrorMsg;
+ Lib.error(msg);
throw new Error(msg);
}
diff --git a/test/image/compare_pixels_test.js b/test/image/compare_pixels_test.js
index 2ada885b019..f8a1ca22f91 100644
--- a/test/image/compare_pixels_test.js
+++ b/test/image/compare_pixels_test.js
@@ -102,6 +102,7 @@ if(allMock || argv.filter) {
var FLAKY_LIST = [
'treemap_textposition',
+ 'treemap_with-without_values_template',
'trace_metatext',
'gl3d_directions-streamtube1'
];
diff --git a/test/jasmine/tests/lib_test.js b/test/jasmine/tests/lib_test.js
index cbcdfb2ec18..34d5d2c43a6 100644
--- a/test/jasmine/tests/lib_test.js
+++ b/test/jasmine/tests/lib_test.js
@@ -1671,8 +1671,9 @@ describe('Test lib.js:', function() {
});
describe('loggers', function() {
- var stashConsole,
- stashLogLevel;
+ var stashConsole;
+ var stashLogLevel;
+ var stashOnGraphLogLevel;
function consoleFn(name, hasApply, messages) {
var out = function() {
@@ -1703,11 +1704,13 @@ describe('Test lib.js:', function() {
beforeEach(function() {
stashConsole = window.console;
stashLogLevel = config.logging;
+ stashOnGraphLogLevel = config.notifyOnLogging;
});
afterEach(function() {
window.console = stashConsole;
config.logging = stashLogLevel;
+ config.notifyOnLogging = stashOnGraphLogLevel;
});
it('emits one console message if apply is available', function() {
@@ -1807,6 +1810,50 @@ describe('Test lib.js:', function() {
['log', [{a: 1, b: 2}]]
]);
});
+
+ describe('should log message in notifier div in accordance notifyOnLogging config option', function() {
+ var query = '.notifier-note';
+
+ beforeEach(function(done) {
+ d3.selectAll(query).each(function() {
+ d3.select(this).select('button').node().click();
+ });
+ setTimeout(done, 1000);
+ });
+
+ function _run(exp) {
+ config.logging = 0;
+
+ Lib.log('log');
+ Lib.warn('warn');
+ Lib.error('error!');
+
+ var notes = d3.selectAll(query);
+
+ expect(notes.size()).toBe(exp.length, '# of notifier notes');
+
+ var actual = [];
+ notes.each(function() {
+ actual.push(d3.select(this).select('p').text());
+ });
+ expect(actual).toEqual(exp);
+ }
+
+ it('with level 2', function() {
+ config.notifyOnLogging = 2;
+ _run(['log', 'warn', 'error!']);
+ });
+
+ it('with level 1', function() {
+ config.notifyOnLogging = 1;
+ _run(['warn', 'error!']);
+ });
+
+ it('with level 0', function() {
+ config.notifyOnLogging = 0;
+ _run([]);
+ });
+ });
});
describe('keyedContainer', function() {
diff --git a/test/jasmine/tests/mapbox_test.js b/test/jasmine/tests/mapbox_test.js
index 75d78fc738b..ebe795b20c3 100644
--- a/test/jasmine/tests/mapbox_test.js
+++ b/test/jasmine/tests/mapbox_test.js
@@ -295,7 +295,7 @@ describe('mapbox credentials', function() {
}]);
}).toThrow(new Error(constants.missingStyleErrorMsg));
- expect(Lib.error).toHaveBeenCalledTimes(0);
+ expect(Lib.error).toHaveBeenCalledWith(constants.missingStyleErrorMsg);
}, LONG_TIMEOUT_INTERVAL);
it('@gl should throw error when setting a Mapbox style w/o a registered token', function() {