Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to customize vega-lite charts via configuration #726

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

ajainarayanan
Copy link
Contributor

Note:

  • Have not modified README about the new API. We can update once the implementation is reviewed.

@ajainarayanan
Copy link
Contributor Author

@kanitw Have tried what we discussed. Let me know if I have missed something.

  • Ran through dev build
  • Ran test
  • Tested lib-voyager in a different project

All seemed to work the way it is expected.

Copy link
Member

@kanitw kanitw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. I have some comments. Hope they make sense to you.

export const Plot = connect<PlotConnectProps, {}, PlotOwnProps>(
(state: State) => {
return {
voyagerConfig: selectConfig(state)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plot should be a dumb (renderer-only) component, so it should not use connect.
Instead, config should be passed from its parent component, which should already contain connect.

Let's just name it config too as config in this project (except in <VegaLite/>) should mean Voyager's config anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok makes sense if we want to extract this as a separate component (or separate repo).

@@ -16,6 +17,8 @@ export interface VegaLiteProps {
logger: Logger;

data: InlineData;

vegaliteConfig: Config;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please just name this config.

src/index.tsx Outdated
import { Data } from 'vega-lite/build/src/data';
import {App} from './components/app';
import { VOYAGER_CONFIG } from './constants';
import { VoyagerConfig } from './models/config';
import { configureStore } from './store';

const store = configureStore();
const config: VoyagerConfig = VOYAGER_CONFIG;
let config: VoyagerConfig = VOYAGER_CONFIG;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the demo is a bit unnecessary (and should not be here). More importantly, the default mark color should not be "black". Please revert this file.

@@ -13,6 +13,10 @@ export function makeResetReducer<T extends object>(
// Need to cast as object as TS somehow doesn't know that T extends object already
const newState = {...state as object} as T;
Object.keys(resetIndex).forEach((key: keyof T) => {
// This is to not reset any property if resetIndex[property] is false.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch. Maybe add a unit test to prevent regression?

* @param {Object} config configuration options
* @param {Array} data data object. Can be a string or an array of objects.
*/
export function CreateVoyager(container: Container, data: Data, config: VoyagerConfig): Voyager {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not offer two versions of a function with a capital C and a lowercase C.

So you have two options:

a) Remove CreateVoyager. (Yes, this will break things, but we are currently under pre-release version, so better make things right right now. I'll note in the release note that the next release includes this breaking changes.)

b) Do not add createVoyager with the new parameter since this PR only modifies VoyagerConfig and doesn't really add new parameter to CreateVoyager anyway.

I strongly prefer a) since it's better prepared for the future. (We also previously let CreateVoyager with capital C slips in by mistake -- so better fix it before it is too late.)

If you do a), please also help:

  1. Update README.md accordingly
  2. submit a relevant PR for voyager-electronto update relevant API calls

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kanitw ok makes sense. I added it as a separate function for gradually letting users know that this function will be deprecated in the next release. But since voyager is still in alpha/beta releases I guess it should be ok. Its a simple API. Will revert back.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will revert back.

Note that if you do b), we will probably still do a) in the future anyway and you'll have to update the API calls. Maybe it's better if you help us do a) now :p

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Will do a). Regarding PR for voyager-electron: There is an already opened PR. Not sure if I can create another one. But will see if I can spare sometime this weekend for it :)

@@ -36,7 +45,8 @@ export class Voyager {
private data: Data;
private filename: string;

constructor(container: Container, config: VoyagerConfig, data: Data) {
constructor(container: Container, params: VoyagerParams = DEFAULT_VOYAGER_PARAMS) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of the top of my head, I think we don't really need the default DEFAULT_VOYAGER_PARAMS as the store already has default data and config? (Let me know if I'm wrong as my memory is not perfect.)

Note that if we really need it, we probably better use

const {config=DEFAULT_VOYAGER_CONFIG, data=DEFAULT_DATA} = params;

so the default is always used if only one parameter is specified.

@ajainarayanan
Copy link
Contributor Author

ajainarayanan commented Sep 20, 2017

@kanitw Have updated the PR based on review comments. Let me know if I had missed anything.

Note:

Haven't added unit test for the reset reducer. Have added unit tests for reset reducer.

@ajainarayanan
Copy link
Contributor Author

@kanitw Can you give it a try now. Have added unit tests for reset reducer.

Copy link
Member

@kanitw kanitw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank so much for helping. I only have a few more comments.

Also, sorry the for the delay for reviewing. I'm quite busy for the next two weeks so there might be some delay.

Note that you might also want to push a few more commits to vega/voyager-electron#32 to also use the latest createVoyager command instead of the old CreateVoyager?

data: {values: ([] as any)},
config: DEFAULT_VOYAGER_CONFIG
};
const DEFAULT_DATA: any = undefined;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this? (We can just not assign default data below.)

@@ -163,6 +163,48 @@ describe('lib-voyager', () => {
}
}, 10);
});
it('CreateVoyager, update config and update data should retain correct config', done => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

creates a Voyager instance, update ...

);
};

it('Should reset to right default value', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use "should" (small cap)

).toEqual(DEFAULT_PERSISTENT_STATE);
});

it('Should reset bookmark when resetIndex is true', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use "should" (small cap)

shelfPreview: true
};

const getResetReducer = (defaultState = DEFAULT_PERSISTENT_STATE) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just export persistentReducer in index.ts and use it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since its a unit test for reset reducer just wanted it to be self contained. If we change persistentReducer this unit test should be independent of that change as it is testing only reset reducer. May be if I change the model then it can become totally independent.

@ajainarayanan
Copy link
Contributor Author

@kanitw Have updated the PR. Could you give it another try.

@ajainarayanan
Copy link
Contributor Author

@kanitw Any updates on this? Does it require any more changes that I missed?

@kanitw
Copy link
Member

kanitw commented Oct 12, 2017

Sorry I was on a conference and a vacation afterward so I'm a bit slow on this, but I will try to get to this soon.

Copy link
Member

@kanitw kanitw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay. I have a few more comments.

Please also submit a PR to update voyager-electron (perhaps fork from vega/voyager-electron#32).

@@ -16,6 +17,8 @@ export interface VegaLiteProps {
logger: Logger;

data: InlineData;

config: Config;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think config should be optional, so as logger and data (we accidentally let them slip through).

vlSpec = {
...vlSpec,
config: {
...vlSpec.config,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the general config should be overridden by a spec specific-config.

{
  ...config
  ...vlSpec.config
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this override the config users pass to modify vega-lite chart's configuration? My understanding was users pass vegaliteConfig to override spec configurations for respective charts (for instance modify the color or axis tick format etc.,)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it will override since we think about the shared config as a theme. So suppose you have multiple Vega-Lite charts and you have a common config that you pass in. Each spec can have config that override the common theme (rather than the other way round). :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that is the case would the common theme ever be applied? Say in the case of bar charts we have defined the fill color to be a blue and if users need to override that would that be possible? I am not sure if I am missing something.

Can you provide an example where a user modifies the fill color of bar charts in voyager with custom config? My assumption was the config user provides are custom config and that would override any default spec config that comes as part of voyager for vega-lite charts.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that is the case would the common theme ever be applied?

Yes, your common theme may have 10 properties and the spec specific theme may have 1 that override the common theme so 9 properties would still be applied.

Can you provide an example where a user modifies the fill color of bar charts in voyager with custom config?

Right now there is no such case. But this is how Vega-Lite treat "common" theme too. So should CompassQL output some config in the future.

That said, thinking more about it I think I agree with you that if users explicitly specify the config, it should override what's automatically generated by CompassQL.

import {SerializableState} from './models/index';

const DEFAULT_TIMEOUT_LENGTH = 300;

const DEFAULT_VOYAGER_PARAMS: VoyagerParams = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this? (given that all of properties are declared as undefined anyway)

* @param {Array} data data object. Can be a string or an array of objects.
* @param {Container} container css selector or HTMLElement that will be the parent
* element of the application
* @param {VoyagerParams} params Voyager params. {data, config}. Any new additional parameter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Voyager parameter object which can contain optional data and config properties.

No need to say "Any new additional parameter required by voyager can be added here as named parameter for easier visibilty" as that's not what users of Voyager would do.

@ajainarayanan
Copy link
Contributor Author

@kanitw Sorry for the delayed response. Was busy at work. Have updated PR based on review comments. Can you give it a try.

@ajainarayanan
Copy link
Contributor Author

Hey @kanitw . Are there any updates on this PR? Did I miss something in my last commit? Can you give another try

@kanitw
Copy link
Member

kanitw commented Nov 21, 2017

Replied. Sorry for delay too, I've been quite busy and a bit sick.

@kanitw
Copy link
Member

kanitw commented Nov 21, 2017

OK i'm convinced. The last part needed is to update the Voyager electron app then. :)

@ajainarayanan
Copy link
Contributor Author

@kanitw Thought of updating the voyager-electron app once we have a npm release of voyager. I can try testing with local npm package but would be easier (or complete) if I work against a version of voyager from npm. Let me know if you are thinking of something else.

Note:

There is an already existing voyager-electron PR for new build changes. Might be easier if I close that and open a new PR with latest voyager changes.

@kanitw
Copy link
Member

kanitw commented Nov 22, 2017

I can try testing with local npm package

I think it's better to test with local npm package first. :)

There is an already existing voyager-electron PR for new build changes. Might be easier if I close that and open a new PR with latest voyager changes.

Do you mean vega/voyager-electron#32? I guess you can fork from that PR instead of closing it -- otherwise we're losing those changes?

@ajainarayanan
Copy link
Contributor Author

:) I understand. The new PR I was planning to open will have both the changes. Thats why mentioned of closing that PR. Forking a PR from an existing PR becomes a hassle to maintain. Let me see if it makes it simpler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants