Skip to content

Instantly share code, notes, and snippets.

@mpiannucci
Created May 25, 2016 19:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mpiannucci/1f93de85ba7898b4185fba282c7f1b4d to your computer and use it in GitHub Desktop.
Save mpiannucci/1f93de85ba7898b4185fba282c7f1b4d to your computer and use it in GitHub Desktop.
Lib UI Rust LineChart
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