Thanks to visit codestin.com
Credit goes to docs.rs

arrayfire/graphics/
mod.rs

1use super::core::{
2    af_array, af_window, AfError, Array, ColorMap, HasAfEnum, MarkerType, HANDLE_ERROR,
3};
4
5use libc::{c_char, c_double, c_float, c_int, c_uint};
6use std::ffi::CString;
7use std::ptr;
8
9/// Represents a sub-view of Window
10///
11/// This struct is used in conjunction with [Window](./struct.Window.html) in multiview
12/// mode to render multiple targets to sub-regions of a given window.
13///
14#[repr(C)]
15struct af_cell {
16    pub row: c_int,
17    pub col: c_int,
18    pub title: *const c_char,
19    pub cmap: c_uint,
20}
21
22extern "C" {
23    fn af_create_window(out: *mut af_window, w: c_int, h: c_int, title: *const c_char) -> c_int;
24
25    fn af_set_position(wnd: af_window, x: c_uint, y: c_uint) -> c_int;
26    fn af_set_title(wnd: af_window, title: *const c_char) -> c_int;
27    fn af_set_size(wnd: af_window, w: c_uint, h: c_uint) -> c_int;
28    fn af_set_visibility(wnd: af_window, is_visible: bool) -> c_int;
29
30    fn af_set_axes_titles(
31        wnd: af_window,
32        xtitle: *const c_char,
33        ytitle: *const c_char,
34        ztitle: *const c_char,
35        props: *const af_cell,
36    ) -> c_int;
37    fn af_set_axes_label_format(
38        wnd: af_window,
39        xformat: *const c_char,
40        yformat: *const c_char,
41        zformat: *const c_char,
42        props: *const af_cell,
43    ) -> c_int;
44    fn af_set_axes_limits_compute(
45        wnd: af_window,
46        x: af_array,
47        y: af_array,
48        z: af_array,
49        exact: bool,
50        props: *const af_cell,
51    ) -> c_int;
52    fn af_set_axes_limits_2d(
53        wnd: af_window,
54        xmin: c_float,
55        xmax: c_float,
56        ymin: c_float,
57        ymax: c_float,
58        exact: bool,
59        props: *const af_cell,
60    ) -> c_int;
61    fn af_set_axes_limits_3d(
62        wnd: af_window,
63        xmin: c_float,
64        xmax: c_float,
65        ymin: c_float,
66        ymax: c_float,
67        zmin: c_float,
68        zmax: c_float,
69        exact: bool,
70        props: *const af_cell,
71    ) -> c_int;
72
73    fn af_draw_image(wnd: af_window, arr: af_array, props: *const af_cell) -> c_int;
74    fn af_draw_hist(
75        wnd: af_window,
76        x: af_array,
77        minval: c_double,
78        maxval: c_double,
79        props: *const af_cell,
80    ) -> c_int;
81    fn af_draw_surface(
82        wnd: af_window,
83        xvals: af_array,
84        yvals: af_array,
85        S: af_array,
86        props: *const af_cell,
87    ) -> c_int;
88
89    fn af_draw_plot_2d(wnd: af_window, x: af_array, y: af_array, props: *const af_cell) -> c_int;
90    fn af_draw_plot_3d(
91        wnd: af_window,
92        x: af_array,
93        y: af_array,
94        z: af_array,
95        props: *const af_cell,
96    ) -> c_int;
97    fn af_draw_plot_nd(wnd: af_window, P: af_array, props: *const af_cell) -> c_int;
98
99    fn af_draw_scatter_2d(
100        wnd: af_window,
101        x: af_array,
102        y: af_array,
103        marker: c_uint,
104        props: *const af_cell,
105    ) -> c_int;
106    fn af_draw_scatter_3d(
107        wnd: af_window,
108        x: af_array,
109        y: af_array,
110        z: af_array,
111        marker: c_uint,
112        props: *const af_cell,
113    ) -> c_int;
114    fn af_draw_scatter_nd(
115        wnd: af_window,
116        P: af_array,
117        marker: c_uint,
118        props: *const af_cell,
119    ) -> c_int;
120
121    fn af_draw_vector_field_2d(
122        wnd: af_window,
123        xpnts: af_array,
124        ypnts: af_array,
125        xdirs: af_array,
126        ydirs: af_array,
127        props: *const af_cell,
128    ) -> c_int;
129    fn af_draw_vector_field_3d(
130        wnd: af_window,
131        xpnts: af_array,
132        ypnts: af_array,
133        xdirs: af_array,
134        ydirs: af_array,
135        zdirs: af_array,
136        zdirs: af_array,
137        props: *const af_cell,
138    ) -> c_int;
139    fn af_draw_vector_field_nd(
140        wnd: af_window,
141        pnts: af_array,
142        dirs: af_array,
143        props: *const af_cell,
144    ) -> c_int;
145
146    fn af_grid(wnd: af_window, rows: c_int, cols: c_int) -> c_int;
147    fn af_show(wnd: af_window) -> c_int;
148    fn af_is_window_closed(out: *mut bool, wnd: af_window) -> c_int;
149    fn af_destroy_window(wnd: af_window) -> c_int;
150}
151
152/// Used to render [Array](./struct.Array.html) objects
153///
154/// The renderings can be either plots, histograms or simply just image displays.
155/// A single window can also display multiple of the above renderings at the same time, which
156/// is known as multiview mode. An example of that is given below.
157///
158/// # Examples
159///
160/// ```rust,no_run
161/// use arrayfire::{histogram, load_image, Window};
162/// let mut wnd = Window::new(1280, 720, String::from("Image Histogram"));
163/// let img = load_image::<f32>("Path to image".to_string(), true/*If color image, 'false' otherwise*/);
164/// let hst = histogram(&img, 256, 0 as f64, 255 as f64);
165///
166/// loop {
167///     wnd.grid(2, 1);
168///
169///     wnd.set_view(0, 0);
170///     wnd.draw_image(&img, Some("Input Image".to_string()));
171///
172///     wnd.set_view(1, 0);
173///     wnd.draw_hist(&hst, 0.0, 255.0, Some("Input Image Histogram".to_string()));
174///
175///     wnd.show();
176///
177///     if wnd.is_closed() == true { break; }
178/// }
179/// ```
180#[derive(Clone)]
181pub struct Window {
182    handle: af_window,
183    row: i32,
184    col: i32,
185    cmap: ColorMap,
186}
187
188impl Drop for Window {
189    fn drop(&mut self) {
190        unsafe {
191            let err_val = af_destroy_window(self.handle);
192            match err_val {
193                0 => (),
194                _ => panic!(
195                    "Window object destruction failed with error code: {}",
196                    err_val
197                ),
198            }
199        }
200    }
201}
202
203impl Window {
204    /// Creates new Window object
205    ///
206    /// # Parameters
207    ///
208    /// - `width` is width of the window
209    /// - `height` is the height of window
210    /// - `title` is the string displayed on window title bar
211    ///
212    /// # Return Values
213    ///
214    /// Window Object
215    #[allow(clippy::match_wild_err_arm)]
216    pub fn new(width: i32, height: i32, title: String) -> Self {
217        unsafe {
218            let cstr_ret = CString::new(title);
219            match cstr_ret {
220                Ok(cstr) => {
221                    let mut temp: af_window = std::ptr::null_mut();
222                    let err_val =
223                        af_create_window(&mut temp as *mut af_window, width, height, cstr.as_ptr());
224                    HANDLE_ERROR(AfError::from(err_val));
225                    Window {
226                        handle: temp,
227                        row: -1,
228                        col: -1,
229                        cmap: ColorMap::DEFAULT,
230                    }
231                }
232                Err(_) => {
233                    panic!("String creation failed while prepping params for window creation.")
234                }
235            }
236        }
237    }
238
239    /// Set window starting position on the screen
240    ///
241    /// # Parameters
242    ///
243    /// - `x` is the horiontal coordinate where window is to be placed
244    /// - `y` is the vertical coordinate where window is to be placed
245    pub fn set_position(&self, x: u32, y: u32) {
246        unsafe {
247            let err_val = af_set_position(self.handle, x, y);
248            HANDLE_ERROR(AfError::from(err_val));
249        }
250    }
251
252    /// Set window title
253    ///
254    /// # Parameters
255    ///
256    /// - `title` is the string to be displayed on window title bar
257    pub fn set_title(&self, title: String) {
258        unsafe {
259            let cstr_ret = CString::new(title);
260            match cstr_ret {
261                Ok(cstr) => {
262                    let err_val = af_set_title(self.handle, cstr.as_ptr());
263                    HANDLE_ERROR(AfError::from(err_val));
264                }
265                Err(_) => HANDLE_ERROR(AfError::ERR_INTERNAL),
266            }
267        }
268    }
269
270    /// Set window visibility
271    ///
272    /// # Parameters
273    ///
274    /// - `is_visible` is a boolean indicating whether window is to be hidden or brought into focus
275    ///
276    /// # Return Values
277    ///
278    /// None
279    pub fn set_visibility(&self, is_visible: bool) {
280        unsafe {
281            let err_val = af_set_visibility(self.handle, is_visible);
282            HANDLE_ERROR(AfError::from(err_val));
283        }
284    }
285
286    /// Set window size
287    ///
288    /// # Parameters
289    ///
290    /// - `w` is the target width of window
291    /// - `h` is the target height of window
292    pub fn set_size(&self, w: u32, h: u32) {
293        unsafe {
294            let err_val = af_set_size(self.handle, w, h);
295            HANDLE_ERROR(AfError::from(err_val));
296        }
297    }
298
299    /// Set color map to be used for rendering image, it can take one of the values of enum
300    /// [ColorMap](./enum.ColorMap.html)
301    pub fn set_colormap(&mut self, cmap: ColorMap) {
302        self.cmap = cmap;
303    }
304
305    /// Returns true if the window close is triggered by the user
306    pub fn is_closed(&self) -> bool {
307        unsafe {
308            let mut temp: bool = true;
309            let err_val = af_is_window_closed(&mut temp as *mut bool, self.handle);
310            HANDLE_ERROR(AfError::from(err_val));
311            temp
312        }
313    }
314
315    /// Setup display layout in multiview mode
316    ///
317    /// # Parameters
318    ///
319    /// - `rows` is the number of rows into which whole window is split into in multiple view mode
320    /// - `cols` is the number of cols into which whole window is split into in multiple view mode
321    pub fn grid(&self, rows: i32, cols: i32) {
322        unsafe {
323            let err_val = af_grid(self.handle, rows, cols);
324            HANDLE_ERROR(AfError::from(err_val));
325        }
326    }
327
328    /// Used in multiview mode to swap back buffer with front buffer to show the recently rendered
329    /// frame
330    pub fn show(&mut self) {
331        unsafe {
332            let err_val = af_show(self.handle);
333            HANDLE_ERROR(AfError::from(err_val));
334            self.row = -1;
335            self.col = -1;
336        }
337    }
338
339    /// Set the current sub-region to render
340    ///
341    /// This function is only to be used into multiview mode
342    ///
343    /// # Parameters
344    ///
345    /// - `r` is the target row id
346    /// - `c` is the target row id
347    pub fn set_view(&mut self, r: i32, c: i32) {
348        self.row = r;
349        self.col = c;
350    }
351
352    /// Set chart axes titles
353    ///
354    /// # Parameters
355    ///
356    /// - `xlabel` is x axis title
357    /// - `ylabel` is y axis title
358    /// - `zlabel` is z axis title
359    pub fn set_axes_titles(&mut self, xlabel: String, ylabel: String, zlabel: String) {
360        let cprops = af_cell {
361            row: self.row,
362            col: self.col,
363            title: ptr::null(),
364            cmap: self.cmap as u32,
365        };
366        let xstr = CString::new(xlabel).unwrap();
367        let ystr = CString::new(ylabel).unwrap();
368        let zstr = CString::new(zlabel).unwrap();
369        unsafe {
370            let err_val = af_set_axes_titles(
371                self.handle,
372                xstr.as_ptr(),
373                ystr.as_ptr(),
374                zstr.as_ptr(),
375                &cprops as *const af_cell,
376            );
377            HANDLE_ERROR(AfError::from(err_val));
378        }
379    }
380
381    /// Set chart axes labels format
382    ///
383    /// # Parameters
384    ///
385    /// - `xlabel_format` is x axis label format. format specific is identical to C's printf format
386    /// - `ylabel_format` is y axis label format. format specific is identical to C's printf format
387    /// - `zlabel_format` is z axis label format. format specific is identical to C's printf format
388    pub fn set_axes_label_format(
389        &mut self,
390        xlabel_format: String,
391        ylabel_format: String,
392        zlabel_format: String,
393    ) {
394        let cprops = af_cell {
395            row: self.row,
396            col: self.col,
397            title: ptr::null(),
398            cmap: self.cmap as u32,
399        };
400        let xstr = CString::new(xlabel_format).unwrap();
401        let ystr = CString::new(ylabel_format).unwrap();
402        let zstr = CString::new(zlabel_format).unwrap();
403        unsafe {
404            let err_val = af_set_axes_label_format(
405                self.handle,
406                xstr.as_ptr(),
407                ystr.as_ptr(),
408                zstr.as_ptr(),
409                &cprops as *const af_cell,
410            );
411            HANDLE_ERROR(AfError::from(err_val));
412        }
413    }
414
415    /// Set chart axes labels formats
416    ///
417    /// Axes labels use printf style format specifiers. Default specifier for the data displayed
418    /// as labels is %4.1f. This function lets the user change this label formatting to whichever
419    /// format that fits their data range and precision.
420    ///
421    /// # Parameters
422    ///
423    /// - `xlabel` is printf style format specifier for x axis
424    /// - `ylabel` is printf style format specifier for y axis
425    /// - `zlabel` is printf style format specifier for z axis
426    pub fn set_axes_label_formats(&mut self, xformat: String, yformat: String, zformat: String) {
427        let cprops = af_cell {
428            row: self.row,
429            col: self.col,
430            title: ptr::null(),
431            cmap: self.cmap as u32,
432        };
433        let xstr = CString::new(xformat).unwrap();
434        let ystr = CString::new(yformat).unwrap();
435        let zstr = CString::new(zformat).unwrap();
436        unsafe {
437            let err_val = af_set_axes_titles(
438                self.handle,
439                xstr.as_ptr(),
440                ystr.as_ptr(),
441                zstr.as_ptr(),
442                &cprops as *const af_cell,
443            );
444            HANDLE_ERROR(AfError::from(err_val));
445        }
446    }
447
448    /// Set chart axes limits by computing limits from data
449    ///
450    /// In multiple view (grid) mode, setting limits will effect the chart that is currently
451    /// active via set_view call
452    ///
453    /// # Parameters
454    ///
455    /// - `xrange` is set of all x values to compute min/max for x axis
456    /// - `yrange` is set of all y values to compute min/max for y axis
457    /// - `zrange` is set of all z values to compute min/max for z axis. If None is passed to
458    ///    this paramter, 2d chart limits are set.
459    /// - `exact` indicates if the exact min/max values from `xrange`, `yrange` and `zrange`
460    ///    are to extracted. If exact is false then the most significant digit is rounded up
461    ///    to next power of 2 and the magnitude remains the same.
462    pub fn set_axes_limits_compute<T>(
463        &mut self,
464        xrange: &Array<T>,
465        yrange: &Array<T>,
466        zrange: Option<&Array<T>>,
467        exact: bool,
468    ) where
469        T: HasAfEnum,
470    {
471        let cprops = af_cell {
472            row: self.row,
473            col: self.col,
474            title: ptr::null(),
475            cmap: self.cmap as u32,
476        };
477        unsafe {
478            let err_val = af_set_axes_limits_compute(
479                self.handle,
480                xrange.get(),
481                yrange.get(),
482                match zrange {
483                    Some(z) => z.get(),
484                    None => std::ptr::null_mut(),
485                },
486                exact,
487                &cprops as *const af_cell,
488            );
489            HANDLE_ERROR(AfError::from(err_val));
490        }
491    }
492
493    /// Set 2d chart axes limits
494    ///
495    /// In multiple view (grid) mode, setting limits will effect the chart that is currently
496    /// active via set_view call
497    ///
498    /// # Parameters
499    ///
500    /// - `xmin` is minimum value on x axis
501    /// - `xmax` is maximum value on x axis
502    /// - `ymin` is minimum value on y axis
503    /// - `ymax` is maximum value on y axis
504    /// - `exact` indicates if the exact min/max values from `xrange`, `yrange` and `zrange`
505    ///    are to extracted. If exact is false then the most significant digit is rounded up
506    ///    to next power of 2 and the magnitude remains the same.
507    pub fn set_axes_limits_2d(&mut self, xmin: f32, xmax: f32, ymin: f32, ymax: f32, exact: bool) {
508        let cprops = af_cell {
509            row: self.row,
510            col: self.col,
511            title: ptr::null(),
512            cmap: self.cmap as u32,
513        };
514        unsafe {
515            let err_val = af_set_axes_limits_2d(
516                self.handle,
517                xmin,
518                xmax,
519                ymin,
520                ymax,
521                exact,
522                &cprops as *const af_cell,
523            );
524            HANDLE_ERROR(AfError::from(err_val));
525        }
526    }
527
528    /// Set 3d chart axes limits
529    ///
530    /// In multiple view (grid) mode, setting limits will effect the chart that is currently
531    /// active via set_view call
532    ///
533    /// # Parameters
534    ///
535    /// - `xmin` is minimum value on x axis
536    /// - `xmax` is maximum value on x axis
537    /// - `ymin` is minimum value on y axis
538    /// - `ymax` is maximum value on y axis
539    /// - `zmin` is minimum value on z axis
540    /// - `zmax` is maximum value on z axis
541    /// - `exact` indicates if the exact min/max values from `xrange`, `yrange` and `zrange`
542    ///    are to extracted. If exact is false then the most significant digit is rounded up
543    ///    to next power of 2 and the magnitude remains the same.
544    #[allow(clippy::too_many_arguments)]
545    pub fn set_axes_limits_3d(
546        &mut self,
547        xmin: f32,
548        xmax: f32,
549        ymin: f32,
550        ymax: f32,
551        zmin: f32,
552        zmax: f32,
553        exact: bool,
554    ) {
555        let cprops = af_cell {
556            row: self.row,
557            col: self.col,
558            title: ptr::null(),
559            cmap: self.cmap as u32,
560        };
561        unsafe {
562            let err_val = af_set_axes_limits_3d(
563                self.handle,
564                xmin,
565                xmax,
566                ymin,
567                ymax,
568                zmin,
569                zmax,
570                exact,
571                &cprops as *const af_cell,
572            );
573            HANDLE_ERROR(AfError::from(err_val));
574        }
575    }
576
577    /// Render given Array as an image
578    ///
579    /// # Parameters
580    ///
581    /// - `input` image
582    /// - `title` parameter has effect only in multiview mode, where this string
583    ///    is displayed as the respective cell/view title.
584    pub fn draw_image<T>(&self, input: &Array<T>, title: Option<String>)
585    where
586        T: HasAfEnum,
587    {
588        let tstr = match title {
589            Some(s) => s,
590            None => format!("Cell({},{}))", self.col, self.row),
591        };
592        let tstr = CString::new(tstr).unwrap();
593        let cprops = af_cell {
594            row: self.row,
595            col: self.col,
596            title: tstr.as_ptr(),
597            cmap: self.cmap as u32,
598        };
599        unsafe {
600            let err_val = af_draw_image(self.handle, input.get(), &cprops as *const af_cell);
601            HANDLE_ERROR(AfError::from(err_val));
602        }
603    }
604
605    /// Render given two Array's `x` and `y` as a 2d line plot
606    ///
607    /// # Parameters
608    ///
609    /// - `x` is the x coordinates of the plot
610    /// - `y` is the y coordinates of the plot
611    /// - `title` parameter has effect only in multiview mode, where this string
612    ///    is displayed as the respective cell/view title.
613    pub fn draw_plot2<T>(&self, x: &Array<T>, y: &Array<T>, title: Option<String>)
614    where
615        T: HasAfEnum,
616    {
617        let tstr = match title {
618            Some(s) => s,
619            None => format!("Cell({},{}))", self.col, self.row),
620        };
621        let tstr = CString::new(tstr).unwrap();
622        let cprops = af_cell {
623            row: self.row,
624            col: self.col,
625            title: tstr.as_ptr(),
626            cmap: self.cmap as u32,
627        };
628        unsafe {
629            let err_val = af_draw_plot_2d(self.handle, x.get(), y.get(), &cprops as *const af_cell);
630            HANDLE_ERROR(AfError::from(err_val));
631        }
632    }
633
634    /// Render given Array's `x`, `y` and `z` as a 3d line plot
635    ///
636    /// # Parameters
637    ///
638    /// - `x` is the x coordinates of the plot
639    /// - `y` is the y coordinates of the plot
640    /// - `z` is the z coordinates of the plot
641    /// - `title` parameter has effect only in multiview mode, where this string
642    ///    is displayed as the respective cell/view title.
643    pub fn draw_plot3<T>(&self, x: &Array<T>, y: &Array<T>, z: &Array<T>, title: Option<String>)
644    where
645        T: HasAfEnum,
646    {
647        let tstr = match title {
648            Some(s) => s,
649            None => format!("Cell({},{}))", self.col, self.row),
650        };
651        let tstr = CString::new(tstr).unwrap();
652        let cprops = af_cell {
653            row: self.row,
654            col: self.col,
655            title: tstr.as_ptr(),
656            cmap: self.cmap as u32,
657        };
658        unsafe {
659            let err_val = af_draw_plot_3d(
660                self.handle,
661                x.get(),
662                y.get(),
663                z.get(),
664                &cprops as *const af_cell,
665            );
666            HANDLE_ERROR(AfError::from(err_val));
667        }
668    }
669
670    /// Render give Arrays of points as a 3d line plot
671    ///
672    /// # Parameters
673    ///
674    /// - `points` is an Array containing list of points of plot
675    /// - `title` parameter has effect only in multiview mode, where this string
676    ///    is displayed as the respective cell/view title.
677    pub fn draw_plot<T>(&self, points: &Array<T>, title: Option<String>)
678    where
679        T: HasAfEnum,
680    {
681        let tstr = match title {
682            Some(s) => s,
683            None => format!("Cell({},{}))", self.col, self.row),
684        };
685        let tstr = CString::new(tstr).unwrap();
686        let cprops = af_cell {
687            row: self.row,
688            col: self.col,
689            title: tstr.as_ptr(),
690            cmap: self.cmap as u32,
691        };
692        unsafe {
693            let err_val = af_draw_plot_nd(self.handle, points.get(), &cprops as *const af_cell);
694            HANDLE_ERROR(AfError::from(err_val));
695        }
696    }
697
698    /// Render given Array as a histogram
699    ///
700    /// # Parameters
701    ///
702    /// - `hst` is an Array containing histogram data
703    /// - `minval` is the minimum bin value of histogram
704    /// - `maxval` is the maximum bin value of histogram
705    /// - `title` parameter has effect only in multiview mode, where this string
706    ///    is displayed as the respective cell/view title.
707    pub fn draw_hist<T>(&self, hst: &Array<T>, minval: f64, maxval: f64, title: Option<String>)
708    where
709        T: HasAfEnum,
710    {
711        let tstr = match title {
712            Some(s) => s,
713            None => format!("Cell({},{}))", self.col, self.row),
714        };
715        let tstr = CString::new(tstr).unwrap();
716        let cprops = af_cell {
717            row: self.row,
718            col: self.col,
719            title: tstr.as_ptr(),
720            cmap: self.cmap as u32,
721        };
722        unsafe {
723            let err_val = af_draw_hist(
724                self.handle,
725                hst.get(),
726                minval,
727                maxval,
728                &cprops as *const af_cell,
729            );
730            HANDLE_ERROR(AfError::from(err_val));
731        }
732    }
733
734    /// Render give Arrays as 3d surface
735    ///
736    /// # Parameters
737    ///
738    /// - `x` is the x coordinates of the surface plot
739    /// - `y` is the y coordinates of the surface plot
740    /// - `z` is the z coordinates of the surface plot
741    /// - `title` parameter has effect only in multiview mode, where this string
742    ///    is displayed as the respective cell/view title.
743    pub fn draw_surface<T>(
744        &self,
745        xvals: &Array<T>,
746        yvals: &Array<T>,
747        zvals: &Array<T>,
748        title: Option<String>,
749    ) where
750        T: HasAfEnum,
751    {
752        let tstr = match title {
753            Some(s) => s,
754            None => format!("Cell({},{}))", self.col, self.row),
755        };
756        let tstr = CString::new(tstr).unwrap();
757        let cprops = af_cell {
758            row: self.row,
759            col: self.col,
760            title: tstr.as_ptr(),
761            cmap: self.cmap as u32,
762        };
763        unsafe {
764            let err_val = af_draw_surface(
765                self.handle,
766                xvals.get(),
767                yvals.get(),
768                zvals.get(),
769                &cprops as *const af_cell,
770            );
771            HANDLE_ERROR(AfError::from(err_val));
772        }
773    }
774
775    /// Render given Arrays as 2d scatter plot
776    ///
777    /// # Parameters
778    ///
779    /// - `xvals` is the x coordinates of the scatter plot
780    /// - `yvals` is the y coordinates of the scatter plot
781    /// - `marker` is of enum type [MarkerType](./enum.MarkerType.html)
782    /// - `title` parameter has effect only in multiview mode, where this string
783    ///    is displayed as the respective cell/view title.
784    pub fn draw_scatter2<T>(
785        &self,
786        xvals: &Array<T>,
787        yvals: &Array<T>,
788        marker: MarkerType,
789        title: Option<String>,
790    ) where
791        T: HasAfEnum,
792    {
793        let tstr = match title {
794            Some(s) => s,
795            None => format!("Cell({},{}))", self.col, self.row),
796        };
797        let tstr = CString::new(tstr).unwrap();
798        let cprops = af_cell {
799            row: self.row,
800            col: self.col,
801            title: tstr.as_ptr(),
802            cmap: self.cmap as u32,
803        };
804        unsafe {
805            let err_val = af_draw_scatter_2d(
806                self.handle,
807                xvals.get(),
808                yvals.get(),
809                marker as c_uint,
810                &cprops as *const af_cell,
811            );
812            HANDLE_ERROR(AfError::from(err_val));
813        }
814    }
815
816    /// Render given Arrays as 3d scatter plot
817    ///
818    /// # Parameters
819    ///
820    /// - `xvals` is the x coordinates of the scatter plot
821    /// - `yvals` is the y coordinates of the scatter plot
822    /// - `zvals` is the z coordinates of the scatter plot
823    /// - `marker` is of enum type [MarkerType](./enum.MarkerType.html)
824    /// - `title` parameter has effect only in multiview mode, where this string
825    ///    is displayed as the respective cell/view title.
826    pub fn draw_scatter3<T>(
827        &self,
828        xvals: &Array<T>,
829        yvals: &Array<T>,
830        zvals: &Array<T>,
831        marker: MarkerType,
832        title: Option<String>,
833    ) where
834        T: HasAfEnum,
835    {
836        let tstr = match title {
837            Some(s) => s,
838            None => format!("Cell({},{}))", self.col, self.row),
839        };
840        let tstr = CString::new(tstr).unwrap();
841        let cprops = af_cell {
842            row: self.row,
843            col: self.col,
844            title: tstr.as_ptr(),
845            cmap: self.cmap as u32,
846        };
847        unsafe {
848            let err_val = af_draw_scatter_3d(
849                self.handle,
850                xvals.get(),
851                yvals.get(),
852                zvals.get(),
853                marker as c_uint,
854                &cprops as *const af_cell,
855            );
856            HANDLE_ERROR(AfError::from(err_val));
857        }
858    }
859
860    /// Render give Array as 3d scatter plot
861    ///
862    /// # Parameters
863    ///
864    /// - `points` is an Array containing list of points of plot
865    /// - `marker` is of enum type [MarkerType](./enum.MarkerType.html)
866    /// - `title` parameter has effect only in multiview mode, where this string
867    ///    is displayed as the respective cell/view title.
868    pub fn draw_scatter<T>(&self, vals: &Array<T>, marker: MarkerType, title: Option<String>)
869    where
870        T: HasAfEnum,
871    {
872        let tstr = match title {
873            Some(s) => s,
874            None => format!("Cell({},{}))", self.col, self.row),
875        };
876        let tstr = CString::new(tstr).unwrap();
877        let cprops = af_cell {
878            row: self.row,
879            col: self.col,
880            title: tstr.as_ptr(),
881            cmap: self.cmap as u32,
882        };
883        unsafe {
884            let err_val = af_draw_scatter_nd(
885                self.handle,
886                vals.get(),
887                marker as c_uint,
888                &cprops as *const af_cell,
889            );
890            HANDLE_ERROR(AfError::from(err_val));
891        }
892    }
893
894    /// Render given Arrays as 2d vector field
895    ///
896    /// # Parameters
897    ///
898    /// - `xpnts` is an Array containing list of x coordinates
899    /// - `xdirs` is an Array containing direction component of x coord
900    /// - `ypnts` is an Array containing list of y coordinates
901    /// - `ydirs` is an Array containing direction component of y coord
902    /// - `title` parameter has effect only in multiview mode, where this string
903    ///    is displayed as the respective cell/view title.
904    pub fn draw_vector_field2<T>(
905        &self,
906        xpnts: &Array<T>,
907        ypnts: &Array<T>,
908        xdirs: &Array<T>,
909        ydirs: &Array<T>,
910        title: Option<String>,
911    ) where
912        T: HasAfEnum,
913    {
914        let tstr = match title {
915            Some(s) => s,
916            None => format!("Cell({},{}))", self.col, self.row),
917        };
918        let tstr = CString::new(tstr).unwrap();
919        let cprops = af_cell {
920            row: self.row,
921            col: self.col,
922            title: tstr.as_ptr(),
923            cmap: self.cmap as u32,
924        };
925        unsafe {
926            let err_val = af_draw_vector_field_2d(
927                self.handle,
928                xpnts.get(),
929                ypnts.get(),
930                xdirs.get(),
931                ydirs.get(),
932                &cprops as *const af_cell,
933            );
934            HANDLE_ERROR(AfError::from(err_val));
935        }
936    }
937
938    /// Render given Arrays as 3d vector field
939    ///
940    /// # Parameters
941    ///
942    /// - `xpnts` is an Array containing list of x coordinates
943    /// - `xdirs` is an Array containing direction component of x coord
944    /// - `ypnts` is an Array containing list of y coordinates
945    /// - `ydirs` is an Array containing direction component of y coord
946    /// - `zpnts` is an Array containing list of z coordinates
947    /// - `zdirs` is an Array containing direction component of z coord
948    /// - `title` parameter has effect only in multiview mode, where this string
949    ///    is displayed as the respective cell/view title.
950    #[allow(clippy::too_many_arguments)]
951    pub fn draw_vector_field3<T>(
952        &self,
953        xpnts: &Array<T>,
954        ypnts: &Array<T>,
955        zpnts: &Array<T>,
956        xdirs: &Array<T>,
957        ydirs: &Array<T>,
958        zdirs: &Array<T>,
959        title: Option<String>,
960    ) where
961        T: HasAfEnum,
962    {
963        let tstr = match title {
964            Some(s) => s,
965            None => format!("Cell({},{}))", self.col, self.row),
966        };
967        let tstr = CString::new(tstr).unwrap();
968        let cprops = af_cell {
969            row: self.row,
970            col: self.col,
971            title: tstr.as_ptr(),
972            cmap: self.cmap as u32,
973        };
974        unsafe {
975            let err_val = af_draw_vector_field_3d(
976                self.handle,
977                xpnts.get(),
978                ypnts.get(),
979                zpnts.get(),
980                xdirs.get(),
981                ydirs.get(),
982                zdirs.get(),
983                &cprops as *const af_cell,
984            );
985            HANDLE_ERROR(AfError::from(err_val));
986        }
987    }
988
989    /// Render given Array as vector field
990    ///
991    /// # Parameters
992    ///
993    /// - `points` is an Array containing list of coordinates of vector field
994    /// - `directions` is an Array containing directions at the coordinates specified in `points`
995    /// Array.
996    /// - `title` parameter has effect only in multiview mode, where this string
997    ///    is displayed as the respective cell/view title.
998    pub fn draw_vector_field<T>(
999        &self,
1000        points: &Array<T>,
1001        directions: &Array<T>,
1002        title: Option<String>,
1003    ) where
1004        T: HasAfEnum,
1005    {
1006        let tstr = match title {
1007            Some(s) => s,
1008            None => format!("Cell({},{}))", self.col, self.row),
1009        };
1010        let tstr = CString::new(tstr).unwrap();
1011        let cprops = af_cell {
1012            row: self.row,
1013            col: self.col,
1014            title: tstr.as_ptr(),
1015            cmap: self.cmap as u32,
1016        };
1017        unsafe {
1018            let err_val = af_draw_vector_field_nd(
1019                self.handle,
1020                points.get(),
1021                directions.get(),
1022                &cprops as *const af_cell,
1023            );
1024            HANDLE_ERROR(AfError::from(err_val));
1025        }
1026    }
1027}