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

[WIP] Add support for Vega and Vega-lite #3931

Closed
wants to merge 6 commits into from
Closed

Conversation

ktmud
Copy link
Contributor

@ktmud ktmud commented Jun 26, 2019

What type of PR is this? (check all applicable)

  • Feature

Description

Vega and Vega-Lite allow a user to specify a JSON configuration
to declaratively define a complex interactive visualization.

It could theoretically become the foundation of many visualizations
we have in Redash.

This PR adds Vega and Vega-Lite and a new visualization type,
and allows users to directly edit a Vega or Vega-Lite spec in either JSON or YAML. A lot of code is borrowed from the official Vega Editor.

While most of the functionalities are working, this is not ready for shipment yet. Some known issues:

  • Vega allows only fixed container size. We need to figure out how to do autoresize.
  • Not all themes are useful to the majority of the users.
  • Haven't tested tooltips.
  • Vega-Embed allows downloading PNG files, which can be very useful. Will add support in future PR.
  • Was trying to add monaco-yaml so the YAML editor can also have the very nice IntelliSense, including autocomplete and linting. But that Monaco plugin isn't working well with ESM yet. Will consider migrating to Monaco in future work.

Related Tickets & Documents

https://discuss.redash.io/t/add-vega-grammar-support-for-advanced-visualizations/3020

Mobile & Desktop Screenshots/Recordings (if there are UI changes)

Visualization editor:

Snip20190625_1

Visualization renderer (with a different Vega theme)

Snip20190625_3

@ktmud ktmud changed the title Add support for Vega and Vega-lite [WIP] Add support for Vega and Vega-lite Jun 26, 2019
@kravets-levko
Copy link
Collaborator

Hi @ktmud! Thanks for your incredible work! I know that this PR is still WIP, but I have some notices that would be better to fix on early stage:

  • don't pass query object to each visualization; you need only URLs there - so pass them; probably, data object is a good place;
  • please try to reuse existing dependencies; I like Monaco as well, but Redash already has an editor library (Ace), so please use it; also, do you really need to update all that dependencies?

Also, please see my comments to the code. Thanks!

return find(
registeredVisualizations,
viz => !viz.isDeprecated && viz.isDefault,
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Now this code assumes that at least one visualization has isDefault attribute; not sure if it's right or not, but I'd add a fallback for this case (if no isDefault visualization - return first non-deprecated). That's just a suggestion

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. Maybe we should pre-sort the registered visualizations and make the default visualization a constant instead of calling find() every time?

This is just a quick hack to avoid Vega showing up as the default editor. If there's any other way of doing it, I'd be happy to avoid adding a new config field.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Adding new config field is a good solution, let's keep it. Calling find every time is not a problem because ATM it is used only in Edit Visualization dialog and is called there only once (on dialog open).

Copy link
Collaborator

Choose a reason for hiding this comment

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

@ktmud I created a separate PR for this feature (#3944) because we needed it right now in few other PRs to fix tests.

'attachment; filename="{}"'.format(filename.encode("utf-8"))
)
if filetype in ('csv', 'json') and request.args.get('download') in ['false', '0']:
response.headers.set('Content-Type', 'text/plain; charset=UTF-8')
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you please explain these changes (what are they needed for?). Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is for allowing users to click on the data source url that populated in Vega schema and review the data directly in browser without automatically downloading a file.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think in this case you have to set a proper MIME type for each extension. E.g. I have a chrome extensions that pretty-print both CSV and JSON (see screenshot with example), and both that extensions detect their targets by MIME type, so changes like this will break them.

image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I also have a JSON prettier extension installed, but couldn't find a good one for CSV. Which one are you using?

Since this change added a new URL parameter "download=false", it shouldn't break any existing links. I'm inclined to keep it. What do you think?

@ktmud
Copy link
Contributor Author

ktmud commented Jun 26, 2019

Hi Levko, thanks for reviewing!

  • please try to reuse existing dependencies; I like Monaco as well, but Redash already has an editor library (Ace), so please use it; also, do you really need to update all that dependencies?

Can we actually replace Ace Editor with Monaco? Monaco comes with some highly desirable advanced features such as inline validation of JSON schemas, which is quite essential for a Vega editor.

I had to upgrade Webpack because the latest version of Monaco wouldn't build.

@kravets-levko
Copy link
Collaborator

Can we actually replace Ace Editor with Monaco?

Well, yes, we can, of course. But definitely not within this PR - we use a lot of Ace features in query editor and all of them should be kept with Monaco.

@ktmud
Copy link
Contributor Author

ktmud commented Jun 26, 2019

Can we actually replace Ace Editor with Monaco?

Well, yes, we can, of course. But definitely not within this PR - we use a lot of Ace features in query editor and all of them should be kept with Monaco.

Sure! I think I'll remove Monaco dependency for now and replace it with Ace Editor. There was some building issues with Monaco as well (it takes forever to build client/dist for Docker image).

@ktmud ktmud force-pushed the vega branch 5 times, most recently from 92e56d4 to 2e522cc Compare July 1, 2019 21:07
// monaco.languages.json.jsonDefaults.setDiagnosticsOptions(monacoDiagnostics);
// monaco.languages.registerDocumentFormattingEditProvider('json', jsonFormatter);
// monaco.languages.registerDocumentFormattingEditProvider('yaml', yamlFormatter);
// }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Keeping the code for Monaco here for now, so later migration will be easier (if we are going to do it)

vPadding += (spec.padding.top || 0) + (spec.padding.bottom || 0);
}
width = width || specWidth || Math.max(parentSize.width - hPadding, 100);
height = height || specHeight || Math.min(400, Math.max(parentSize.height - vPadding, 300));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

By default, a Vega visualization has min-height 300px and max-height 400px. This is inline with what Plot.ly currently has, although I was not able to find where we set the height for Plot.ly...

Copy link
Collaborator

Choose a reason for hiding this comment

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

We don't set height for Plotly charts: on Dashboard page chart fits it's container in widget, and on Query page it has fixed height (IIRC, 500px) and width 100%.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So the default height 500px comes from Plot.ly library itself?

I implemented 100% height for Vega charts everywhere.

@ktmud ktmud changed the title [WIP] Add support for Vega and Vega-lite Add support for Vega and Vega-lite Jul 2, 2019
@ktmud
Copy link
Contributor Author

ktmud commented Jul 2, 2019

@kravets-levko @arikfr I think this PR is more or less ready now. Can you please take another look? It's actually quite fun to play with Vega specs.

import { Handler } from 'vega-tooltip';
import { Alert, Icon } from 'antd';
import LZString from 'lz-string';
import memoize from 'memoize-one';
Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

_.memoize does not cache only one return value, having higher risk of memory leaks.
useMemo does not work with class components. I don't see the added benefits of rewriting my class to a function component.

memoize-one only has 45 LOC.

@rastafarra
Copy link

hi!

can you please check conflicts?

@bazhenov
Copy link

Hi.

We are very interested in this functionality, as standard visualisations types are quite limiting for us. What is the status of this MR and do you need any help? Maybe some functionality should be implemented before it considered "done"?

@kravets-levko kravets-levko self-requested a review March 30, 2020 07:50
@kravets-levko
Copy link
Collaborator

Hi @ktmud! I'd like to review your PR once more, so can you please resolve conflicts? Also, I'd ask you to remove changes that are not related to subject of this PR and commented out fragments. Thank you!

P.S. Please ping me when it's ready for review 🙇‍♂️

@ktmud ktmud changed the title Add support for Vega and Vega-lite [WIP] Add support for Vega and Vega-lite Mar 31, 2020
@ktmud
Copy link
Contributor Author

ktmud commented Mar 31, 2020

Hi all, I just pushed a quick fix to resolve the conflicts. Things might still not work. Will pick this up again during the weekend.

@ktmud
Copy link
Contributor Author

ktmud commented Mar 31, 2020

I haven't worked on Redash for a while, so things might be a little slow.

@itssimon
Copy link

This looks amazing @ktmud! Do you think you'll get a chance to get this across the line? Happy to help!

@ktmud ktmud force-pushed the vega branch 2 times, most recently from 802c9dc to 2b6427e Compare August 14, 2020 09:05
@ktmud
Copy link
Contributor Author

ktmud commented Aug 14, 2020

Just updated the branch and it is now 90% done.

It depends on #5104 , but the dependency can be easily removed if that PR isn't going anywhere.

@ktmud ktmud force-pushed the vega branch 3 times, most recently from 01ae06d to 96d38c6 Compare August 14, 2020 18:13
ktmud and others added 6 commits August 14, 2020 11:20
Optimize typescript configuration

Fix webpack for prod

Adjust cypress timeout

Fix viz-lib build
Vega and Vega-Lite allow users to specify a JSON configuration
to declaratively define a complex interactive visualization.

It could thoeretically become the foundation of many visualizations
we already have.

This commit adds integration with Vega and Vega-Lite, with a lot
of code borrowed from the official Vega Editor[1].

[1] https://vega.github.io/editor/
@vadimcn
Copy link

vadimcn commented Feb 2, 2023

Hi! What happened to this PR? Is it abandoned?

@guidopetri
Copy link
Contributor

@ktmud , thanks for the PR! We've updated a lot of things now that we're Community-driven so - if you're still interested in getting this merged - would you mind rebasing off master to re-run the CI?

We're trying to clean up our PR todo list, so if you're not interested, that's fine - we'll close the PR in about a week if we don't hear back. If you're interested in reopening the PR afterwards, we would also very much welcome that.

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.

7 participants