-
Notifications
You must be signed in to change notification settings - Fork 622
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
Support href and cursor properties for marks #3229
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,11 +125,16 @@ The rest of this section describe groups of properties supported by the `mark` c | |
|
||
{% include table.html props="opacity,fillOpacity,strokeOpacity" source="MarkConfig" %} | ||
|
||
|
||
### Stroke Style | ||
|
||
{% include table.html props="strokeWidth,strokeDash,strokeDashOffset" source="MarkConfig" %} | ||
|
||
### Link Properties | ||
|
||
Marks can act as hyperlinks when the `href` property is defined. A `cursor` property can also be provided to serve as affordance for the links. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(add link for "channel" part) |
||
|
||
{% include table.html props="href,cursor" source="MarkConfig" %} | ||
|
||
<!-- one example for custom fill/stroke --> | ||
|
||
{:#interpolate} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ export namespace Channel { | |
export const ORDER: 'order' = 'order'; | ||
export const DETAIL: 'detail' = 'detail'; | ||
export const TOOLTIP: 'tooltip' = 'tooltip'; | ||
export const HREF: 'href' = 'href'; | ||
} | ||
|
||
export type Channel = keyof Encoding<any> | keyof FacetMapping<any>; | ||
|
@@ -50,6 +51,7 @@ export const DETAIL = Channel.DETAIL; | |
export const ORDER = Channel.ORDER; | ||
export const OPACITY = Channel.OPACITY; | ||
export const TOOLTIP = Channel.TOOLTIP; | ||
export const HREF = Channel.HREF; | ||
|
||
const UNIT_CHANNEL_INDEX: Flag<keyof Encoding<any>> = { | ||
x: 1, | ||
|
@@ -63,7 +65,8 @@ const UNIT_CHANNEL_INDEX: Flag<keyof Encoding<any>> = { | |
opacity: 1, | ||
text: 1, | ||
detail: 1, | ||
tooltip: 1 | ||
tooltip: 1, | ||
href: 1, | ||
}; | ||
|
||
const FACET_CHANNEL_INDEX: Flag<keyof FacetMapping<any>> = { | ||
|
@@ -93,7 +96,7 @@ export const SINGLE_DEF_CHANNELS: SingleDefChannel[] = flagKeys(SINGLE_DEF_CHANN | |
// Using the following line leads to TypeError: Cannot read property 'elementTypes' of undefined | ||
// when running the schema generator | ||
// export type SingleDefChannel = typeof SINGLE_DEF_CHANNELS[0]; | ||
export type SingleDefChannel = 'x' | 'y' | 'x2' | 'y2' | 'row' | 'column' | 'size' | 'shape' | 'color' | 'opacity' | 'text' | 'tooltip'; | ||
export type SingleDefChannel = 'x' | 'y' | 'x2' | 'y2' | 'row' | 'column' | 'size' | 'shape' | 'color' | 'opacity' | 'text' | 'tooltip' | 'href'; | ||
|
||
|
||
|
||
|
@@ -124,9 +127,9 @@ export type PositionScaleChannel = typeof POSITION_SCALE_CHANNELS[0]; | |
|
||
// NON_POSITION_SCALE_CHANNEL = SCALE_CHANNELS without X, Y | ||
const { | ||
// x2 and y2 share the same scale as x and y | ||
// text and tooltip has format instead of scale | ||
text: _t, tooltip: _tt, | ||
// x2 and y2 share the same scale as x and y | ||
// text, tooltip, and href have format instead of scale | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. href does not have format |
||
text: _t, tooltip: _tt, href: _hr, | ||
// detail and order have no scale | ||
detail: _dd, order: _oo, | ||
...NONPOSITION_SCALE_CHANNEL_INDEX | ||
|
@@ -159,7 +162,6 @@ export interface SupportedMark { | |
line?: boolean; | ||
area?: boolean; | ||
text?: boolean; | ||
tooltip?: boolean; | ||
} | ||
|
||
/** | ||
|
@@ -184,6 +186,7 @@ export function getSupportedMark(channel: Channel): SupportedMark { | |
case COLOR: | ||
case DETAIL: | ||
case TOOLTIP: | ||
case HREF: | ||
case ORDER: // TODO: revise (order might not support rect, which is not stackable?) | ||
case OPACITY: | ||
case ROW: | ||
|
@@ -223,9 +226,10 @@ export function rangeType(channel: Channel): RangeType { | |
case ROW: | ||
case COLUMN: | ||
case SHAPE: | ||
// TEXT and TOOLTIP have no scale but have discrete output | ||
// TEXT, TOOLTIP, and HREF have no scale but have discrete output | ||
case TEXT: | ||
case TOOLTIP: | ||
case HREF: | ||
return 'discrete'; | ||
|
||
// Color can be either continuous or discrete, depending on scale type. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -193,7 +193,7 @@ export interface VgSignal { | |
push?: string; | ||
} | ||
|
||
export type VgEncodeChannel = 'x'|'x2'|'xc'|'width'|'y'|'y2'|'yc'|'height'|'opacity'|'fill'|'fillOpacity'|'stroke'|'strokeWidth'|'strokeOpacity'|'strokeDash'|'strokeDashOffset'|'cursor'|'clip'|'size'|'shape'|'path'|'innerRadius'|'outerRadius'|'startAngle'|'endAngle'|'interpolate'|'tension'|'orient'|'url'|'align'|'baseline'|'text'|'dir'|'ellipsis'|'limit'|'dx'|'dy'|'radius'|'theta'|'angle'|'font'|'fontSize'|'fontWeight'|'fontStyle'; | ||
export type VgEncodeChannel = 'x'|'x2'|'xc'|'width'|'y'|'y2'|'yc'|'height'|'opacity'|'fill'|'fillOpacity'|'stroke'|'strokeWidth'|'strokeOpacity'|'strokeDash'|'strokeDashOffset'|'cursor'|'clip'|'size'|'shape'|'path'|'innerRadius'|'outerRadius'|'startAngle'|'endAngle'|'interpolate'|'tension'|'orient'|'url'|'align'|'baseline'|'text'|'dir'|'ellipsis'|'limit'|'dx'|'dy'|'radius'|'theta'|'angle'|'font'|'fontSize'|'fontWeight'|'fontStyle'|'href'|'cursor'; | ||
export type VgEncodeEntry = { | ||
[k in VgEncodeChannel]?: VgValueRef | (VgValueRef & {test?: string})[]; | ||
}; | ||
|
@@ -1056,6 +1056,18 @@ export interface VgMarkConfig { | |
* Placeholder text if the `text` channel is not specified | ||
*/ | ||
text?: string; | ||
|
||
/** | ||
* A URL to load upon mouse click. If defined, the mark acts as a hyperlink. | ||
* | ||
* @format uri | ||
*/ | ||
href?: string; | ||
|
||
/** | ||
* The mouse cursor used over the mark. Any valid [CSS cursor type](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#Values) can be used. | ||
*/ | ||
cursor?: 'auto' | 'default' | 'none' | 'context-menu' | 'help' | 'pointer' | 'progress' | 'wait' | 'cell' | 'crosshair' | 'text' | 'vertical-text' | 'alias' | 'copy' | 'move' | 'no-drop' | 'not-allowed' | 'e-resize' | 'n-resize' | 'ne-resize' | 'nw-resize' | 's-resize' | 'se-resize' | 'sw-resize' | 'w-resize' | 'ew-resize' | 'ns-resize' | 'nesw-resize' | 'nwse-resize' | 'col-resize' | 'row-resize' | 'all-scroll' | 'zoom-in' | 'zoom-out' | 'grab' | 'grabbing'; | ||
} | ||
|
||
const VG_MARK_CONFIG_INDEX: Flag<keyof VgMarkConfig> = { | ||
|
@@ -1084,17 +1096,18 @@ const VG_MARK_CONFIG_INDEX: Flag<keyof VgMarkConfig> = { | |
font: 1, | ||
fontSize: 1, | ||
fontWeight: 1, | ||
fontStyle: 1 | ||
fontStyle: 1, | ||
cursor: 1, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure why previously list Btw, does it really make sense to have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Working on it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
works |
||
href: 1, | ||
// commented below are vg channel that do not have mark config. | ||
// 'x'|'x2'|'xc'|'width'|'y'|'y2'|'yc'|'height' | ||
// cursor: 1, | ||
// clip: 1, | ||
// dir: 1, | ||
// ellipsis: 1, | ||
// endAngle: 1, | ||
// path: 1, | ||
// innerRadius: 1, | ||
// outerRadius: 1, | ||
// path: 1, | ||
// startAngle: 1, | ||
// url: 1, | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -120,6 +120,21 @@ describe('Mark', function() { | |
assert.equal(markGroup[0].encode.update.tooltip.value, 'foo'); | ||
}); | ||
}); | ||
|
||
describe('Bar with href', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So far, I have created test for these types of basic test in point. Also, going forward, let's try to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay. I'm moving the tooltip and href tests. |
||
it('should pass href value to encoding', () => { | ||
const model = parseUnitModelWithScaleAndLayoutSize({ | ||
"mark": "bar", | ||
"encoding": { | ||
"x": {"type": "quantitative", "field": "Cost__Other", "aggregate": "sum"}, | ||
"y": {"bin": true, "type": "quantitative", "field": "Cost__Total_$"}, | ||
"href": {"value": "https://idl.cs.washington.edu/"} | ||
} | ||
}); | ||
const markGroup = parseMarkGroup(model); | ||
assert.equal(markGroup[0].encode.update.href.value, 'https://idl.cs.washington.edu/'); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('getPathSort', () => { | ||
|
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.
add a link for "The
cursor
mark property"?