# Where is canvas expression documentation?

**URL:** <https://discuss.elastic.co/t/where-is-canvas-expression-documentation/172753>\
**Category:** Kibana\
**Tags:** canvas\
**Created:** [March 18, 2019, 11:20am UTC](https://discuss.elastic.co/t/where-is-canvas-expression-documentation/172753 "2019-03-18T11:20:36Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![jpazsedano](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jpazsedano/32/39689_2.png) [@jpazsedano](https://discuss.elastic.co/u/jpazsedano)\
**Post date:** [March 18, 2019, 11:20am UTC](https://discuss.elastic.co/t/where-is-canvas-expression-documentation/172753/1 "2019-03-18T11:20:36Z")

</div>

Hi

Well, my situation is simple. I've run into some trouble using Canvas expressions and in the docs all I've found is this: [https://www.elastic.co/guide/en/kibana/master/canvas-function-reference.html](https://www.elastic.co/guide/en/kibana/master/canvas-function-reference.html)

It's just a very brief function reference that doesn't even explain basic concepts like what exactly is a context or how it's passed around (and doesn't even have all the functions documented). Some of the functions are explained in a way that presumes you already have some knowledge about it and they have no examples. Like the `any` function. It doesn't say anywhere how to actually pass several values to it, if I do:

`any condition={getCell "Test" getCell "Test2"}`

Only the value of "Test2" is evaluated. "Test" is completely ignored.

But there are people out there who have a good knowlegde about how expressions work, so I guess there is documentation _somewhere_, just I'm not able to find it.

So my question is: Is there any docs about it? Or will I have to study the interpreter's code?

---

<div class="post-metadata">

**Author:** ![azasypkin](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/azasypkin/32/42216_2.png) [@azasypkin](https://discuss.elastic.co/u/azasypkin)\
**Post date:** [March 18, 2019, 11:45am UTC](https://discuss.elastic.co/t/where-is-canvas-expression-documentation/172753/2 "2019-03-18T11:45:22Z")

</div>

Hi @jpazsedano,

I don't think we have any Canvas specific documentation other than you've already found. I know the team is working hard on improving documentation since Canvas API/feature surface is quite big, you can track progress [here](https://github.com/elastic/kibana/issues/23109).

In the meantime, @Joe_Fleming can you please help to answer questions above?

Best,  
Oleg

---

<div class="post-metadata">

**Author:** ![jpazsedano](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jpazsedano/32/39689_2.png) [@jpazsedano](https://discuss.elastic.co/u/jpazsedano)\
**Post date:** [March 18, 2019, 11:49am UTC](https://discuss.elastic.co/t/where-is-canvas-expression-documentation/172753/3 "2019-03-18T11:49:30Z")

</div>

Thanks! I didn't know that the feature was in such an early stage, that explains a lot. I will take a deeper look at the github to see if I can find the info I'm looking for. Maybe I can even contribute to the docs.

---

<div class="post-metadata">

**Author:** ![Joe\_Fleming](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/joe_fleming/32/3561_2.png) [@Joe\_Fleming](https://discuss.elastic.co/u/Joe_Fleming)\
**Post date:** [March 19, 2019, 8:44pm UTC](https://discuss.elastic.co/t/where-is-canvas-expression-documentation/172753/4 "2019-03-19T20:44:48Z")

</div>

> It's just a very brief function reference that doesn't even explain basic concepts like what exactly is a context or how it's passed around (and doesn't even have all the functions documented). Some of the functions are explained in a way that presumes you already have some knowledge about it and they have no examples.

Examples are something we're working on providing more of for sure. It's been an ask for a very long time, we're just a bit behind on the documentation part, sadly. I can try to explain it here though.

First, let's talk about context. Every function in the expression is stateless, it gets two pieces of input and produces an output. The first type of input is arguments, which you seem to understand already, and "context", which is just a fancy way to refer to the output of the previous function. For example, given this expression:

```auto
demodata
| table

```

The context that is provided to `demodata` is null, since there is no input proceeding that function. It produces a bunch of data, in a "datatable" format (basic two-dimensional data, rows and columns, like in a speadsheet) and then is piped to the `table` function. The datatable produced from the `demodata` function is now the "context" for the `table` function, which just renders that data as a table vis.

Next, let's talk sub-expressions, which are expressions wrapped in `{` and `}` and are generally used to provide dynamic values for function arguments based on data you already have. You can also nest sub-expressions inside of other sub-expressions, which allows you to compose functions to produce values. Sub-expressions are executed before the top-level function, from the most nested to the least, and they are passed the same context value. So, taking your example expression, and pre-pending demodata just as an example...

```auto
demodata
| any condition={getCell "Test"}

```

First `demodata` is run and returns a bunch of data. Then, that data is provided as the context to the `getCell` function (sub-expressions run first, remember), which is executed, and the "resolved value" becomes the value of the `condition` argument for the `any` function. Then the `any` function is _also_ given the output of `demodata` as its context, and then run to produce some new output. If there was another function being piped to, the output of `any` would become the context for that function.

...I need to break up this response because apparently there's a 7000 word limit here ☹.

---

<div class="post-metadata">

**Author:** ![Joe\_Fleming](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/joe_fleming/32/3561_2.png) [@Joe\_Fleming](https://discuss.elastic.co/u/Joe_Fleming)\
**Post date:** [March 19, 2019, 8:45pm UTC](https://discuss.elastic.co/t/where-is-canvas-expression-documentation/172753/5 "2019-03-19T20:45:08Z")

</div>

> Like the `any` function. It doesn't say anywhere how to actually pass several values to it, if I do:
> 
> `any condition={getCell "Test" getCell "Test2"}`
> 
> Only the value of "Test2" is evaluated. "Test" is completely ignored.

That's correct, because that argument for the `getCell` function is not a "multi arg", you can only provide the argument one time. That's something the docs are entirely missing, unfortunately; whether or not an argument is a multi arg. The way it deals with argument values when they are specified multiple times but are not multi args is that last value wins ("Test2" in your case).

Since the docs are a little incomplete, the best way to look up how a function is used is to look at the code for it, since the arguments are defined pretty clearly: [https://github.com/elastic/kibana/blob/56cafd3a859c1a45c1d00b0ff9980b774df678d3/x-pack/plugins/canvas/canvas\_plugin\_src/functions/common/getCell.js](https://github.com/elastic/kibana/blob/56cafd3a859c1a45c1d00b0ff9980b774df678d3/x-pack/plugins/canvas/canvas_plugin_src/functions/common/getCell.js). The unnamed arg (denoted with the `_` alias) is not defined as "multi: true", so it's just a single value (the default).

For comparison, take a look at the `any` function, defined here: [https://github.com/elastic/kibana/blob/56cafd3a859c1a45c1d00b0ff9980b774df678d3/x-pack/plugins/canvas/canvas\_plugin\_src/functions/common/any.js](https://github.com/elastic/kibana/blob/56cafd3a859c1a45c1d00b0ff9980b774df678d3/x-pack/plugins/canvas/canvas_plugin_src/functions/common/any.js). The `condition` argument (also unnamed, note the `_` alias) _is_ a multi arg (`multi: true`), so it can be provided multiple times. And as the help text explains, it will "[r]eturn true if any of the conditions are true."

> It doesn't say anywhere how to actually pass several values to it

Yes, but knowing what you know now, you can hopefully make sense of how this works; you use `getCell` multiple times in the `any` function, instead of trying to select multiple column values via a single `getCell` call. Let's review why:

- Context is simply the value produced from the previous function
- Sub-expressions are run first to produce a value
- Every sub-expression gets the same context as the function it's used in
- The `condition` argument of the `any` function is a multi arg
- The `any` function produces a boolean value, which is true if any of the `condition` values is true

So let's tweak your example a little to add a comparison to the value we're reading from the cells:

```auto
| any {getCell "Test" | eq 10} {getCell "Test2" | gt 20}

```

Note that I left off the `condition=` part, since the argument has an unnamed alias (again, the `_` in the docs). I'm just using `eq` and `gt` to compare values and produce some boolean value, since the value of the `condition` argument needs to be a boolean or null (noted by `types: ['boolean', 'null'],` in the argument's definition).

If you think about this in steps that the interpreter performs, sub-expressions are run first and resolve to some value, which becomes the value of the argument. So we get two boolean values, after they are resolved. Let's say it produces something like this:

```auto
| any true false

```

`true` and `false` here are made up resolved values for the two sub-expressions that were originally there. Then _that_ function is executed, and since one of the values is true, `any`'s output is also true.

I suspect what you're really trying to do here is add a new column to your data though, otherwise this will simply reduce your entire data structure into a true/false value based on just the values in the first row (the default row for `getCell`). To do this _for every row_, you'd need to map over each row and perform this check, which is exactly what `mapColumn` is for. So, using a little pseudo-data source, you might do something like this:

```auto
<however you're getting your data>
| mapColumn "my new column" fn={any {getCell "Test" | eq 10} {getCell "Test2" | gt 20}}

```

Let's assume you have data like this already:

| Test | Test2 |
| --- | --- |
| 2 | 50 |
| 12 | 13 |
| 42 | 42 |

`mapColumn` will run the `fn` argument's function with each row in your data by passing the rows in one by one as context to the subexpression, take whatever output is generated, and put it into a new column ("my new column" from the expression above). This would result in this updated data:

| Test | Test2 | my new column |
| --- | --- | --- |
| 2 | 50 | true |
| 12 | 13 | false |
| 10 | 2 | true |

The first row is true because "Test2" is greater than 20, and the last row matches because "Test" is equal to 10. Hopefully you can see how I've composed a bunch of functions together to produce the output I wanted here.

But hold on, I said earlier that sub-expressions get the output of the previous function as context, but in `mapColumn` the context is each row, so how is that possible? The answer to that lies in the argument definition in the `mapColumn` function: [https://github.com/elastic/kibana/blob/56cafd3a859c1a45c1d00b0ff9980b774df678d3/x-pack/plugins/canvas/canvas\_plugin\_src/functions/common/mapColumn.js](https://github.com/elastic/kibana/blob/56cafd3a859c1a45c1d00b0ff9980b774df678d3/x-pack/plugins/canvas/canvas_plugin_src/functions/common/mapColumn.js)

See the `expression` argument there, and note that is has `resolve: false`. Normally argument values are resolved directly, and that's when they get the context value. But in this case, we tell the interpreter not to resolve it, but instead to pass the expression itself into the function, and it's up to the function to do something with the expression. This can vary for each function, but in this case, every row is split out and passed in as context to the sub-expression, and the value it produces is simply appended as a new column on each row.

So, now you know basically everything you need to know to make sense of function and argument definitions:

- Context
- Sub-expressions
- Multi args
- Resolved values (and `resolve: false`)

Types are also kind of important, but from what I've seen, users have been really successful with the expression even without that knowledge, so I usually don't bother diving into that part. It's more of an implementation detail in practice, you just need to make sure your argument value's type is one of the types that it accepts, and is usually some primitive type (number, sting, boolean...).

* * *

> But there are people out there who have a good knowledge about how expressions work, so I guess there is documentation _somewhere_ , just I'm not able to find it.
> 
> So my question is: Is there any docs about it? Or will I have to study the interpreter's code?

Ironically, there used to be better documentation, and videos that explained a bunch of the concepts (like all the stuff I just added here), back when Canvas was still just a technical preview, but all that content was taken down and the only parts that remain are the function docs. You don't really need to dig into the interpreter code, you just need to understand how context and sub-expressions work and then looking at the function definitions is usually enough to put things together. And yes, we're working on bringing all this information back to the docs.

That was a lot to take in, but I hope it was helpful. If you have a more concrete example of what you're trying to do, I can try to help you write an expression for it.

---

<div class="post-metadata">

**Author:** ![jpazsedano](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jpazsedano/32/39689_2.png) [@jpazsedano](https://discuss.elastic.co/u/jpazsedano)\
**Post date:** [March 20, 2019, 11:04am UTC](https://discuss.elastic.co/t/where-is-canvas-expression-documentation/172753/6 "2019-03-20T11:04:36Z")

</div>

Amazing! I wasn't expecting such a detailed answer. Well, I've already sorted out my problem with this, but just for the info:

I have a series of samples that I wanted to represent as a gaussian curve (well, bars, actually), and I wanted to paint the bars in different colors depending on the range of X they are (one color if they are between mean-var and mean+var and another if they are outside that range).

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [April 17, 2019, 11:04am UTC](https://discuss.elastic.co/t/where-is-canvas-expression-documentation/172753/7 "2019-04-17T11:04:51Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
