PistonDevelopers / conrod

An easy-to-use, 2D GUI library written entirely in Rust.
Other
3.35k stars 297 forks source link

Graph / Chart widget #84

Open mitchmindtree opened 10 years ago

mitchmindtree commented 10 years ago

I was just reading a great article that had absolutely terrible graphs, which got me thinking about a Graph widget! I think this would be so useful for visualising application data and fairly easy to implement (I'm currently finishing of an XYPad which isn't too far removed).

Also it would be nice to be able to pass in something like:

// in graph.rs
pub enum Type {
    Line,
    Bar,
    Dot,
}

To specify the way it should be visualised.

bvssvni commented 10 years ago

This would be nice!

abonander commented 10 years ago

The three different types of graphs would take differently structured datasets. A bar graph should have a label for each datapoint, whereas a line graph would have a label for each line. A dot graph may have each point labeled or not.

Perhaps:

// Bar graphs are one-dimensional
type BarData<'a, D: Num> = &'a [(D, & 'a str)];
type LineData<'a, D: Num> = &'a [(Vec<(D, D), &'a str>)];
type Dot<D: Num> = (D, D);

pub enum Graph<'a, D> {
    Bar(BarData<'a, D>),
    Line(LineData<'a, D>),
    Dot(Vec<Dot<D>>),
    LabeledDot(Vec<(Dot<D>, &'a str)>,
}

That's not including colors for each bar/line/dot.

It might make for a less polluted API if there was a Graph widget, and then adapters for each data type that implemented a common trait, like Graphable.

A crude draft:


pub struct Graph<D: Num> {
    min_x: D,
    min_y: D,
    max_x: D,
    max_y: D,
}

impl Graph<D: Num> {
    fn draw_point(x: D, y: D, col: Color) {...}
    fn draw_label(x: D, y: D, val: &'a str, col: Color) {...}
    fn draw_line(x1: D, y1: D, x2: D, y2: D, col: Color) {...}
    fn draw_bar(pos: D, height: D, width: D, col: Color) {...} 
}

pub trait Graphable {
    fn draw(&self, graph: &Graph);
}

pub struct BarGraph<'a, D: Num> {
    data: &'a [(D, &'a str, Color)],
}

impl<'a> Graphable for BarGraph<'a> {...}

pub struct LineGraph<'a, D: Num> {
    data: &'a [(Vec<(D, D)>, &'a str, Color)],
}

impl<'a> Graphable for LineGraph<'a> {...}

pub enum DotGraph<'a, D: Num> {
    Labeled(&'a [(D, D, &'a str, Color)].
    Unlabled(&'a [(D, D, Color)],
}

impl<'a> Graphable for DotGraph<'a> {...}

The bonus of the adapter pattern is that the API user could write their own implementation of Graphable.

winding-lines commented 8 years ago

I am playing with some code around displaying Charts in an application. If time allows I would love to extract it and contribute.

The examples above use the word Graph, however I prefer to use Chart. The title itself has this as an option and my code may manipulate graphs in a CS sense.

winding-lines commented 8 years ago

I just ported my piston-chart https://github.com/winding-lines/piston-chart to the latest conrod. Any feedback is appreciated :)

barafael commented 6 years ago

What is the status on charts in conrod?

The guide shows Charts as planned but unimplemented and the piston-chart repo is gone.