Skip to content

Commit

Permalink
feat: support add theme function
Browse files Browse the repository at this point in the history
  • Loading branch information
vicanso committed Aug 2, 2024
1 parent bd9db14 commit 2fd6214
Show file tree
Hide file tree
Showing 14 changed files with 87 additions and 66 deletions.
12 changes: 7 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ rust-version = "1.65"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
charts-rs-derive = { path = "./charts-rs-derive", version = "0.2.1" }
ahash = "0.8.11"
arc-swap = "1.7.1"
charts-rs-derive = { path = "./charts-rs-derive", version = "0.2.2" }
fontdue = "0.9.2"
image = { version = "0.25.1", features = [
image = { version = "0.25.2", features = [
"webp",
"avif",
"jpeg",
Expand All @@ -29,9 +31,9 @@ resvg = { version = "0.42.0", default-features = false, features = [
"text",
"system-fonts",
], optional = true }
serde = { version = "1.0.203", features = ["derive"] }
serde_json = "1.0.117"
snafu = "0.8.3"
serde = { version = "1.0.204", features = ["derive"] }
serde_json = "1.0.122"
snafu = "0.8.4"
substring = "1.4.5"

[features]
Expand Down
2 changes: 1 addition & 1 deletion src/charts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,5 @@ pub use radar_chart::{RadarChart, RadarIndicator};
pub use scatter_chart::ScatterChart;
pub use table_chart::{TableCellStyle, TableChart};
pub use theme::Theme;
pub use theme::{get_or_init_default_theme, THEME_ANT, THEME_DARK, THEME_GRAFANA};
pub use theme::{add_theme, get_theme, THEME_ANT, THEME_DARK, THEME_GRAFANA};
pub use util::*;
5 changes: 3 additions & 2 deletions src/charts/bar_chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ use super::color::*;
use super::common::*;
use super::component::*;
use super::params::*;
use super::theme::{get_default_theme, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::theme::{get_default_theme_name, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::util::*;
use super::Canvas;
use crate::charts::measure_text_width_family;
use charts_rs_derive::Chart;
use serde::{Deserialize, Serialize};
use std::sync::Arc;

#[derive(Serialize, Deserialize, Clone, Debug, Default, Chart)]
pub struct BarChart {
Expand Down Expand Up @@ -127,7 +128,7 @@ impl BarChart {
}
/// Creates a bar chart with default theme.
pub fn new(series_list: Vec<Series>, x_axis_data: Vec<String>) -> BarChart {
BarChart::new_with_theme(series_list, x_axis_data, &get_default_theme())
BarChart::new_with_theme(series_list, x_axis_data, &get_default_theme_name())
}
/// Converts bar chart to svg.
pub fn svg(&self) -> canvas::Result<String> {
Expand Down
5 changes: 3 additions & 2 deletions src/charts/candlestick_chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ use super::color::*;
use super::common::*;
use super::component::*;
use super::params::*;
use super::theme::{get_default_theme, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::theme::{get_default_theme_name, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::util::*;
use super::Canvas;
use crate::charts::measure_text_width_family;
use charts_rs_derive::Chart;
use serde::{Deserialize, Serialize};
use std::sync::Arc;

#[derive(Serialize, Deserialize, Clone, Debug, Default, Chart)]
pub struct CandlestickChart {
Expand Down Expand Up @@ -155,7 +156,7 @@ impl CandlestickChart {
}
/// Creates a candlestick chart with default theme.
pub fn new(series_list: Vec<Series>, x_axis_data: Vec<String>) -> CandlestickChart {
CandlestickChart::new_with_theme(series_list, x_axis_data, &get_default_theme())
CandlestickChart::new_with_theme(series_list, x_axis_data, &get_default_theme_name())
}
/// Converts candlestick chart to svg.
pub fn svg(&self) -> canvas::Result<String> {
Expand Down
10 changes: 8 additions & 2 deletions src/charts/heatmap_chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ use super::common::*;
use super::component::*;
use super::font::measure_max_text_width_family;
use super::params::*;
use super::theme::{get_default_theme, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::theme::{get_default_theme_name, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::util::*;
use super::Canvas;
use crate::charts::measure_text_width_family;
use charts_rs_derive::Chart;
use std::sync::Arc;

#[derive(Clone, Debug, Default)]
pub struct HeatmapData {
Expand Down Expand Up @@ -228,7 +229,12 @@ impl HeatmapChart {
x_axis_data: Vec<String>,
y_axis_data: Vec<String>,
) -> HeatmapChart {
HeatmapChart::new_with_theme(series_data, x_axis_data, y_axis_data, &get_default_theme())
HeatmapChart::new_with_theme(
series_data,
x_axis_data,
y_axis_data,
&get_default_theme_name(),
)
}
/// Creates a heatmap chart with custom theme.
pub fn new_with_theme(
Expand Down
5 changes: 3 additions & 2 deletions src/charts/horizontal_bar_chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ use super::color::*;
use super::common::*;
use super::component::*;
use super::params::*;
use super::theme::{get_default_theme, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::theme::{get_default_theme_name, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::util::*;
use super::Canvas;
use crate::charts::measure_text_width_family;
use charts_rs_derive::Chart;
use std::sync::Arc;

#[derive(Clone, Debug, Default, Chart)]
pub struct HorizontalBarChart {
Expand Down Expand Up @@ -111,7 +112,7 @@ impl HorizontalBarChart {
}
/// Creates a horizontal bar with default theme.
pub fn new(series_list: Vec<Series>, x_axis_data: Vec<String>) -> HorizontalBarChart {
HorizontalBarChart::new_with_theme(series_list, x_axis_data, &get_default_theme())
HorizontalBarChart::new_with_theme(series_list, x_axis_data, &get_default_theme_name())
}
/// Converts horizontal bar chart to svg.
pub fn svg(&self) -> canvas::Result<String> {
Expand Down
5 changes: 3 additions & 2 deletions src/charts/line_chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ use super::color::*;
use super::common::*;
use super::component::*;
use super::params::*;
use super::theme::{get_default_theme, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::theme::{get_default_theme_name, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::util::*;
use super::Canvas;
use crate::charts::measure_text_width_family;
use charts_rs_derive::Chart;
use std::sync::Arc;

#[derive(Clone, Debug, Default, Chart)]
pub struct LineChart {
Expand Down Expand Up @@ -113,7 +114,7 @@ impl LineChart {
}
/// Creates a line chart with default theme.
pub fn new(series_list: Vec<Series>, x_axis_data: Vec<String>) -> LineChart {
LineChart::new_with_theme(series_list, x_axis_data, &get_default_theme())
LineChart::new_with_theme(series_list, x_axis_data, &get_default_theme_name())
}
fn render_mark_line(
&self,
Expand Down
8 changes: 5 additions & 3 deletions src/charts/params.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::sync::Arc;

use crate::{
MarkLine, MarkLineCategory, MarkPoint, MarkPointCategory, Position, Symbol, NIL_VALUE,
};
Expand Down Expand Up @@ -212,7 +214,7 @@ pub(crate) fn get_string_slice_from_value(
}

/// Gets y axis config value from serde json.
pub(crate) fn get_y_axis_config_from_value(t: &Theme, item: &serde_json::Value) -> YAxisConfig {
pub(crate) fn get_y_axis_config_from_value(t: Arc<Theme>, item: &serde_json::Value) -> YAxisConfig {
let mut y_config = YAxisConfig {
axis_font_size: t.y_axis_font_size,
axis_font_color: t.y_axis_font_color,
Expand Down Expand Up @@ -259,7 +261,7 @@ pub(crate) fn get_y_axis_config_from_value(t: &Theme, item: &serde_json::Value)

/// Gets y axis config value from serde json.
pub(crate) fn get_y_axis_configs_from_value(
t: &Theme,
t: Arc<Theme>,
value: &serde_json::Value,
key: &str,
) -> Option<Vec<YAxisConfig>> {
Expand All @@ -268,7 +270,7 @@ pub(crate) fn get_y_axis_configs_from_value(
return Some(
values
.iter()
.map(|item| get_y_axis_config_from_value(t, item))
.map(|item| get_y_axis_config_from_value(t.clone(), item))
.collect(),
);
}
Expand Down
5 changes: 3 additions & 2 deletions src/charts/pie_chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ use super::color::*;
use super::common::*;
use super::component::*;
use super::params::*;
use super::theme::{get_default_theme, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::theme::{get_default_theme_name, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::util::*;
use super::Canvas;
use crate::charts::measure_text_width_family;
use charts_rs_derive::Chart;
use std::sync::Arc;

#[derive(Clone, Debug, Default, Chart)]
pub struct PieChart {
Expand Down Expand Up @@ -124,7 +125,7 @@ impl PieChart {
}
/// Creates a pie chart with default theme.
pub fn new(series_list: Vec<Series>) -> PieChart {
PieChart::new_with_theme(series_list, &get_default_theme())
PieChart::new_with_theme(series_list, &get_default_theme_name())
}
/// Converts pie chart to svg.
pub fn svg(&self) -> canvas::Result<String> {
Expand Down
5 changes: 3 additions & 2 deletions src/charts/radar_chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ use super::color::*;
use super::common::*;
use super::component::*;
use super::params::*;
use super::theme::{get_default_theme, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::theme::{get_default_theme_name, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::util::*;
use super::Canvas;
use crate::charts::measure_text_width_family;
use charts_rs_derive::Chart;
use std::sync::Arc;

#[derive(Clone, Debug, Default)]
pub struct RadarIndicator {
Expand Down Expand Up @@ -142,7 +143,7 @@ impl RadarChart {
}
/// Creates a radar chart with default theme.
pub fn new(series_list: Vec<Series>, indicators: Vec<RadarIndicator>) -> RadarChart {
RadarChart::new_with_theme(series_list, indicators, &get_default_theme())
RadarChart::new_with_theme(series_list, indicators, &get_default_theme_name())
}
/// Converts bar chart to svg.
pub fn svg(&self) -> canvas::Result<String> {
Expand Down
5 changes: 3 additions & 2 deletions src/charts/scatter_chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ use super::color::*;
use super::common::*;
use super::component::*;
use super::params::*;
use super::theme::{get_default_theme, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::theme::{get_default_theme_name, get_theme, Theme, DEFAULT_Y_AXIS_WIDTH};
use super::util::*;
use super::Canvas;
use crate::charts::measure_text_width_family;
use charts_rs_derive::Chart;
use serde::{Deserialize, Serialize};
use std::sync::Arc;

#[derive(Serialize, Deserialize, Clone, Debug, Default, Chart)]
pub struct ScatterChart {
Expand Down Expand Up @@ -133,7 +134,7 @@ impl ScatterChart {
}
/// Creates a scatter chart with default theme.
pub fn new(series_list: Vec<Series>) -> ScatterChart {
ScatterChart::new_with_theme(series_list, &get_default_theme())
ScatterChart::new_with_theme(series_list, &get_default_theme_name())
}
/// Converts scatter chart to svg.
pub fn svg(&self) -> canvas::Result<String> {
Expand Down
7 changes: 4 additions & 3 deletions src/charts/table_chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ use super::common::*;
use super::component::*;
use super::font::text_wrap_fit;
use super::params::*;
use super::theme::{get_default_theme, get_theme, Theme};
use super::theme::{get_default_theme_name, get_theme, Theme};
use super::util::*;
use super::Canvas;
use crate::charts::measure_text_width_family;
use std::sync::Arc;

#[derive(Clone, Debug, Default)]
pub struct TableCellStyle {
Expand Down Expand Up @@ -242,7 +243,7 @@ impl TableChart {
table.fill_theme(get_theme(theme));
table
}
fn fill_theme(&mut self, t: &Theme) {
fn fill_theme(&mut self, t: Arc<Theme>) {
self.font_family.clone_from(&t.font_family);
self.width = t.width;
self.background_color = t.background_color;
Expand Down Expand Up @@ -271,7 +272,7 @@ impl TableChart {
}
/// Creates a table chart with default theme.
pub fn new(data: Vec<Vec<String>>) -> TableChart {
TableChart::new_with_theme(data, &get_default_theme())
TableChart::new_with_theme(data, &get_default_theme_name())
}
fn render_title(&self, c: Canvas) -> f32 {
let mut title_height = 0.0;
Expand Down
70 changes: 41 additions & 29 deletions src/charts/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use super::color::Color;
use super::common::Align;
use super::font::DEFAULT_FONT_FAMILY;
use super::util::Box;
use once_cell::sync::{Lazy, OnceCell};
use ahash::AHashMap;
use arc_swap::ArcSwap;
use once_cell::sync::Lazy;
use std::sync::Arc;

pub static DEFAULT_WIDTH: f32 = 600.0;
pub static DEFAULT_HEIGHT: f32 = 400.0;
Expand All @@ -26,21 +29,6 @@ pub static THEME_GRAFANA: &str = "grafana";

static LIGHT_THEME_NAME: &str = "light";

pub fn get_or_init_default_theme(theme: &str) -> String {
static DEFAULT_THEME: OnceCell<String> = OnceCell::new();
let value = DEFAULT_THEME.get_or_init(|| {
if theme.is_empty() {
return LIGHT_THEME_NAME.to_string();
}
theme.to_string()
});
value.to_owned()
}

pub fn get_default_theme() -> String {
get_or_init_default_theme(LIGHT_THEME_NAME)
}

#[derive(Clone, Debug, Default)]

pub struct Theme {
Expand Down Expand Up @@ -763,18 +751,42 @@ static SHADCN_THEME: Lazy<Theme> = Lazy::new(|| {
}
});

pub fn get_theme(theme: &str) -> &'static Theme {
match theme {
"dark" => &DARK_THEME,
"ant" => &ANT_THEME,
"grafana" => &GRAFANA_THEME,
"vintage" => &VINTAGE_THEME,
"shine" => &SHINE_THEME,
"walden" => &WALDEN_THEME,
"westeros" => &WESTEROS_THEME,
"chalk" => &CHALK_THEME,
"shadcn" => &SHADCN_THEME,
// echart
_ => &LIGHT_THEME,
type Themes = AHashMap<String, Arc<Theme>>;
static THEME_MAP: Lazy<ArcSwap<Themes>> = Lazy::new(|| {
let mut m = AHashMap::new();
m.insert("dark".to_string(), Arc::new(DARK_THEME.clone()));
m.insert("ant".to_string(), Arc::new(ANT_THEME.clone()));
m.insert("grafana".to_string(), Arc::new(GRAFANA_THEME.clone()));
m.insert("vintage".to_string(), Arc::new(VINTAGE_THEME.clone()));
m.insert("shine".to_string(), Arc::new(SHINE_THEME.clone()));
m.insert("walden".to_string(), Arc::new(WALDEN_THEME.clone()));
m.insert("westeros".to_string(), Arc::new(WESTEROS_THEME.clone()));
m.insert("chalk".to_string(), Arc::new(CHALK_THEME.clone()));
m.insert("shadcn".to_string(), Arc::new(SHADCN_THEME.clone()));
m.insert("light".to_string(), Arc::new(LIGHT_THEME.clone()));
ArcSwap::from_pointee(m)
});

/// Add theme of charts
pub fn add_theme(name: &str, data: Theme) {
let mut m: Themes = AHashMap::new();
for (name, data) in THEME_MAP.load().iter() {
m.insert(name.to_string(), data.clone());
}
m.insert(name.to_string(), Arc::new(data));
THEME_MAP.store(Arc::new(m))
}

/// Get the theme of charts
pub fn get_theme(theme: &str) -> Arc<Theme> {
if let Some(theme) = THEME_MAP.load().get(theme) {
theme.clone()
} else {
Arc::new(LIGHT_THEME.clone())
}
}

/// Get default theme
pub fn get_default_theme_name() -> String {
LIGHT_THEME_NAME.to_string()
}
9 changes: 0 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,6 @@
//! println!("{}", bar_chart.svg().unwrap());
//!```
//!
//! # Change default theme
//! The default theme will be initialized only once,
//! so it can be changed before any chart is created.
//! ```rust
//! use charts_rs::{get_or_init_default_theme, THEME_GRAFANA};
//! let theme = get_or_init_default_theme(THEME_GRAFANA);
//! assert_eq!(theme, THEME_GRAFANA);
//! // now the default theme of new chart is grafana
//! ```
//!
//! # Add more font
//! The fonts will be initialized once, it can be changed before used.
Expand Down

0 comments on commit 2fd6214

Please sign in to comment.