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}