dataviz\figure\figuretypes/scattergraph.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
use crate::figure::{
canvas::pixelcanvas::PixelCanvas, configuration::figureconfig::FigureConfig,
datasets::scattergraphdataset::ScatterGraphDataset, utilities::scatterdottype::ScatterDotType,
};
/// Represents a scatter graph, including title, axis labels, datasets, and configuration settings.
pub struct ScatterGraph {
/// Title of the scatter graph.
pub title: String,
/// Label for the X-axis.
pub x_label: String,
/// Label for the Y-axis.
pub y_label: String,
/// A collection of datasets to be visualized on the scatter graph.
pub datasets: Vec<ScatterGraphDataset>,
/// Configuration settings for rendering the graph (e.g., colors, fonts, grid).
pub config: FigureConfig,
}
impl ScatterGraph {
/// Creates a new `ScatterGraph` instance with the specified title, labels, and configuration.
///
/// # Parameters
/// - `title`: The title of the scatter graph.
/// - `x_label`: The label for the X-axis.
/// - `y_label`: The label for the Y-axis.
/// - `config`: The `FigureConfig` containing appearance and behavior settings.
///
/// # Returns
/// A new `ScatterGraph` instance with an empty dataset.
///
/// # Example
/// ```rust
/// use crate::figure::configuration::figureconfig::FigureConfig;
/// use crate::figure::scattergraph::ScatterGraph;
///
/// let config = FigureConfig::default();
/// let scatter_graph = ScatterGraph::new("Data Points", "X Axis", "Y Axis", config);
/// ```
pub fn new(title: &str, x_label: &str, y_label: &str, config: FigureConfig) -> Self {
Self {
title: title.to_string(),
x_label: x_label.to_string(),
y_label: y_label.to_string(),
datasets: Vec::new(),
config,
}
}
/// Adds a dataset to the scatter graph.
///
/// # Parameters
/// - `dataset`: The `ScatterGraphDataset` to be added to the graph.
///
/// # Example
/// ```rust
/// use crate::figure::datasets::scattergraphdataset::ScatterGraphDataset;
/// use crate::figure::utilities::scatterdottype::ScatterDotType;
///
/// let dataset = ScatterGraphDataset {
/// points: vec![(1.0, 2.0), (3.0, 4.0)],
/// color: [255, 0, 0],
/// label: "Dataset 1".to_string(),
/// dot_type: ScatterDotType::Circle(5),
/// };
/// scatter_graph.add_dataset(dataset);
/// ```
pub fn add_dataset(&mut self, dataset: ScatterGraphDataset) {
self.datasets.push(dataset);
}
/// Draws a single dot on the canvas using the specified dot type and color.
///
/// # Parameters
/// - `canvas`: The `PixelCanvas` to draw the dot on.
/// - `x`: The x-coordinate of the dot's center on the canvas.
/// - `y`: The y-coordinate of the dot's center on the canvas.
/// - `dot_type`: The shape and size of the dot (`ScatterDotType`).
/// - `color`: The RGB color of the dot.
///
/// # Details
/// Supports different dot types:
/// - `Circle`: A circular dot with a specified radius.
/// - `Square`: A square-shaped dot with a specified size.
/// - `Cross`: A cross-shaped dot with a specified thickness.
/// - `Triangle`: An upward-pointing triangular dot with a specified base width.
///
/// # Example
/// ```rust
/// scatter_graph.draw_dot(&mut canvas, 100, 100, ScatterDotType::Circle(5), [255, 0, 0]);
/// ```
pub fn draw_dot(
&self,
canvas: &mut PixelCanvas,
x: i32,
y: i32,
dot_type: ScatterDotType,
color: [u8; 3],
) {
match dot_type {
ScatterDotType::Circle(radius) => {
for dy in -(radius as i32)..=radius as i32 {
for dx in -(radius as i32)..=radius as i32 {
if dx * dx + dy * dy <= (radius * radius) as i32 {
canvas.draw_pixel((x + dx) as u32, (y + dy) as u32, color);
}
}
}
}
ScatterDotType::Square(size) => {
for dy in -(size as i32) / 2..=(size as i32) / 2 {
for dx in -(size as i32) / 2..=(size as i32) / 2 {
canvas.draw_pixel((x + dx) as u32, (y + dy) as u32, color);
}
}
}
ScatterDotType::Cross(thickness) => {
for i in -(thickness as i32)..=(thickness as i32) {
canvas.draw_pixel((x + i) as u32, y as u32, color); // Horizontal line
canvas.draw_pixel(x as u32, (y + i) as u32, color); // Vertical line
}
}
ScatterDotType::Triangle(base) => {
for dy in 0..=base as i32 {
let dx = (base as f64 * (1.0 - dy as f64 / base as f64)) as i32;
for x_offset in -dx..=dx {
canvas.draw_pixel((x + x_offset) as u32, (y - dy) as u32, color);
}
}
}
}
}
}