-
Notifications
You must be signed in to change notification settings - Fork 13.9k
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
New chart type : Chord Diagrams #3013
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!!
@@ -622,6 +624,37 @@ const visTypes = { | |||
}, | |||
}, | |||
}, | |||
chord: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file contains configuration of the new chord
viz type. It defines the panels of controls that should render on the left panel of the explore view.
controlSetRows
references controls defined in controls.jsx
, and can have one or two items and that defines how many items will render on that row.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file contains configuration of the new chord viz type. It defines the panels of controls that should render on the left panel of the explore view.
controlSetRows references controls defined in controls.jsx, and can have one or two items and that defines how many items will render on that row.
Could I please ask some questiones? I want to show a metric and some filter in the superset dashboard, after reading some articles, i am confused because the configuration needed to be changed does not exist in the files. For example,
superset/assets/javascripts/explore/stores/visTypes.js, this file does not exist in the current code file. So, how can i add a metric in the superset now and which files should i modify in order to achieve this?
], | ||
}, | ||
], | ||
controlOverrides: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
controlOverrides
allows you to override the control configuration coming from controls.jsx
. By reusing the same control across visualizations we allow continuity in the sense that the values are carried over when going from a viz type to the next. For instance as you go from one viz type to the next, it's nice to have metrics
carried over, though you might want a slightly different label or tooltip in the different contexts, this is what the overrides are for.
default: [], | ||
description: 'One or many controls to pivot as columns', | ||
optionRenderer: c => <ColumnOption column={c} />, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file (controls.jsx
) holds configuration for a "pool" of controls that can be used across visualizations. When creating a new visualization, you'll want to reuse controls that already exist. If the exact control that you need doesn't exist already, you'll want to create it here.
Note that type
references controls React components defined in javascripts/explore/component/controls/
.
Also note that controls can be dynamic with mapStateToProps
, allowing to map anything from the app's state into a prop for the component. This allows in this case to get configuration elements proper to the datasource in this case, but can also be used to change a control based on another control's value.
@@ -0,0 +1,17 @@ | |||
.chord svg #circle circle { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by convention each visualization has its own css
file, and the entries need to be "namespaced" properly to make sure that one viz's css doesn't spill and apply to other viz types
import { category21 } from '../javascripts/modules/colors'; | ||
import './chord.css'; | ||
|
||
function chordViz(slice, json) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is the heart of this new visualization, the framework will pass it a slice
and json
object, and expects you to mutate the dom element referenced in the slice object. It will be called whenever the slice needs to be rendered or re-rendered. Knowing that this function may be called many times, you can use closures here if you want to persists certain things in the module namespace.
The json objects corresponds to the data returned from running your query and related context. To see exactly what you should expect in here you can click the json
button in the explore view.
The slice object contains, amongst other things, a reference to the dom element that you should mutate.
|
||
const div = d3.select(slice.selector); | ||
const nodes = json.data.nodes; | ||
const fd = slice.formData; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On of the things that the slice object exposes isf the information provided by the user controls. The keys of this slice.formData
object are the control's "id" defined in controls.jsx
and their values are the ones provided by the user.
const fd = slice.formData; | ||
const f = d3.format(fd.y_axis_format); | ||
|
||
const width = slice.width(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The slice object exposes width()
and height()
methods that can be useful while rendering your chart.
}); | ||
} | ||
|
||
module.exports = chordViz; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that function should be exported as the default export for the visualization module
@@ -10,6 +10,7 @@ const vizMap = { | |||
cal_heatmap: require('./cal_heatmap.js'), | |||
compare: require('./nvd3_vis.js'), | |||
directed_force: require('./directed_force.js'), | |||
chord: require('./chord.jsx'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simply adding the mapping from the chord
visualization type to the appropriate javascript modules. It's possible here to have multiple visualization types target the same module (look at nvd3.js!)
@@ -1231,6 +1232,39 @@ def get_data(self, df): | |||
return df.to_dict(orient='records') | |||
|
|||
|
|||
class ChordViz(BaseViz): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the backend part of this component, you can derive BaseViz
or other BaseViz
derivatives
credits = '<a href="https://github.com/d3/d3-chord">Bostock</a>' | ||
is_timeseries = False | ||
|
||
def query_obj(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to override query_obj
and it has to return a query object, which is essentially a Python dict
with key/values that are expected by the query
method of the connectors. Until this is better documented, you can look at the connector's Datasource query
method to get a sense for it.
qry['metrics'] = [fd.get('metric')] | ||
return qry | ||
|
||
def get_data(self, df): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_data
receives a pandas dataframe (df) that correspond to what is returned when applying your query object defined above. The shape of that dataframe is related to what you ask for in that query_obj
.
Now whatever get_data
returns needs to be json-serializable, and will be made available to the javascript visualization function as payload.data
.
slice.container.html(''); | ||
|
||
const div = d3.select(slice.selector); | ||
const nodes = json.data.nodes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
json.data
corresponds exactly to what is returned in the backend ChordViz.get_data
lower in this PR.
Mistercrunch, I'm new to Superset. We are doing a POC here at work, and we want to know how easy it would be to add a new visualization to it. So I just updated all the files from your example to my superset local server, but the new visualization is not showing on the visualization tab. |
@Visitante just use master as this PR has been merged there. |
@xrmx thanks for the fast reply. The point of my POC is to see how hard it would be to add a new visualization to Superset. |
Hi! Our team followed the FAQ on the Is there a mechanism for adding source for a new visualization type without manually building the Superset source? Since we are using Superset by installing via pip, is there a way to drop in new javascript files in a directory etc. that Superset knows to look for? |
@apoku nope |
@apoku thought quite a bit about that and given the modern javascript building pipeline there's no easy/clean way to do this without bundling all of Superset together. We may reorganize visualizations so that it's easier to maintain a fork. The idea would be to have all the code related to one each visualization (js & py) in a specific folder. |
@Visitante you're probably missing something like an entry in |
I get an error when trying to make a custom build so I can use the chord visualization: |
@ouyangal the actual error would be helpful but please try to reproduce with a modern version of node (6+) and if you cannot upgrade to a node with npm 5+ try to build with yarn instead. |
Have the file locations changed? I can't find "controls.jsx" in the stores folder. |
The new path of "controls.jsx" is superset/assets/src/explore/controls.jsx |
Hello, excuse me, superset and druid combine, how to achieve year-on-year, month-to-month function? |
The code and file architecture of present version of superset seems very different. @mistercrunch Can you help me how to add new chart visualization in the current version of the superset. |
Hey, did you add the visualization in the current version of superset. @MTShannon @HaiNguyenHuynh. |
@ankit6373 hello, we also try to add new custom chart to current version of superset (0.35.2) but as you said it seems very different then the older versions. Did you manage how to add it? |
mgulaydin hi. Please help me how to add new chart in current version superset |
Hi everyone, It seems there are a lot of people still looking to build new viz components for Superset, and that's awesome! I hope that this recently published blog post can help get you started, using the latest tools and practices. https://preset.io/blog/2020-07-02-hello-world/ Thanks! |
Windows isn't officially supported, fire up a VM! |
This PR is used as an example on how to add new visualizations to Superset, find comments in the code that put things into perspective.