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
134
135
136
137
138
139
140
141
142
143
144
145
#![deny(warnings)]
#![deny(missing_docs)]

//! A real-time graphing experiment.
//!
//! rt-graph uses GTK (via the gtk-rs Rust bindings) for its UI and is
//! designed to be embedded into any gtk::Container in your
//! application.

#[macro_use]
extern crate derive_builder;

#[macro_use]
extern crate log;

use std::fmt::Debug;

mod graph;
pub use graph::{Config, ConfigBuilder, Graph, PointStyle, View, ViewMode};

mod graph_with_controls;
pub use graph_with_controls::GraphWithControls;

mod null_data_source;
pub use null_data_source::NullDataSource;

pub mod observable_value;

mod signal;
pub use signal::Signal;

mod store;
use store::Store;

mod test_data_generator;
pub use test_data_generator::TestDataGenerator;

/// Represents an error that could occur using the crate
#[derive(Debug)]
pub enum Error {
    /// An error described by a `String`.
    String(String),
}

/// Represents either a value or an error from the crate.
pub type Result<T> = std::result::Result<T, Error>;

/// A point in time when a data point was emitted.
pub type Time = u32;

/// The value of a data point
pub type Value = u16;

/// A data point on a graph.
#[derive(Debug, Clone)]
pub struct Point {
    /// The time when this data point was emitted.
    pub t: Time,

    /// The values this point holds.
    pub vs: Vec<Value>,
}

impl Point {
    /// Return the time when this data point was emitted.
    pub fn t(&self) -> Time {
        self.t
    }

    /// Return the values that this point holds.
    pub fn vals(&self) -> &[Value] {
        &self.vs
    }
}

/// A color in RGB format.
///
/// The tuple values are the red, green, and blue components of the
/// color respectively.
#[derive(Clone, Copy)]
pub struct Color(pub u8, pub u8, pub u8);

impl Color {
    /// Create a color from red, green, and blue components.
    pub fn from_rgb(r: u8, g: u8, b: u8) -> Color {
        Color(r, g, b)
    }

    /// Return the red component of the `Color`.
    pub fn r(&self) -> u8 {
        self.0
    }

    /// Return the green component of the `Color`.
    pub fn g(&self) -> u8 {
        self.1
    }

    /// Return the blue component of the `Color`.
    pub fn b(&self) -> u8 {
        self.2
    }
}

#[cfg(test)]
mod color_tests {
    use super::Color;

    #[test]
    fn values() {
        let c = Color::from_rgb(10, 20, 30);
        assert_eq!(c.r(), 10);
        assert_eq!(c.g(), 20);
        assert_eq!(c.b(), 30);
    }
}

/// Implement this to get your own data into a `Graph`.
pub trait DataSource: Debug + Send {
    /// Return whatever points you have available when this method is called.
    ///
    /// Each point must have a `t` field greater than the previous point.
    ///
    /// Each point must have a `vs` field with length equal to the
    /// value returned by `get_num_values`.
    ///
    /// This is currently called once a frame.
    fn get_data(&mut self) -> Result<Vec<Point>>;

    /// The number of values that each Point will have.
    fn get_num_values(&self) -> Result<usize>;

    /// Return the colors you want to use to display each value of the graph.
    ///
    /// Some sample colors are returned by default.
    ///
    /// If you don't supply enough colors for the number of values
    /// returned, these colors will be repeated.
    fn get_colors(&self) -> Result<Vec<Color>> {
        Ok(vec![Color(255u8, 0u8,   0u8),
                Color(0u8,   255u8, 0u8),
                Color(0u8,   0u8,   255u8)
        ])
    }
}