You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ma...@apache.org on 2017/10/16 06:38:47 UTC
[incubator-superset] branch master updated: Add a
ColorPickerControl (#3653)
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 d0b5b44 Add a ColorPickerControl (#3653)
d0b5b44 is described below
commit d0b5b449b281022d497f2079f83b103602c7077c
Author: Maxime Beauchemin <ma...@gmail.com>
AuthorDate: Sun Oct 15 23:38:38 2017 -0700
Add a ColorPickerControl (#3653)
* Add a ColorPickerControl
* Tests
---
.../components/controls/ColorPickerControl.jsx | 92 ++++++++++++++++++++++
.../explore/components/controls/index.js | 2 +
superset/assets/javascripts/explore/main.css | 8 ++
.../assets/javascripts/explore/stores/controls.jsx | 6 ++
superset/assets/javascripts/modules/colors.js | 2 +-
superset/assets/package.json | 3 +-
.../explore/components/ColorPickerControl_spec.jsx | 41 ++++++++++
.../explore/components/ColorScheme_spec.jsx | 25 ++++++
8 files changed, 177 insertions(+), 2 deletions(-)
diff --git a/superset/assets/javascripts/explore/components/controls/ColorPickerControl.jsx b/superset/assets/javascripts/explore/components/controls/ColorPickerControl.jsx
new file mode 100644
index 0000000..ecccc8e
--- /dev/null
+++ b/superset/assets/javascripts/explore/components/controls/ColorPickerControl.jsx
@@ -0,0 +1,92 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { OverlayTrigger, Popover } from 'react-bootstrap';
+import { SketchPicker } from 'react-color';
+
+import ControlHeader from '../ControlHeader';
+import { bnbColors } from '../../../modules/colors';
+
+const propTypes = {
+ onChange: PropTypes.func,
+ value: PropTypes.object,
+};
+
+const defaultProps = {
+ onChange: () => {},
+};
+
+const swatchCommon = {
+ position: 'absolute',
+ width: '50px',
+ height: '20px',
+ top: '0px',
+ left: '0px',
+ right: '0px',
+ bottom: '0px',
+};
+
+const styles = {
+ swatch: {
+ width: '50px',
+ height: '20px',
+ position: 'relative',
+ padding: '5px',
+ borderRadius: '1px',
+ display: 'inline-block',
+ cursor: 'pointer',
+ boxShadow: 'rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset, rgba(0, 0, 0, 0.25) 0px 0px 4px inset',
+ },
+ color: {
+ ...swatchCommon,
+ borderRadius: '2px',
+ },
+ checkboard: {
+ ...swatchCommon,
+ background: 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVQ4T2NkYGAQYcAP3uCTZhw1gGGYhAGBZIA/nYDCgBDAm9BGDWAAJyRCgLaBCAAgXwixzAS0pgAAAABJRU5ErkJggg==") left center',
+ },
+};
+export default class ColorPickerControl extends React.Component {
+ constructor(props) {
+ super(props);
+ this.onChange = this.onChange.bind(this);
+ }
+ onChange(col) {
+ this.props.onChange(col.rgb);
+ }
+ renderPopover() {
+ return (
+ <Popover id="filter-popover" className="color-popover">
+ <SketchPicker
+ color={this.props.value}
+ onChange={this.onChange}
+ presetColors={bnbColors.filter((s, i) => i < 7)}
+ />
+ </Popover>);
+ }
+ render() {
+ const c = this.props.value || { r: 0, g: 0, b: 0, a: 0 };
+ const colStyle = Object.assign(
+ {}, styles.color, { background: `rgba(${c.r}, ${c.g}, ${c.b}, ${c.a})` });
+ return (
+ <div>
+ <ControlHeader {...this.props} />
+ <OverlayTrigger
+ container={document.body}
+ trigger="click"
+ rootClose
+ ref="trigger"
+ placement="right"
+ overlay={this.renderPopover()}
+ >
+ <div style={styles.swatch}>
+ <div style={styles.checkboard} />
+ <div style={colStyle} />
+ </div>
+ </OverlayTrigger>
+ </div>
+ );
+ }
+}
+
+ColorPickerControl.propTypes = propTypes;
+ColorPickerControl.defaultProps = defaultProps;
diff --git a/superset/assets/javascripts/explore/components/controls/index.js b/superset/assets/javascripts/explore/components/controls/index.js
index e2840fb..876bc4a 100644
--- a/superset/assets/javascripts/explore/components/controls/index.js
+++ b/superset/assets/javascripts/explore/components/controls/index.js
@@ -1,6 +1,7 @@
import BoundsControl from './BoundsControl';
import CheckboxControl from './CheckboxControl';
import CollectionControl from './CollectionControl';
+import ColorPickerControl from './ColorPickerControl';
import ColorSchemeControl from './ColorSchemeControl';
import DatasourceControl from './DatasourceControl';
import DateFilterControl from './DateFilterControl';
@@ -17,6 +18,7 @@ const controlMap = {
BoundsControl,
CheckboxControl,
CollectionControl,
+ ColorPickerControl,
ColorSchemeControl,
DatasourceControl,
DateFilterControl,
diff --git a/superset/assets/javascripts/explore/main.css b/superset/assets/javascripts/explore/main.css
index bc67249..a6afe5e 100644
--- a/superset/assets/javascripts/explore/main.css
+++ b/superset/assets/javascripts/explore/main.css
@@ -113,3 +113,11 @@
.list-group {
margin-bottom: 10px;
}
+.color-popover.popover {
+ border: none;
+ background-color: transparent;
+}
+.color-popover .popover-content {
+ padding: 0;
+ background-color: transparent;
+}
diff --git a/superset/assets/javascripts/explore/stores/controls.jsx b/superset/assets/javascripts/explore/stores/controls.jsx
index da8f22d..e926a47 100644
--- a/superset/assets/javascripts/explore/stores/controls.jsx
+++ b/superset/assets/javascripts/explore/stores/controls.jsx
@@ -1343,6 +1343,12 @@ export const controls = {
description: t('The color for points and clusters in RGB'),
},
+ color: {
+ type: 'ColorPickerControl',
+ label: t('Color'),
+ description: t('Pick a color'),
+ },
+
ranges: {
type: 'TextControl',
label: t('Ranges'),
diff --git a/superset/assets/javascripts/modules/colors.js b/superset/assets/javascripts/modules/colors.js
index 803b683..663fd6e 100644
--- a/superset/assets/javascripts/modules/colors.js
+++ b/superset/assets/javascripts/modules/colors.js
@@ -3,7 +3,7 @@ import d3 from 'd3';
export const brandColor = '#00A699';
// Color related utility functions go in this object
-const bnbColors = [
+export const bnbColors = [
'#ff5a5f', // rausch
'#7b0051', // hackb
'#007A87', // kazan
diff --git a/superset/assets/package.json b/superset/assets/package.json
index 06ae765..83c87fd 100644
--- a/superset/assets/package.json
+++ b/superset/assets/package.json
@@ -72,8 +72,9 @@
"react-alert": "^2.3.0",
"react-bootstrap": "^0.31.2",
"react-bootstrap-table": "^4.0.2",
- "react-dom": "^15.6.2",
+ "react-color": "^2.13.8",
"react-datetime": "2.9.0",
+ "react-dom": "^15.6.2",
"react-gravatar": "^2.6.1",
"react-grid-layout": "^0.14.4",
"react-map-gl": "^3.0.4",
diff --git a/superset/assets/spec/javascripts/explore/components/ColorPickerControl_spec.jsx b/superset/assets/spec/javascripts/explore/components/ColorPickerControl_spec.jsx
new file mode 100644
index 0000000..9ce2f47
--- /dev/null
+++ b/superset/assets/spec/javascripts/explore/components/ColorPickerControl_spec.jsx
@@ -0,0 +1,41 @@
+/* eslint-disable no-unused-expressions */
+import React from 'react';
+import { expect } from 'chai';
+import { describe, it, beforeEach } from 'mocha';
+import { shallow } from 'enzyme';
+import { OverlayTrigger } from 'react-bootstrap';
+import { SketchPicker } from 'react-color';
+
+import ColorPickerControl from
+ '../../../../javascripts/explore/components/controls/ColorPickerControl';
+import ControlHeader from '../../../../javascripts/explore/components/ControlHeader';
+
+const defaultProps = {
+ value: { },
+};
+
+describe('ColorPickerControl', () => {
+ let wrapper;
+ let inst;
+ beforeEach(() => {
+ wrapper = shallow(<ColorPickerControl {...defaultProps} />);
+ inst = wrapper.instance();
+ });
+
+ it('renders a OverlayTrigger', () => {
+ const controlHeader = wrapper.find(ControlHeader);
+ expect(controlHeader).to.have.lengthOf(1);
+ expect(wrapper.find(OverlayTrigger)).to.have.length(1);
+ });
+
+ it('renders a OverlayTrigger', () => {
+ const controlHeader = wrapper.find(ControlHeader);
+ expect(controlHeader).to.have.lengthOf(1);
+ expect(wrapper.find(OverlayTrigger)).to.have.length(1);
+ });
+
+ it('renders a Popover with a SketchPicker', () => {
+ const popOver = shallow(inst.renderPopover());
+ expect(popOver.find(SketchPicker)).to.have.lengthOf(1);
+ });
+});
diff --git a/superset/assets/spec/javascripts/explore/components/ColorScheme_spec.jsx b/superset/assets/spec/javascripts/explore/components/ColorScheme_spec.jsx
new file mode 100644
index 0000000..1f5ee69
--- /dev/null
+++ b/superset/assets/spec/javascripts/explore/components/ColorScheme_spec.jsx
@@ -0,0 +1,25 @@
+/* eslint-disable no-unused-expressions */
+import React from 'react';
+import { expect } from 'chai';
+import { describe, it, beforeEach } from 'mocha';
+import { mount } from 'enzyme';
+import { Creatable } from 'react-select';
+
+import ColorSchemeControl from
+ '../../../../javascripts/explore/components/controls/ColorSchemeControl';
+import { ALL_COLOR_SCHEMES } from '../../../../javascripts/modules/colors';
+
+const defaultProps = {
+ options: Object.keys(ALL_COLOR_SCHEMES).map(s => ([s, s])),
+};
+
+describe('ColorSchemeControl', () => {
+ let wrapper;
+ beforeEach(() => {
+ wrapper = mount(<ColorSchemeControl {...defaultProps} />);
+ });
+
+ it('renders a Creatable', () => {
+ expect(wrapper.find(Creatable)).to.have.length(1);
+ });
+});
--
To stop receiving notification emails like this one, please contact
['"commits@superset.apache.org" <co...@superset.apache.org>'].