From 3cb5144f7f5829357b48d5ed5666876ea9fbb855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Fri, 29 Jul 2016 17:15:18 -0400 Subject: [PATCH 1/4] color: add contrast method --- src/components/color/index.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/components/color/index.js b/src/components/color/index.js index fe22aca72aa..35ac2a0552e 100644 --- a/src/components/color/index.js +++ b/src/components/color/index.js @@ -57,6 +57,16 @@ color.combine = function(front, back) { return tinycolor(fcflat).toRgbString(); }; +color.contrast = function(cstr, lightAmount, darkAmount) { + var tc = tinycolor(cstr); + + var newColor = tc.isLight() ? + tc.darken(darkAmount) : + tc.lighten(lightAmount); + + return newColor.toString(); +}; + color.stroke = function(s, c) { var tc = tinycolor(c); s.style({'stroke': color.tinyRGB(tc), 'stroke-opacity': tc.getAlpha()}); From e2db21349bb51374d1d46e0d0c695c835a4dddef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Fri, 29 Jul 2016 17:17:06 -0400 Subject: [PATCH 2/4] rangeselector: add 'activecolor' attribute - making the color of the active / hovered button configurable - by default, the 'activecolor' is set using Color.constrast - fix test cases accordingly --- src/components/rangeselector/attributes.js | 5 +++++ src/components/rangeselector/constants.js | 5 +++-- src/components/rangeselector/defaults.js | 4 +++- src/components/rangeselector/draw.js | 2 +- test/image/mocks/range_selector_style.json | 1 + test/jasmine/tests/range_selector_test.js | 3 +-- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/components/rangeselector/attributes.js b/src/components/rangeselector/attributes.js index c0c58429bd9..4c4bb88128f 100644 --- a/src/components/rangeselector/attributes.js +++ b/src/components/rangeselector/attributes.js @@ -81,6 +81,11 @@ module.exports = { role: 'style', description: 'Sets the background color of the range selector buttons.' }, + activecolor: { + valType: 'color', + role: 'style', + description: 'Sets the background color of the active range selector button.' + }, bordercolor: { valType: 'color', dflt: colorAttrs.defaultLine, diff --git a/src/components/rangeselector/constants.js b/src/components/rangeselector/constants.js index e598ab45d69..6e2818a9c3c 100644 --- a/src/components/rangeselector/constants.js +++ b/src/components/rangeselector/constants.js @@ -21,6 +21,7 @@ module.exports = { rx: 3, ry: 3, - // color given to active and hovered buttons - activeColor: '#d3d3d3' + // light fraction used to compute the 'activecolor' default + lightAmount: 25, + darkAmount: 10 }; diff --git a/src/components/rangeselector/defaults.js b/src/components/rangeselector/defaults.js index 108b888c8eb..c616d41d261 100644 --- a/src/components/rangeselector/defaults.js +++ b/src/components/rangeselector/defaults.js @@ -9,6 +9,7 @@ 'use strict'; var Lib = require('../../lib'); +var Color = require('../color'); var attributes = require('./attributes'); var buttonAttrs = require('./button_attributes'); @@ -38,7 +39,8 @@ module.exports = function rangeSelectorDefaults(containerIn, containerOut, layou Lib.coerceFont(coerce, 'font', layout.font); - coerce('bgcolor'); + var bgColor = coerce('bgcolor'); + coerce('activecolor', Color.contrast(bgColor, constants.lightAmount, constants.darkAmount)); coerce('bordercolor'); coerce('borderwidth'); }; diff --git a/src/components/rangeselector/draw.js b/src/components/rangeselector/draw.js index 2eef35a05c6..53c499781cd 100644 --- a/src/components/rangeselector/draw.js +++ b/src/components/rangeselector/draw.js @@ -142,7 +142,7 @@ function drawButtonRect(button, selectorLayout, d) { function getFillColor(selectorLayout, d) { return (d.isActive || d.isHovered) ? - constants.activeColor : + selectorLayout.activecolor : selectorLayout.bgcolor; } diff --git a/test/image/mocks/range_selector_style.json b/test/image/mocks/range_selector_style.json index cbb3bc50a91..101620a4ed0 100644 --- a/test/image/mocks/range_selector_style.json +++ b/test/image/mocks/range_selector_style.json @@ -1025,6 +1025,7 @@ "y": 0.2, "yanchor": "bottom", "bgcolor": "#d3d3d3", + "activecolor": "#d3d3d3", "borderwidth": 2, "bordercolor": "#ff7f0e" }, diff --git a/test/jasmine/tests/range_selector_test.js b/test/jasmine/tests/range_selector_test.js index c48a3e36f0f..b6630bdde36 100644 --- a/test/jasmine/tests/range_selector_test.js +++ b/test/jasmine/tests/range_selector_test.js @@ -1,6 +1,5 @@ var RangeSelector = require('@src/components/rangeselector'); var getUpdateObject = require('@src/components/rangeselector/get_update_object'); -var constants = require('@src/components/rangeselector/constants'); var d3 = require('d3'); var Plotly = require('@lib'); @@ -482,7 +481,7 @@ describe('range selector interactions:', function() { var pos = getRectCenter(button.node()); var fillColor = Color.rgb(gd._fullLayout.xaxis.rangeselector.bgcolor); - var activeColor = Color.rgb(constants.activeColor); + var activeColor = 'rgb(212, 212, 212)'; expect(button.style('fill')).toEqual(fillColor); From 3b3e019b091df3bfe2ab579712eb32c9c1b669c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 2 Aug 2016 14:38:41 -0400 Subject: [PATCH 3/4] test: add test cases for Color.contrast --- test/jasmine/tests/color_test.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/jasmine/tests/color_test.js b/test/jasmine/tests/color_test.js index aef74e24a78..3f776337bcb 100644 --- a/test/jasmine/tests/color_test.js +++ b/test/jasmine/tests/color_test.js @@ -175,4 +175,25 @@ describe('Test color:', function() { }); }); + + describe('contrast', function() { + + it('should darken light colors', function() { + var out = Color.contrast('#eee', 10, 20); + + expect(out).toEqual('#bbbbbb'); + }); + + it('should darken light colors (2)', function() { + var out = Color.contrast('#fdae61', 10, 20); + + expect(out).toEqual('#f57a03'); + }); + + it('should lighten dark colors', function() { + var out = Color.contrast('#2b83ba', 10, 20); + + expect(out).toEqual('#449dd4'); + }); + }); }); From 63e622f754e4e3166a2447111b5e085ea46aac11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 2 Aug 2016 14:58:27 -0400 Subject: [PATCH 4/4] test: add test case for range selector style change on relayout --- test/jasmine/tests/range_selector_test.js | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/jasmine/tests/range_selector_test.js b/test/jasmine/tests/range_selector_test.js index b6630bdde36..a88b05738a2 100644 --- a/test/jasmine/tests/range_selector_test.js +++ b/test/jasmine/tests/range_selector_test.js @@ -426,6 +426,16 @@ describe('range selector interactions:', function() { }); } + function checkButtonColor(bgColor, activeColor) { + d3.selectAll('.button').each(function(d) { + var rect = d3.select(this).select('rect'); + + expect(rect.style('fill')).toEqual( + d.isActive ? activeColor : bgColor + ); + }); + } + it('should display the correct nodes', function() { assertNodeCount('.rangeselector', 1); assertNodeCount('.button', mockCopy.layout.xaxis.rangeselector.buttons.length); @@ -456,6 +466,22 @@ describe('range selector interactions:', function() { }); }); + it('should be able to change its style on `relayout`', function(done) { + var prefix = 'xaxis.rangeselector.'; + + checkButtonColor('rgb(238, 238, 238)', 'rgb(212, 212, 212)'); + + Plotly.relayout(gd, prefix + 'bgcolor', 'red').then(function() { + checkButtonColor('rgb(255, 0, 0)', 'rgb(255, 128, 128)'); + + return Plotly.relayout(gd, prefix + 'activecolor', 'blue'); + }).then(function() { + checkButtonColor('rgb(255, 0, 0)', 'rgb(0, 0, 255)'); + + done(); + }); + }); + it('should update range and active button when clicked', function() { var range0 = gd.layout.xaxis.range[0]; var buttons = d3.selectAll('.button').select('rect');