-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Filling support for quak; add quak/mosaic to examples (#155)
- Loading branch information
Showing
6 changed files
with
152 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
meta: | ||
title: Cross-Filter Flights (200k) | ||
description: > | ||
Histograms showing arrival delay, departure time, and distance flown for over 200,000 flights. | ||
Select a histogram region to cross-filter the charts. | ||
Each plot uses an `intervalX` interactor to populate a shared Selection | ||
with `crossfilter` resolution. | ||
data: | ||
flights: { file: data/flights-200k.parquet } | ||
params: | ||
brush: { select: crossfilter } | ||
vconcat: | ||
- plot: | ||
- mark: rectY | ||
data: { from: flights, filterBy: $brush } | ||
x: { bin: delay } | ||
y: { count: } | ||
fill: steelblue | ||
inset: 0.5 | ||
- select: intervalX | ||
as: $brush | ||
xDomain: Fixed | ||
yTickFormat: s | ||
width: 1200 | ||
height: 250 | ||
- plot: | ||
- mark: rectY | ||
data: { from: flights, filterBy: $brush } | ||
x: { bin: time } | ||
y: { count: } | ||
fill: steelblue | ||
inset: 0.5 | ||
- select: intervalX | ||
as: $brush | ||
xDomain: Fixed | ||
yTickFormat: s | ||
width: 1200 | ||
height: 250 | ||
- plot: | ||
- mark: rectY | ||
data: { from: flights, filterBy: $brush } | ||
x: { bin: distance } | ||
y: { count: } | ||
fill: steelblue | ||
inset: 0.5 | ||
- select: intervalX | ||
as: $brush | ||
xDomain: Fixed | ||
yTickFormat: s | ||
width: 1200 | ||
height: 250 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -110,24 +110,40 @@ class IPyWidgetOutput extends Shiny.OutputBinding { | |
// The ipywidgets container (.lmWidget) | ||
const lmWidget = el.children[0] as HTMLElement; | ||
|
||
this._maybeResize(lmWidget); | ||
if (fill) { | ||
this._onImplementation(lmWidget, () => this._doAddFillClasses(lmWidget)); | ||
} | ||
this._onImplementation(lmWidget, this._doResize); | ||
} | ||
_maybeResize(lmWidget: HTMLElement): void { | ||
_onImplementation(lmWidget: HTMLElement, callback: () => void): void { | ||
if (this._hasImplementation(lmWidget)) { | ||
return this._doResize(); | ||
callback(); | ||
return; | ||
} | ||
|
||
// Some widget implementation (e.g., ipyleaflet, pydeck) won't actually | ||
// have rendered to the DOM at this point, so wait until they do | ||
const mo = new MutationObserver((mutations) => { | ||
if (this._hasImplementation(lmWidget)) { | ||
mo.disconnect(); | ||
this._doResize(); | ||
callback(); | ||
} | ||
}); | ||
|
||
mo.observe(lmWidget, {childList: true}); | ||
} | ||
// In most cases, we can get widgets to fill through Python/CSS, but some widgets | ||
// (e.g., quak) don't have a Python API and use shadow DOM, which can only access | ||
// from JS | ||
_doAddFillClasses(lmWidget: HTMLElement): void { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
cpsievert
Author
Collaborator
|
||
const impl = lmWidget.children[0]; | ||
const isQuakWidget = impl && !!impl.shadowRoot?.querySelector(".quak"); | ||
if (isQuakWidget) { | ||
impl.classList.add("html-fill-container", "html-fill-item"); | ||
const quakWidget = impl.shadowRoot.querySelector(".quak") as HTMLElement; | ||
quakWidget.style.maxHeight = "unset"; | ||
} | ||
} | ||
_doResize(): void { | ||
// Trigger resize event to force layout (setTimeout() is needed for altair) | ||
// TODO: debounce this call? | ||
|
@@ -137,7 +153,7 @@ class IPyWidgetOutput extends Shiny.OutputBinding { | |
} | ||
_hasImplementation(lmWidget: HTMLElement): boolean { | ||
const impl = lmWidget.children[0]; | ||
return impl && impl.children.length > 0; | ||
return impl && (impl.children.length > 0 || impl.shadowRoot?.children.length > 0); | ||
} | ||
} | ||
|
||
|
Oops, something went wrong.
Perhaps this could be a discussion point for external APIs for controlling anywidgets.