@@ -81,39 +81,38 @@ where
8181 }
8282}
8383
84- /// For any discrete ranged coordiante, one possible transformation is instead of using the exact point to represent the value
85- /// We are now using an interval [value, value + 1) as the representation of that value.
86- /// A good example for this transformation is histogram's bucket, each bucket is actually represented by a interval instead of a single point.
87- /// In addition to that, all the labels should be appreas in the middle of the representing intervals.
88- ///
89- /// The `CentricDiscreteRange` decorator that makes key-point in the center of the value range
90- /// This is useful when we draw a histogram, since we want the axis value label
91- /// to be shown in the middle of the range rather than exactly the location where
92- /// the value mapped to.
93- pub struct CentricDiscreteRange < D : DiscreteRanged > ( D ) ;
84+ /// A `SegmentedCoord` is a decorator on any discrete coordinate specification.
85+ /// This decorator will convert the discrete coordiante in two ways:
86+ /// - Add an extra dummy element after all the values in origianl discrete coordinate
87+ /// - Logically each value `v` from original coordinate system is mapped into an segment `[v, v+1)` where `v+1` denotes the sucessor of the `v`
88+ /// - Introduce two types of values `SegmentValue::Exact(value)` which denotes the left end of value's segment and `SegmentValue::CenterOf(value)` which refers the center of the segment.
89+ /// This is used in histogram types, which uses a discrete coordinate as the buckets. The segmented coord always emits `CenterOf(value)` key points, thus it allows all the label and tick marks
90+ /// of the coordinate rendered in the middle of each segment.
91+ /// The coresponding trait [IntoSegmentedCoord](trait.IntoSegmentedCoord.html) is used to apply this decorator to coordinates.
92+ pub struct SegmentedCoord < D : DiscreteRanged > ( D ) ;
9493
95- impl < D : DiscreteRanged + Clone > Clone for CentricDiscreteRange < D > {
94+ impl < D : DiscreteRanged + Clone > Clone for SegmentedCoord < D > {
9695 fn clone ( & self ) -> Self {
97- CentricDiscreteRange ( self . 0 . clone ( ) )
96+ SegmentedCoord ( self . 0 . clone ( ) )
9897 }
9998}
10099
101- /// The trait for types that can decorated by `CentricDiscreteRange` decorator. See [struct CentricDiscreteRange ](struct.CentricDiscreteRange .html) for details .
102- pub trait IntoCentric : AsRangedCoord
100+ /// The trait for types that can decorated by [SegmentedCoord ](struct.SegmentedCoord .html) decorator .
101+ pub trait IntoSegmentedCoord : AsRangedCoord
103102where
104103 Self :: CoordDescType : DiscreteRanged ,
105104{
106- /// Convert current ranged value into a centric ranged value
107- fn into_centric ( self ) -> CentricDiscreteRange < Self :: CoordDescType > {
108- CentricDiscreteRange ( self . into ( ) )
105+ /// Convert current ranged value into a segmented coordinate
106+ fn into_segmented ( self ) -> SegmentedCoord < Self :: CoordDescType > {
107+ SegmentedCoord ( self . into ( ) )
109108 }
110109}
111110
112- impl < R : AsRangedCoord > IntoCentric for R where R :: CoordDescType : DiscreteRanged { }
111+ impl < R : AsRangedCoord > IntoSegmentedCoord for R where R :: CoordDescType : DiscreteRanged { }
113112
114- /// The value that used by the centric coordinate.
113+ /// The value that used by the segmented coordinate.
115114#[ derive( Clone , Debug ) ]
116- pub enum CentricValues < T > {
115+ pub enum SegmentValue < T > {
117116 /// Means we are referring the exact position of value `T`
118117 Exact ( T ) ,
119118 /// Means we are referring the center of position `T` and the successor of `T`
@@ -122,30 +121,30 @@ pub enum CentricValues<T> {
122121 Last ,
123122}
124123
125- impl < T , D : DiscreteRanged + Ranged < ValueType = T > > ValueFormatter < CentricValues < T > >
126- for CentricDiscreteRange < D >
124+ impl < T , D : DiscreteRanged + Ranged < ValueType = T > > ValueFormatter < SegmentValue < T > >
125+ for SegmentedCoord < D >
127126where
128127 D : ValueFormatter < T > ,
129128{
130- fn format ( value : & CentricValues < T > ) -> String {
129+ fn format ( value : & SegmentValue < T > ) -> String {
131130 match value {
132- CentricValues :: Exact ( ref value) => D :: format ( value) ,
133- CentricValues :: CenterOf ( ref value) => D :: format ( value) ,
131+ SegmentValue :: Exact ( ref value) => D :: format ( value) ,
132+ SegmentValue :: CenterOf ( ref value) => D :: format ( value) ,
134133 _ => "" . to_string ( ) ,
135134 }
136135 }
137136}
138137
139- impl < D : DiscreteRanged > Ranged for CentricDiscreteRange < D > {
138+ impl < D : DiscreteRanged > Ranged for SegmentedCoord < D > {
140139 type FormatOption = crate :: coord:: ranged:: NoDefaultFormatting ;
141- type ValueType = CentricValues < D :: ValueType > ;
140+ type ValueType = SegmentValue < D :: ValueType > ;
142141
143142 fn map ( & self , value : & Self :: ValueType , limit : ( i32 , i32 ) ) -> i32 {
144143 let margin = ( ( limit. 1 - limit. 0 ) as f32 / self . 0 . size ( ) as f32 ) . round ( ) as i32 ;
145144
146145 match value {
147- CentricValues :: Exact ( coord) => self . 0 . map ( coord, ( limit. 0 , limit. 1 - margin) ) ,
148- CentricValues :: CenterOf ( coord) => {
146+ SegmentValue :: Exact ( coord) => self . 0 . map ( coord, ( limit. 0 , limit. 1 - margin) ) ,
147+ SegmentValue :: CenterOf ( coord) => {
149148 let left = self . 0 . map ( coord, ( limit. 0 , limit. 1 - margin) ) ;
150149 if let Some ( idx) = self . 0 . index_of ( coord) {
151150 if idx + 1 < self . 0 . size ( ) {
@@ -158,51 +157,51 @@ impl<D: DiscreteRanged> Ranged for CentricDiscreteRange<D> {
158157 }
159158 left + margin / 2
160159 }
161- CentricValues :: Last => limit. 1 ,
160+ SegmentValue :: Last => limit. 1 ,
162161 }
163162 }
164163
165164 fn key_points ( & self , max_points : usize ) -> Vec < Self :: ValueType > {
166165 self . 0
167166 . key_points ( max_points)
168167 . into_iter ( )
169- . map ( CentricValues :: CenterOf )
168+ . map ( SegmentValue :: CenterOf )
170169 . collect ( )
171170 }
172171
173172 fn range ( & self ) -> Range < Self :: ValueType > {
174173 let range = self . 0 . range ( ) ;
175- CentricValues :: Exact ( range. start ) ..CentricValues :: Exact ( range. end )
174+ SegmentValue :: Exact ( range. start ) ..SegmentValue :: Exact ( range. end )
176175 }
177176}
178177
179- impl < D : DiscreteRanged > DiscreteRanged for CentricDiscreteRange < D > {
178+ impl < D : DiscreteRanged > DiscreteRanged for SegmentedCoord < D > {
180179 fn size ( & self ) -> usize {
181180 self . 0 . size ( ) + 1
182181 }
183182
184183 fn index_of ( & self , value : & Self :: ValueType ) -> Option < usize > {
185184 match value {
186- CentricValues :: Exact ( value) => self . 0 . index_of ( value) ,
187- CentricValues :: CenterOf ( value) => self . 0 . index_of ( value) ,
188- CentricValues :: Last => Some ( self . 0 . size ( ) ) ,
185+ SegmentValue :: Exact ( value) => self . 0 . index_of ( value) ,
186+ SegmentValue :: CenterOf ( value) => self . 0 . index_of ( value) ,
187+ SegmentValue :: Last => Some ( self . 0 . size ( ) ) ,
189188 }
190189 }
191190
192191 fn from_index ( & self , idx : usize ) -> Option < Self :: ValueType > {
193192 if idx < self . 0 . size ( ) {
194- self . 0 . from_index ( idx) . map ( |x| CentricValues :: Exact ( x) )
193+ self . 0 . from_index ( idx) . map ( |x| SegmentValue :: Exact ( x) )
195194 } else if idx == self . 0 . size ( ) {
196- Some ( CentricValues :: Last )
195+ Some ( SegmentValue :: Last )
197196 } else {
198197 None
199198 }
200199 }
201200}
202201
203- impl < T > From < T > for CentricValues < T > {
204- fn from ( this : T ) -> CentricValues < T > {
205- CentricValues :: Exact ( this)
202+ impl < T > From < T > for SegmentValue < T > {
203+ fn from ( this : T ) -> SegmentValue < T > {
204+ SegmentValue :: Exact ( this)
206205 }
207206}
208207
@@ -243,26 +242,26 @@ mod test {
243242
244243 #[ test]
245244 fn test_centric_coord ( ) {
246- let coord = ( 0 ..10 ) . into_centric ( ) ;
245+ let coord = ( 0 ..10 ) . into_segmented ( ) ;
247246
248247 assert_eq ! ( coord. size( ) , 12 ) ;
249248 for i in 0 ..=11 {
250249 match coord. from_index ( i as usize ) {
251- Some ( CentricValues :: Exact ( value) ) => assert_eq ! ( i, value) ,
252- Some ( CentricValues :: Last ) => assert_eq ! ( i, 11 ) ,
250+ Some ( SegmentValue :: Exact ( value) ) => assert_eq ! ( i, value) ,
251+ Some ( SegmentValue :: Last ) => assert_eq ! ( i, 11 ) ,
253252 _ => panic ! ( ) ,
254253 }
255254 }
256255
257256 for ( kps, idx) in coord. key_points ( 20 ) . into_iter ( ) . zip ( 0 ..) {
258257 match kps {
259- CentricValues :: CenterOf ( value) if value <= 10 => assert_eq ! ( value, idx) ,
258+ SegmentValue :: CenterOf ( value) if value <= 10 => assert_eq ! ( value, idx) ,
260259 _ => panic ! ( ) ,
261260 }
262261 }
263262
264- assert_eq ! ( coord. map( & CentricValues :: CenterOf ( 0 ) , ( 0 , 24 ) ) , 1 ) ;
265- assert_eq ! ( coord. map( & CentricValues :: Exact ( 0 ) , ( 0 , 24 ) ) , 0 ) ;
266- assert_eq ! ( coord. map( & CentricValues :: Exact ( 1 ) , ( 0 , 24 ) ) , 2 ) ;
263+ assert_eq ! ( coord. map( & SegmentValue :: CenterOf ( 0 ) , ( 0 , 24 ) ) , 1 ) ;
264+ assert_eq ! ( coord. map( & SegmentValue :: Exact ( 0 ) , ( 0 , 24 ) ) , 0 ) ;
265+ assert_eq ! ( coord. map( & SegmentValue :: Exact ( 1 ) , ( 0 , 24 ) ) , 2 ) ;
267266 }
268267}
0 commit comments