@@ -418,10 +418,72 @@ pub enum SpikeSnap {
418418 HoveredData ,
419419}
420420
421+ #[ derive( Serialize , Debug , Clone ) ]
422+ pub enum CategoryOrder {
423+ #[ serde( rename = "trace" ) ]
424+ Trace ,
425+ #[ serde( rename = "category ascending" ) ]
426+ CategoryAscending ,
427+ #[ serde( rename = "category descending" ) ]
428+ CategoryDescending ,
429+ #[ serde( rename = "array" ) ]
430+ Array ,
431+ #[ serde( rename = "total ascending" ) ]
432+ TotalAscending ,
433+ #[ serde( rename = "total descending" ) ]
434+ TotalDescending ,
435+ #[ serde( rename = "min ascending" ) ]
436+ MinAscending ,
437+ #[ serde( rename = "min descending" ) ]
438+ MinDescending ,
439+ #[ serde( rename = "max ascending" ) ]
440+ MaxAscending ,
441+ #[ serde( rename = "max descending" ) ]
442+ MaxDescending ,
443+ #[ serde( rename = "sum ascending" ) ]
444+ SumAscending ,
445+ #[ serde( rename = "sum descending" ) ]
446+ SumDescending ,
447+ #[ serde( rename = "mean ascending" ) ]
448+ MeanAscending ,
449+ #[ serde( rename = "mean descending" ) ]
450+ MeanDescending ,
451+ #[ serde( rename = "geometric mean ascending" ) ]
452+ GeometricMeanAscending ,
453+ #[ serde( rename = "geometric mean descending" ) ]
454+ GeometricMeanDescending ,
455+ #[ serde( rename = "median ascending" ) ]
456+ MedianAscending ,
457+ #[ serde( rename = "median descending" ) ]
458+ MedianDescending ,
459+ }
460+
421461#[ serde_with:: skip_serializing_none]
422462#[ derive( Serialize , Debug , Clone , FieldSetter ) ]
423463pub struct Axis {
424464 visible : Option < bool > ,
465+ /// Sets the order in which categories on this axis appear. Only has an
466+ /// effect if `category_order` is set to [`CategoryOrder::Array`].
467+ /// Used with `category_order`.
468+ #[ serde( rename = "categoryarray" ) ]
469+ category_array : Option < NumOrStringCollection > ,
470+ /// Specifies the ordering logic for the case of categorical variables.
471+ /// By default, plotly uses [`CategoryOrder::Trace`], which specifies
472+ /// the order that is present in the data supplied. Set `category_order` to
473+ /// [`CategoryOrder::CategoryAscending`] or
474+ /// [`CategoryOrder::CategoryDescending`] if order should be determined
475+ /// by the alphanumerical order of the category names. Set `category_order`
476+ /// to [`CategoryOrder::Array`] to derive the ordering from the attribute
477+ /// `category_array`. If a category is not found in the `category_array`
478+ /// array, the sorting behavior for that attribute will be identical to the
479+ /// [`CategoryOrder::Trace`] mode. The unspecified categories will follow
480+ /// the categories in `category_array`. Set `category_order` to
481+ /// [`CategoryOrder::TotalAscending`] or
482+ /// [`CategoryOrder::TotalDescending`] if order should be determined by the
483+ /// numerical order of the values. Similarly, the order can be determined
484+ /// by the min, max, sum, mean, geometric mean or median of all the values.
485+ #[ serde( rename = "categoryorder" ) ]
486+ category_order : Option < CategoryOrder > ,
425487 color : Option < Box < dyn Color > > ,
426488 title : Option < Title > ,
427489 #[ field_setter( skip) ]
@@ -2341,6 +2403,29 @@ mod tests {
23412403 assert_eq ! ( to_value( SpikeSnap :: HoveredData ) . unwrap( ) , json!( "hovered data" ) ) ;
23422404 }
23432405
2406+ #[ test]
2407+ #[ rustfmt:: skip]
2408+ fn test_serialize_category_order ( ) {
2409+ assert_eq ! ( to_value( CategoryOrder :: Trace ) . unwrap( ) , json!( "trace" ) ) ;
2410+ assert_eq ! ( to_value( CategoryOrder :: CategoryAscending ) . unwrap( ) , json!( "category ascending" ) ) ;
2411+ assert_eq ! ( to_value( CategoryOrder :: CategoryDescending ) . unwrap( ) , json!( "category descending" ) ) ;
2412+ assert_eq ! ( to_value( CategoryOrder :: Array ) . unwrap( ) , json!( "array" ) ) ;
2413+ assert_eq ! ( to_value( CategoryOrder :: TotalAscending ) . unwrap( ) , json!( "total ascending" ) ) ;
2414+ assert_eq ! ( to_value( CategoryOrder :: TotalDescending ) . unwrap( ) , json!( "total descending" ) ) ;
2415+ assert_eq ! ( to_value( CategoryOrder :: MinAscending ) . unwrap( ) , json!( "min ascending" ) ) ;
2416+ assert_eq ! ( to_value( CategoryOrder :: MinDescending ) . unwrap( ) , json!( "min descending" ) ) ;
2417+ assert_eq ! ( to_value( CategoryOrder :: MaxAscending ) . unwrap( ) , json!( "max ascending" ) ) ;
2418+ assert_eq ! ( to_value( CategoryOrder :: MaxDescending ) . unwrap( ) , json!( "max descending" ) ) ;
2419+ assert_eq ! ( to_value( CategoryOrder :: SumAscending ) . unwrap( ) , json!( "sum ascending" ) ) ;
2420+ assert_eq ! ( to_value( CategoryOrder :: SumDescending ) . unwrap( ) , json!( "sum descending" ) ) ;
2421+ assert_eq ! ( to_value( CategoryOrder :: MeanAscending ) . unwrap( ) , json!( "mean ascending" ) ) ;
2422+ assert_eq ! ( to_value( CategoryOrder :: MeanDescending ) . unwrap( ) , json!( "mean descending" ) ) ;
2423+ assert_eq ! ( to_value( CategoryOrder :: GeometricMeanAscending ) . unwrap( ) , json!( "geometric mean ascending" ) ) ;
2424+ assert_eq ! ( to_value( CategoryOrder :: GeometricMeanDescending ) . unwrap( ) , json!( "geometric mean descending" ) ) ;
2425+ assert_eq ! ( to_value( CategoryOrder :: MedianAscending ) . unwrap( ) , json!( "median ascending" ) ) ;
2426+ assert_eq ! ( to_value( CategoryOrder :: MedianDescending ) . unwrap( ) , json!( "median descending" ) ) ;
2427+ }
2428+
23442429 #[ test]
23452430 fn test_serialize_selector_button ( ) {
23462431 let selector_button = SelectorButton :: new ( )
@@ -2490,7 +2575,9 @@ mod tests {
24902575 . position ( 0.6 )
24912576 . range_slider ( RangeSlider :: new ( ) )
24922577 . range_selector ( RangeSelector :: new ( ) )
2493- . calendar ( Calendar :: Coptic ) ;
2578+ . calendar ( Calendar :: Coptic )
2579+ . category_order ( CategoryOrder :: Array )
2580+ . category_array ( vec ! [ "Category0" , "Category1" ] ) ;
24942581
24952582 let expected = json ! ( {
24962583 "visible" : false ,
@@ -2556,6 +2643,8 @@ mod tests {
25562643 "rangeslider" : { } ,
25572644 "rangeselector" : { } ,
25582645 "calendar" : "coptic" ,
2646+ "categoryorder" : "array" ,
2647+ "categoryarray" : [ "Category0" , "Category1" ]
25592648 } ) ;
25602649
25612650 assert_eq ! ( to_value( axis) . unwrap( ) , expected) ;
0 commit comments