-
Notifications
You must be signed in to change notification settings - Fork 8.1k
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
updating tagcloud interpreter func arguments #33773
updating tagcloud interpreter func arguments #33773
Conversation
💔 Build Failed |
ec3850c
to
ecef915
Compare
💔 Build Failed |
ecef915
to
b47107d
Compare
💔 Build Failed |
💔 Build Failed |
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.
Sorry if I jumped the gun here (I realize this is still WIP), but figured I’d add a couple comments since I was looking at it anyway.
metric: [0], | ||
segment: [1, 2] | ||
metric: [{ accessor: 0 }], | ||
segment: [{ accessor: 1 }] |
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.
We should probably add all of the new params here so that the snapshots are testing everything
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.
i'll add another test for that, as this actually hit a bug :)
bucketFormatParams: { | ||
types: ['string'], | ||
default: '"{}"', | ||
} |
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 interpreter tagcloud function unit tests will probably need to be updated too
src/legacy/core_plugins/interpreter/public/functions/tagcloud.js
Outdated
Show resolved
Hide resolved
default: 18, | ||
}, | ||
maxFontSize: { | ||
types: ['number'], |
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.
should we (and how) provide minimum and maximum for this property ?
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.
@w33ble ^^ whats the canvas way ?
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.
Much like options, the interpreter doesn't care. Check it in the function, if the wrong value is provided, just throw with a helpful message.
types: ['string', 'null'], | ||
default: '"{}"', | ||
scale: { | ||
types: ['string'], |
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.
should we provide allowed options here ? ('linear', 'log', 'sqrt')
we already have this check on the chart level
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.
@w33ble ^^ whats the canvas way ?
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.
Use the options
argument for the function definition, since the auto-complete dialog will show those values. Then in the function itself, just throw with a helpful message if the value is invalid. An example of this is alterColumn
💔 Build Failed |
💔 Build Failed |
args.metric : | ||
context.columns.find(c => c.id === args.metric); | ||
if (metricAccessor === undefined) { | ||
throw new Error('invalid column name'); |
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 user sees these errors, giving them a little more information would likely help them be successful. Right now they get the same message with an invalid metric or bucket, at the very least you should tell them which argument is causing the error. Telling them why it's failing (unable to find column foo, or no column at index X) would be ideal.
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.
also these all need to be translated
So, I suspect you're not going to want all the arguments you've added, otherwise you're going to end up with a ton of code duplication, and it's going to get really hard to use when you have more than a single metric and bucket. Instead, I would recommend thinking about how you can compose functions and types to build what you need. As one example, and for lack of a better name, maybe a
Where the Using composition like that allows you to build visConfig objects in other functions as well, so when you have a more complex use case (tables come to mind), it might make sense to write a new function for that use case, but produce the same Hypothetically, you could end up with stuff like this, as examples:
It might also make sense to go even further and create functions that can produce metric and bucket objects...
Or even without the function nesting...
Imagine
I'm not sure which option is the best, I know practically nothing about visConfig objects, so you'd have to experiment a bit to figure that out. But function composition seems like a better way to do this. |
I like the idea of making this more composable, since some visTypes will certainly have a lot more args than others (e.g. tile/region maps will have a ton). But I also am not sure what the best solution is as I can see pros and cons to both approaches. For example, On the other hand, we could benefit from some sort of uniformity across visConfigs to enforce things like keeping keynames consistent between vis types. Composition can help here, as could proper (shared) typings for the visConfig object. The one item that is somewhat consistent across all vis types is dimensions/metrics/buckets, and they are also conceptually different from most other visConfig items (which are more like "options" for the vis that a user might configure in the UI, whereas the dimensions have to do with selecting the right underlying data and aren't something a user is really going to see). So perhaps @w33ble's idea of Not trying to spin the conversation too far outside the scope of this PR; I'm mostly just thinking through this out loud. 😉 Still not sure what the right answer is. |
💔 Build Failed |
lets leave this PR for now and not merge it, i will work on another function in the meanwhile. i'll take lets see how that goes, and then i'll give histogram a try: multiple metrics, multiple buckets, split charts and configuration on per-series level (one for each metric-bucket combination) ... it will be then easier to figure out the best syntax. |
6fe2bdb
to
55cf736
Compare
💔 Build Failed |
…tics/tagcloud # Conflicts: # src/legacy/ui/public/visualize/loader/embedded_visualize_handler.ts
💔 Build Failed |
format: { | ||
types: ['string'], | ||
default: 'string' | ||
}, |
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.
nit: would be good to add help
text on format
too
@ppisljar Nice, I think this approach strikes a good balance. |
fn: (context, args) => { | ||
const accessor = Number.isInteger(args.accessor) ? | ||
args.accessor : | ||
context.columns.find(c => c.id === args.accessor); |
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're making assumptions about the type of context you're working with here. You should be explicit about only accepting a datatable
type, so the interpreter can report an incorrect type, and also do automatic conversions, instead of the function just throwing.
Adding this to the function definition would be all it takes.
context: {
types: ['datatable'],
}
@@ -27,7 +27,12 @@ export const kibanaDatatable = () => ({ | |||
return { | |||
type: 'kibana_datatable', | |||
rows: context.rows, | |||
columns: context.columns, | |||
columns: context.columns.map(column => { |
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.
Why is this change part of this PR? And also, do you still need the code on line 26?
context.columns.forEach(c => c.id = c.name);
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 was broken before, kibana_datatable requires column.id
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.
Right, but the code on line 26 appears to be attempting to do the same thing. Can that be removed?
@@ -9,14 +9,13 @@ Object { | |||
"listenOnChange": true, | |||
}, | |||
"visConfig": Object { | |||
"bucket": undefined, |
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.
Is this safe? And is it safe for metric: undefined
as well? You don't check for a value of either property before putting it on the visConfig
object in tag_cloud_fn.js
, so that can end up as the output.
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.
should be safe, but i will still remove this, better if its not set at all
minFontSize: args.minFontSize, | ||
maxFontSize: args.maxFontSize, | ||
showLabel: args.showLabel, | ||
metric: args.metric, |
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.
metric
and bucket
both lack a default value, so they can both end up being undefined, as noted in the snapshot. I wanted to point that out since I don't know how safe that behavior is.
💔 Build Failed |
💔 Build Failed |
import { i18n } from '@kbn/i18n'; | ||
|
||
export const visDimension = () => ({ | ||
name: 'vis_dimension', |
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.
Quick note on the function name, we've avoided using underscores and other characters in Canvas because it makes the expression much more confusing. It's true for arguments, but it's especially true for function names.
For example, if I know I need the "vis dimension" function, I could type it as visdimension
or visDimension
, or even ViSdImEnSiOn
... it's all case-insensitive for that reason. That underscore breaks that convention, now I need to know your naming scheme.
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.
Still think you can remove line 26 in kibana_datatable.js
now, but I don't see any reason to block the PR over it. Everything else looks good enough.
I encourage you to consider renaming the vis dimension function, and to generally avoid underscores when naming functions and arguments.
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 LGTM too. Thanks @w33ble for the thoughts on naming & autocomplete... hadn't considered that. Currently we're using underscores in most of our vis function names, so perhaps it's worth updating all of them at once, as this isn't the only place underscores have been used.
Still think you can remove line 26 in kibana_datatable.js now
I agree with this, looks like that line is unnecessary and should probably be deleted.
💔 Build Failed |
💔 Build Failed |
63f6fa5
to
5815675
Compare
💚 Build Succeeded |
Summary
updating tagcloud interpreter func arguments:
for example:
tagcloud visConfig='{"metric": { "accessor": 1 }, "bucket": { "accessor": 0, "format": { "type": "ip" }}, "scale":"linear", "orientation": "angled", "minFontSize": 12, "maxFontSize": 24 }'
becomes:
tagcloud metric={vis_dimension 1} bucket={vis_dimension 0 format='ip'} scale='linear' orientation='angled' minFontSize: 12, maxFontSize: 24
this one was pretty simple, but indicates what we want to do.
Checklist
Use
strikethroughsto remove checklist items you don't feel are applicable to this PR.[ ] This was checked for cross-browser compatibility, including a check against IE11[ ] This was checked for keyboard-only and screenreader accessibilityFor maintainers
[ ] This was checked for breaking API changes and was labeled appropriately[ ] This includes a feature addition or change that requires a release note and was labeled appropriately