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: Allow for percentages to appear in stack: "normalize" theta tooltips #8308

Merged
merged 5 commits into from Jul 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 8 additions & 8 deletions build/vega-lite-schema.json

Large diffs are not rendered by default.

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/arc_pie_normalize_tooltip.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
80 changes: 80 additions & 0 deletions examples/compiled/arc_pie_normalize_tooltip.vg.json
@@ -0,0 +1,80 @@
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "Pie Chart with percentage_tooltip",
"background": "white",
"padding": 5,
"width": 200,
"height": 200,
"data": [
{
"name": "source_0",
"values": [
{"category": 1, "value": 4},
{"category": 2, "value": 6},
{"category": 3, "value": 10},
{"category": 4, "value": 3},
{"category": 5, "value": 7},
{"category": 6, "value": 8}
]
},
{
"name": "data_0",
"source": "source_0",
"transform": [
{
"type": "stack",
"groupby": [],
"field": "value",
"sort": {"field": ["category"], "order": ["ascending"]},
"as": ["value_start", "value_end"],
"offset": "normalize"
},
{
"type": "filter",
"expr": "isValid(datum[\"value\"]) && isFinite(+datum[\"value\"])"
}
]
}
],
"marks": [
{
"name": "marks",
"type": "arc",
"style": ["arc"],
"from": {"data": "data_0"},
"encode": {
"update": {
"tooltip": {
"signal": "{\"value\": format(datum[\"value_end\"]-datum[\"value_start\"], \".0%\"), \"category\": isValid(datum[\"category\"]) ? datum[\"category\"] : \"\"+datum[\"category\"]}"
},
"fill": {"scale": "color", "field": "category"},
"description": {
"signal": "\"value: \" + (format(datum[\"value_end\"]-datum[\"value_start\"], \".0%\")) + \"; category: \" + (isValid(datum[\"category\"]) ? datum[\"category\"] : \"\"+datum[\"category\"])"
},
"x": {"signal": "width", "mult": 0.5},
"y": {"signal": "height", "mult": 0.5},
"outerRadius": {"signal": "min(width,height)/2"},
"innerRadius": {"value": 0},
"startAngle": {"scale": "theta", "field": "value_end"},
"endAngle": {"scale": "theta", "field": "value_start"}
}
}
}
],
"scales": [
{
"name": "theta",
"type": "linear",
"domain": [0, 1],
"range": [0, 6.283185307179586],
"zero": true
},
{
"name": "color",
"type": "ordinal",
"domain": {"data": "data_0", "field": "category", "sort": true},
"range": "category"
}
],
"legends": [{"fill": "color", "symbolType": "circle", "title": "category"}]
}
19 changes: 19 additions & 0 deletions examples/specs/arc_pie_normalize_tooltip.vl.json
@@ -0,0 +1,19 @@
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "Pie Chart with percentage_tooltip",
"data": {
"values": [
{"category": 1, "value": 4},
{"category": 2, "value": 6},
{"category": 3, "value": 10},
{"category": 4, "value": 3},
{"category": 5, "value": 7},
{"category": 6, "value": 8}
]
},
"mark": {"type": "arc", "tooltip": true},
"encoding": {
"theta": {"field": "value", "type": "quantitative", "stack": "normalize"},
"color": {"field": "category", "type": "nominal"}
}
}
13 changes: 9 additions & 4 deletions site/_data/examples.json
Expand Up @@ -400,6 +400,11 @@
"title": "Pie Chart",
"description": "A pie chart encodes proportional differences among a set of numeric values as the angular extent and area of a circular slice."
},
{
"name": "arc_pie_normalize_tooltip",
"title": "Pie Chart with percentage_tooltip",
"description": "A pie chart with a tooltip that shows the percentage covered by the hovered slice."
},
{
"name": "arc_donut",
"title": "Donut Chart",
Expand Down Expand Up @@ -778,10 +783,10 @@
"png": true
},
{
"name": "interactive_geo_earthquakes",
"title": "Earthquakes Example",
"description": "Interactive globe visualization of earthquakes",
"png": true
"name": "interactive_geo_earthquakes",
"title": "Earthquakes Example",
"description": "Interactive globe visualization of earthquakes",
"png": true
}
]
},
Expand Down
12 changes: 12 additions & 0 deletions site/docs/mark/arc.md
Expand Up @@ -67,6 +67,18 @@ You can also add a text layer to add labels to a pie chart.

**Note:** For now, [you need to add `stack: true`](https://github.com/vega/vega-lite/issues/5078) to theta to force the text to apply the same polar stacking layout.

{:#tooltip}

### Pie Charts with Tooltips

To add tooltip, you can set `tooltip: true` in `mark`

<span class="vl-example" data-name="arc_pie_normalize_tooltip"></span>

By default, the tooltip will show actual value of the theta field.

Alternatively, setting `stack: "normalize"` allows for tooltips that display the percentage of the pie taken up by a each slice.

## Arc Config

```js
Expand Down
2 changes: 1 addition & 1 deletion src/channeldef.ts
Expand Up @@ -463,7 +463,7 @@ export interface PositionBaseMixins {
*
* `stack` can be one of the following values:
* - `"zero"` or `true`: stacking with baseline offset at zero value of the scale (for creating typical stacked [bar](https://vega.github.io/vega-lite/docs/stack.html#bar) and [area](https://vega.github.io/vega-lite/docs/stack.html#area) chart).
* - `"normalize"` - stacking with normalized domain (for creating [normalized stacked bar and area charts](https://vega.github.io/vega-lite/docs/stack.html#normalized). <br/>
* - `"normalize"` - stacking with normalized domain (for creating [normalized stacked bar and area charts](https://vega.github.io/vega-lite/docs/stack.html#normalized) and pie charts [with percentage tooltip](https://vega.github.io/vega-lite/docs/arc.html#tooltip)). <br/>
* -`"center"` - stacking with center baseline (for [streamgraph](https://vega.github.io/vega-lite/docs/stack.html#streamgraph)).
* - `null` or `false` - No-stacking. This will produce layered [bar](https://vega.github.io/vega-lite/docs/stack.html#layered-bar-chart) and area chart.
*
Expand Down
29 changes: 18 additions & 11 deletions src/compile/mark/encode/tooltip.ts
@@ -1,6 +1,6 @@
import {array, isArray, isObject, isString} from 'vega-util';
import {isBinned} from '../../../bin';
import {getMainRangeChannel, isXorY, Channel} from '../../../channel';
import {getMainRangeChannel, isXorY, Channel, THETA, RADIUS} from '../../../channel';
import {
defaultTitle,
getFieldDef,
Expand Down Expand Up @@ -101,19 +101,26 @@ export function tooltipData(
const {format, formatType} = getFormatMixins(fieldDef);
value = binFormatExpression(startField, endField, format, formatType, config);
toSkip[channel2] = true;
} else if (stack && stack.fieldChannel === channel && stack.offset === 'normalize') {
const {format, formatType} = getFormatMixins(fieldDef);
value = formatSignalRef({
fieldOrDatumDef: fieldDef,
format,
formatType,
expr,
config,
normalizeStack: true
}).signal;
}
}

if (
(isXorY(channel) || channel === THETA || channel === RADIUS) &&
stack &&
stack.fieldChannel === channel &&
stack.offset === 'normalize'
) {
const {format, formatType} = getFormatMixins(fieldDef);
value = formatSignalRef({
fieldOrDatumDef: fieldDef,
format,
formatType,
expr,
config,
normalizeStack: true
}).signal;
}

value ??= textRef(fieldDef, config, expr).signal;

tuples.push({channel, key, value});
Expand Down
27 changes: 26 additions & 1 deletion test/compile/mark/encode/tooltip.test.ts
Expand Up @@ -173,7 +173,7 @@ describe('compile/mark/encode/tooltip', () => {
});
});

it('returns correct tooltip signal for normalized stacked field', () => {
it('returns correct tooltip signal for normalized x|y stacked field', () => {
expect(
tooltipRefForEncoding(
{
Expand All @@ -198,6 +198,31 @@ describe('compile/mark/encode/tooltip', () => {
});
});

it('returns correct tooltip signal for normalized theta stacked field', () => {
expect(
tooltipRefForEncoding(
{
theta: {
aggregate: 'sum',
field: 'IMDB_Rating',
type: 'quantitative'
}
},
{
fieldChannel: 'theta',
groupbyChannels: [],
groupbyFields: new Set(),
offset: 'normalize',
impute: false,
stackBy: []
},
defaultConfig
)
).toEqual({
signal: `{"Sum of IMDB_Rating": format(datum["sum_IMDB_Rating_end"]-datum["sum_IMDB_Rating_start"], ".0%")}`
});
});

it('returns correct tooltip signal for formatted normalized stacked field', () => {
expect(
tooltipRefForEncoding(
Expand Down