I would like to try and extend MultiLine to support vertical offsets as described in #3443
I have tried copy pasting multiline properties from glyph.py and multi_line.js as a start.
This has already helped me implement box selection as discussed in #6336 (by implementing _hit_rect
for any point on the curve)
However, this time I need to implement offset
and scale
vector parameters so I started to try and find out how to parse the extra parameters and update the ys
parameter.
My offset_multiline.py:
from typing import Any
from bokeh.core.property.dataspec import NumberSpec, field
from bokeh.io import output_file, show
from bokeh.models import MultiLine, ColumnDataSource, GlyphRenderer
import numpy as np
from bokeh.plotting._decorators import glyph_method
class OffsetMultiLine(MultiLine):
__implementation__ = "offset_multiline.js"
_args = ('xs', 'ys', 'offset', 'scale')
offset = NumberSpec(default=field("offset"), help="""
The offset in the y-scale
""")
scale = NumberSpec(default=field("scale"), help="""
The gain in y-scale
""")
@glyph_method(OffsetMultiLine)
def offset_multiline(self, *args: Any, **kwargs: Any) -> GlyphRenderer:
pass
from bokeh.plotting import Figure, figure
Figure.offset_multiline = offset_multiline
if __name__ == '__main__':
x = np.linspace(0, 10, 100)
xs = [x]*2
ys = [np.sin(x+i) for i in range(2)]
offset= np.linspace(0,2,2)
scale=[1,1]
source = ColumnDataSource(dict(xs=xs,ys=ys,offset=offset,scale=scale))
p = figure(tools='tap,wheel_zoom,pan,box_select')
p.offset_multiline(source=source, xs="xs", ys="ys",
offset="offset", scale="scale",
line_color="#8073ac", line_width=2, hover_line_width=5)
show(p)
and offset_multiline.js:
var _a;
import {MultiLine, MultiLineView} from "models/glyphs/multi_line"
import * as p from "core/properties";
import {LineVector} from "core/property_mixins";
export class OffsetMultiLineView extends MultiLineView {
}
export class OffsetMultiLine extends MultiLine {
}
_a = OffsetMultiLine;
_a.__name__ = "OffsetMultiLine";
(() => {
_a.prototype.default_view = OffsetMultiLineView;
// When I include the following lines, I get an "Error: Model 'OffsetMulitiLine' does not exist"
_a.define(({}) => ({
xs: [p.XCoordinateSeqSpec, { field: "xs" }],
ys: [p.YCoordinateSeqSpec, { field: "ys" }],
}));
_a.mixins(LineVector);
})();
The problem arises when I include the _a.define()
and _a.mixins()
lines in the bottom of the .js file. (which probably just exposes my limited knowledge about JS.)
Secondly I would implement the offset
and scale
and parameters but I am happy to do some exploring/experimenting myself…