prism 0.1.0

An experimental chart library for iced.
Documentation
use iced::Rectangle;
use ordered_float::OrderedFloat;

use std::collections::BTreeMap;

type BTreeMapFloat<V> = BTreeMap<OrderedFloat<f32>, V>;

pub struct Entry<Id> {
    id: Id,
    location: iced::Point,
}

impl<Id> Entry<Id>
where
    Id: Clone,
{
    pub fn new(id: Id, location: iced::Point) -> Self {
        Self { id, location }
    }
}

pub struct Items<SeriesId, ItemId>(BTreeMapFloat<BTreeMapFloat<(SeriesId, ItemId)>>);

impl<SeriesId, ItemId> Items<SeriesId, ItemId>
where
    SeriesId: Clone,
    ItemId: Clone + std::fmt::Debug,
{
    pub fn add_series(&mut self, id: SeriesId, series: &[Entry<ItemId>]) {
        for entry in series.iter() {
            let point = entry.location;

            self.0
                .entry(OrderedFloat(point.x))
                .or_default()
                .insert(OrderedFloat(point.y), (id.clone(), entry.id.clone()));
        }
    }

    pub fn collision(&self, rect: Rectangle) -> Vec<(SeriesId, ItemId)> {
        let range = OrderedFloat(rect.x)..OrderedFloat(rect.x + rect.width);

        let mut items = vec![];
        for (_, bucket) in self.0.range(range) {
            let range = OrderedFloat(rect.y)..OrderedFloat(rect.y + rect.height);

            let item_list = bucket
                .range(range)
                .map(|(_key, (series_id, item_id))| (series_id.clone(), item_id.clone()));

            items.extend(item_list);
        }

        items
    }
}

impl<SeriesId, ItemId> Default for Items<SeriesId, ItemId> {
    fn default() -> Self {
        Self(BTreeMapFloat::new())
    }
}