use std::io::{self, Write}; use std::path::PathBuf; use std::process::{self, Command, Stdio}; pub struct Gnuplot; const GNUPLOT_COMMAND: &str = "gnuplot"; const OUTPUT_FILE: &str = "data"; fn create_gnuplot_process(path: &str, chunk_size: u32, start: usize, end: usize) -> Result { Command::new(GNUPLOT_COMMAND) .args(&[ "-e", format!("states={}; start={}; end={}", chunk_size, start, end).as_ref(), "-c", path, ]) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn() } fn write_data_file(path: &str, data: &[[f64; 6]]) -> Result<(), io::Error> { let mut file = std::fs::File::create(OUTPUT_FILE)?; for line in data { file.write_fmt(format_args!( "{}; {}; {}; {}; {}; {}\n", line[0], line[1], line[2], line[3], line[4], line[5] ))?; } } impl Gnuplot { fn exec_plot( data: &[[f64; 6]], chunk_size: u32, start: usize, end: usize, script: &str, ) -> Result { let path: PathBuf = ["gnuplot/", script].iter().collect(); let path = path.to_str().unwrap_or(script); let process = create_gnuplot_process(path, chunk_size, start, end)?; write_data_file(path, data).map(|_| process) } } fn plot_with(data: &[[f64; 6]], chunk_size: u32, start: usize, end: usize, name: &str) { match Gnuplot::exec_plot(data, chunk_size, start, end, name) { Ok(mut process) => println!("opening gnuplot {:?}", process.wait()), Err(err) => println!("failed to start gnuplot: {}", err), } } impl super::Graph for Gnuplot { fn plot3d(data: &[[f64; 6]], chunk_size: u32) { let iterations = data.len() / chunk_size as usize; plot_with(data, chunk_size, 1, iterations, "anim3d.plt"); } fn animate3d(data: &[[f64; 6]], chunk_size: u32, start: usize, end: usize) { plot_with(data, chunk_size, start, end, "anim3d.plt") } fn plot2d(data: &[[f64; 6]], chunk_size: u32) { let iterations = data.len() / chunk_size as usize; plot_with(data, chunk_size, 1, iterations, "anim2d.plt") } fn animate2d(data: &[[f64; 6]], chunk_size: u32, start: usize, end: usize) { plot_with(data, chunk_size, start, end, "anim2d.plt") } }