From 5d94347aff7a4b988eaf249cf0fd239da90b45ab Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Fri, 6 Jul 2018 09:04:04 -0700 Subject: [PATCH 01/18] Initial commit --- .../encoding-pane/value-customizer.scss | 0 .../encoding-pane/value-customizer.tsx | 27 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/components/encoding-pane/value-customizer.scss create mode 100644 src/components/encoding-pane/value-customizer.tsx diff --git a/src/components/encoding-pane/value-customizer.scss b/src/components/encoding-pane/value-customizer.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/encoding-pane/value-customizer.tsx b/src/components/encoding-pane/value-customizer.tsx new file mode 100644 index 000000000..791f996f7 --- /dev/null +++ b/src/components/encoding-pane/value-customizer.tsx @@ -0,0 +1,27 @@ +import * as CSSModules from 'react-css-modules'; +import {ActionHandler, SpecEncodingAction} from "../../actions"; +import {ShelfId, ShelfValueDef} from "../../models"; +import React = require("../../../node_modules/@types/react"); +import Form from 'react-jsonschema-form'; +import * as styles from './value-customizer.scss'; + +export interface ValueCustomizerProps extends ActionHandler { + shelfId: ShelfId; + valueDef: ShelfValueDef; +} + +export class ValueCustomizerBase extends React.PureComponent { + public render() { + // TODO: Figure out the UI of what value-customizer will look like + return ( +
+ ); + } +} + +export const ValueCustomizer = CSSModules(ValueCustomizerBase, styles); From db83899bf0dc65c2374f03be62d08f0f6fb23281 Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Mon, 9 Jul 2018 10:29:40 -0700 Subject: [PATCH 02/18] Add ValueCustomizer infrastructure --- src/api/api.ts | 1 + .../encoding-pane/encoding-shelf.tsx | 30 ++++++++----- .../encoding-pane/property-editor-schema.ts | 22 ++++++++++ .../encoding-pane/value-customizer.scss | 43 ++++++++++++++++++ .../encoding-pane/value-customizer.tsx | 44 +++++++++++++++---- 5 files changed, 120 insertions(+), 20 deletions(-) diff --git a/src/api/api.ts b/src/api/api.ts index e1d68f32b..4921b19bb 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -19,6 +19,7 @@ export function fetchCompassQLRecommend(query: Query, schema: Schema, data: Inli Promise { if (config && config.serverUrl) { + console.log("FUKC YALL"); const endpoint = "recommend"; return fetch(`${config.serverUrl}/${endpoint}` , { diff --git a/src/components/encoding-pane/encoding-shelf.tsx b/src/components/encoding-pane/encoding-shelf.tsx index 149efeea3..d71369299 100644 --- a/src/components/encoding-pane/encoding-shelf.tsx +++ b/src/components/encoding-pane/encoding-shelf.tsx @@ -21,6 +21,7 @@ import * as styles from './encoding-shelf.scss'; import {FieldCustomizer} from './field-customizer'; import {FunctionPicker, FunctionPickerWildcardHandler} from './function-picker'; import {CUSTOMIZABLE_ENCODING_CHANNELS} from './property-editor-schema'; +import {ValueCustomizer} from './value-customizer'; /** * Props for react-dnd of EncodingShelf @@ -50,7 +51,7 @@ export interface EncodingShelfState { } class EncodingShelfBase extends React.PureComponent< EncodingShelfProps, EncodingShelfState -> implements FunctionPickerWildcardHandler { + > implements FunctionPickerWildcardHandler { private fieldCustomizer: HTMLElement; private encodingShelf: HTMLElement; @@ -79,7 +80,7 @@ class EncodingShelfBase extends React.PureComponent< } public render() { - const {id, connectDropTarget, fieldDef, handleAction} = this.props; + const {id, connectDropTarget, fieldDef, valueDef, handleAction} = this.props; const isWildcardShelf = isWildcard(id.channel); const channelName = isWildcardShelf ? 'any' : id.channel; @@ -91,9 +92,9 @@ class EncodingShelfBase extends React.PureComponent< attachment="top left" targetAttachment="bottom left" > - {(fieldDef && !isWildcardChannelId(id) && contains(CUSTOMIZABLE_ENCODING_CHANNELS, id.channel)) ? + {(!isWildcardChannelId(id) && contains(CUSTOMIZABLE_ENCODING_CHANNELS, id.channel)) ? - {channelName}{' '} + {channelName}{' '} : {channelName} @@ -101,13 +102,20 @@ class EncodingShelfBase extends React.PureComponent< } {this.state.customizerIsOpened && -
- -
+
+ {fieldDef ? + : + + } +
} diff --git a/src/components/encoding-pane/property-editor-schema.ts b/src/components/encoding-pane/property-editor-schema.ts index 4e1bd5ba3..9deb07cae 100644 --- a/src/components/encoding-pane/property-editor-schema.ts +++ b/src/components/encoding-pane/property-editor-schema.ts @@ -232,6 +232,28 @@ function getSupportedScaleTypes(channel: Channel, fieldDef: ShelfFieldDef): stri } } +// TODO: Refactor +export function generateColorPickerSchema(propertyKey: string, title: string) { + const schema: ObjectSchema = { + type: 'object', + properties: { + [propertyKey]: { + type: 'string', + title: title, + default: '#151ce6' + } + } + }; + + const uiSchema: UISchema = { + [propertyKey]: { + 'ui:widget': 'color' + } + }; + + return {schema, uiSchema}; +} + function generateSelectSchema(propertyKey: string, enumVals: string[], title: string) { const schema: ObjectSchema = { type: 'object', diff --git a/src/components/encoding-pane/value-customizer.scss b/src/components/encoding-pane/value-customizer.scss index e69de29bb..dc47c9008 100644 --- a/src/components/encoding-pane/value-customizer.scss +++ b/src/components/encoding-pane/value-customizer.scss @@ -0,0 +1,43 @@ +.value-customizer { + background-color: #eee; + border-bottom: 5px solid #eee; + border-radius: 3px; + width: 250px; + + fieldset { + border: 0; + padding-bottom: 10px; + padding-top: 10px; + } + + form { + height: 1.8em; + } + + label { + display: inline-block; + font-size: 11px !important; // cannot access react-form's css attributes, so have to use important + padding-right: 10px; + text-align: left; + width: 75px; + } + + ul { + border-bottom: 1px solid #aaa; + margin: 0 0; + padding: 2px; + height: 18px; + } + + li { + display: inline-block; + border: 1px solid transparent; + border-bottom: none; + bottom: -1px; + position: relative; + list-style: none; + padding: 2px 10px; + cursor: pointer; + font-size: 12px; + } +} diff --git a/src/components/encoding-pane/value-customizer.tsx b/src/components/encoding-pane/value-customizer.tsx index 791f996f7..0096b4e00 100644 --- a/src/components/encoding-pane/value-customizer.tsx +++ b/src/components/encoding-pane/value-customizer.tsx @@ -1,8 +1,9 @@ +import * as React from 'react'; import * as CSSModules from 'react-css-modules'; -import {ActionHandler, SpecEncodingAction} from "../../actions"; -import {ShelfId, ShelfValueDef} from "../../models"; -import React = require("../../../node_modules/@types/react"); import Form from 'react-jsonschema-form'; +import {ActionHandler, SPEC_VALUE_CHANGE, SpecEncodingAction} from "../../actions"; +import {ShelfId, ShelfValueDef} from "../../models"; +import {generateColorPickerSchema} from './property-editor-schema'; import * as styles from './value-customizer.scss'; export interface ValueCustomizerProps extends ActionHandler { @@ -11,17 +12,42 @@ export interface ValueCustomizerProps extends ActionHandler } export class ValueCustomizerBase extends React.PureComponent { + + constructor(props: ValueCustomizerProps) { + super(props); + this.changeValue = this.changeValue.bind(this); + // this.changeValue = debounce(500, this.changeValue); + } public render() { - // TODO: Figure out the UI of what value-customizer will look like + const {shelfId} = this.props; + const {schema, uiSchema} = generateColorPickerSchema(shelfId.channel.toString(), 'Color'); return ( + schema={schema} + uiSchema={uiSchema} + // formData={} + onChange={this.changeValue} + > + + ); } + + protected changeValue(result: any) { + const value = result.formData[Object.keys(result.formData)[0]].toString(); + const {shelfId, handleAction} = this.props; + const valueDef: ShelfValueDef = { + value + }; + + handleAction({ + type: SPEC_VALUE_CHANGE, + payload: { + shelfId, + valueDef + } + }); + } } export const ValueCustomizer = CSSModules(ValueCustomizerBase, styles); From f181885b42a0f932e6a7d5bc2b6bd6e89df833a0 Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Thu, 12 Jul 2018 13:23:32 -0700 Subject: [PATCH 03/18] Add functional colorpicker for Valuedef --- .../encoding-pane/value-customizer.tsx | 5 ++--- src/components/plot/index.tsx | 22 ++++++++++--------- src/queries/alternative-encodings.ts | 3 ++- src/queries/index.ts | 15 ++++++++----- src/selectors/shelf.ts | 3 ++- 5 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/components/encoding-pane/value-customizer.tsx b/src/components/encoding-pane/value-customizer.tsx index 0096b4e00..71927004f 100644 --- a/src/components/encoding-pane/value-customizer.tsx +++ b/src/components/encoding-pane/value-customizer.tsx @@ -20,6 +20,7 @@ export class ValueCustomizerBase extends React.PureComponent { + > { data: InlineData; filters: ShelfFilter[]; fieldInfos?: PlotFieldInfo[]; @@ -137,7 +137,7 @@ export class PlotBase extends React.PureComponent { onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} > - + {notesDiv} @@ -249,14 +249,16 @@ export class PlotBase extends React.PureComponent { private renderSortButton(channel: 'x' | 'y') { const {spec} = this.props; - const channelDef = spec.encoding[channel]; - if (isFieldDef(channelDef) && isDiscrete(channelDef)) { - return ; + if (spec.encoding) { + const channelDef = spec.encoding[channel]; + if (isFieldDef(channelDef) && isDiscrete(channelDef)) { + return ; + } } return undefined; } diff --git a/src/queries/alternative-encodings.ts b/src/queries/alternative-encodings.ts index 7b020df63..9b98cb7fe 100644 --- a/src/queries/alternative-encodings.ts +++ b/src/queries/alternative-encodings.ts @@ -1,6 +1,7 @@ import {Query} from 'compassql/build/src/query/query'; import {isWildcard, SHORT_WILDCARD} from 'compassql/build/src/wildcard'; +import {isValueQuery} from '../../node_modules/compassql/build/src/query/encoding'; import {QueryCreator} from './base'; import {makeWildcard} from './common'; @@ -16,7 +17,7 @@ export const alternativeEncodings: QueryCreator = { ...query.spec, mark: makeWildcard(mark), encodings: encodings.map(encQ => { - if (isWildcard(encQ.channel)) { + if (isWildcard(encQ.channel) || isValueQuery(encQ)) { return encQ; } return { diff --git a/src/queries/index.ts b/src/queries/index.ts index 9b839b8a6..2a804cba2 100644 --- a/src/queries/index.ts +++ b/src/queries/index.ts @@ -9,6 +9,7 @@ import {contains} from 'compassql/build/src/util'; import {Store} from 'redux'; import {isString} from 'util'; import {NONPOSITION_SCALE_CHANNELS} from 'vega-lite/build/src/channel'; +import {isFieldQuery} from '../../node_modules/compassql/build/src/query/encoding'; import {resultRequest} from '../actions/result'; import {State} from '../models/index'; import {ResultType} from '../models/result'; @@ -86,12 +87,14 @@ function getFeaturesForRelatedViewRules(spec: SpecQuery) { let hasOpenFacet = false; spec.encodings.forEach(encQ => { - if (encQ.channel === 'x' || encQ.channel === 'y') { - hasOpenPosition = true; - } else if (encQ.channel === 'row' || encQ.channel === 'column') { - hasOpenFacet = true; - } else if (contains(NONPOSITION_SCALE_CHANNELS, encQ.channel)) { - hasStyleChannel = true; + if (isFieldQuery(encQ)) { + if (encQ.channel === 'x' || encQ.channel === 'y') { + hasOpenPosition = true; + } else if (encQ.channel === 'row' || encQ.channel === 'column') { + hasOpenFacet = true; + } else if (contains(NONPOSITION_SCALE_CHANNELS, encQ.channel)) { + hasStyleChannel = true; + } } }); diff --git a/src/selectors/shelf.ts b/src/selectors/shelf.ts index a21572bf9..ca6457695 100644 --- a/src/selectors/shelf.ts +++ b/src/selectors/shelf.ts @@ -7,6 +7,7 @@ import {GenericState, State, UndoableStateBase} from '../models/index'; import {Query} from 'compassql/build/src/query/query'; import {SpecQuery} from 'compassql/build/src/query/spec'; import {createSelector} from 'reselect'; +import {isFieldQuery} from '../../node_modules/compassql/build/src/query/encoding'; import {PlotTabState} from '../models'; import {ShelfFilter} from '../models/shelf/filter'; import {getDefaultGroupBy, Shelf, ShelfGroupBy, toQuery} from '../models/shelf/index'; @@ -64,6 +65,6 @@ export const selectIsQuerySpecific = createSelector( export const selectIsQueryEmpty = createSelector( selectQuerySpec, (spec: SpecQuery) => { - return spec.encodings.length === 0; + return spec.encodings.filter(encQ => isFieldQuery(encQ)).length === 0; } ); From 0f39e9e374af92c57363bc81b2ceab7a700fb706 Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Thu, 12 Jul 2018 14:11:51 -0700 Subject: [PATCH 04/18] Add logic to toggle between FieldCustomizer and ValueCustomizer --- src/components/encoding-pane/encoding-shelf.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/encoding-pane/encoding-shelf.tsx b/src/components/encoding-pane/encoding-shelf.tsx index d71369299..7a39f9665 100644 --- a/src/components/encoding-pane/encoding-shelf.tsx +++ b/src/components/encoding-pane/encoding-shelf.tsx @@ -5,6 +5,7 @@ import * as CSSModules from 'react-css-modules'; import {ConnectDropTarget, DropTarget, DropTargetCollector, DropTargetSpec} from 'react-dnd'; import * as TetherComponent from 'react-tether'; import {contains} from 'vega-lite/build/src/util'; +import {isValueDef} from '../../../node_modules/vega-lite/build/src/fielddef'; import {ActionHandler} from '../../actions/index'; import { SPEC_FIELD_ADD, SPEC_FIELD_MOVE, SPEC_FIELD_REMOVE, SPEC_FUNCTION_ADD_WILDCARD, @@ -103,15 +104,15 @@ class EncodingShelfBase extends React.PureComponent< {this.state.customizerIsOpened &&
- {fieldDef ? - : - } From 56250f78793e2335617c3661b8eeaaafa93ce52b Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Thu, 12 Jul 2018 14:41:15 -0700 Subject: [PATCH 05/18] Add formdata for ValueCustomizer --- src/components/encoding-pane/property-editor-schema.ts | 2 +- src/components/encoding-pane/property-editor.tsx | 4 ++-- src/components/encoding-pane/value-customizer.tsx | 6 ++++-- src/components/encoding-pane/value-editor-schema.ts | 5 +++++ 4 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 src/components/encoding-pane/value-editor-schema.ts diff --git a/src/components/encoding-pane/property-editor-schema.ts b/src/components/encoding-pane/property-editor-schema.ts index 9deb07cae..18b4b7ef7 100644 --- a/src/components/encoding-pane/property-editor-schema.ts +++ b/src/components/encoding-pane/property-editor-schema.ts @@ -328,7 +328,7 @@ export function getFieldPropertyGroupIndex(shelfId: ShelfId, fieldDef: ShelfFiel } } -export function generateFormData(shelfId: ShelfId, fieldDef: ShelfFieldDef) { +export function generateFieldDefFormData(shelfId: ShelfId, fieldDef: ShelfFieldDef) { const index = getFieldPropertyGroupIndex(shelfId, fieldDef); const formDataIndex = {}; for (const key of Object.keys(index)) { diff --git a/src/components/encoding-pane/property-editor.tsx b/src/components/encoding-pane/property-editor.tsx index 0bd4de5fb..611c7ed94 100644 --- a/src/components/encoding-pane/property-editor.tsx +++ b/src/components/encoding-pane/property-editor.tsx @@ -7,7 +7,7 @@ import {Channel} from 'vega-lite/build/src/channel'; import {ActionHandler} from '../../actions'; import {SPEC_FIELD_NESTED_PROP_CHANGE, SPEC_FIELD_PROP_CHANGE, SpecEncodingAction} from '../../actions/shelf'; import {isWildcardChannelId, ShelfFieldDef, ShelfId} from '../../models/shelf/spec'; -import {generateFormData, generatePropertyEditorSchema, isContinuous} from './property-editor-schema'; +import {generateFieldDefFormData, generatePropertyEditorSchema, isContinuous} from './property-editor-schema'; import * as styles from './property-editor.scss'; export interface PropertyEditorProps extends ActionHandler { @@ -31,7 +31,7 @@ export class PropertyEditorBase extends React.PureComponent
{ shelfId: ShelfId; @@ -19,14 +20,15 @@ export class ValueCustomizerBase extends React.PureComponent diff --git a/src/components/encoding-pane/value-editor-schema.ts b/src/components/encoding-pane/value-editor-schema.ts new file mode 100644 index 000000000..c7cedda7b --- /dev/null +++ b/src/components/encoding-pane/value-editor-schema.ts @@ -0,0 +1,5 @@ +import {ShelfId, ShelfValueDef} from "../../models"; + +export function generateValueDefFormData(shelfId: ShelfId, valueDef: ShelfValueDef) { + return {[shelfId.channel.toString()]: valueDef ? valueDef.value : undefined}; +} From 35834bbd9eab21ece550d6ce2ca3364943efb471 Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Thu, 12 Jul 2018 23:54:19 -0700 Subject: [PATCH 06/18] Update CompassQL Add UISchema for all value-customizable channels --- package.json | 2 +- .../encoding-pane/property-editor-schema.ts | 28 ++++++++++++++++--- .../encoding-pane/value-customizer.scss | 16 +++++++++-- .../encoding-pane/value-customizer.tsx | 27 ++++++++++-------- .../encoding-pane/value-editor-schema.ts | 19 +++++++++++++ src/queries/field-suggestions.ts | 4 +-- src/queries/index.ts | 4 +-- src/selectors/shelf.ts | 4 +-- yarn.lock | 6 ++-- 9 files changed, 82 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index a47122187..a5d1e0b9c 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ }, "dependencies": { "ajv": "^5.2.2", - "compassql": "0.20.2", + "compassql": "0.20.3", "font-awesome": "^4.7.0", "font-awesome-sass-loader": "^1.0.3", "isomorphic-fetch": "^2.2.1", diff --git a/src/components/encoding-pane/property-editor-schema.ts b/src/components/encoding-pane/property-editor-schema.ts index 18b4b7ef7..24227b9f7 100644 --- a/src/components/encoding-pane/property-editor-schema.ts +++ b/src/components/encoding-pane/property-editor-schema.ts @@ -59,7 +59,8 @@ export interface PropertyEditorSchema { } // Currently supported customizble encoding channels that display caret in customizer UI -export const CUSTOMIZABLE_ENCODING_CHANNELS = [Channel.X, Channel.Y, Channel.COLOR, Channel.SIZE, Channel.SHAPE]; +export const CUSTOMIZABLE_ENCODING_CHANNELS = [Channel.X, Channel.Y, Channel.COLOR, Channel.SIZE, Channel.SHAPE, + Channel.TEXT]; // ------------------------------------------------------------------------------ // Channel-Field Indexes for custom encoding @@ -254,7 +255,7 @@ export function generateColorPickerSchema(propertyKey: string, title: string) { return {schema, uiSchema}; } -function generateSelectSchema(propertyKey: string, enumVals: string[], title: string) { +export function generateSelectSchema(propertyKey: string, enumVals: string[], title: string) { const schema: ObjectSchema = { type: 'object', properties: { @@ -277,8 +278,8 @@ function generateSelectSchema(propertyKey: string, enumVals: string[], title: st return {schema, uiSchema}; } -function generateTextBoxSchema(propKey: string, placeHolderText: string, title: string, - primitiveType: 'string' | 'number') { +export function generateTextBoxSchema(propKey: string, placeHolderText: string, title: string, + primitiveType: 'string' | 'number') { const schema: ObjectSchema = { type: 'object', properties: { @@ -298,6 +299,25 @@ function generateTextBoxSchema(propKey: string, placeHolderText: string, title: return {schema, uiSchema}; } +export function generateSliderSchema(propKey: string, min: number, max: number) { + const schema: ObjectSchema = { + type: 'object', + properties: { + [propKey]: { + title: 'integer range', + type: 'number' + } as SchemaProperty + } + }; + const uiSchema: UISchema = { + [propKey]: { + "ui:widget": "range" + } + }; + + return {schema, uiSchema}; +} + export function getFieldPropertyGroupIndex(shelfId: ShelfId, fieldDef: ShelfFieldDef) { if (fieldDef && (shelfId.channel === Channel.X || shelfId.channel === Channel.Y)) { switch (fieldDef.type) { diff --git a/src/components/encoding-pane/value-customizer.scss b/src/components/encoding-pane/value-customizer.scss index dc47c9008..93424c33d 100644 --- a/src/components/encoding-pane/value-customizer.scss +++ b/src/components/encoding-pane/value-customizer.scss @@ -2,7 +2,11 @@ background-color: #eee; border-bottom: 5px solid #eee; border-radius: 3px; - width: 250px; + width: 190px; + + select { + font-size: 10px; + } fieldset { border: 0; @@ -11,7 +15,15 @@ } form { - height: 1.8em; + height: 3.1em; + } + + select option{ + font-size: 10px; + } + + option { + font-size: 11px; } label { diff --git a/src/components/encoding-pane/value-customizer.tsx b/src/components/encoding-pane/value-customizer.tsx index 7d7de9267..1805d2a67 100644 --- a/src/components/encoding-pane/value-customizer.tsx +++ b/src/components/encoding-pane/value-customizer.tsx @@ -1,11 +1,12 @@ import * as React from 'react'; import * as CSSModules from 'react-css-modules'; import Form from 'react-jsonschema-form'; +import {debounce} from 'throttle-debounce'; +import {Channel} from '../../../node_modules/vega-lite/build/src/channel'; import {ActionHandler, SPEC_VALUE_CHANGE, SpecEncodingAction} from "../../actions"; import {ShelfId, ShelfValueDef} from "../../models"; -import {generateColorPickerSchema} from './property-editor-schema'; import * as styles from './value-customizer.scss'; -import {generateValueDefFormData} from './value-editor-schema'; +import {generateValueDefFormData, generateValueEditorSchema} from './value-editor-schema'; export interface ValueCustomizerProps extends ActionHandler { shelfId: ShelfId; @@ -17,22 +18,24 @@ export class ValueCustomizerBase extends React.PureComponent - - +
+
+ +
+
); } diff --git a/src/components/encoding-pane/value-editor-schema.ts b/src/components/encoding-pane/value-editor-schema.ts index c7cedda7b..6b5b81a0e 100644 --- a/src/components/encoding-pane/value-editor-schema.ts +++ b/src/components/encoding-pane/value-editor-schema.ts @@ -1,5 +1,24 @@ +import {Channel} from "vega-lite/build/src/channel"; +import * as vlSchema from 'vega-lite/build/vega-lite-schema.json'; import {ShelfId, ShelfValueDef} from "../../models"; +import {generateColorPickerSchema, generateSelectSchema, + generateSliderSchema, generateTextBoxSchema} from "./property-editor-schema"; export function generateValueDefFormData(shelfId: ShelfId, valueDef: ShelfValueDef) { return {[shelfId.channel.toString()]: valueDef ? valueDef.value : undefined}; } + +export function generateValueEditorSchema(channel: Channel): any { + switch (channel) { + case 'color': + return generateColorPickerSchema(channel, undefined); + case 'shape': + return generateSelectSchema(channel, (vlSchema as any).definitions.Mark.enum, undefined); + case 'text': + return generateTextBoxSchema(channel, 'Some Text...', undefined, 'string'); + case 'size': + return generateSliderSchema(channel, 1, 100); + default: + return {}; + } +} diff --git a/src/queries/field-suggestions.ts b/src/queries/field-suggestions.ts index b7003ca63..b75c7b2b4 100644 --- a/src/queries/field-suggestions.ts +++ b/src/queries/field-suggestions.ts @@ -1,5 +1,5 @@ -import {FieldQuery} from 'compassql/build/src/query/encoding'; +import {FieldQuery, isAutoCountQuery, isFieldQuery} from 'compassql/build/src/query/encoding'; import {Query} from 'compassql/build/src/query/query'; import {SHORT_WILDCARD} from 'compassql/build/src/wildcard'; import {ResultIndex} from '../models/result'; @@ -20,7 +20,7 @@ function makeFieldSuggestionQueryCreator(params: { spec: { ...query.spec, encodings: [ - ...query.spec.encodings, + ...query.spec.encodings.filter(p => isFieldQuery(p) || isAutoCountQuery(p)), additionalFieldQuery ] }, diff --git a/src/queries/index.ts b/src/queries/index.ts index 2a804cba2..9a67f09dd 100644 --- a/src/queries/index.ts +++ b/src/queries/index.ts @@ -9,7 +9,7 @@ import {contains} from 'compassql/build/src/util'; import {Store} from 'redux'; import {isString} from 'util'; import {NONPOSITION_SCALE_CHANNELS} from 'vega-lite/build/src/channel'; -import {isFieldQuery} from '../../node_modules/compassql/build/src/query/encoding'; +import {isAutoCountQuery, isFieldQuery} from '../../node_modules/compassql/build/src/query/encoding'; import {resultRequest} from '../actions/result'; import {State} from '../models/index'; import {ResultType} from '../models/result'; @@ -87,7 +87,7 @@ function getFeaturesForRelatedViewRules(spec: SpecQuery) { let hasOpenFacet = false; spec.encodings.forEach(encQ => { - if (isFieldQuery(encQ)) { + if (isFieldQuery(encQ) || isAutoCountQuery(encQ)) { if (encQ.channel === 'x' || encQ.channel === 'y') { hasOpenPosition = true; } else if (encQ.channel === 'row' || encQ.channel === 'column') { diff --git a/src/selectors/shelf.ts b/src/selectors/shelf.ts index ca6457695..5f121ffe1 100644 --- a/src/selectors/shelf.ts +++ b/src/selectors/shelf.ts @@ -7,7 +7,7 @@ import {GenericState, State, UndoableStateBase} from '../models/index'; import {Query} from 'compassql/build/src/query/query'; import {SpecQuery} from 'compassql/build/src/query/spec'; import {createSelector} from 'reselect'; -import {isFieldQuery} from '../../node_modules/compassql/build/src/query/encoding'; +import {isAutoCountQuery, isFieldQuery} from '../../node_modules/compassql/build/src/query/encoding'; import {PlotTabState} from '../models'; import {ShelfFilter} from '../models/shelf/filter'; import {getDefaultGroupBy, Shelf, ShelfGroupBy, toQuery} from '../models/shelf/index'; @@ -65,6 +65,6 @@ export const selectIsQuerySpecific = createSelector( export const selectIsQueryEmpty = createSelector( selectQuerySpec, (spec: SpecQuery) => { - return spec.encodings.filter(encQ => isFieldQuery(encQ)).length === 0; + return spec.encodings.filter(encQ => isFieldQuery(encQ) || isAutoCountQuery(encQ)).length === 0; } ); diff --git a/yarn.lock b/yarn.lock index a23f43cca..35b89f84b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1239,9 +1239,9 @@ commander@2, commander@2.9.0, commander@2.9.x, commander@^2.9.0, commander@~2.9. dependencies: graceful-readlink ">= 1.0.0" -compassql@0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/compassql/-/compassql-0.20.2.tgz#1d524eaf662f115b3f719a1ed95348824188403b" +compassql@0.20.3: + version "0.20.3" + resolved "https://registry.yarnpkg.com/compassql/-/compassql-0.20.3.tgz#71497134e4a58ac3f1515f18770d86e22bc8d004" dependencies: datalib "~1.7.0" typescript-json-schema "^0.9.0" From 1a0d6be2421c6aaa74b04bf15a304af9bf33dec8 Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Fri, 13 Jul 2018 10:21:52 -0700 Subject: [PATCH 07/18] Add logic to not add pill when valueDef specified --- src/components/encoding-pane/encoding-shelf.tsx | 3 ++- src/components/encoding-pane/value-editor-schema.ts | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/encoding-pane/encoding-shelf.tsx b/src/components/encoding-pane/encoding-shelf.tsx index 7a39f9665..ffef130a8 100644 --- a/src/components/encoding-pane/encoding-shelf.tsx +++ b/src/components/encoding-pane/encoding-shelf.tsx @@ -120,7 +120,8 @@ class EncodingShelfBase extends React.PureComponent< }
- {fieldDef ? this.renderField() : this.renderFieldPlaceholder()} + {valueDef && valueDef.value ? this.renderFieldPlaceholder() : fieldDef ? this.renderField() : + this.renderFieldPlaceholder()} ); } diff --git a/src/components/encoding-pane/value-editor-schema.ts b/src/components/encoding-pane/value-editor-schema.ts index 6b5b81a0e..009406b11 100644 --- a/src/components/encoding-pane/value-editor-schema.ts +++ b/src/components/encoding-pane/value-editor-schema.ts @@ -1,9 +1,10 @@ import {Channel} from "vega-lite/build/src/channel"; -import * as vlSchema from 'vega-lite/build/vega-lite-schema.json'; import {ShelfId, ShelfValueDef} from "../../models"; import {generateColorPickerSchema, generateSelectSchema, generateSliderSchema, generateTextBoxSchema} from "./property-editor-schema"; +const SHAPE_VALUES = ['circle', 'square', 'cross', 'diamond', 'triangle-up', 'triangle-down', ]; + export function generateValueDefFormData(shelfId: ShelfId, valueDef: ShelfValueDef) { return {[shelfId.channel.toString()]: valueDef ? valueDef.value : undefined}; } @@ -13,7 +14,7 @@ export function generateValueEditorSchema(channel: Channel): any { case 'color': return generateColorPickerSchema(channel, undefined); case 'shape': - return generateSelectSchema(channel, (vlSchema as any).definitions.Mark.enum, undefined); + return generateSelectSchema(channel, SHAPE_VALUES, undefined); case 'text': return generateTextBoxSchema(channel, 'Some Text...', undefined, 'string'); case 'size': From ab0fa6c093de0b32e57e1528339e812ca18180d2 Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Mon, 23 Jul 2018 08:22:00 -0700 Subject: [PATCH 08/18] Use title of prop for form --- src/api/api.ts | 1 - src/components/encoding-pane/property-editor-schema.ts | 3 +-- src/components/encoding-pane/value-customizer.tsx | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/api/api.ts b/src/api/api.ts index 4921b19bb..e1d68f32b 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -19,7 +19,6 @@ export function fetchCompassQLRecommend(query: Query, schema: Schema, data: Inli Promise { if (config && config.serverUrl) { - console.log("FUKC YALL"); const endpoint = "recommend"; return fetch(`${config.serverUrl}/${endpoint}` , { diff --git a/src/components/encoding-pane/property-editor-schema.ts b/src/components/encoding-pane/property-editor-schema.ts index 24227b9f7..74395b37a 100644 --- a/src/components/encoding-pane/property-editor-schema.ts +++ b/src/components/encoding-pane/property-editor-schema.ts @@ -233,7 +233,6 @@ function getSupportedScaleTypes(channel: Channel, fieldDef: ShelfFieldDef): stri } } -// TODO: Refactor export function generateColorPickerSchema(propertyKey: string, title: string) { const schema: ObjectSchema = { type: 'object', @@ -304,7 +303,7 @@ export function generateSliderSchema(propKey: string, min: number, max: number) type: 'object', properties: { [propKey]: { - title: 'integer range', + title: propKey, type: 'number' } as SchemaProperty } diff --git a/src/components/encoding-pane/value-customizer.tsx b/src/components/encoding-pane/value-customizer.tsx index 1805d2a67..30496f050 100644 --- a/src/components/encoding-pane/value-customizer.tsx +++ b/src/components/encoding-pane/value-customizer.tsx @@ -23,7 +23,7 @@ export class ValueCustomizerBase extends React.PureComponent From a38776aaece220e83683e45da18c10e85539f824 Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Mon, 23 Jul 2018 11:00:18 -0700 Subject: [PATCH 09/18] Remove todo comment --- src/components/encoding-pane/value-customizer.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/encoding-pane/value-customizer.tsx b/src/components/encoding-pane/value-customizer.tsx index 30496f050..ac70d3059 100644 --- a/src/components/encoding-pane/value-customizer.tsx +++ b/src/components/encoding-pane/value-customizer.tsx @@ -22,7 +22,6 @@ export class ValueCustomizerBase extends React.PureComponent Date: Wed, 25 Jul 2018 16:15:28 -0700 Subject: [PATCH 10/18] Address immediate PR comments --- src/components/encoding-pane/encoding-shelf.tsx | 8 ++++---- src/components/encoding-pane/index.tsx | 7 ++++--- src/components/encoding-pane/property-editor-schema.ts | 2 ++ src/components/encoding-pane/value-customizer.tsx | 4 ++-- src/models/shelf/spec/encoding.ts | 4 ++-- src/queries/alternative-encodings.ts | 2 +- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/components/encoding-pane/encoding-shelf.tsx b/src/components/encoding-pane/encoding-shelf.tsx index ffef130a8..630ac4ecf 100644 --- a/src/components/encoding-pane/encoding-shelf.tsx +++ b/src/components/encoding-pane/encoding-shelf.tsx @@ -5,7 +5,6 @@ import * as CSSModules from 'react-css-modules'; import {ConnectDropTarget, DropTarget, DropTargetCollector, DropTargetSpec} from 'react-dnd'; import * as TetherComponent from 'react-tether'; import {contains} from 'vega-lite/build/src/util'; -import {isValueDef} from '../../../node_modules/vega-lite/build/src/fielddef'; import {ActionHandler} from '../../actions/index'; import { SPEC_FIELD_ADD, SPEC_FIELD_MOVE, SPEC_FIELD_REMOVE, SPEC_FUNCTION_ADD_WILDCARD, @@ -21,7 +20,7 @@ import {DraggedFieldIdentifier, Field} from '../field/index'; import * as styles from './encoding-shelf.scss'; import {FieldCustomizer} from './field-customizer'; import {FunctionPicker, FunctionPickerWildcardHandler} from './function-picker'; -import {CUSTOMIZABLE_ENCODING_CHANNELS} from './property-editor-schema'; +import {CUSTOMIZABLE_ENCODING_CHANNELS, CUSTOMIZABLE_VALUE_ENCODING_CHANNELS} from './property-editor-schema'; import {ValueCustomizer} from './value-customizer'; /** @@ -93,7 +92,8 @@ class EncodingShelfBase extends React.PureComponent< attachment="top left" targetAttachment="bottom left" > - {(!isWildcardChannelId(id) && contains(CUSTOMIZABLE_ENCODING_CHANNELS, id.channel)) ? + {(!isWildcardChannelId(id) && (!fieldDef && contains(CUSTOMIZABLE_VALUE_ENCODING_CHANNELS, id.channel) || + fieldDef && contains(CUSTOMIZABLE_ENCODING_CHANNELS, id.channel))) ? {channelName}{' '} : @@ -104,7 +104,7 @@ class EncodingShelfBase extends React.PureComponent< {this.state.customizerIsOpened &&
- { (!fieldDef && !valueDef) || isValueDef(valueDef) ? + { !fieldDef ? { const {handleAction, spec, specPreview, schema} = this.props; const {encoding} = specPreview || spec; + const encodingChannel = encoding[channel]; return ( ); } diff --git a/src/components/encoding-pane/property-editor-schema.ts b/src/components/encoding-pane/property-editor-schema.ts index 74395b37a..8a11ba115 100644 --- a/src/components/encoding-pane/property-editor-schema.ts +++ b/src/components/encoding-pane/property-editor-schema.ts @@ -62,6 +62,8 @@ export interface PropertyEditorSchema { export const CUSTOMIZABLE_ENCODING_CHANNELS = [Channel.X, Channel.Y, Channel.COLOR, Channel.SIZE, Channel.SHAPE, Channel.TEXT]; +export const CUSTOMIZABLE_VALUE_ENCODING_CHANNELS = [Channel.COLOR, Channel.SIZE, Channel.SHAPE, Channel.TEXT]; + // ------------------------------------------------------------------------------ // Channel-Field Indexes for custom encoding // Key is Tab name, value is list of fieldDef properties diff --git a/src/components/encoding-pane/value-customizer.tsx b/src/components/encoding-pane/value-customizer.tsx index ac70d3059..e4c935827 100644 --- a/src/components/encoding-pane/value-customizer.tsx +++ b/src/components/encoding-pane/value-customizer.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import * as CSSModules from 'react-css-modules'; import Form from 'react-jsonschema-form'; import {debounce} from 'throttle-debounce'; -import {Channel} from '../../../node_modules/vega-lite/build/src/channel'; +import {Channel} from 'vega-lite/build/src/channel'; import {ActionHandler, SPEC_VALUE_CHANGE, SpecEncodingAction} from "../../actions"; import {ShelfId, ShelfValueDef} from "../../models"; import * as styles from './value-customizer.scss'; @@ -39,7 +39,7 @@ export class ValueCustomizerBase extends React.PureComponent Date: Thu, 26 Jul 2018 10:51:06 -0700 Subject: [PATCH 11/18] Add mark to EncodingShelf props & add logic for displaying ValueCust --- .../encoding-pane/encoding-shelf.tsx | 44 +++++++++++++------ src/components/encoding-pane/index.tsx | 5 ++- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/components/encoding-pane/encoding-shelf.tsx b/src/components/encoding-pane/encoding-shelf.tsx index 630ac4ecf..b2c0d0cd8 100644 --- a/src/components/encoding-pane/encoding-shelf.tsx +++ b/src/components/encoding-pane/encoding-shelf.tsx @@ -4,6 +4,8 @@ import * as React from 'react'; import * as CSSModules from 'react-css-modules'; import {ConnectDropTarget, DropTarget, DropTargetCollector, DropTargetSpec} from 'react-dnd'; import * as TetherComponent from 'react-tether'; +import {SHAPE} from 'vega-lite/build/src/channel'; +import {POINT, TEXT} from 'vega-lite/build/src/mark'; import {contains} from 'vega-lite/build/src/util'; import {ActionHandler} from '../../actions/index'; import { @@ -15,7 +17,7 @@ import {DraggableType, FieldParentType} from '../../constants'; import {ShelfFieldDef, ShelfId} from '../../models'; import {ShelfFunction} from '../../models/shelf'; import {ShelfValueDef} from '../../models/shelf/spec'; -import {isWildcardChannelId} from '../../models/shelf/spec/encoding'; +import {ShelfMark} from '../../models/shelf/spec/encoding'; import {DraggedFieldIdentifier, Field} from '../field/index'; import * as styles from './encoding-shelf.scss'; import {FieldCustomizer} from './field-customizer'; @@ -42,6 +44,8 @@ export interface EncodingShelfPropsBase extends ActionHandler
@@ -92,19 +94,10 @@ class EncodingShelfBase extends React.PureComponent< attachment="top left" targetAttachment="bottom left" > - {(!isWildcardChannelId(id) && (!fieldDef && contains(CUSTOMIZABLE_VALUE_ENCODING_CHANNELS, id.channel) || - fieldDef && contains(CUSTOMIZABLE_ENCODING_CHANNELS, id.channel))) ? - - {channelName}{' '} - : - - {channelName} - - } - + {this.renderDropdownCaret()} {this.state.customizerIsOpened &&
- { !fieldDef ? + {!fieldDef ? + {channelName} + + ); + } else { + return ( + + {channelName}{' '} + + ); + } + } + + private renderField() { const {id, fieldDef, schema} = this.props; const renderFunctionPicker = fieldDef.type === 'quantitative' || fieldDef.type === 'temporal'; diff --git a/src/components/encoding-pane/index.tsx b/src/components/encoding-pane/index.tsx index 79d12cdb3..aba6230a6 100644 --- a/src/components/encoding-pane/index.tsx +++ b/src/components/encoding-pane/index.tsx @@ -110,6 +110,7 @@ class EncodingPanelBase extends React.PureComponent { const {handleAction, spec, specPreview, schema} = this.props; const {encoding} = specPreview || spec; + const {mark} = specPreview || spec; const encodingChannel = encoding[channel]; return ( { schema={schema} handleAction={handleAction} valueDef={isShelfValueDef(encodingChannel) ? encodingChannel : undefined} + mark={mark} /> ); } @@ -135,7 +137,7 @@ class EncodingPanelBase extends React.PureComponent { private wildcardShelf(index: number) { const {handleAction, spec, specPreview, schema} = this.props; const {anyEncodings} = specPreview || spec; - + const {mark} = specPreview || spec; const id = { channel: SHORT_WILDCARD, index @@ -149,6 +151,7 @@ class EncodingPanelBase extends React.PureComponent { fieldDef={anyEncodings[index]} handleAction={handleAction} valueDef={undefined} // don't support constant value for wildcard shelf + mark = {mark} /> ); } From 2564e6dbbda87fe06b05d9d6a096a28d007de83f Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Thu, 26 Jul 2018 13:56:58 -0700 Subject: [PATCH 12/18] Style changes --- .../encoding-pane/property-editor-schema.ts | 4 ++-- .../encoding-pane/value-customizer.scss | 24 ++++--------------- .../encoding-pane/value-customizer.tsx | 8 ++++++- .../encoding-pane/value-editor-schema.ts | 6 ++--- 4 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/components/encoding-pane/property-editor-schema.ts b/src/components/encoding-pane/property-editor-schema.ts index 8a11ba115..f61604ca5 100644 --- a/src/components/encoding-pane/property-editor-schema.ts +++ b/src/components/encoding-pane/property-editor-schema.ts @@ -300,12 +300,12 @@ export function generateTextBoxSchema(propKey: string, placeHolderText: string, return {schema, uiSchema}; } -export function generateSliderSchema(propKey: string, min: number, max: number) { +export function generateSliderSchema(propKey: string, min: number, max: number, title: string) { const schema: ObjectSchema = { type: 'object', properties: { [propKey]: { - title: propKey, + title: title, type: 'number' } as SchemaProperty } diff --git a/src/components/encoding-pane/value-customizer.scss b/src/components/encoding-pane/value-customizer.scss index 93424c33d..0db29d59e 100644 --- a/src/components/encoding-pane/value-customizer.scss +++ b/src/components/encoding-pane/value-customizer.scss @@ -2,7 +2,7 @@ background-color: #eee; border-bottom: 5px solid #eee; border-radius: 3px; - width: 190px; + width: 250px; select { font-size: 10px; @@ -27,29 +27,15 @@ } label { - display: inline-block; + float: left; font-size: 11px !important; // cannot access react-form's css attributes, so have to use important padding-right: 10px; text-align: left; width: 75px; + font-weight: bold; } - ul { - border-bottom: 1px solid #aaa; - margin: 0 0; - padding: 2px; - height: 18px; - } - - li { - display: inline-block; - border: 1px solid transparent; - border-bottom: none; - bottom: -1px; - position: relative; - list-style: none; - padding: 2px 10px; - cursor: pointer; - font-size: 12px; + input { + float: left; } } diff --git a/src/components/encoding-pane/value-customizer.tsx b/src/components/encoding-pane/value-customizer.tsx index e4c935827..e413661e9 100644 --- a/src/components/encoding-pane/value-customizer.tsx +++ b/src/components/encoding-pane/value-customizer.tsx @@ -32,14 +32,20 @@ export class ValueCustomizerBase extends React.PureComponent +
); } + protected resetValue() { + // read default values of mark from VL + // Then call SPEC_VALUE_CHANGE with the corresponding valueDef + } + protected changeValue(result: any) { - const value = result.formData[Object.keys(result.formData)[0]]; + const value = result.formData ? result.formData[Object.keys(result.formData)[0]] : undefined; const {shelfId, handleAction} = this.props; const valueDef: ShelfValueDef = {value}; diff --git a/src/components/encoding-pane/value-editor-schema.ts b/src/components/encoding-pane/value-editor-schema.ts index 009406b11..aca174e32 100644 --- a/src/components/encoding-pane/value-editor-schema.ts +++ b/src/components/encoding-pane/value-editor-schema.ts @@ -12,13 +12,13 @@ export function generateValueDefFormData(shelfId: ShelfId, valueDef: ShelfValueD export function generateValueEditorSchema(channel: Channel): any { switch (channel) { case 'color': - return generateColorPickerSchema(channel, undefined); + return generateColorPickerSchema(channel, 'Color Value'); case 'shape': - return generateSelectSchema(channel, SHAPE_VALUES, undefined); + return generateSelectSchema(channel, SHAPE_VALUES, 'Shape Value'); case 'text': return generateTextBoxSchema(channel, 'Some Text...', undefined, 'string'); case 'size': - return generateSliderSchema(channel, 1, 100); + return generateSliderSchema(channel, 1, 100, 'Size Value'); default: return {}; } From c272d90417d6c46a8a4cc4a8936b6250b7048df9 Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Mon, 30 Jul 2018 10:27:08 -0700 Subject: [PATCH 13/18] Add reset to default logic --- .../encoding-pane/encoding-shelf.tsx | 3 +- .../encoding-pane/property-editor-schema.ts | 2 +- .../encoding-pane/value-customizer.scss | 19 +++++++----- .../encoding-pane/value-customizer.tsx | 24 ++++++++++++--- .../encoding-pane/value-editor-schema.ts | 30 ++++++++++++++++--- 5 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/components/encoding-pane/encoding-shelf.tsx b/src/components/encoding-pane/encoding-shelf.tsx index b2c0d0cd8..81acaf39c 100644 --- a/src/components/encoding-pane/encoding-shelf.tsx +++ b/src/components/encoding-pane/encoding-shelf.tsx @@ -84,7 +84,7 @@ class EncodingShelfBase extends React.PureComponent< } public render() { - const {id, connectDropTarget, fieldDef, valueDef, handleAction} = this.props; + const {id, connectDropTarget, fieldDef, valueDef, handleAction, mark} = this.props; const isWildcardShelf = isWildcard(id.channel); return connectDropTarget( @@ -102,6 +102,7 @@ class EncodingShelfBase extends React.PureComponent< shelfId={id} valueDef={valueDef} handleAction={handleAction} + mark={mark} /> : { shelfId: ShelfId; valueDef: ShelfValueDef; + mark: ShelfMark; } export class ValueCustomizerBase extends React.PureComponent { @@ -18,8 +20,10 @@ export class ValueCustomizerBase extends React.PureComponent - +
); } - protected resetValue() { + protected resetValue(e: any) { // read default values of mark from VL // Then call SPEC_VALUE_CHANGE with the corresponding valueDef + const {shelfId, handleAction, mark} = this.props; + const value = getDefaultsForChannel(shelfId.channel as Channel, mark); + const valueDef: ShelfValueDef = {value}; + + handleAction({ + type: SPEC_VALUE_CHANGE, + payload: { + shelfId, + valueDef + } + }); + } protected changeValue(result: any) { diff --git a/src/components/encoding-pane/value-editor-schema.ts b/src/components/encoding-pane/value-editor-schema.ts index aca174e32..29662035f 100644 --- a/src/components/encoding-pane/value-editor-schema.ts +++ b/src/components/encoding-pane/value-editor-schema.ts @@ -1,9 +1,31 @@ -import {Channel} from "vega-lite/build/src/channel"; -import {ShelfId, ShelfValueDef} from "../../models"; -import {generateColorPickerSchema, generateSelectSchema, - generateSliderSchema, generateTextBoxSchema} from "./property-editor-schema"; +import {Channel, COLOR, SHAPE, SIZE, TEXT} from "vega-lite/build/src/channel"; +import {CIRCLE, POINT, RECT, SQUARE} from "vega-lite/build/src/mark"; +import {ShelfId, ShelfMark, ShelfValueDef} from "../../models"; +import { + generateColorPickerSchema, generateSelectSchema, + generateSliderSchema, generateTextBoxSchema +} from "./property-editor-schema"; const SHAPE_VALUES = ['circle', 'square', 'cross', 'diamond', 'triangle-up', 'triangle-down', ]; +const defaultSymbolSize = 30; +const defaultColor = '#4c78a8'; +const defaultTextFontSize = 11; + +const MARK_DEFAULT_INDEX = { + [SIZE]: { + [POINT]: defaultSymbolSize, + [CIRCLE]: defaultSymbolSize, + [SQUARE]: defaultSymbolSize, + [RECT]: defaultSymbolSize, + [TEXT]: defaultTextFontSize + }, + [SHAPE]: CIRCLE, + [COLOR]: defaultColor, +}; + +export function getDefaultsForChannel(channel: Channel, mark: ShelfMark) { + return channel === SIZE ? MARK_DEFAULT_INDEX[channel][mark] : MARK_DEFAULT_INDEX[channel]; +} export function generateValueDefFormData(shelfId: ShelfId, valueDef: ShelfValueDef) { return {[shelfId.channel.toString()]: valueDef ? valueDef.value : undefined}; From acbc7fba8d9bbde2a76371859cca29469ff1404f Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Tue, 7 Aug 2018 09:29:56 -0700 Subject: [PATCH 14/18] Update to CQL 0.20.4 --- package.json | 2 +- src/components/encoding-pane/value-customizer.tsx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index a5d1e0b9c..0e5124032 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ }, "dependencies": { "ajv": "^5.2.2", - "compassql": "0.20.3", + "compassql": "0.20.4", "font-awesome": "^4.7.0", "font-awesome-sass-loader": "^1.0.3", "isomorphic-fetch": "^2.2.1", diff --git a/src/components/encoding-pane/value-customizer.tsx b/src/components/encoding-pane/value-customizer.tsx index 4e7d70046..cd0233ef7 100644 --- a/src/components/encoding-pane/value-customizer.tsx +++ b/src/components/encoding-pane/value-customizer.tsx @@ -8,7 +8,6 @@ import {ShelfId, ShelfMark, ShelfValueDef} from "../../models"; import * as styles from './value-customizer.scss'; import {generateValueDefFormData, generateValueEditorSchema, getDefaultsForChannel} from './value-editor-schema'; -const defaultSymbolSize = 30; export interface ValueCustomizerProps extends ActionHandler { shelfId: ShelfId; valueDef: ShelfValueDef; From 7e7f3d456b86065421d432e8ec2249c0ca1441bd Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Tue, 7 Aug 2018 10:28:01 -0700 Subject: [PATCH 15/18] Add styles & defaults for marks --- src/components/encoding-pane/value-customizer.scss | 12 +++++++++++- src/components/encoding-pane/value-customizer.tsx | 6 ++++-- src/components/encoding-pane/value-editor-schema.ts | 12 +++++++++--- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/components/encoding-pane/value-customizer.scss b/src/components/encoding-pane/value-customizer.scss index ec1a1438b..0df67fa2b 100644 --- a/src/components/encoding-pane/value-customizer.scss +++ b/src/components/encoding-pane/value-customizer.scss @@ -8,6 +8,16 @@ display: inline-block; } + a { + font-size: 10px; + color: blue; + margin-bottom: 15px; + } + + span { + padding: 5px; + } + select:focus { outline: none } @@ -23,7 +33,7 @@ } form { - height: 2.8em; + height: 3.4em; } select option { diff --git a/src/components/encoding-pane/value-customizer.tsx b/src/components/encoding-pane/value-customizer.tsx index cd0233ef7..80414a695 100644 --- a/src/components/encoding-pane/value-customizer.tsx +++ b/src/components/encoding-pane/value-customizer.tsx @@ -24,7 +24,7 @@ export class ValueCustomizerBase extends React.PureComponent - + {mark !== '?' && + Reset + }
diff --git a/src/components/encoding-pane/value-editor-schema.ts b/src/components/encoding-pane/value-editor-schema.ts index 29662035f..71f51e096 100644 --- a/src/components/encoding-pane/value-editor-schema.ts +++ b/src/components/encoding-pane/value-editor-schema.ts @@ -1,5 +1,5 @@ import {Channel, COLOR, SHAPE, SIZE, TEXT} from "vega-lite/build/src/channel"; -import {CIRCLE, POINT, RECT, SQUARE} from "vega-lite/build/src/mark"; +import {BAR, CIRCLE, POINT, RECT, SQUARE, TICK} from "vega-lite/build/src/mark"; import {ShelfId, ShelfMark, ShelfValueDef} from "../../models"; import { generateColorPickerSchema, generateSelectSchema, @@ -10,17 +10,23 @@ const SHAPE_VALUES = ['circle', 'square', 'cross', 'diamond', 'triangle-up', 'tr const defaultSymbolSize = 30; const defaultColor = '#4c78a8'; const defaultTextFontSize = 11; +const defaultBarSize = 20; // find config for this +const defaultTickSize = 18; +// TODO: Verify/Find the correct default values for each mark const MARK_DEFAULT_INDEX = { [SIZE]: { [POINT]: defaultSymbolSize, [CIRCLE]: defaultSymbolSize, [SQUARE]: defaultSymbolSize, [RECT]: defaultSymbolSize, - [TEXT]: defaultTextFontSize + [TEXT]: defaultTextFontSize, + [BAR]: defaultBarSize }, [SHAPE]: CIRCLE, [COLOR]: defaultColor, + [TEXT]: '', + [TICK]: defaultTickSize }; export function getDefaultsForChannel(channel: Channel, mark: ShelfMark) { @@ -38,7 +44,7 @@ export function generateValueEditorSchema(channel: Channel): any { case 'shape': return generateSelectSchema(channel, SHAPE_VALUES, 'Shape Value'); case 'text': - return generateTextBoxSchema(channel, 'Some Text...', undefined, 'string'); + return generateTextBoxSchema(channel, 'Some Text...', 'Text Value', 'string'); case 'size': return generateSliderSchema(channel, 1, 100, 'Size Value'); default: From 5da835b98fc9440bea8a0393d9e62b40eca2ae33 Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Tue, 7 Aug 2018 17:23:12 -0700 Subject: [PATCH 16/18] Add mainspec prop to read mark from main view Remove ../node_modules prefix asdf --- src/components/encoding-pane/encoding-shelf.tsx | 6 +++++- src/components/encoding-pane/index.tsx | 14 ++++++++++---- src/components/encoding-pane/value-customizer.tsx | 15 +++++++-------- src/selectors/shelf.ts | 2 +- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/components/encoding-pane/encoding-shelf.tsx b/src/components/encoding-pane/encoding-shelf.tsx index 81acaf39c..6a24e4bee 100644 --- a/src/components/encoding-pane/encoding-shelf.tsx +++ b/src/components/encoding-pane/encoding-shelf.tsx @@ -6,6 +6,7 @@ import {ConnectDropTarget, DropTarget, DropTargetCollector, DropTargetSpec} from import * as TetherComponent from 'react-tether'; import {SHAPE} from 'vega-lite/build/src/channel'; import {POINT, TEXT} from 'vega-lite/build/src/mark'; +import {TopLevelFacetedUnitSpec} from 'vega-lite/build/src/spec'; import {contains} from 'vega-lite/build/src/util'; import {ActionHandler} from '../../actions/index'; import { @@ -46,6 +47,8 @@ export interface EncodingShelfPropsBase extends ActionHandler : { @@ -108,7 +111,7 @@ class EncodingPanelBase extends React.PureComponent { private encodingShelf(channel: Channel) { // This one can't be wildcard, thus we use VL's Channel, not our ShelfChannel - const {handleAction, spec, specPreview, schema} = this.props; + const {handleAction, mainSpec, spec, specPreview, schema} = this.props; const {encoding} = specPreview || spec; const {mark} = specPreview || spec; const encodingChannel = encoding[channel]; @@ -121,6 +124,7 @@ class EncodingPanelBase extends React.PureComponent { handleAction={handleAction} valueDef={isShelfValueDef(encodingChannel) ? encodingChannel : undefined} mark={mark} + mainSpec={mainSpec} /> ); } @@ -135,7 +139,7 @@ class EncodingPanelBase extends React.PureComponent { } private wildcardShelf(index: number) { - const {handleAction, spec, specPreview, schema} = this.props; + const {handleAction, spec, specPreview, schema, mainSpec} = this.props; const {anyEncodings} = specPreview || spec; const {mark} = specPreview || spec; const id = { @@ -152,6 +156,7 @@ class EncodingPanelBase extends React.PureComponent { handleAction={handleAction} valueDef={undefined} // don't support constant value for wildcard shelf mark = {mark} + mainSpec={mainSpec} /> ); } @@ -181,7 +186,8 @@ export const EncodingPane = connect( schema: selectDataset(state).schema, fieldDefs: selectSchemaFieldDefs(state), specPreview: selectShelfPreview(state).spec, - config: selectConfig(state) + config: selectConfig(state), + mainSpec: selectMainSpec(state) }; }, createDispatchHandler() diff --git a/src/components/encoding-pane/value-customizer.tsx b/src/components/encoding-pane/value-customizer.tsx index 80414a695..e71dc82d4 100644 --- a/src/components/encoding-pane/value-customizer.tsx +++ b/src/components/encoding-pane/value-customizer.tsx @@ -3,6 +3,7 @@ import * as CSSModules from 'react-css-modules'; import Form from 'react-jsonschema-form'; import {debounce} from 'throttle-debounce'; import {Channel} from 'vega-lite/build/src/channel'; +import {TopLevelFacetedUnitSpec} from 'vega-lite/build/src/spec'; import {ActionHandler, SPEC_VALUE_CHANGE, SpecEncodingAction} from "../../actions"; import {ShelfId, ShelfMark, ShelfValueDef} from "../../models"; import * as styles from './value-customizer.scss'; @@ -12,6 +13,7 @@ export interface ValueCustomizerProps extends ActionHandler shelfId: ShelfId; valueDef: ShelfValueDef; mark: ShelfMark; + mainSpec: TopLevelFacetedUnitSpec; } export class ValueCustomizerBase extends React.PureComponent { @@ -24,7 +26,7 @@ export class ValueCustomizerBase extends React.PureComponent - {mark !== '?' && - Reset - } + Reset @@ -45,10 +45,9 @@ export class ValueCustomizerBase extends React.PureComponent Date: Tue, 7 Aug 2018 17:32:29 -0700 Subject: [PATCH 17/18] Remove node_modules --- src/queries/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/queries/index.ts b/src/queries/index.ts index 9a67f09dd..1f1f51cfe 100644 --- a/src/queries/index.ts +++ b/src/queries/index.ts @@ -3,13 +3,13 @@ */ import {getGroupByKey} from 'compassql/build/src/nest'; +import {isAutoCountQuery, isFieldQuery} from 'compassql/build/src/query/encoding'; import {Query} from 'compassql/build/src/query/query'; import {isAggregate, SpecQuery} from 'compassql/build/src/query/spec'; import {contains} from 'compassql/build/src/util'; import {Store} from 'redux'; import {isString} from 'util'; import {NONPOSITION_SCALE_CHANNELS} from 'vega-lite/build/src/channel'; -import {isAutoCountQuery, isFieldQuery} from '../../node_modules/compassql/build/src/query/encoding'; import {resultRequest} from '../actions/result'; import {State} from '../models/index'; import {ResultType} from '../models/result'; From 1b97be5a007b9845be200bed1410bff1aab14e1d Mon Sep 17 00:00:00 2001 From: Shaheen Sharifian Date: Wed, 8 Aug 2018 11:04:07 -0700 Subject: [PATCH 18/18] Add test for valueQuery --- src/queries/alternative-encodings.test.ts | 53 +++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/queries/alternative-encodings.test.ts b/src/queries/alternative-encodings.test.ts index 08e15fc7c..9879b111e 100644 --- a/src/queries/alternative-encodings.test.ts +++ b/src/queries/alternative-encodings.test.ts @@ -58,4 +58,57 @@ describe('queries/alternative-encodings', () => { chooseBy: ['aggregationQuality', 'effectiveness'] }); }); + + it.only('should correctly produce a query given ValueDef encoding', () => { + const query: Query = { + spec: { + transform: [{ + filter: { + field: 'a', + oneOf: ['1, 2'] + } + }], + mark: 'point', + encodings: [{ + channel: 'y', + field: 'a', + type: 'quantitative' + }, { + channel: 'color', + value: '#ffffff' + }, { + channel: 'x', + field: 'c', + type: 'temporal' + }] + } + }; + + expect(alternativeEncodings.createQuery(query)).toEqual({ + spec: { + transform: [{ + filter: { + field: 'a', + oneOf: ['1, 2'] + } + }], + mark: SHORT_WILDCARD, + encodings: [{ + channel: SHORT_WILDCARD, + field: 'a', + type: 'quantitative' + }, { + channel: 'color', + value: '#ffffff' + }, { + channel: SHORT_WILDCARD, + field: 'c', + type: 'temporal' + }] + }, + groupBy: 'encoding', + orderBy: ['fieldOrder', 'aggregationQuality', 'effectiveness'], + chooseBy: ['aggregationQuality', 'effectiveness'] + }); + }); });