Skip to content

Commit

Permalink
Encapsulate the usage of the drawing backend
Browse files Browse the repository at this point in the history
  • Loading branch information
dorian.pinaud committed Feb 16, 2024
1 parent 0c94ea9 commit 3346802
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 40 deletions.
34 changes: 31 additions & 3 deletions backend-dioxus/src/dioxus_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,35 @@ use plotters_backend::{
use plotters_backend::text_anchor::{ HPos, VPos };
use std::io::Error;

use plotters::prelude::*;
use dioxus::prelude::*;
use dioxus::core::DynamicNode;
use plotters::coord::Shift;

use std::rc::Rc;
use std::fmt::Write as _;

pub struct DioxusBackend<'a> {
pub struct DioxusDrawingBackend<'a> {
pub svg_children: Vec<LazyNodes<'a, 'a>>,
size: (u32, u32),
}

pub struct DioxusBackend<'a> {
register: Rc<std::cell::RefCell<DioxusDrawingBackend<'a>>>,
pub drawing_area: DrawingArea<DioxusDrawingBackend<'a>, Shift>,
}

impl<'a> DioxusBackend<'a> {
pub fn new(size: (u32, u32)) -> Self {
let backend = Rc::new(std::cell::RefCell::new(DioxusDrawingBackend::new(size)));
Self {
register: backend.clone(),
drawing_area: DrawingArea::<DioxusDrawingBackend, Shift>::from(&backend),
}
}
}

impl<'a> DioxusDrawingBackend<'a> {
pub fn new(size: (u32, u32)) -> Self {
Self { svg_children: Vec::<LazyNodes<'a, 'a>>::new(), size: size }
}
Expand All @@ -36,7 +54,7 @@ fn make_svg_opacity(color: BackendColor) -> String {
return format!("{}", color.alpha);
}

impl<'a> IntoDynNode<'a> for DioxusBackend<'a> {
impl<'a> IntoDynNode<'a> for DioxusDrawingBackend<'a> {
fn into_vnode(self, cx: &'a ScopeState) -> DynamicNode<'a> {
rsx!(
svg {
Expand All @@ -52,7 +70,17 @@ impl<'a> IntoDynNode<'a> for DioxusBackend<'a> {
}
}

impl<'a> DrawingBackend for DioxusBackend<'a> {
impl<'a> IntoDynNode<'a> for DioxusBackend<'a> {
fn into_vnode(self, cx: &'a ScopeState) -> DynamicNode<'a> {
drop(self.drawing_area);
Rc::into_inner(self.register)
.expect("Only one strong reference should exist")
.into_inner()
.into_vnode(cx)
}
}

impl<'a> DrawingBackend for DioxusDrawingBackend<'a> {
type ErrorType = Error;

fn get_size(&self) -> (u32, u32) {
Expand Down
69 changes: 32 additions & 37 deletions demo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,50 @@
use dioxus::prelude::*;
use backend_dioxus::DioxusBackend;
use plotters::prelude::*;
use plotters::coord::Shift;
use std::rc::Rc;

fn main() {
dioxus_desktop::launch(App);
}

fn build_histogram<'a>(size: (u32, u32)) -> DioxusBackend<'a> {
let backend = Rc::new(std::cell::RefCell::new(DioxusBackend::new(size)));
{
let root_area = DrawingArea::<DioxusBackend, Shift>::from(&backend);
let _ = root_area.fill(&WHITE);
let mut chart = ChartBuilder::on(&root_area)
.x_label_area_size(35)
.y_label_area_size(40)
.margin(5)
.caption("Histogram Test", ("sans-serif", 50.0))
.build_cartesian_2d((0u32..10u32).into_segmented(), 0u32..10u32)
.expect("Expect a chart to be build");
let backend = DioxusBackend::new(size);
let _ = backend.drawing_area.fill(&WHITE);
let mut chart = ChartBuilder::on(&backend.drawing_area)
.x_label_area_size(35)
.y_label_area_size(40)
.margin(5)
.caption("Histogram Test", ("sans-serif", 50.0))
.build_cartesian_2d((0u32..10u32).into_segmented(), 0u32..10u32)
.expect("Expect a chart to be build");

let _ = chart
.configure_mesh()
.disable_x_mesh()
.bold_line_style(WHITE.mix(0.3))
.y_desc("Count")
.x_desc("Bucket")
.axis_desc_style(("sans-serif", 15))
.draw();
let _ = chart
.configure_mesh()
.disable_x_mesh()
.bold_line_style(WHITE.mix(0.3))
.y_desc("Count")
.x_desc("Bucket")
.axis_desc_style(("sans-serif", 15))
.draw();

let data = [0u32, 1, 1, 1, 4, 2, 5, 7, 8, 6, 4, 2, 1, 8, 3, 3, 3, 4, 4, 3, 3, 3];
let data = [0u32, 1, 1, 1, 4, 2, 5, 7, 8, 6, 4, 2, 1, 8, 3, 3, 3, 4, 4, 3, 3, 3];

let _ = chart.draw_series(
Histogram::vertical(&chart)
.style(RED.mix(0.5).filled())
.data(data.iter().map(|x: &u32| (*x, 1)))
);
let _ = chart.draw_series(
Histogram::vertical(&chart)
.style(RED.mix(0.5).filled())
.data(data.iter().map(|x: &u32| (*x, 1)))
);

// To avoid the IO failure being ignored silently, we manually call the present function
root_area
.present()
.expect(
"Unable to write result to file, please make sure 'plotters-doc-data' dir exists under current dir"
);
}
Rc::into_inner(backend).expect("Should be working").into_inner()
// To avoid the IO failure being ignored silently, we manually call the present function
backend.drawing_area
.present()
.expect(
"Unable to write result to file, please make sure 'plotters-doc-data' dir exists under current dir"
);
drop(chart);
backend
}

fn App<'a>(cx: Scope<'a>) -> Element {
let size = (400, 400);
let backend = build_histogram(size);
let backend = build_histogram((400, 400));
render!(backend)
}

0 comments on commit 3346802

Please sign in to comment.