Created
May 25, 2016 19:15
-
-
Save mpiannucci/1f93de85ba7898b4185fba282c7f1b4d to your computer and use it in GitHub Desktop.
Lib UI Rust LineChart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate ui; | |
use ui::{Area, AreaDrawParams, AreaHandler}; | |
use ui::draw::{Brush, FillMode, Path, SolidBrush, StrokeParams, LineCap, LineJoin}; | |
use ui::draw::text::{Layout, Font, FontDescriptor, Weight, Italic, Stretch}; | |
pub struct LineChart { | |
pub title: String, | |
pub x_axis_label: String, | |
pub y_axis_label: String, | |
pub values: Vec<i32>, | |
} | |
impl AreaHandler for LineChart { | |
fn draw(&mut self, area: &Area, area_draw_params: &AreaDrawParams) { | |
// AXIS LINES DRAWING | |
let axis_path = Path::new(FillMode::Winding); | |
let max_width = area_draw_params.area_width * 0.89; | |
let min_width = area_draw_params.area_width - max_width; | |
let max_height = area_draw_params.area_height * 0.92; | |
let min_height = area_draw_params.area_height - max_height; | |
let width_range = max_width - min_width; | |
let height_range = max_height - min_height; | |
axis_path.new_figure(min_width, min_height); | |
axis_path.line_to(min_width, max_height); | |
axis_path.line_to(max_width, max_height); | |
axis_path.end(); | |
let axis_brush = Brush::Solid(SolidBrush { | |
r: 0.0, | |
g: 0.0, | |
b: 0.0, | |
a: 255.0, | |
}); | |
let stroke_params = StrokeParams { | |
cap: LineCap::Round, | |
join: LineJoin:: Round, | |
thickness: 3.0, | |
miter_limit: 1.0, | |
dashes: Vec::new(), | |
dash_phase: 1.0, | |
}; | |
area_draw_params.context.stroke(&axis_path, &axis_brush, &stroke_params); | |
// TITLE DRAWING | |
let title_fd = FontDescriptor::new("serif", 12.0, Weight::Normal, Italic::Normal, Stretch::Normal); | |
let title_width = 200.0; | |
let title_text_layout = Layout::new(self.title.as_str(), &title_fd.load_closest_font(), title_width); | |
let title_location = min_width + (width_range * 0.5) - (title_width * 0.5); | |
area_draw_params.context.draw_text(title_location, min_height * 0.5, &title_text_layout); | |
// X AXIS DRAWING | |
let x_axis_fd = FontDescriptor::new("serif", 10.0, Weight::Normal, Italic::Normal, Stretch::Normal); | |
let x_axis_width = 200.0; | |
let x_axis_text_layout = Layout::new(self.x_axis_label.as_str(), &x_axis_fd.load_closest_font(), title_width); | |
let x_axis_location = min_width + (width_range * 0.5) - (title_width * 0.5); | |
area_draw_params.context.draw_text(x_axis_location, max_height + (min_height * 0.5), &x_axis_text_layout); | |
// Y AXIS DRAWING | |
let y_axis_fd = FontDescriptor::new("serif", 10.0, Weight::Normal, Italic::Normal, Stretch::Normal); | |
let y_axis_width = min_width * 0.7; | |
let y_axis_text_layout = Layout::new(self.y_axis_label.as_str(), &y_axis_fd.load_closest_font(), title_width); | |
let y_axis_location = min_width * 0.2; | |
area_draw_params.context.draw_text(y_axis_location, min_height + (height_range * 0.5), &y_axis_text_layout); | |
// DATA DRAWING | |
let data_path = Path::new(FillMode::Winding); | |
let value_count = self.values.len(); | |
let x_division = width_range / (value_count as f64 - 1.0); | |
let y_min = self.values.iter().min().unwrap() - 1; | |
let y_max = self.values.iter().max().unwrap() + 1; | |
let y_range = y_max - y_min; | |
data_path.new_figure(min_width, max_height - ((self.values[0] as f64 / (y_min as f64 + y_range as f64)) * height_range)); | |
for (raw_xval, raw_yval) in self.values.iter().enumerate() { | |
let xval = min_width + (x_division * raw_xval as f64); | |
let yval = max_height - ((*raw_yval as f64 / (y_min as f64 + y_range as f64)) * height_range); | |
data_path.line_to(xval, yval); | |
}; | |
data_path.end(); | |
let data_brush = Brush::Solid(SolidBrush { | |
r: 255.0, | |
g: 0.0, | |
b: 0.0, | |
a: 255.0, | |
}); | |
area_draw_params.context.stroke(&data_path, &data_brush, &stroke_params); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment