Skip to content

Commit

Permalink
Don't sort indices by distance in _hit_point() (bokeh#10163)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattpap authored Jun 16, 2020
1 parent 00cdec4 commit 5bcb525
Show file tree
Hide file tree
Showing 12 changed files with 39 additions and 41 deletions.
12 changes: 6 additions & 6 deletions bokehjs/src/lib/models/glyphs/annular_wedge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export class AnnularWedgeView extends XYGlyphView {
;[y0, y1] = this.renderer.yscale.r_invert(sy0, sy1)
}

const candidates = []
const candidates: number[] = []

for (const i of this.index.indices({x0, x1, y0, y1})) {
const or2 = this.souter_radius[i]**2
Expand All @@ -114,20 +114,20 @@ export class AnnularWedgeView extends XYGlyphView {
const [sy0, sy1] = this.renderer.yscale.r_compute(y, this._y[i])
const dist = (sx0-sx1)**2 + (sy0-sy1)**2
if (dist <= or2 && dist >= ir2)
candidates.push([i, dist])
candidates.push(i)
}

const direction = this.model.properties.direction.value()
const hits: [number, number][] = []
for (const [i, dist] of candidates) {
const indices: number[] = []
for (const i of candidates) {
// NOTE: minus the angle because JS uses non-mathy convention for angles
const angle = Math.atan2(sy-this.sy[i], sx-this.sx[i])
if (angle_between(-angle, -this._start_angle[i], -this._end_angle[i], direction)) {
hits.push([i, dist])
indices.push(i)
}
}

return Selection.from_hits(hits)
return new Selection({indices})
}

draw_legend_for_index(ctx: Context2d, bbox: Rect, index: number): void {
Expand Down
7 changes: 3 additions & 4 deletions bokehjs/src/lib/models/glyphs/annulus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,18 @@ export class AnnulusView extends XYGlyphView {
;[y0, y1] = this.renderer.yscale.r_invert(sy0, sy1)
}

const hits: [number, number][] = []

const indices: number[] = []
for (const i of this.index.indices({x0, x1, y0, y1})) {
const or2 = this.souter_radius[i]**2
const ir2 = this.sinner_radius[i]**2
const [sx0, sx1] = this.renderer.xscale.r_compute(x, this._x[i])
const [sy0, sy1] = this.renderer.yscale.r_compute(y, this._y[i])
const dist = (sx0 - sx1)**2 + (sy0 - sy1)**2
if (dist <= or2 && dist >= ir2)
hits.push([i, dist])
indices.push(i)
}

return Selection.from_hits(hits)
return new Selection({indices})
}

draw_legend_for_index(ctx: Context2d, {x0, y0, x1, y1}: Rect, index: number): void {
Expand Down
8 changes: 4 additions & 4 deletions bokehjs/src/lib/models/glyphs/circle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,28 +141,28 @@ export class CircleView extends XYGlyphView {

const candidates = this.index.indices({x0, x1, y0, y1})

const hits: [number, number][] = []
const indices: number[] = []
if (this._radius != null && this.model.properties.radius.units == "data") {
for (const i of candidates) {
const r2 = this.sradius[i]**2
const [sx0, sx1] = this.renderer.xscale.r_compute(x, this._x[i])
const [sy0, sy1] = this.renderer.yscale.r_compute(y, this._y[i])
const dist = (sx0 - sx1)**2 + (sy0 - sy1)**2
if (dist <= r2) {
hits.push([i, dist])
indices.push(i)
}
}
} else {
for (const i of candidates) {
const r2 = this.sradius[i]**2
const dist = (this.sx[i] - sx)**2 + (this.sy[i] - sy)**2
if (dist <= r2) {
hits.push([i, dist])
indices.push(i)
}
}
}

return Selection.from_hits(hits)
return new Selection({indices})
}

protected _hit_span(geometry: SpanGeometry): Selection {
Expand Down
15 changes: 6 additions & 9 deletions bokehjs/src/lib/models/glyphs/ellipse_oval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ export abstract class EllipseOvalView extends CenterRotatableView {
}

protected _hit_point(geometry: PointGeometry): Selection {
let x0, x1, y0, y1, cond, dist, sx0, sx1, sy0, sy1
let x0, x1, y0, y1, cond, sx0, sx1, sy0, sy1

const {sx, sy} = geometry
const x = this.renderer.xscale.invert(sx)
const y = this.renderer.yscale.invert(sy)

if (this.model.properties.width.units == "data"){
if (this.model.properties.width.units == "data") {
x0 = x - this.max_width
x1 = x + this.max_width
} else {
Expand All @@ -73,7 +73,7 @@ export abstract class EllipseOvalView extends CenterRotatableView {
;[x0, x1] = this.renderer.xscale.r_invert(sx0, sx1)
}

if (this.model.properties.height.units == "data"){
if (this.model.properties.height.units == "data") {
y0 = y - this.max_height
y1 = y + this.max_height
} else {
Expand All @@ -83,19 +83,16 @@ export abstract class EllipseOvalView extends CenterRotatableView {
}

const candidates = this.index.indices({x0, x1, y0, y1})
const hits: [number, number][] = []
const indices: number[] = []

for (const i of candidates) {
cond = hittest.point_in_ellipse(sx, sy, this._angle[i], this.sh[i]/2, this.sw[i]/2, this.sx[i], this.sy[i])
if (cond) {
[sx0, sx1] = this.renderer.xscale.r_compute(x, this._x[i])
;[sy0, sy1] = this.renderer.yscale.r_compute(y, this._y[i])
dist = (sx0-sx1)**2 + (sy0-sy1)**2
hits.push([i, dist])
indices.push(i)
}
}

return Selection.from_hits(hits)
return new Selection({indices})
}

draw_legend_for_index(ctx: Context2d, {x0, y0, x1, y1}: Rect, index: number): void {
Expand Down
2 changes: 1 addition & 1 deletion bokehjs/src/lib/models/glyphs/hex_tile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ export class HexTileView extends GlyphView {
const y = this.renderer.yscale.invert(sy)

const candidates = this.index.indices({x0: x, y0: y, x1: x, y1: y})

const indices = []

for (const i of candidates) {
if (hittest.point_in_poly(sx-this.sx[i], sy-this.sy[i], this.svx, this.svy)) {
indices.push(i)
Expand Down
1 change: 1 addition & 0 deletions bokehjs/src/lib/models/glyphs/image_base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ export abstract class ImageBaseView extends XYGlyphView {
const {sx, sy} = geometry
const x = this.renderer.xscale.invert(sx)
const y = this.renderer.yscale.invert(sy)

const candidates = this.index.indices({x0: x, x1: x, y0: y, y1: y})
const result = new Selection()

Expand Down
2 changes: 2 additions & 0 deletions bokehjs/src/lib/models/glyphs/multi_polygons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,10 @@ export class MultiPolygonsView extends GlyphView {
const ys = [sy0, sy0, sy1, sy1]
const [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1)
const [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1)

const candidates = this.index.indices({x0, x1, y0, y1})
const indices = []

for (let i = 0, end = candidates.length; i < end; i++) {
const index = candidates[i]
const sxss = this.sxs[index]
Expand Down
2 changes: 2 additions & 0 deletions bokehjs/src/lib/models/glyphs/patches.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,10 @@ export class PatchesView extends GlyphView {
const ys = [sy0, sy0, sy1, sy1]
const [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1)
const [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1)

const candidates = this.index.indices({x0, x1, y0, y1})
const indices = []

for (let i = 0, end = candidates.length; i < end; i++) {
const index = candidates[i]
const sxss = this.sxs[index]
Expand Down
3 changes: 2 additions & 1 deletion bokehjs/src/lib/models/glyphs/segment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ export class SegmentView extends GlyphView {

const [x0, x1] = this.renderer.xscale.r_invert(sx-lw_voffset, sx+lw_voffset)
const [y0, y1] = this.renderer.yscale.r_invert(sy-lw_voffset, sy+lw_voffset)
const candidates = this.index.indices({x0, y0, x1, y1})

const candidates = this.index.indices({x0, y0, x1, y1})
const indices = []

for (const i of candidates) {
const threshold2 = Math.max(2, this.visuals.line.cache_select('line_width', i) / 2)**2
const p0 = {x: this.sx0[i], y: this.sy0[i]}
Expand Down
13 changes: 7 additions & 6 deletions bokehjs/src/lib/models/glyphs/wedge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,29 +82,30 @@ export class WedgeView extends XYGlyphView {
;[y0, y1] = this.renderer.yscale.r_invert(sy0, sy1)
}

const candidates = []
const candidates: number[] = []

for (const i of this.index.indices({x0, x1, y0, y1})) {
const r2 = this.sradius[i]**2
;[sx0, sx1] = this.renderer.xscale.r_compute(x, this._x[i])
;[sy0, sy1] = this.renderer.yscale.r_compute(y, this._y[i])
dist = (sx0-sx1)**2 + (sy0-sy1)**2
if (dist <= r2) {
candidates.push([i, dist])
candidates.push(i)
}
}

const direction = this.model.properties.direction.value()
const hits: [number, number][] = []
for (const [i, dist] of candidates) {
const indices: number[] = []

for (const i of candidates) {
// NOTE: minus the angle because JS uses non-mathy convention for angles
const angle = Math.atan2(sy-this.sy[i], sx-this.sx[i])
if (angle_between(-angle, -this._start_angle[i], -this._end_angle[i], direction)) {
hits.push([i, dist])
indices.push(i)
}
}

return Selection.from_hits(hits)
return new Selection({indices})
}

draw_legend_for_index(ctx: Context2d, bbox: Rect, index: number): void {
Expand Down
8 changes: 4 additions & 4 deletions bokehjs/src/lib/models/markers/marker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,16 @@ export abstract class MarkerView extends XYGlyphView {
const [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1)

const candidates = this.index.indices({x0, x1, y0, y1})
const indices: number[] = []

const hits: [number, number][] = []
for (const i of candidates) {
const s2 = this._size[i]/2
const dist = Math.abs(this.sx[i] - sx) + Math.abs(this.sy[i] - sy)
if (Math.abs(this.sx[i] - sx) <= s2 && Math.abs(this.sy[i] - sy) <= s2) {
hits.push([i, dist])
indices.push(i)
}
}
return Selection.from_hits(hits)

return new Selection({indices})
}

protected _hit_span(geometry: SpanGeometry): Selection {
Expand Down
7 changes: 1 addition & 6 deletions bokehjs/src/lib/models/selections/selection.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Model} from "../../model"
import * as p from "core/properties"
import {SelectionMode} from "core/enums"
import {union, intersection, difference, sort_by} from "core/util/array"
import {union, intersection, difference} from "core/util/array"
import {merge} from "core/util/object"
import {Glyph, GlyphView} from "../glyphs/glyph"

Expand Down Expand Up @@ -57,11 +57,6 @@ export class Selection extends Model {
this.get_view = () => null
}

static from_hits(hits: [number, number][]): Selection {
const indices = sort_by(hits, ([, dist]) => dist).map(([i]) => i)
return new Selection({indices})
}

get selected_glyph(): Glyph | null {
return this.selected_glyphs.length > 0 ? this.selected_glyphs[0] : null
}
Expand Down

0 comments on commit 5bcb525

Please sign in to comment.