superset-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From maximebeauche...@apache.org
Subject [incubator-superset] branch master updated: Allow users to specify label->color mapping (#3879)
Date Fri, 17 Nov 2017 23:56:10 GMT
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new a82bb58  Allow users to specify label->color mapping (#3879)
a82bb58 is described below

commit a82bb588f4647c36161d8d9a5dcfc49128288605
Author: Maxime Beauchemin <maximebeauchemin@gmail.com>
AuthorDate: Fri Nov 17 15:56:04 2017 -0800

    Allow users to specify label->color mapping (#3879)
    
    Users can define `label_colors` in a dashboard's JSON metadata that
    enforces a label to color mapping.
    
    This also makes the function that maps labels to colors case insensitive.
---
 docs/faq.rst                                       | 16 ++++++++++++++
 superset/assets/javascripts/dashboard/reducers.js  | 10 +++++++++
 superset/assets/javascripts/modules/colors.js      | 25 +++++++++++++++++++---
 .../spec/javascripts/modules/colors_spec.jsx       | 17 ++++++++++++++-
 4 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/docs/faq.rst b/docs/faq.rst
index d825ef5..0ca341e 100644
--- a/docs/faq.rst
+++ b/docs/faq.rst
@@ -221,3 +221,19 @@ When adding columns to a table, you can have Superset detect and merge
the
 new columns in by using the "Refresh Metadata" action in the
 ``Source -> Tables`` page. Simply check the box next to the tables
 you want the schema refreshed, and click ``Actions -> Refresh Metadata``.
+
+Is there a way to force the use specific colors?
+------------------------------------------------
+
+It is possible on a per-dashboard basis by providing a mapping of
+labels to colors in the ``JSON Metadata`` attribute using the
+``label_colors`` key.
+
+..code::
+
+	{
+	  "label_colors": {
+		"Girls": "#FF69B4",
+		"Boys": "#ADD8E6"
+	  }
+	}
diff --git a/superset/assets/javascripts/dashboard/reducers.js b/superset/assets/javascripts/dashboard/reducers.js
index 5001fd1..487f56f 100644
--- a/superset/assets/javascripts/dashboard/reducers.js
+++ b/superset/assets/javascripts/dashboard/reducers.js
@@ -6,6 +6,7 @@ import * as actions from './actions';
 import { getParam } from '../modules/utils';
 import { alterInArr, removeFromArr } from '../reduxUtils';
 import { applyDefaultFormData } from '../explore/stores/store';
+import { getColorFromScheme } from '../modules/colors';
 
 export function getInitialState(bootstrapData) {
   const { user_id, datasources, common } = bootstrapData;
@@ -25,6 +26,15 @@ export function getInitialState(bootstrapData) {
     //
   }
 
+  // Priming the color palette with user's label-color mapping provided in
+  // the dashboard's JSON metadata
+  if (dashboard.metadata && dashboard.metadata.label_colors) {
+    const colorMap = dashboard.metadata.label_colors;
+    for (const label in colorMap) {
+      getColorFromScheme(label, null, colorMap[label]);
+    }
+  }
+
   dashboard.posDict = {};
   dashboard.layout = [];
   if (dashboard.position_json) {
diff --git a/superset/assets/javascripts/modules/colors.js b/superset/assets/javascripts/modules/colors.js
index 0c3d06a..03c3bb2 100644
--- a/superset/assets/javascripts/modules/colors.js
+++ b/superset/assets/javascripts/modules/colors.js
@@ -103,17 +103,36 @@ export const spectrums = {
   ],
 };
 
+/**
+ * Get a color from a scheme specific palette (scheme)
+ * The function cycles through the palette while memoizing labels
+ * association to colors. If the function is called twice with the
+ * same string, it will return the same color.
+ *
+ * @param {string} s - The label for which we want to get a color
+ * @param {string} scheme - The palette name, or "scheme"
+ * @param {string} forcedColor - A color that the caller wants to
+    forcibly associate to a label.
+ */
 export const getColorFromScheme = (function () {
-  // Color factory
   const seen = {};
-  return function (s, scheme) {
+  const forcedColors = {};
+  return function (s, scheme, forcedColor) {
     if (!s) {
       return;
     }
     const selectedScheme = scheme ? ALL_COLOR_SCHEMES[scheme] : ALL_COLOR_SCHEMES.bnbColors;
-    let stringifyS = String(s);
+    let stringifyS = String(s).toLowerCase();
     // next line is for superset series that should have the same color
     stringifyS = stringifyS.replace('---', '');
+
+    if (forcedColor && !forcedColors[stringifyS]) {
+      forcedColors[stringifyS] = forcedColor;
+    }
+    if (forcedColors[stringifyS]) {
+      return forcedColors[stringifyS];
+    }
+
     if (seen[selectedScheme] === undefined) {
       seen[selectedScheme] = {};
     }
diff --git a/superset/assets/spec/javascripts/modules/colors_spec.jsx b/superset/assets/spec/javascripts/modules/colors_spec.jsx
index 31ccea8..2a24633 100644
--- a/superset/assets/spec/javascripts/modules/colors_spec.jsx
+++ b/superset/assets/spec/javascripts/modules/colors_spec.jsx
@@ -8,7 +8,7 @@ describe('colors', () => {
     const color1 = getColorFromScheme('CA');
     expect(color1).to.equal(ALL_COLOR_SCHEMES.bnbColors[0]);
   });
-  it('series with same scheme should have the same color', () => {
+  it('getColorFromScheme series with same scheme should have the same color', () => {
     const color1 = getColorFromScheme('CA', 'bnbColors');
     const color2 = getColorFromScheme('CA', 'googleCategory20c');
     const color3 = getColorFromScheme('CA', 'bnbColors');
@@ -19,7 +19,22 @@ describe('colors', () => {
     expect(color1).to.equal(color3);
     expect(color4).to.equal(ALL_COLOR_SCHEMES.bnbColors[1]);
   });
+  it('getColorFromScheme forcing colors persists through calls', () => {
+    expect(getColorFromScheme('boys', 'bnbColors', 'blue')).to.equal('blue');
+    expect(getColorFromScheme('boys', 'bnbColors')).to.equal('blue');
+    expect(getColorFromScheme('boys', 'googleCategory20c')).to.equal('blue');
 
+    expect(getColorFromScheme('girls', 'bnbColors', 'pink')).to.equal('pink');
+    expect(getColorFromScheme('girls', 'bnbColors')).to.equal('pink');
+    expect(getColorFromScheme('girls', 'googleCategory20c')).to.equal('pink');
+  });
+  it('getColorFromScheme is not case sensitive', () => {
+    const c1 = getColorFromScheme('girls', 'bnbColors');
+    const c2 = getColorFromScheme('Girls', 'bnbColors');
+    const c3 = getColorFromScheme('GIRLS', 'bnbColors');
+    expect(c1).to.equal(c2);
+    expect(c3).to.equal(c2);
+  });
   it('hexToRGB converts properly', () => {
     expect(hexToRGB('#FFFFFF')).to.have.same.members([255, 255, 255, 255]);
     expect(hexToRGB('#000000')).to.have.same.members([0, 0, 0, 255]);

-- 
To stop receiving notification emails like this one, please contact
['"commits@superset.apache.org" <commits@superset.apache.org>'].

Mime
View raw message