@@ -183,6 +183,7 @@ def __init__(
183183        nudge_x : int  =  0 ,
184184        nudge_y : int  =  0 ,
185185        verbose : bool  =  False ,
186+         fill_area : bool  =  False ,
186187        ** kwargs ,
187188    ) ->  None :
188189
@@ -318,6 +319,8 @@ def __init__(
318319        self ._circle_palette  =  None 
319320        self .plot_line_point  =  None 
320321
322+         self ._fill_area  =  fill_area 
323+ 
321324    @staticmethod  
322325    def  _get_font_height (font , scale : int ) ->  Tuple [int , int ]:
323326        if  hasattr (font , "get_bounding_box" ):
@@ -501,8 +504,8 @@ def _add_point(self, x: int, y: int) -> None:
501504        :param int x: ``x`` coordinate in the local plane 
502505        :param int y: ``y`` coordinate in the local plane 
503506        :return: None 
504-         rtype: None 
505507        """ 
508+ 
506509        local_x , local_y  =  self ._calc_local_xy (x , y )
507510        if  self ._verbose :
508511            print ("" )
@@ -562,6 +565,7 @@ def _add_point(self, x: int, y: int) -> None:
562565                            self .height ,
563566                        )
564567                    )
568+ 
565569        else :
566570            # for better error messages we check in detail what failed... 
567571            if  not  self ._check_x_in_range (x ):
@@ -591,7 +595,6 @@ def update_pointer(self, x: int, y: int) -> None:
591595        :param int x: ``x`` coordinate in the local plane 
592596        :param int y: ``y`` coordinate in the local plane 
593597        :return: None 
594-         rtype: None 
595598        """ 
596599        self ._add_point (x , y )
597600        if  not  self ._pointer :
@@ -603,6 +606,15 @@ def update_pointer(self, x: int, y: int) -> None:
603606            self ._pointer .x  =  self .plot_line_point [- 1 ][0 ]
604607            self ._pointer .y  =  self .plot_line_point [- 1 ][1 ]
605608
609+     @property  
610+     def  fill_area (self ) ->  bool :
611+         """Whether the area under the graph (integral) should be shaded""" 
612+         return  self ._fill_area 
613+ 
614+     @fill_area .setter  
615+     def  fill_area (self , setting : bool ) ->  None :
616+         self ._fill_area  =  setting 
617+ 
606618    def  add_plot_line (self , x : int , y : int ) ->  None :
607619        """add_plot_line function. 
608620
@@ -612,8 +624,6 @@ def add_plot_line(self, x: int, y: int) -> None:
612624        :param int x: ``x`` coordinate in the local plane 
613625        :param int y: ``y`` coordinate in the local plane 
614626        :return: None 
615- 
616-         rtype: None 
617627        """ 
618628        self ._add_point (x , y )
619629        if  len (self .plot_line_point ) >  1 :
@@ -625,17 +635,59 @@ def add_plot_line(self, x: int, y: int) -> None:
625635                self .plot_line_point [- 1 ][1 ],
626636                1 ,
627637            )
638+             # Plot area under graph 
639+             if  self ._fill_area :
640+ 
641+                 delta_x  =  self .plot_line_point [- 2 ][0 ] -  self .plot_line_point [- 1 ][0 ]
642+                 delta_y  =  self .plot_line_point [- 2 ][1 ] -  self .plot_line_point [- 1 ][1 ]
643+                 delta_y_product  =  (
644+                     self .plot_line_point [- 1 ][1 ] *  self .plot_line_point [- 2 ][1 ]
645+                 )
646+ 
647+                 if  delta_x  ==  0 :
648+                     return 
649+ 
650+                 slope  =  delta_y  /  delta_x 
651+ 
652+                 if  delta_y_product  <  0 :
653+ 
654+                     intercept  =  self .plot_line_point [- 1 ][1 ]
655+                     zero_point_x  =  (- 1  *  intercept ) /  slope 
656+ 
657+                     self ._draw_area_under (self .plot_line_point [- 2 ], (zero_point_x , 0 ))
658+                     self ._draw_area_under ((zero_point_x , 0 ), self .plot_line_point [- 1 ])
659+ 
660+                 else :
661+ 
662+                     self ._draw_area_under (
663+                         self .plot_line_point [- 2 ], self .plot_line_point [- 1 ]
664+                     )
665+ 
666+     def  _draw_area_under (
667+         self , xy0 : Tuple [float , float ], xy1 : Tuple [float , float ]
668+     ) ->  None :
669+ 
670+         _ , plot_y_zero  =  self ._calc_local_xy (0 , 0 )
671+ 
672+         delta_x  =  self .plot_line_point [- 2 ][0 ] -  self .plot_line_point [- 1 ][0 ]
673+         delta_y  =  self .plot_line_point [- 2 ][1 ] -  self .plot_line_point [- 1 ][1 ]
674+         slope  =  delta_y  /  delta_x 
675+ 
676+         for  pixel_x  in  range (xy0 [0 ], xy1 [0 ] +  1 ):
677+             if  pixel_x  !=  xy1 [0 ]:
678+                 pixel_y  =  round (slope  *  (pixel_x  -  xy1 [0 ]) +  xy1 [1 ])
679+             bitmaptools .draw_line (
680+                 self ._plot_bitmap , pixel_x , pixel_y , pixel_x , plot_y_zero , 1 
681+             )
628682
629-     def  clear_plot_lines (self , palette_index = 5 ) :
683+     def  clear_plot_lines (self , palette_index :  int   =   5 )  ->   None :
630684        """clear_plot_lines function. 
631685
632686        clear all added lines 
633687        (clear line-plot graph) 
634688
635689        :param int palette_index: color palett index. Defaults to 5 
636690        :return: None 
637- 
638-         rtype: None 
639691        """ 
640692        self .plot_line_point  =  None 
641693        self ._plot_bitmap .fill (palette_index )
0 commit comments