Skip to content

Commit f49bcc1

Browse files
mattpapphilippjfrmosc9575chinmaychahar
authored
Backports for 3.7.3 (bokeh#14455)
* Update switcher.json * Fix Legend's glyph rendering for `dpr != 1` (bokeh#14443) * Fix Legend's glyph rendering for dpr != 1 * Allow to override screen scaling in testing * Add regression tests * Fix Legend's inactive visuals in CSS mode (bokeh#14454) * Fix Legend's inactive visuals in CSS mode * Add visual regression tests * Update child views without removing their elements (bokeh#14459) * Implement LayoutDOM.update_children without explicitly removing nodes * Fix lint * Fix logic * More lint * Simplify for loop * No tabs * Also update handling of element views * Remove empty line * Fix self_target children lookup * Fix type errors * Fix and simplify logic * Fix element views * Apply suggestions from code review * Simplify further * Fix lint * Revert to append (instead of appendChild) Rever * Compare DOM nodes non-structurally by identity * Add regression tests * Unify all rebuilding of child views --------- Co-authored-by: Mateusz Paprocki <[email protected]> * update docs for DatetimeTickFormatter (bokeh#14452) * Updated formatters.py --------- Co-authored-by: Chinmay <[email protected]> * fix links to code pen (bokeh#14471) * add jquery to fix links to code pen * remove jquery dependency * remove patched show function * use Node.COMMENT_NODE instead of number * avoid line breaks in templates and code pen * fix missing title * Fix positioning of DOM rendered Legend annotations (bokeh#14457) * Fix positioning of DOM rendered Legend annotations * Treat inner canvas panels equally to outer * Robustify resize of canvas after layout * Update visual baselines * Make sticky toolbar work correctly * Refactor PlotView._update_layout() * Invalidate layout if renderers change * Add more regression tests * Update visual baselines * Always repaint Legend's glyphs after rendering * Update visual baselines * Implement move semantics in Plot.add_layout() * Tighten regressions' baseline viewports * Fix types of splattable figure's attributes (bokeh#14401) * Fix types of splattable figure's attributes * Add rudimentary typing tests * Python 3.10 compatibility * Improve corner case handling in datetime formatter (bokeh#14473) * Add release notes --------- Co-authored-by: Philipp Rudiger <[email protected]> Co-authored-by: Moritz Schreiber <[email protected]> Co-authored-by: Chinmay <[email protected]>
2 parents 119bb23 + 6ef7b29 commit f49bcc1

File tree

81 files changed

+1515
-811
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+1515
-811
lines changed

bokehjs/src/less/canvas.less

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,16 @@
1010
}
1111

1212
.bk-events {
13+
display: grid;
14+
grid-template-areas:
15+
". above . "
16+
"left center right"
17+
". below . ";
18+
1319
touch-action: none;
1420
overflow: visible;
1521
cursor: default;
22+
1623
}
1724

1825
.bk-events:focus, .bk-events:focus-visible {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@import "./_mixins.less";
2+
3+
:host {
4+
display: grid;
5+
grid-template-areas:
6+
". above . "
7+
"left center right"
8+
". below . ";
9+
grid-template-rows: max-content 1fr max-content;
10+
grid-template-columns: max-content 1fr max-content;
11+
}

bokehjs/src/less/legend.less

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,25 @@
5656
background-color: var(--item-background-color);
5757
}
5858

59-
.bk-item.bk-active {
60-
background-color: var(--item-background-active-color);
61-
}
62-
6359
:host(.bk-interactive) .bk-item {
6460
cursor: pointer;
6561
}
6662

6763
.bk-glyph {
6864
position: relative;
6965
}
66+
67+
.bk-overlay {
68+
position: absolute;
69+
left: 0;
70+
top: 0;
71+
width: 100%;
72+
height: 100%;
73+
pointer-events: none;
74+
}
75+
76+
.bk-item.bk-inactive {
77+
.bk-overlay {
78+
background-color: var(--item-background-inactive-color);
79+
}
80+
}

bokehjs/src/less/toolbar.less

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
flex-wrap: nowrap;
1313
align-items: center;
1414
.no-user-select();
15+
pointer-events: all;
1516
}
1617

1718
:host(.bk-inner) {

bokehjs/src/lib/core/util/eq.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -234,19 +234,23 @@ export class Comparator {
234234
}
235235

236236
nodes(a: Node, b: Node): boolean {
237-
if (a.nodeType != b.nodeType) {
238-
return false
239-
}
237+
if (this.structural) {
238+
if (a.nodeType != b.nodeType) {
239+
return false
240+
}
240241

241-
if (a.textContent != b.textContent) {
242-
return false
243-
}
242+
if (a.textContent != b.textContent) {
243+
return false
244+
}
244245

245-
if (!this.iterables(a.childNodes, b.childNodes)) {
246-
return false
247-
}
246+
if (!this.iterables(a.childNodes, b.childNodes)) {
247+
return false
248+
}
248249

249-
return true
250+
return true
251+
} else {
252+
return a === b
253+
}
250254
}
251255
}
252256

bokehjs/src/lib/core/util/templating.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,21 @@ export const DEFAULT_FORMATTERS: {[key in BuiltinFormatter]: FormatterFunc} = {
2424
raw: (value: unknown, _format: string, _special_vars: Vars) => to_string(value),
2525
basic: (value: unknown, format: string, special_vars: Vars) => basic_formatter(value, format, special_vars),
2626
numeral: (value: unknown, format: string, _special_vars: Vars) => Numbro.format(value, format),
27-
datetime: (value: unknown, format: string, _special_vars: Vars) => tz(value, format),
27+
datetime: (value: unknown, format: string, _special_vars: Vars) => datetime(value, format),
2828
printf: (value: unknown, format: string, _special_vars: Vars) => sprintf(format, value),
2929
}
3030

31+
/**
32+
* Format finite numbers as dates or return NaN.
33+
*/
34+
export function datetime(value: unknown, format?: string): string {
35+
if (isNumber(value) && isFinite(value)) {
36+
return tz(value, format)
37+
} else {
38+
return "NaN"
39+
}
40+
}
41+
3142
export function sprintf(format: string, ...args: unknown[]): string {
3243
return sprintf_js(format, ...args)
3344
}

bokehjs/src/lib/models/annotations/legend.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ export class LegendView extends AnnotationView {
154154
return false
155155
}
156156

157+
protected _toggle_inactive({el, item}: Entry): void {
158+
el.classList.toggle(legend_css.inactive, !this.is_active(item))
159+
}
160+
157161
protected _render_items(): void {
158162
this.entries = []
159163

@@ -169,17 +173,20 @@ export class LegendView extends AnnotationView {
169173

170174
const glyph_el = glyph.canvas
171175
const label_el = div({class: legend_css.label}, `${label}`)
172-
const item_el = div({class: legend_css.item}, glyph_el, label_el)
176+
const overlay_el = div({class: legend_css.overlay})
177+
const item_el = div({class: legend_css.item}, glyph_el, label_el, overlay_el)
173178
item_el.classList.toggle(legend_css.hidden, !item.visible)
174179

180+
const entry: Entry = {el: item_el, glyph, label_el, item, label, i: i++, row: 0, col: 0}
181+
this.entries.push(entry)
182+
175183
item_el.addEventListener("pointerdown", () => {
176184
this.model.trigger_event(new LegendItemClick(this.model, item))
177185
for (const renderer of item.renderers) {
178186
click_policy(renderer)
179187
}
188+
this._toggle_inactive(entry)
180189
})
181-
182-
this.entries.push({el: item_el, glyph, label_el, item, label, i: i++, row: 0, col: 0})
183190
}
184191
}
185192

@@ -235,11 +242,8 @@ export class LegendView extends AnnotationView {
235242
}
236243
}
237244

238-
const {is_active} = this
239-
for (const {el, item} of this.entries) {
240-
if (!is_active(item)) {
241-
el.classList.add(legend_css.active)
242-
}
245+
for (const entry of this.entries) {
246+
this._toggle_inactive(entry)
243247
}
244248

245249
for (const {el, i, row, col} of this.entries) {
@@ -339,7 +343,7 @@ export class LegendView extends AnnotationView {
339343
const {color} = this.visuals.inactive_fill.computed_values()
340344
this.style.append(`
341345
.${legend_css.item} {
342-
--item-background-active-color: ${color};
346+
--item-background-inactive-color: ${color};
343347
}
344348
`)
345349
}
@@ -411,6 +415,7 @@ export class LegendView extends AnnotationView {
411415
override after_render(): void {
412416
super.after_render()
413417
this.update_position()
418+
this.request_paint() // paint glyphs
414419
}
415420

416421
get location(): {x: HAlign | number, y: VAlign | number} {
@@ -616,7 +621,7 @@ export class LegendView extends AnnotationView {
616621

617622
ctx.layer.undo_transform(() => {
618623
const glyph_el = glyph.canvas
619-
const glyph_bbox = bounding_box(glyph_el).relative_to(canvas_bbox)
624+
const glyph_bbox = bounding_box(glyph_el).relative_to(canvas_bbox).scale(ctx.layer.pixel_ratio)
620625
ctx.drawImage(glyph_el, glyph_bbox.x, glyph_bbox.y)
621626
})
622627

bokehjs/src/lib/models/annotations/toolbar_panel.ts

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,15 @@ import type {ToolbarView} from "../tools/toolbar"
33
import {Toolbar} from "../tools/toolbar"
44
import type {IterViews} from "core/build_views"
55
import {build_view} from "core/build_views"
6-
import {empty, position, display, undisplay} from "core/dom"
76
import type {Size, Layoutable} from "core/layout"
87
import {SideLayout} from "core/layout/side_panel"
9-
import {BBox} from "core/util/bbox"
108
import type * as p from "core/properties"
119

1210
export class ToolbarPanelView extends AnnotationView {
1311
declare model: ToolbarPanel
1412

1513
declare layout: Layoutable
1614

17-
override rendering_target(): HTMLElement {
18-
return this.plot_view.canvas_view.events_el
19-
}
20-
2115
override update_layout(): void {
2216
this.layout = new SideLayout(this.panel!, () => this.get_size(), true)
2317
}
@@ -70,33 +64,27 @@ export class ToolbarPanelView extends AnnotationView {
7064
this.toolbar_view.render_to(this.shadow_el)
7165
}
7266

73-
private _previous_bbox: BBox = new BBox()
67+
private get is_horizontal(): boolean {
68+
return this.toolbar_view.model.horizontal
69+
}
7470

7571
protected _paint(): void {
76-
// TODO this shouldn't be necessary
77-
display(this.el)
78-
79-
// TODO: this should be handled by the layout
80-
const {bbox} = this.layout
81-
if (!this._previous_bbox.equals(bbox)) {
82-
position(this.el, bbox)
83-
this._previous_bbox = bbox
84-
85-
empty(this.el)
86-
this.el.style.position = "absolute"
87-
88-
const {style} = this.toolbar_view.el
89-
if (this.toolbar_view.model.horizontal) {
90-
style.width = "100%"
91-
style.height = "unset"
92-
} else {
93-
style.width = "unset"
94-
style.height = "100%"
95-
}
72+
const {style} = this.toolbar_view.el
73+
if (this.is_horizontal) {
74+
style.width = "100%"
75+
style.height = "unset"
76+
} else {
77+
style.width = "unset"
78+
style.height = "100%"
9679
}
9780

98-
if (!this.model.visible) {
99-
undisplay(this.el)
81+
// allow shrinking past content size in flex layouts
82+
if (this.is_horizontal) {
83+
this.el.style.minWidth = "0"
84+
this.el.style.minHeight = "unset"
85+
} else {
86+
this.el.style.minWidth = "unset"
87+
this.el.style.minHeight = "0"
10088
}
10189
}
10290

bokehjs/src/lib/models/canvas/canvas_panel.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import type {Node} from "../coordinates/node"
44
import type * as p from "core/properties"
55
import {InlineStyleSheet} from "core/dom"
66
import type {StyleSheetLike} from "core/dom"
7+
import type {RenderingTarget} from "core/dom_view"
78
import type {XY} from "core/util/bbox"
89
import {BBox} from "core/util/bbox"
910
import {Place} from "core/enums"
11+
import {Bool} from "core/kinds"
1012
import {isNumber} from "core/util/types"
1113
import * as css from "styles/canvas_panel.css"
1214

@@ -25,8 +27,12 @@ export class CanvasPanelView extends StyledElementView {
2527
return [...super.stylesheets(), css.default, this.position]
2628
}
2729

28-
override rendering_target(): HTMLElement {
29-
return this.parent.canvas_view.events_el
30+
override rendering_target(): RenderingTarget {
31+
if (this.model.inner) {
32+
return this.parent.frame_view.shadow_el
33+
} else {
34+
return this.parent.canvas_view.events_el
35+
}
3036
}
3137

3238
override render(): void {
@@ -72,6 +78,7 @@ export namespace CanvasPanel {
7278
export type Attrs = p.AttrsOf<Props>
7379
export type Props = StyledElement.Props & {
7480
place: p.Property<Place>
81+
inner: p.Property<boolean>
7582
}
7683
}
7784

@@ -90,6 +97,7 @@ export class CanvasPanel extends StyledElement {
9097

9198
this.define<CanvasPanel.Props>({
9299
place: [ Place ],
100+
inner: [ Bool, false ],
93101
})
94102
}
95103
}

bokehjs/src/lib/models/canvas/cartesian_frame.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import type {BBox} from "core/util/bbox"
1111
import {entries} from "core/util/object"
1212
import {assert} from "core/util/assert"
1313
import type {Dict} from "core/types"
14+
import type {StyleSheetLike} from "core/dom"
1415
import type * as p from "core/properties"
16+
import * as css from "styles/cartesian_frame.css"
1517

1618
type Ranges = Dict<Range>
1719
type Scales = Dict<Scale>
@@ -29,6 +31,10 @@ export class CartesianFrameView extends CanvasPanelView {
2931
super.remove()
3032
}
3133

34+
override stylesheets(): StyleSheetLike[] {
35+
return [...super.stylesheets(), css.default]
36+
}
37+
3238
override connect_signals(): void {
3339
super.connect_signals()
3440
const {x_range, y_range, x_scale, y_scale, extra_x_ranges, extra_y_ranges, extra_x_scales, extra_y_scales} = this.model.properties

0 commit comments

Comments
 (0)