Skip to content

Commit 15b243a

Browse files
committed
group_by and nested coord now supports the key point hint
1 parent 1e8dda8 commit 15b243a

File tree

2 files changed

+54
-15
lines changed

2 files changed

+54
-15
lines changed

src/coord/group_by.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use super::numeric::RangedCoordusize;
21
use super::{AsRangedCoord, DiscreteRanged, KeyPointHint, Ranged, ValueFormatter};
32
use std::ops::Range;
43

@@ -64,11 +63,35 @@ impl<T: DiscreteRanged> Ranged for GroupBy<T> {
6463
}
6564
// TODO: See issue issue #88
6665
fn key_points<HintType: KeyPointHint>(&self, hint: HintType) -> Vec<T::ValueType> {
67-
let range = 0..(self.0.size() + self.1 - 1) / self.1;
68-
let logic_range: RangedCoordusize = range.into();
66+
let range = 0..(self.0.size() + self.1) / self.1;
67+
//let logic_range: RangedCoordusize = range.into();
6968

70-
logic_range
71-
.key_points(hint)
69+
let interval =
70+
((range.end - range.start + hint.bold_points() - 1) / hint.bold_points()).max(1);
71+
let count = (range.end - range.start) / interval;
72+
73+
let idx_iter = (0..hint.bold_points()).map(|x| x * interval);
74+
75+
if hint.weight().allow_light_points() && count < hint.bold_points() * 2 {
76+
let outter_ticks = idx_iter;
77+
let outter_tick_size = interval * self.1;
78+
let inner_ticks_per_group = hint.max_num_points() / outter_ticks.len();
79+
let inner_ticks =
80+
(outter_tick_size + inner_ticks_per_group - 1) / inner_ticks_per_group;
81+
let inner_ticks: Vec<_> = (0..(outter_tick_size / inner_ticks))
82+
.map(move |x| x * inner_ticks)
83+
.collect();
84+
let size = self.0.size();
85+
return outter_ticks
86+
.into_iter()
87+
.map(|base| inner_ticks.iter().map(move |&ofs| base * self.1 + ofs))
88+
.flatten()
89+
.take_while(|&idx| idx < size)
90+
.map(|x| self.0.from_index(x).unwrap())
91+
.collect();
92+
}
93+
94+
idx_iter
7295
.into_iter()
7396
.map(|x| self.0.from_index(x * self.1).unwrap())
7497
.collect()

src/coord/nested.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ impl<P: DiscreteRanged, S: Ranged> Ranged for NestedRange<P, S> {
8989
}
9090

9191
let s_left = limit.0 + bucket_size * idx as i32 + residual.min(idx as i32);
92-
let s_right =
93-
limit.0 + s_left + bucket_size + if (residual as usize) < idx { 1 } else { 0 };
92+
let s_right = s_left + bucket_size + if (residual as usize) < idx { 1 } else { 0 };
9493

9594
if let Some(secondary_value) = value.nested_value() {
9695
self.secondary[idx].map(secondary_value, (s_left, s_right))
@@ -100,14 +99,31 @@ impl<P: DiscreteRanged, S: Ranged> Ranged for NestedRange<P, S> {
10099
}
101100

102101
fn key_points<Hint: KeyPointHint>(&self, hint: Hint) -> Vec<Self::ValueType> {
103-
// TODO: Currently it's tricky to control the labels.
104-
// The problem is if we need to emit the nested keypoint in this vector?
105-
// Once we introduce the additional metadata on the key points, we probably have better way to handle this.
106-
self.primary
107-
.key_points(hint)
108-
.into_iter()
109-
.map(|x| NestedValue::Category(x))
110-
.collect()
102+
if !hint.weight().allow_light_points() || hint.max_num_points() < self.primary.size() * 2 {
103+
self.primary
104+
.key_points(hint)
105+
.into_iter()
106+
.map(|x| NestedValue::Category(x))
107+
.collect()
108+
} else {
109+
let secondary_size =
110+
(hint.max_num_points() - self.primary.size()) / self.primary.size();
111+
self.primary
112+
.values()
113+
.enumerate()
114+
.map(|(idx, val)| {
115+
std::iter::once(NestedValue::Category(val)).chain(
116+
self.secondary[idx]
117+
.key_points(secondary_size)
118+
.into_iter()
119+
.map(move |v| {
120+
NestedValue::Value(self.primary.from_index(idx).unwrap(), v)
121+
}),
122+
)
123+
})
124+
.flatten()
125+
.collect()
126+
}
111127
}
112128
}
113129

0 commit comments

Comments
 (0)