plotly_fork/traces/
table.rs1use plotly_derive::FieldSetter;
4use serde::Serialize;
5
6use crate::{
7 color::Color,
8 common::{Font, Line, PlotType, Visible},
9 Trace,
10};
11
12#[serde_with::skip_serializing_none]
13#[derive(Serialize, Clone, Debug, FieldSetter)]
14#[field_setter(box_self, kind = "trace")]
15pub struct Table<T, N>
16where
17 T: Serialize + Clone + 'static,
18 N: Serialize + Clone + 'static,
19{
20 #[field_setter(default = "PlotType::Table")]
21 r#type: PlotType,
22 name: Option<String>,
25 #[serde(rename = "columnorder")]
26 visible: Option<Visible>,
30 column_order: Option<Vec<usize>>,
34 #[serde(rename = "columnwidth")]
35 column_width: Option<f64>,
38 header: Option<Header<T>>,
42 cells: Option<Cells<N>>,
46}
47
48impl<T, N> Table<T, N>
49where
50 T: Serialize + Clone + Default + 'static,
51 N: Serialize + Clone + Default + 'static,
52{
53 pub fn new(header: Vec<T>, cells: Vec<Vec<N>>) -> Box<Self> {
54 Box::new(Table {
55 header: Header::new().values(header).into(),
56 cells: Cells::new().values(cells).into(),
57 ..Default::default()
58 })
59 }
60}
61
62impl<T, N> Trace for Table<T, N>
63where
64 T: Serialize + Clone + 'static,
65 N: Serialize + Clone + 'static,
66{
67 fn to_json(&self) -> String {
68 serde_json::to_string(self).unwrap()
69 }
70}
71
72#[serde_with::skip_serializing_none]
73#[derive(Serialize, Clone, Debug, FieldSetter)]
74pub struct Cells<N> {
75 values: Option<Vec<Vec<N>>>,
79 prefix: Option<String>,
81 suffix: Option<String>,
83 height: Option<f64>,
84 align: Option<String>,
85 line: Option<Line>,
86 fill: Option<Fill>,
89 font: Option<Font>,
90}
91
92impl<N> Cells<N>
93where
94 N: Serialize + Clone + Default + 'static,
95{
96 pub fn new() -> Self {
97 Default::default()
98 }
99}
100
101#[serde_with::skip_serializing_none]
102#[derive(Serialize, Clone, Debug, FieldSetter)]
103pub struct Header<T> {
104 values: Option<Vec<T>>,
108 prefix: Option<String>,
110 suffix: Option<String>,
112 height: Option<f64>,
113 align: Option<String>,
114 line: Option<Line>,
115 fill: Option<Fill>,
118 font: Option<Font>,
119}
120
121impl<T> Header<T>
122where
123 T: Serialize + Clone + Default + 'static,
124{
125 pub fn new() -> Self {
126 Default::default()
127 }
128}
129
130#[serde_with::skip_serializing_none]
131#[derive(Serialize, Clone, Debug, FieldSetter)]
132pub struct Fill {
133 color: Option<Box<dyn Color>>,
134}
135
136impl Fill {
137 pub fn new() -> Self {
138 Default::default()
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use serde_json::{json, to_value};
145
146 use super::*;
147
148 #[test]
149 fn test_serialize_table() {
150 let columns = vec![String::from("col1"), String::from("col2")];
151 let values = vec![vec![1, 2], vec![2, 3]];
152 let trace = Table::new(columns.clone(), values);
153
154 let expected = json!({
155 "type": "table",
156 "cells": {
157 "values": [[1, 2], [2, 3]],
158 },
159 "header": {
160 "values": ["col1", "col2"],
161 },
162 });
163
164 assert_eq!(to_value(trace).unwrap(), expected);
165 }
166}