10000 Respect glyph protocol in graph renderer · bokeh/bokeh@75dcee0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 75dcee0

Browse files
committed
Respect glyph protocol in graph renderer
1 parent fbf4f0c commit 75dcee0

File tree

6 files changed

+88
-78
lines changed

6 files changed

+88
-78
lines changed

bokehjs/src/lib/core/properties.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ export abstract class BaseCoordinateSpec<T> extends DataSpec<T> {
438438
} E85A
439439

440440
export abstract class CoordinateSpec extends BaseCoordinateSpec<number | Factor> {}
441-
export abstract class CoordinateSeqSpec extends BaseCoordinateSpec<number[] | Factor[]> {}
441+
export abstract class CoordinateSeqSpec extends BaseCoordinateSpec<Arrayable<number> | Arrayable<Factor>> {}
442442
export abstract class CoordinateSeqSeqSeqSpec extends BaseCoordinateSpec<number[][][] | Factor[][][]> {}
443443

444444
export class XCoordinateSpec extends CoordinateSpec { readonly dimension = "x" }

bokehjs/src/lib/models/graphs/layout_provider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {Model} from "../../model"
22
import {ColumnarDataSource} from "../sources/columnar_data_source"
3-
import {NumberArray, RaggedArray} from "core/types"
3+
import {Arrayable, NumberArray} from "core/types"
44
import * as p from "core/properties"
55

66
export namespace LayoutProvider {
@@ -20,5 +20,5 @@ export abstract class LayoutProvider extends Model {
2020

2121
abstract get_node_coordinates(graph_source: ColumnarDataSource): [NumberArray, NumberArray]
2222

23-
abstract get_edge_coordinates(graph_source: ColumnarDataSource): [RaggedArray, RaggedArray]
23+
abstract get_edge_coordinates(graph_source: ColumnarDataSource): [Arrayable<number>[], Arrayable<number>[]]
2424
}

bokehjs/src/lib/models/graphs/static_layout_provider.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {LayoutProvider} from "./layout_provider"
22
import {ColumnarDataSource} from "../sources/columnar_data_source"
3-
import {NumberArray, RaggedArray} from "core/types"
3+
import {Arrayable, NumberArray} from "core/types"
44
import * as p from "core/properties"
55

66
export namespace StaticLayoutProvider {
@@ -40,7 +40,7 @@ export class StaticLayoutProvider extends LayoutProvider {
4040
return [xs, ys]
4141
}
4242

43-
get_edge_coordinates(edge_source: ColumnarDataSource): [RaggedArray, RaggedArray] {
43+
get_edge_coordinates(edge_source: ColumnarDataSource): [Arrayable<number>[], Arrayable<number>[]] {
4444
const starts = edge_source.data.start
4545
const ends = edge_source.data.end
4646
const n = starts.length
@@ -65,9 +65,6 @@ export class StaticLayoutProvider extends LayoutProvider {
6565
ys.push([start[1], end[1]])
6666
}
6767
}
68-
return [
69-
RaggedArray.from(xs),
70-
RaggedArray.from(ys),
71-
]
68+
return [xs, ys]
7269
}
7370
}

bokehjs/src/lib/models/renderers/graph_renderer.ts

Lines changed: 68 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,73 +3,86 @@ import {GlyphRenderer, GlyphRendererView} from "./glyph_renderer"
33
import {LayoutProvider} from "../graphs/layout_provider"
44
import {GraphHitTestPolicy, NodesOnly} from "../graphs/graph_hit_test_policy"
55
import * as p from "core/properties"
6-
import {build_views, remove_views} from "core/build_views"
6+
import {build_view} from "core/build_views"
77
import {SelectionManager} from "core/selection_manager"
8+
import {XYGlyph} from "../glyphs/xy_glyph"
9+
import {MultiLine} from "../glyphs/multi_line"
10+
import {ColumnarDataSource} from "../sources/columnar_data_source"
11+
import {Arrayable} from "core/types"
12+
import {assert} from "core/util/assert"
813

914
export class GraphRendererView extends DataRendererView {
1015
model: GraphRenderer
1116

12-
node_view: GlyphRendererView
1317
edge_view: GlyphRendererView
14-
15-
protected _renderer_views: Map<GlyphRenderer, GlyphRendererView>
16-
17-
initialize(): void {
18-
super.initialize()
19-
this._renderer_views = new Map()
20-
}
18+
node_view: GlyphRendererView
2119

2220
async lazy_initialize(): Promise<void> {
23-
[this.node_view, this.edge_view] = await build_views(this._renderer_views, [
24-
this.model.node_renderer,
25-
this.model.edge_renderer,
26-
], {parent: this.parent})
27-
28-
this.set_data()
29-
}
30-
31-
remove(): void {
32-
remove_views(this._renderer_views)
33-
super.remove()
34-
}
35-
36-
connect_signals(): void {
37-
super.connect_signals()
21+
await super.lazy_initialize()
3822

39-
this.connect(this.model.layout_provider.change, () => this.set_data())
40-
this.connect(this.model.node_renderer.data_source._select, () => this.set_data())
41-
this.connect(this.model.node_renderer.data_source.inspect, () => this.set_data())
42-
this.connect(this.model.node_renderer.data_source.change, () => this.set_data())
43-
this.connect(this.model.edge_renderer.data_source._select, () => this.set_data())
44-
this.connect(this.model.edge_renderer.data_source.inspect, () => this.set_data())
45-
this.connect(this.model.edge_renderer.data_source.change, () => this.set_data())
23+
const graph = this.model
4624

47-
const {x_ranges, y_ranges} = this.plot_view.frame
25+
// TODO: replace this with bi-variate transforms
26+
let xs_ys: [Arrayable<number>[], Arrayable<number>[]] | null = null
27+
let x_y: [Arrayable<number>, Arrayable<number>] | null = null
4828

49-
for (const [, range] of x_ranges) {
50-
this.connect(range.change, () => this.set_data())
29+
const xs_expr = {
30+
v_compute(source: ColumnarDataSource) {
31+
assert(xs_ys == null)
32+
const [xs] = xs_ys = graph.layout_provider.get_edge_coordinates(source)
33+
return xs
34+
},
35+
}
36+
const ys_expr = {
37+
v_compute(_source: ColumnarDataSource) {
38+
assert(xs_ys != null)
39+
const [, ys] = xs_ys
40+
xs_ys = null
41+
return ys
42+
},
5143
}
5244

53-
for (const [, range] of y_ranges) {
54-
this.connect(range.change, () => this.set_data())
45+
const x_expr = {
46+
v_compute(source: ColumnarDataSource) {
47+
assert(x_y == null)
48+
const [x] = x_y = graph.layout_provider.get_node_coordinates(source)
49+
return x
50+
},
51+
}
52+
const y_expr = {
53+
v_compute(_source: ColumnarDataSource) {
54+
assert(x_y != null)
55+
const [, y] = x_y
56+
x_y = null
57+
return y
58+
},
5559
}
56-
}
5760

58-
set_data(request_render: boolean = true): void {
59-
// XXX
60-
const node_glyph: any = this.node_view.glyph
61-
;[node_glyph._x, node_glyph._y] =
62-
this.model.layout_provider.get_node_coordinates(this.model.node_renderer.data_source) as any
61+
const {edge_renderer, node_renderer} = this.model
6362

64-
const edge_glyph: any = this.edge_view.glyph
65-
;[edge_glyph._xs, edge_glyph._ys] =
66-
this.model.layout_provider.get_edge_coordinates(this.model.edge_renderer.data_source) as any
63+
edge_renderer.glyph.xs = {expr: xs_expr}
64+
edge_renderer.glyph.ys = {expr: ys_expr}
6765

68-
node_glyph.index_data()
69-
edge_glyph.index_data()
66+
node_renderer.glyph.x = {expr: x_expr}
67+
node_renderer.glyph.y = {expr: y_expr}
7068

71-
if (request_render)
69+
this.edge_view = await build_view(edge_renderer, {parent: this.parent})
70+
this.node_view = await build_view(node_renderer, {parent: this.parent})
71+
}
72+
73+
connect_signals(): void {
74+
super.connect_signals()
75+
this.connect(this.model.layout_provider.change, () => {
76+
this.edge_view.set_data(false)
77+
this.node_view.set_data(false)
7278
this.request_render()
79+
})
80+
}
81+
82+
remove(): void {
83+
this.edge_view.remove()
84+
this.node_view.remove()
85+
super.remove()
7386
}
7487

7588
protected _render(): void {
@@ -83,8 +96,8 @@ export namespace GraphRenderer {
8396

8497
export type Props = DataRenderer.Props & {
8598
layout_provider: p.Property<LayoutProvider>
86-
node_renderer: p.Property<GlyphRenderer>
87-
edge_renderer: p.Property<GlyphRenderer>
99+
node_renderer: p.Property<GlyphRenderer & {glyph: XYGlyph}>
100+
edge_renderer: p.Property<GlyphRenderer & {glyph: MultiLine}>
88101
selection_policy: p.Property<GraphHitTestPolicy>
89102
inspection_policy: p.Property<GraphHitTestPolicy>
90103
}
@@ -104,11 +117,11 @@ export class GraphRenderer extends DataRenderer {
104117
this.prototype.default_view = GraphRendererView
105118

106119
this.define<GraphRenderer.Props>({
107-
layout_provider: [ p.Instance ],
108-
node_renderer: [ p.Instance ],
109-
edge_renderer: [ p.Instance ],
110-
selection_policy: [ p.Instance, () => new NodesOnly() ],
111-
inspection_policy: [ p.Instance, () => new NodesOnly() ],
120+
layout_provider: [ p.Instance ],
121+
node_renderer: [ p.Instance ],
122+
edge_renderer: [ p.Instance ],
123+
selection_policy: [ p.Instance, () => new NodesOnly() ],
124+
inspection_policy: [ p.Instance, () => new NodesOnly() ],
112125
})
113126
}
114127

bokehjs/test/unit/models/graphs/graph_hit_test_policy.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ import {ColumnarDataSource} from "@bokehjs/models/sources/columnar_data_source"
1515
import {ColumnDataSource} from "@bokehjs/models/sources/column_data_source"
1616
import {Document} from "@bokehjs/document"
1717
import {build_view} from "@bokehjs/core/build_views"
18-
import {NumberArray, RaggedArray} from "@bokehjs/core/types"
18+
import {Arrayable, NumberArray} from "@bokehjs/core/types"
1919

2020
class TrivialLayoutProvider extends LayoutProvider {
2121

2222
get_node_coordinates(_graph_source: ColumnarDataSource): [NumberArray, NumberArray] {
2323
return [new NumberArray(0), new NumberArray(0)]
2424
}
2525

26-
get_edge_coordinates(_graph_source: ColumnarDataSource): [RaggedArray, RaggedArray] {
27-
return [RaggedArray.from([]), RaggedArray.from([])]
26+
get_edge_coordinates(_graph_source: ColumnarDataSource): [Arrayable<number>[], Arrayable<number>[]] {
27+
return [[], []]
2828
}
2929
}
3030

@@ -59,8 +59,8 @@ describe("GraphHitTestPolicy", () => {
5959
ys: [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
6060
},
6161
})
62-
const node_renderer = new GlyphRenderer({data_source: node_source, glyph: new Circle()})
63-
const edge_renderer = new GlyphRenderer({data_source: edge_source, glyph: new MultiLine()})
62+
const node_renderer = new GlyphRenderer({data_source: node_source, glyph: new Circle()}) as GlyphRenderer & {glyph: Circle}
63+
const edge_renderer = new GlyphRenderer({data_source: edge_source, glyph: new MultiLine()}) as GlyphRenderer & {glyph: MultiLine}
6464

6565
gr = new GraphRenderer({
6666
node_renderer,

bokehjs/test/unit/models/graphs/static_layout_provider.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {expect} from "assertions"
22

33
import {StaticLayoutProvider} from "@bokehjs/models/graphs/static_layout_provider"
44
import {ColumnDataSource} from "@bokehjs/models/sources/column_data_source"
5-
import {NumberArray, RaggedArray} from "@bokehjs/core/types"
5+
import {NumberArray} from "@bokehjs/core/types"
66

77
describe("StaticLayoutProvider", () => {
88

@@ -52,8 +52,8 @@ describe("StaticLayoutProvider", () => {
5252
edge_source.data.end = [1, 2, 3]
5353

5454
const [xs, ys] = layout_provider.get_edge_coordinates(edge_source)
55-
expect(xs).to.be.equal(RaggedArray.from([[-1, 0], [-1, 1], [-1, 0]]))
56-
expect(ys).to.be.equal(RaggedArray.from([[0, 1], [0, 0], [0, -1]]))
55+
expect(xs).to.be.equal([[-1, 0], [-1, 1], [-1, 0]])
56+
expect(ys).to.be.equal([[0, 1], [0, 0], [0, -1]])
5757
})
5858

5959
it("should return explicit edge coords if exist", () => {
@@ -64,8 +64,8 @@ describe("StaticLayoutProvider", () => {
6464
edge_source.data.ys = [[0, 0.5, 1], [0, 0, 0], [0, -0.5, -1]]
6565

6666
const [xs, ys] = layout_provider.get_edge_coordinates(edge_source)
67-
expect(xs).to.be.equal(RaggedArray.from([[-1, -0.5, 0], [-1, 0, 1], [-1, -0.5, 0]]))
68-
expect(ys).to.be.equal(RaggedArray.from([[0, 0.5, 1], [0, 0, 0], [0, -0.5, -1]]))
67+
expect(xs).to.be.equal([[-1, -0.5, 0], [-1, 0, 1], [-1, -0.5, 0]])
68+
expect(ys).to.be.equal([[0, 0.5, 1], [0, 0, 0], [0, -0.5, -1]])
6969
})
7070

7171
it("should return NaNs if coords don't exist", () => {
@@ -74,8 +74,8 @@ describe("StaticLayoutProvider", () => {
7474
edge_source.data.end = [5, 6, 7]
7575

7676
const [xs, ys] = layout_provider.get_edge_coordinates(edge_source)
77-
expect(xs).to.be.equal(RaggedArray.from([[NaN, NaN], [NaN, NaN], [NaN, NaN]]))
78-
expect(ys).to.be.equal(RaggedArray.from([[NaN, NaN], [NaN, NaN], [NaN, NaN]]))
77+
expect(xs).to.be.equal([[NaN, NaN], [NaN, NaN], [NaN, NaN]])
78+
expect(ys).to.be.equal([[NaN, NaN], [NaN, NaN], [NaN, NaN]])
7979
})
8080

8181
it("should not return explicit edge coords if coords don't exist", () => {
@@ -86,8 +86,8 @@ describe("StaticLayoutProvider", () => {
8686
edge_source.data.ys = [[0, 0.5, 1], [0, 0, 0], [0, -0.5, -1]]
8787

8888
const [xs, ys] = layout_provider.get_edge_coordinates(edge_source)
89-
expect(xs).to.be.equal(RaggedArray.from([[NaN, NaN], [NaN, NaN], [NaN, NaN]]))
90-
expect(ys).to.be.equal(RaggedArray.from([[NaN, NaN], [NaN, NaN], [NaN, NaN]]))
89+
expect(xs).to.be.equal([[NaN, NaN], [NaN, NaN], [NaN, NaN]])
90+
expect(ys).to.be.equal([[NaN, NaN], [NaN, NaN], [NaN, NaN]])
9191
})
9292
})
9393
})

0 commit comments

Comments
 (0)
0