use super::*;
pub(crate) fn collect_values(option: &ChartOption) -> Vec<Vec<f64>> {
option
.series
.iter()
.map(|series: &SeriesOption| {
series
.data
.iter()
.map(|value: &DataValue| animated_value(value).unwrap_or(0.0))
.collect()
})
.collect()
}
pub(crate) fn animated_value(value: &DataValue) -> Option<f64> {
match value {
DataValue::Number(number) => Some(*number),
DataValue::List(items) => items.get(1).and_then(|item: &DataValue| item.to_number()),
DataValue::Object(_) => value
.get(DATA_VALUE_KEY)
.and_then(|item: &DataValue| item.to_number()),
_ => None,
}
}
pub(crate) fn write_value(data: &mut DataValue, value: f64) {
match data {
DataValue::Number(number) => *number = value,
DataValue::List(items) => {
if let Some(slot) = items.get_mut(1) {
*slot = DataValue::Number(value);
}
}
DataValue::Object(_) => {
if let Some(slot) = data.get_mut(DATA_VALUE_KEY) {
*slot = DataValue::Number(value);
}
}
_ => {}
}
}
pub(crate) fn align_values(current: &[Vec<f64>], target: &[Vec<f64>]) -> Vec<Vec<f64>> {
let mut aligned: Vec<Vec<f64>> = Vec::with_capacity(target.len());
for (index, values) in target.iter().enumerate() {
let previous: Option<&Vec<f64>> = current.get(index);
let mut series: Vec<f64> = Vec::with_capacity(values.len());
for (position, _value) in values.iter().enumerate() {
match previous.and_then(|previous: &Vec<f64>| previous.get(position)) {
Some(previous) => series.push(*previous),
None => series.push(0.0),
}
}
aligned.push(series);
}
aligned
}
pub(crate) fn interpolate(from: &[Vec<f64>], to: &[Vec<f64>], progress: f64) -> Vec<Vec<f64>> {
let mut result: Vec<Vec<f64>> = Vec::with_capacity(to.len());
for (index, values) in to.iter().enumerate() {
let previous: Option<&Vec<f64>> = from.get(index);
let mut series: Vec<f64> = Vec::with_capacity(values.len());
for (position, value) in values.iter().enumerate() {
let start: f64 = previous
.and_then(|previous: &Vec<f64>| previous.get(position))
.copied()
.unwrap_or(0.0);
series.push(start + (value - start) * progress);
}
result.push(series);
}
result
}