colorimetry_plot/
lib.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2// Copyright (c) 2025, Harbers Bik LLC
3
4//! # Colorimetry Plot Library
5//!
6//! This colormimetry library provides functionality for generating SVG-based color plots,
7//! with both low-level and higher level API, based on top of the [Rust-SVG](https://crates.io/crates/svg) library.
8//! It includes generating basic 2D (x,y) charts composed of several layers, and more complex chromaticity diagrams with
9//! the spectral locus, and gamut fills.
10//! Here is an example of a XY Chromaticity Diagram for the DisplayP3 color space, using the CIE 2015 observer:
11//! ![XY Chromaticity Diagram](https://harbik.github.io/colorimetry/img/srgb_gamut.svg)
12//! Plots are built up in `Layers` using coordinate transformations between plot space and world coordinates.
13//!
14//! ## Modules
15//!
16//! - `chart`: Chart composition and rendering.
17//! - `layer`: Layered rendering support for compositing multiple plot elements.
18//! - `rendable`: Traits and types for objects that can be rendered to SVG.
19//! - `spectrum`: Spectrum data visualization and color representation.
20//! - `style_attr`: SVG styling attributes and utilities.
21//! - `svgdoc`: SVG document creation and manipulation.
22//! - `view`: Viewport and plot area management.
23//!
24//! ## Core Features
25//!
26//! - **Layered Architecture**: Build complex plots by compositing multiple layers
27//! - **Coordinate Transforms**: Seamless conversion between plot and world coordinate systems
28//! - **SVG Generation**: High-quality vector graphics output
29//! - **Configurable Styling**: Flexible styling system for plot elements
30//! - **Precision Control**: Configurable floating-point precision for clean output
31
32pub mod chart;
33pub mod layer;
34pub mod rendable;
35pub mod style_attr;
36pub mod svgdoc;
37pub mod view;
38
39pub use crate::style_attr::{class, id, style, StyleAttr};
40
41use std::sync::atomic::{AtomicUsize, Ordering};
42
43static COUNTER: AtomicUsize = AtomicUsize::new(0);
44static PRECISION: i32 = 1; // 1 decimal place
45
46/// Generates a new unique ID for SVG elements.
47/// The ID is prefixed with "id" and is incremented each time this function is called.
48/// This is useful for ensuring that each SVG element has a unique identifier.
49/// # Returns
50/// A unique ID string in the format "idN", where N is an incrementing number.
51pub fn new_id() -> String {
52    format!("id{}", COUNTER.fetch_add(1, Ordering::Relaxed))
53}
54
55/// Returns the last generated ID as a string.
56/// This can be useful for referencing the last created SVG element without generating a new ID.
57pub fn last_id() -> String {
58    COUNTER.load(Ordering::Relaxed).to_string()
59}
60
61/// Rounds a floating-point value to the specified precision.
62/// For example, round_to_precision(1.23456, 100.0) returns 1.23.
63///
64/// # Arguments
65/// * `value` - The value to round.
66/// * `precision` - The precision
67///
68/// # Returns
69/// The rounded value.
70pub fn round_to_precision(value: f64, precision: i32) -> f64 {
71    let multiplier = 10f64.powi(precision);
72    (value * multiplier).round() / multiplier
73}
74
75/// Rounds a floating-point value to the default precision.
76/// For example, round_to_default_precision(1.23456) returns 1.2.
77/// /// # Arguments
78/// * `value` - The value to round.
79///     
80/// # Returns
81/// The rounded value.
82pub fn round_to_default_precision(value: f64) -> f64 {
83    round_to_precision(value, PRECISION)
84}