#[derive(Clone, Debug)]
pub struct ScatterPlotData {
pub points: Vec<(f32, f32)>,
pub gate_ids: Option<Vec<u32>>,
pub z_values: Option<Vec<f32>>,
}
impl ScatterPlotData {
pub fn new(points: Vec<(f32, f32)>) -> Self {
Self {
points,
gate_ids: None,
z_values: None,
}
}
pub fn with_gates(
points: Vec<(f32, f32)>,
gate_ids: Vec<u32>,
) -> Result<Self, ScatterDataError> {
if gate_ids.len() != points.len() {
return Err(ScatterDataError {
points_len: points.len(),
metadata_len: gate_ids.len(),
field: "gate_ids",
});
}
Ok(Self {
points,
gate_ids: Some(gate_ids),
z_values: None,
})
}
pub fn with_z(points: Vec<(f32, f32)>, z_values: Vec<f32>) -> Result<Self, ScatterDataError> {
if z_values.len() != points.len() {
return Err(ScatterDataError {
points_len: points.len(),
metadata_len: z_values.len(),
field: "z_values",
});
}
Ok(Self {
points,
gate_ids: None,
z_values: Some(z_values),
})
}
pub fn xy(&self) -> &[(f32, f32)] {
&self.points
}
pub fn has_gates(&self) -> bool {
self.gate_ids.is_some()
}
pub fn has_z(&self) -> bool {
self.z_values.is_some()
}
}
impl From<Vec<(f32, f32)>> for ScatterPlotData {
fn from(points: Vec<(f32, f32)>) -> Self {
Self::new(points)
}
}
#[derive(Debug, Clone)]
pub struct ScatterDataError {
points_len: usize,
metadata_len: usize,
field: &'static str,
}
impl std::fmt::Display for ScatterDataError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"length mismatch: points has {} elements but {} has {}",
self.points_len, self.field, self.metadata_len
)
}
}
impl std::error::Error for ScatterDataError {}