///|
priv struct BarbIntent {
artist : Artist
view : @render.BarbHitView
}
///|
fn barb_source(
xs : Array[Double],
ys : Array[Double],
us : Array[Double],
vs : Array[Double],
label : String,
) -> @render.BarbHitData {
let points = Array(capacity=xs.length())
let vectors = Array(capacity=xs.length())
for i, x in xs {
points.push(@core.point(x, ys[i]))
vectors.push(@core.point(us[i], vs[i]))
}
@render.barb_hit_data(points, vectors, label).unwrap()
}
///|
fn Axes::push_barb_component(
self : Axes,
artist : Artist,
source : @render.BarbHitData,
index : Int32,
) -> Unit {
let (component, points) = match artist {
Line(points, _) => (@render.BarbComponent::Stroke, points)
Polygon(points, _) => (@render.BarbComponent::Flag, points)
Scatter(points, _) => (@render.BarbComponent::Calm, points)
_ => return
}
let view = source.view(index, component, points).unwrap()
self.push_artist(artist)
let records = self.state.val.artist_hits
let record = records[records.length() - 1]
record.barb = Some(view)
record.series = view.series()
self.state.val.barb_intents[self.state.val.artists.length() - 1] = {
artist,
view,
}
}
///|
// Normal Line removal shifts known component slots, independently of the
// metadata record cursor (which can omit images and expanded contour lines).
fn AxesData::remove_barb_slot(self : AxesData, removed : Int32) -> Unit {
if self.barb_intents.is_empty() {
return
}
let next = Map([])
for slot, intent in self.barb_intents {
if slot != removed {
next[if slot > removed { slot - 1 } else { slot }] = intent
}
}
self.barb_intents.clear()
for slot, intent in next {
self.barb_intents[slot] = intent
}
}