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

feat: add extent transform #8940

Merged
merged 19 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions build/vega-lite-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -8744,6 +8744,24 @@
],
"type": "object"
},
"ExtentTransform": {
"additionalProperties": false,
"properties": {
"extent": {
"$ref": "#/definitions/FieldName",
"description": "The field of which to get the extent."
},
"param": {
"$ref": "#/definitions/ParameterName",
"description": "The output parameter produced by the extent transform."
}
},
"required": [
"extent",
"param"
],
"type": "object"
},
"FacetEncodingFieldDef": {
"additionalProperties": false,
"properties": {
Expand Down Expand Up @@ -30190,6 +30208,9 @@
{
"$ref": "#/definitions/DensityTransform"
},
{
"$ref": "#/definitions/ExtentTransform"
},
{
"$ref": "#/definitions/FilterTransform"
},
Expand Down
Binary file added examples/compiled/bar_simple_extent.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/compiled/bar_simple_extent.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
151 changes: 151 additions & 0 deletions examples/compiled/bar_simple_extent.vg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"background": "white",
"padding": 5,
"width": 200,
"title": {
"text": "A Simple Bar Chart with Lines at Extents",
"frame": "group"
},
"style": "cell",
"data": [
{
"name": "source_0",
"values": [
{"a": "A", "b": 28},
{"a": "B", "b": 55},
{"a": "C", "b": 43},
{"a": "D", "b": 91},
{"a": "E", "b": 81},
{"a": "F", "b": 53},
{"a": "G", "b": 19},
{"a": "H", "b": 87},
{"a": "I", "b": 52}
]
},
{
"name": "data_0",
"source": "source_0",
"transform": [{"type": "extent", "field": "b", "signal": "b_extent"}]
},
{
"name": "data_1",
"source": "data_0",
"transform": [
{
"type": "stack",
"groupby": ["a"],
"field": "b",
"sort": {"field": [], "order": []},
"as": ["b_start", "b_end"],
"offset": "zero"
},
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
}
]
}
],
"signals": [
{"name": "y_step", "value": 20},
{
"name": "height",
"update": "bandspace(domain('y').length, 0.1, 0.05) * y_step"
}
],
"marks": [
{
"name": "layer_0_marks",
"type": "rect",
"style": ["bar"],
"from": {"data": "data_1"},
"encode": {
"update": {
"fill": {"value": "#4c78a8"},
"ariaRoleDescription": {"value": "bar"},
"description": {
"signal": "\"b: \" + (format(datum[\"b\"], \"\")) + \"; a: \" + (isValid(datum[\"a\"]) ? datum[\"a\"] : \"\"+datum[\"a\"])"
},
"x": {"scale": "x", "field": "b_end"},
"x2": {"scale": "x", "field": "b_start"},
"y": {"scale": "y", "field": "a"},
"height": {"signal": "max(0.25, bandwidth('y'))"}
}
}
},
{
"name": "layer_1_marks",
"type": "rule",
"style": ["rule"],
"from": {"data": "data_0"},
"encode": {
"update": {
"stroke": {"value": "firebrick"},
"x": {"signal": "scale('x', b_extent[0])"},
"y": {"value": 0},
"y2": {"field": {"group": "height"}}
}
}
},
{
"name": "layer_2_marks",
"type": "rule",
"style": ["rule"],
"from": {"data": "data_0"},
"encode": {
"update": {
"stroke": {"value": "#ca8861"},
"x": {"signal": "scale('x', b_extent[1])"},
"y": {"value": 0},
"y2": {"field": {"group": "height"}}
}
}
}
],
"scales": [
{
"name": "x",
"type": "linear",
"domain": {"data": "data_1", "fields": ["b_start", "b_end"]},
"range": [0, {"signal": "width"}],
"nice": true,
"zero": true
},
{
"name": "y",
"type": "band",
"domain": {"data": "data_1", "field": "a", "sort": true},
"range": {"step": {"signal": "y_step"}},
"paddingInner": 0.1,
"paddingOuter": 0.05
}
],
"axes": [
{
"scale": "x",
"orient": "bottom",
"gridScale": "y",
"grid": true,
"tickCount": {"signal": "ceil(width/40)"},
"domain": false,
"labels": false,
"aria": false,
"maxExtent": 0,
"minExtent": 0,
"ticks": false,
"zindex": 0
},
{
"scale": "x",
"orient": "bottom",
"grid": false,
"title": "b",
"labelFlush": true,
"labelOverlap": true,
"tickCount": {"signal": "ceil(width/40)"},
"zindex": 0
},
{"scale": "y", "orient": "left", "grid": false, "title": "a", "zindex": 0}
]
}
33 changes: 33 additions & 0 deletions examples/specs/bar_simple_extent.vl.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"title": "A Simple Bar Chart with Lines at Extents",
"data": {
"values": [
{"a": "A", "b": 28}, {"a": "B", "b": 55}, {"a": "C", "b": 43},
{"a": "D", "b": 91}, {"a": "E", "b": 81}, {"a": "F", "b": 53},
{"a": "G", "b": 19}, {"a": "H", "b": 87}, {"a": "I", "b": 52}
]
},
"transform": [{"extent": "b", "param": "b_extent" }],
"layer": [
{
"mark": "bar",
"encoding": {
"y": {"field": "a", "type": "nominal"},
"x": {"field": "b", "type": "quantitative"}
}
},
{
"mark": {"type": "rule", "stroke": "firebrick"},
"encoding": {
"x": {"value": {"expr": "scale('x', b_extent[0])"}}
lsh marked this conversation as resolved.
Show resolved Hide resolved
}
},
{
"mark": {"type": "rule", "stroke": "#ca8861"},
"encoding": {
"x": {"value": {"expr": "scale('x', b_extent[1])"}}
}
}
]
}
4 changes: 4 additions & 0 deletions site/_includes/docs_toc.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
- [Density]({{site.baseurl}}/docs/density.html)
- [Density Transform Definition]({{site.baseurl}}/docs/density.html#density-transform-definition)
- [Usage]({{site.baseurl}}/docs/density.html#usage)
- [Extent]({{site.baseurl}}/docs/extent.html)
- [Extent Transform Definition]({{site.baseurl}}/docs/extent.html#extent-transform-definition)
- [Usage]({{site.baseurl}}/docs/extent.html#usage)
- [Example]({{site.baseurl}}/docs/extent.html#example)
- [Filter]({{site.baseurl}}/docs/filter.html)
- [Flatten]({{site.baseurl}}/docs/flatten.html)
- [Flatten Transform Definition]({{site.baseurl}}/docs/flatten.html#flatten-transform-definition)
Expand Down
2 changes: 2 additions & 0 deletions site/_layouts/docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
url: calculate
- text: Density
url: density
- text: Extent
url: extent
- text: Filter
url: filter
- text: Flatten
Expand Down
59 changes: 59 additions & 0 deletions site/docs/transform/extent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
layout: docs
menu: docs
title: Extent
permalink: /docs/extent.html
---

The extent transform finds the extent of a field and stores the result in a [parameter]({{site.baseurl}}/docs/parameter.html).

```js
// Any View Specification
{
...
"transform": [
{"extent": ..., "param": ...} // Extent Transform
...
],
...
}
```

## Extent Transform Definition

{% include table.html props="extent,param" source="ExtentTransform" %}

## Usage

Given the following data:

```json
"data": {
"values": [
{"a": "A", "b": 28}, {"a": "B", "b": 55}, {"a": "C", "b": 43},
{"a": "D", "b": 91}, {"a": "E", "b": 81}, {"a": "F", "b": 53},
{"a": "G", "b": 19}, {"a": "H", "b": 87}, {"a": "I", "b": 52}
]
}
```

And the transform:

```json
"transform": [
{"extent": "b", "param": "b_extent"}
]
```

this example produces the output `param` will look like:
lsh marked this conversation as resolved.
Show resolved Hide resolved

```json
{
"name": "b_extent",
"value": [19, 91]
}
```

## Example

<div class="vl-example" data-name="bar_simple_extent"></div>
1 change: 1 addition & 0 deletions site/docs/transform/transform.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ The View-level `transform` object is an array of objects describing transformati
- [Bin](bin.html#transform)
- [Calculate](calculate.html)
- [Density](density.html)
- [Extent](extent.html)
- [Filter](filter.html)
- [Flatten](flatten.html)
- [Fold](fold.html)
Expand Down
4 changes: 3 additions & 1 deletion src/compile/data/assemble.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {BinNode} from './bin';
import {CalculateNode} from './calculate';
import {DataFlowNode, OutputNode} from './dataflow';
import {DensityTransformNode} from './density';
import {ExtentTransformNode} from './extent';
import {FacetNode} from './facet';
import {FilterNode} from './filter';
import {FilterInvalidNode} from './filterinvalid';
Expand Down Expand Up @@ -106,7 +107,8 @@ function makeWalkTree(data: VgData[]) {
node instanceof RegressionTransformNode ||
node instanceof IdentifierNode ||
node instanceof SampleTransformNode ||
node instanceof PivotTransformNode
node instanceof PivotTransformNode ||
node instanceof ExtentTransformNode
) {
dataSource.transform.push(node.assemble());
}
Expand Down
40 changes: 40 additions & 0 deletions src/compile/data/extent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {ExtentTransform as VgExtentTransform} from 'vega';
import {ExtentTransform} from '../../transform';
import {duplicate, hash} from '../../util';
import {DataFlowNode} from './dataflow';

/**
* A class for flatten transform nodes
lsh marked this conversation as resolved.
Show resolved Hide resolved
*/
export class ExtentTransformNode extends DataFlowNode {
public clone() {
return new ExtentTransformNode(null, duplicate(this.transform));
}

constructor(parent: DataFlowNode, private transform: ExtentTransform) {
super(parent);
this.transform = duplicate(transform);
}

public dependentFields() {
return new Set([this.transform.extent]);
}

public producedFields() {
return new Set([this.transform.param]);
lsh marked this conversation as resolved.
Show resolved Hide resolved
}

public hash() {
return `ExtentTransform ${hash(this.transform)}`;
}

public assemble(): VgExtentTransform {
const {extent, param} = this.transform;
const result: VgExtentTransform = {
type: 'extent',
field: extent,
signal: param
};
return result;
}
}
Loading