Skip to content

Commit

Permalink
Make 'sort' parameter appear in a higher level, as part of the encoding.
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-cheliu committed Oct 23, 2023
1 parent af04935 commit c4a954d
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 22 deletions.
19 changes: 12 additions & 7 deletions build/vega-lite-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -5064,6 +5064,10 @@
],
"description": "The tooltip text to show upon mouse hover. Specifying `tooltip` encoding overrides [the `tooltip` property in the mark definition](https://vega.github.io/vega-lite/docs/mark.html#mark-def).\n\nSee the [`tooltip`](https://vega.github.io/vega-lite/docs/tooltip.html) documentation for a detailed discussion about tooltip in Vega-Lite."
},
"sort_tooltip": {
"$ref": "#/definitions/TooltipSort",
"description": "Parameter to control whether and how the tooltip is sorted. It's users' responsibilities to make sure to put non-sortable fields or the fields they do not want to sort at the beginning or the end of the tooltip array, otherwise the order will be messed up."
},
"url": {
"anyOf": [
{
Expand Down Expand Up @@ -27227,6 +27231,14 @@
]
}
},
"TooltipSort": {
"value": {
"enum": [
"ascending",
"descending"
]
}
},
"TooltipFieldDef": {
"additionalProperties": false,
"properties": {
Expand Down Expand Up @@ -27306,13 +27318,6 @@
"filter": {
"$ref": "#/definitions/TooltipFilter",
"description": "The tooltip filter object to control what values to show/hide in the tooltip."
},
"sorted": {
"enum": [
"ascending",
"descending"
],
"description": "Parameter to control whether and how the tooltip is sorted. The first defined 'sorted' parameter that appears in the tooltip array controls the sorting order, and any defined parameters after that will simply be ignored. "
}
},
"type": "object"
Expand Down
8 changes: 7 additions & 1 deletion src/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ export const DETAIL = 'detail' as const;
export const KEY = 'key' as const;

export const TOOLTIP = 'tooltip' as const;

export const SORT_TOOLTIP = 'sort_tooltip' as const;
export const HREF = 'href' as const;

export const URL = 'url' as const;
Expand Down Expand Up @@ -154,7 +156,8 @@ const UNIT_CHANNEL_INDEX: Flag<Channel> = {
tooltip: 1,
href: 1,
url: 1,
description: 1
description: 1,
sort_tooltip: 1
};

export type ColorChannel = 'color' | 'fill' | 'stroke';
Expand Down Expand Up @@ -431,6 +434,7 @@ const {
// href has neither format, nor scale
text: _t,
tooltip: _tt,
sort_tooltip: _stt,
href: _hr,
url: _u,
description: _al,
Expand Down Expand Up @@ -532,6 +536,7 @@ function getSupportedMark(channel: ExtendedChannel): SupportedMark {
case DETAIL:
case KEY:
case TOOLTIP:
case SORT_TOOLTIP:
case HREF:
case ORDER: // TODO: revise (order might not support rect, which is not stackable?)
case OPACITY:
Expand Down Expand Up @@ -641,6 +646,7 @@ export function rangeType(channel: ExtendedChannel): RangeType {
// TEXT, TOOLTIP, URL, and HREF have no scale but have discrete output [falls through]
case TEXT:
case TOOLTIP:
case SORT_TOOLTIP:
case HREF:
case URL:
case DESCRIPTION:
Expand Down
9 changes: 7 additions & 2 deletions src/channeldef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
ROW,
SHAPE,
SIZE,
SORT_TOOLTIP,
STROKE,
STROKEDASH,
STROKEOPACITY,
Expand Down Expand Up @@ -651,11 +652,14 @@ export interface TooltipFilter {

export interface TooltipFieldDef<F extends Field> extends StringFieldDef<F> {
filter?: TooltipFilter
sorted?: "ascending" | "descending"
};

export interface TooltipSort {
value: "ascending" | "descending"
}

export function isTooltipFieldDef<F extends Field>(fieldDef: FieldDef<F>): fieldDef is TooltipFieldDef<F> {
return "filter" in fieldDef || "sorted" in fieldDef;
return "filter" in fieldDef;
}


Expand Down Expand Up @@ -1280,6 +1284,7 @@ export function channelCompatibility(
case DETAIL:
case KEY:
case TOOLTIP:
case SORT_TOOLTIP:
case HREF:
case URL:
case ANGLE:
Expand Down
22 changes: 10 additions & 12 deletions src/compile/mark/encode/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
isTypedFieldDef,
SecondaryFieldDef,
TooltipFilter,
TooltipSort,
TypedFieldDef,
vgField
} from '../../../channeldef';
Expand All @@ -29,7 +30,8 @@ export function tooltip(model: UnitModel, opt: {reactiveGeom?: boolean} = {}) {
const {encoding, markDef, config, stack} = model;
const channelDef = encoding.tooltip;
if (isArray(channelDef)) {
return {tooltip: tooltipRefForEncoding({tooltip: channelDef}, stack, config, opt)};
const sort_tooltip: TooltipSort | undefined = "sort_tooltip" in encoding ? encoding.sort_tooltip : undefined;
return {tooltip: tooltipRefForEncoding({tooltip: channelDef, sort_tooltip: sort_tooltip}, stack, config, opt)};
} else {
const datum = opt.reactiveGeom ? 'datum.datum' : 'datum';
return wrapCondition(model, channelDef, 'tooltip', cDef => {
Expand Down Expand Up @@ -74,10 +76,13 @@ export function tooltipData(
config: Config,
{reactiveGeom}: {reactiveGeom?: boolean} = {}
) {

const toSkip = {};
const expr = reactiveGeom ? 'datum.datum' : 'datum';
const tuples: {channel: Channel; key: string; value: string}[] = [];
var sort_tooltip: boolean = false;
if (encoding.sort_tooltip != undefined && (encoding.sort_tooltip.value == "ascending" || encoding.sort_tooltip.value == "descending")) {
tuples.push({channel: "sort_tooltip", key: "tooltip_sort_placeholder", value: (encoding.sort_tooltip.value == "ascending" ? "0" : "1")}); // Encode ascending as "0", descending as "1"
}

function add(fDef: TypedFieldDef<string> | SecondaryFieldDef<string>, channel: Channel) {
const mainChannel = getMainRangeChannel(channel);
Expand Down Expand Up @@ -128,16 +133,9 @@ export function tooltipData(

// New feature: add filter for each tooltip field.
if (isTooltipFieldDef(fieldDef)) {
if ("filter" in fieldDef) {
const filter: TooltipFilter = fieldDef.filter;
const comp_value = filter.literal;
value = `${value} ${filter.operator} ${comp_value} ? ${value} : ${expr + '[""]'}`; // Trigeer 'undefined' when evaluating the tooltip value such that it is filtered out by vega-tooltip.
}

if ("sorted" in fieldDef && !sort_tooltip) {
tuples.push({channel, key: "tooltip_sort_placeholder", value: (fieldDef.sorted == "ascending" ? "0" : "1")}); // Encode ascending as "0", descending as "1"
sort_tooltip = true;
}
const filter: TooltipFilter = fieldDef.filter;
const comp_value = filter.literal;
value = `${value} ${filter.operator} ${comp_value} ? ${value} : ${expr + '[""]'}`; // Trigeer 'undefined' when evaluating the tooltip value such that it is filtered out by vega-tooltip.
}

tuples.push({channel, key, value});
Expand Down
6 changes: 6 additions & 0 deletions src/encoding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
RADIUS2,
SHAPE,
SIZE,
SORT_TOOLTIP,
STROKE,
STROKEDASH,
STROKEOPACITY,
Expand Down Expand Up @@ -83,6 +84,7 @@ import {
TextDef,
title,
TooltipFieldDef,
TooltipSort,
TypedFieldDef,
vgField
} from './channeldef';
Expand Down Expand Up @@ -323,6 +325,8 @@ export interface Encoding<F extends Field> {
* __Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping.
*/
order?: OrderFieldDef<F> | OrderFieldDef<F>[] | OrderValueDef;

sort_tooltip?: TooltipSort;
}

export interface EncodingWithFacet<F extends Field> extends Encoding<F>, EncodingFacetMapping<F> { }
Expand Down Expand Up @@ -738,6 +742,8 @@ export function pathGroupingFields(mark: Mark, encoding: Encoding<string>): stri
// tooltip fields should not be added to group by [falls through]
case TOOLTIP:
return details;
case SORT_TOOLTIP:
return details;

case ORDER:
// order should not group line / trail
Expand Down

0 comments on commit c4a954d

Please sign in to comment.