From 6325c6ec2e770c3c6056591420b6789176609842 Mon Sep 17 00:00:00 2001
From: Tolga Yurtseven <tolgayurt02@outlook.de>
Date: Tue, 20 Oct 2020 18:12:41 +0200
Subject: [PATCH] updated poly_edit_tool

---
 mysite/plots/polygon.py                | 801 +++++++++++++++++++++----
 mysite/plots/templates/plots/test.html |  19 +-
 mysite/plots/urls.py                   |   5 +-
 mysite/plots/views.py                  | 160 ++++-
 mysite/requirements/base.txt           |   3 +-
 5 files changed, 844 insertions(+), 144 deletions(-)

diff --git a/mysite/plots/polygon.py b/mysite/plots/polygon.py
index 7c921112..eaee6603 100644
--- a/mysite/plots/polygon.py
+++ b/mysite/plots/polygon.py
@@ -1,7 +1,8 @@
 import sys, path
 import mpld3
 #import import_ipynb
-import plots.avl_tree
+from plots import avl_tree
+import pandas as pd
 from matplotlib import pyplot as plt
 from shapely.geometry import Point, Polygon, LineString
 from shapely.geometry.base import BaseGeometry, geos_geom_from_py
@@ -29,8 +30,6 @@ from bokeh.palettes import Dark2_5 as palette
 from bokeh.palettes import Viridis256
 from bokeh.models import CustomJS
 import itertools
-import pdb
-
 
 a = 0.407
 
@@ -102,8 +101,8 @@ class Polygon2(object):
         if spine[0][0] == spine[1][0]:  # Sonderfall für eine senkrechte
             slope = math.inf
         else:
-            slope = (spine[1][1] - spine[0][1]) / (spine[1][0] - spine[0][0])
-            # m = y2-y1/x2-x1 Formel für die Geradensteigung mithilfe aus zwei verschiedenen Punkten der Geraden
+            slope = (spine[1][1] - spine[0][1]) / (spine[1][0] - spine[0][
+                0])  # m = y2-y1/x2-x1 Formel für die Geradensteigung mithilfe aus zwei verschiedenen Punkten der Geraden
         return slope
 
     def plot_polygon(self, title="", render=True):
@@ -145,15 +144,15 @@ class Polygon2(object):
         spine_bottom_not_horizontal = False
         while spine_bottom_found == False:  # Phase 1 der Funktion sie sucht den bottom spine, dabei werden die Ecken die nicht der Spine Bottom sind ans Ende der Liste geschoben
             if help_array[0] == spine_bottom:
-                if spine_bottom[1] != help_array[-1][1]:
-                    # checkt ob Spine bottom ein horizontalen Nachbar hat falls ja wird ein Flag gesetzt damit Spine bottomt später nicht in die Rechte mitgenommen wird
+                if spine_bottom[1] != help_array[-1][
+                    1]:  # checkt ob Spine bottom ein horizontalen Nachbar hat falls ja wird ein Flag gesetzt damit Spine bottomt später nicht in die Rechte mitgenommen wird
                     spine_bottom_not_horizontal = True
                 spine_bottom_found = True
                 left.append(help_array.pop(0))
             else:
                 help_array.append(help_array.pop(0))
         while spine_top_found == False:  # iterieren die Liste erneut durch bis wir spine top finden, falls spine top gefunden wurde wird auch geschaut ob spine top ein horizontalen linken
-            if help_array[0] == spine_top:  # Nachbar hat falls ja wird spine top nicht in die rechte Liste miteingefügt
+            if help_array[0] == spine_top:  # Nachbar hat falls ja wird spine top nicht in die Linke Liste miteingefügt
                 spine_top_found = True
                 if spine_top[1] != left[-1][1]:
                     left.append(spine_top)
@@ -181,7 +180,7 @@ class HighClass(object):
         self.spine_ordered_polygons = spine_ordered_polygons
         return spine_ordered_polygons
 
-    def plot_hc(self, ordered=False,stretch=False, render=True, plot_width=250, plot_height=250):
+    def plot_hc(self, ordered=False, render=True, plot_width=250, plot_height=250):
         plots = []
         if ordered:
             polygon_list = self.spine_ordered_polygons
@@ -190,10 +189,7 @@ class HighClass(object):
         for counter, polygon in enumerate(polygon_list):
             title = "Polygon {}".format(counter)
             plots.append(polygon.plot_polygon(title=title, render=False))
-        if stretch:
-            grid = gridplot(plots, ncols=4, sizing_mode='stretch_both')
-        else:
-            grid = gridplot(plots, ncols=4, plot_width=plot_width, plot_height=plot_height)
+        grid = gridplot(plots, ncols=4, plot_width=plot_width, plot_height=plot_height)
         if render:
             return show(grid)
         else:
@@ -266,29 +262,81 @@ def create_convex_polygon(
     return polygon2
 
 
-def plot_polygons(polygon_list, render=True, stretch=False,plot_width=250, plot_height=250):
+def plot_polygons(polygon_list, render=True, plot_width=250, plot_height=250):
     plots = []
     for counter, polygon in enumerate(polygon_list):
         title = "Polygon {}".format(counter)
         plots.append(polygon.plot_polygon(title=title, render=False))
-    if stretch:
-        grid = gridplot(plots, ncols=4, sizing_mode='stretch_both')
-    else:
-        grid = gridplot(plots, ncols=4, plot_width=plot_width, plot_height=plot_height)
+    grid = gridplot(plots, ncols=4, plot_width=plot_width, plot_height=plot_height)
     if render:
         return show(grid)
     else:
         return grid
 
 
+def plot_polygons_in_single_plot(polygon_list, title="", render=True, border=None):
+    polygon_number = len(polygon_list)
+    #         x_data = self.x_values
+    #         y_data = self.y_values
+    TOOLTIPS = [("index", "$index"), ("(x,y)", "($x, $y)"), ]
+    #         if title=="":
+    #             title= 'height:{}  slope:{}'.format(height,slope)
+    #         else:
+    #             title= '{} height:{}  slope:{}'.format(title,height,slope)
+    fig = figure(title=title, x_axis_label='x', y_axis_label='y', tooltips=TOOLTIPS, toolbar_location="below")
+    colors = itertools.cycle(palette)
+    legend_items = []
+    legend_polygons = []
+    for counter, polygon in enumerate(polygon_list):
+        color = next(colors)
+        x = polygon.x_values
+        y = polygon.y_values
+        legend_label = "Polygon {}".format(counter)
+        poly_fig = fig.line(x, y, color=color, line_width=2, muted_alpha=0.2)
+        circle_fig = fig.circle(x, y, color=color, line_width=2, muted_alpha=0.2, size=8)
+        legend_polygons.append((legend_label, [poly_fig, circle_fig]))
+    #         spine_x_values = [x[0] for x in self.spine]
+    #         spine_y_values = [x[1] for x in self.spine]
+    if border != None:
+        fig_border = fig.line(border[0], border[1], line_color="red", line_width=2, muted_alpha=0.2)
+        legend_items.append(("border", [fig_border]))
+    legend_items = legend_items + legend_polygons
+    legend = Legend(items=legend_items)
+    legend.click_policy = "mute"
+    fig.add_layout(legend, 'right')
+    fig.legend.click_policy = "mute"
+    if render:
+        return show(fig)
+    else:
+        return fig
+
+
 def pack_polygons(polygons):
-    list_hc = height_classes(polygons)
+    copy_polygons = deepcopy(polygons)
+    list_hc = height_classes(copy_polygons)
     list_containers = building_containers(list_hc)
     list_mini_containers = pack_mini_containers(list_containers)
-    end_container = End_Container(list_mini_containers, True)
+    end_container = End_Container(list_mini_containers)
     return end_container
 
 
+# https://kodify.net/python/math/truncate-decimals/
+def truncate(number, decimals=0):
+    """
+    Returns a value truncated to a specific number of decimal places.
+    """
+    if not isinstance(decimals, int):
+        raise TypeError("decimal places must be an integer.")
+    elif decimals < 0:
+        raise ValueError("decimal places has to be 0 or more.")
+    elif decimals == 0:
+        return math.trunc(number)
+
+    factor = 10.0 ** decimals
+    return math.trunc(number * factor) / factor
+
+
+
 class Container(object):
     def __init__(self, hc):
         self.hc = hc
@@ -296,7 +344,7 @@ class Container(object):
         self.y_boundary = hc.max_border
         self.x_boundary = 0
         self.sigma = []
-        self.Tree = plots.avl_tree.AVLTree()
+        self.Tree = avl_tree.AVLTree()
         self.root = None
         self.box_boundarys_x_values = []
         self.plot_steps = []
@@ -409,9 +457,8 @@ class Container(object):
         grid = gridplot(self.plot_steps, ncols=colums, plot_width=plot_width, plot_height=plot_height)
         min_border = (int(self.hc.min_border * 10)) / 10
         max_border = (int(self.hc.max_border * 10)) / 10
-        # title = Div(
-        #     text="<h1>Highclass Container {}, Polygon height: {}-{} </h1>".format(self.hc.i, min_border, max_border))
-        # r = column(title, grid)
+        #         title = Div(text="<h1>Highclass Container {}, Polygon height: {}-{} </h1>".format(self.hc.i,min_border,max_border))
+        #         r = column(title, grid)
         if render:
             return show(grid)
         else:
@@ -552,7 +599,6 @@ class Container(object):
                     successor_vertex = self.Tree.find_edges(self.root, vertex_y, self.root)
                     corresponding_edge_points = (successor_vertex.vertice, successor_vertex.vertice_neighbour)
                     # print("corresponding edge points",corresponding_edge_points,"for vertex",vertex)#p
-                    #pdb.set_trace()
                     distance = self.slope3(corresponding_edge_points, vertex)
                     if distance <= min_horizontal_distance:
                         min_horizontal_distance = distance
@@ -612,9 +658,11 @@ class Mini_Container(object):
     def __init__(self, max_width, max_height, max_polygon_width, hc_i):
         self.max_polygon_width = max_polygon_width
         self.current_right_boundary = 0
+        self.height = 0
         self.hc_i = hc_i
+        self.hc_height = max_height
         self.max_width = max_width
-        self.height = max_height
+
         self.c = 2.214
         self.polygons = []
         self.y_offset = 0
@@ -657,8 +705,12 @@ class Mini_Container(object):
                                 [0 + self.y_offset, 0 + self.y_offset, self.height + self.y_offset,
                                  self.height + self.y_offset, 0 + self.y_offset]
                                 , line_color="black", line_width=2, muted_alpha=0.2, )
+        fig_polygon_boundary = fig.line([self.current_right_boundary, self.current_right_boundary],
+                                        [0 + self.y_offset, self.height + self.y_offset]
+                                        , line_color="black", line_dash="dotted", line_width=2, muted_alpha=0.2, )
         items = legend_polygons + [("spine", legend_spine)]
-        items.append(("boundary", [fig_boundary]))
+        items.append(("container-boundary", [fig_boundary]))
+        items.append(("last polygon-boundary", [fig_polygon_boundary]))
         legend = Legend(items=items)
         legend.click_policy = "mute"
         fig.add_layout(legend, 'right')
@@ -696,64 +748,85 @@ class Mini_Container(object):
 def pack_mini_containers(container_array, plot_steps=False):
     mini_container_array = []
     plot_steps_helper_tuples = []
-
     colors = itertools.cycle(palette)
     background_color_list = [next(colors)]
     for container in container_array:
         mini_container_plot = []
-        copy_container = container  # nochmal schauen ob der Schritt nötig ist bzw. ob nur ein Pointer kopiert wird statt eine deepcopy
-        box_width = 2.214 * copy_container.hc.w_max
+        box_width = 2.214 * container.hc.w_max
         box_width_helper = 0
-
-        box_counter = 1
-        # print("container boundarys",copy_container.x_boundary)
-        while box_width_helper < copy_container.x_boundary:
+        box_counter = 1  # hilft dabei wie oft der Container in Mini-Container geteilt wird
+        while box_width_helper < container.x_boundary:
             container.box_boundarys_x_values.append(box_width_helper)
             box_width_helper += box_width
             background_color_list.append(next(colors))
-        # if plot == True:
-        #     copy_container.plot_container(copy_container.sigma)
-        # container.plot_steps.append(copy_container.plot_container(copy_container.sigma, render=True))
-        container_plot = copy_container.plot_container(copy_container.sigma, render=False,
-                                                       background_c_list=background_color_list)
-        max_width_mini_container = box_width + copy_container.hc.w_max
+        container_plot = container.plot_container(container.sigma, render=False,
+                                                  background_c_list=background_color_list)  # will added to the plots
+        max_width_mini_container = box_width + container.hc.w_max
         background_counter = 0
-        while len(copy_container.sigma) > 0 and (box_width * box_counter) < (copy_container.x_boundary):
+        # wichtig zu kucken ob der container noch Polygone enthält da die linkesten Punkte noch in der anderen Box liegen können und eine Box leer sein kann
+        while len(container.sigma) > 0 and (box_width * box_counter) < (container.x_boundary):
+
             # print("max_with,y_boundary",max_width_mini_container,(copy_container.y_boundary))
             b_color = background_color_list[background_counter]
-            mini_container = Mini_Container(max_width_mini_container, (copy_container.y_boundary),
-                                            copy_container.hc.w_max, copy_container.hc.i)
+            mini_container = Mini_Container(max_width_mini_container, (container.y_boundary),
+                                            container.hc.w_max, container.hc.i)
             translation_flag = True
-            while len(copy_container.sigma) > 0 and (copy_container.sigma[0].min_x) < (box_width * box_counter):
-                if translation_flag:
-                    translation = copy_container.sigma[0].min_x
-                    translation_flag = False
-                copy_container.sigma[0].translation(-translation, 0)
-                mini_container.polygons.append(copy_container.sigma.pop(0))
+            mini_container_y_border = 0
+            mini_container_x_border = 0
+            # while len(container.sigma) > 0 and (container.sigma[0].min_x) < (box_width * box_counter):
+            pop_list = []  # enthält die counter der Polygone die zur box gehören
+            for counter, polygon in enumerate(container.sigma):
+                if polygon.min_x < (box_width * box_counter):
+                    if translation_flag:
+                        translation = container.sigma[counter].min_x
+                        translation_flag = False
+                    container.sigma[counter].translation(-translation, 0)
+                    pop_list.append(counter)
+                    if mini_container_y_border < container.sigma[counter].max_y:
+                        mini_container_y_border = container.sigma[counter].max_y
+                    if mini_container_x_border < container.sigma[counter].max_x:
+                        mini_container_x_border = container.sigma[counter].max_x
+                        # selbst wenn man das 0 Element poped gibt es keine Probleme
+            pop_helper = 0
+            if pop_list != []:
+                for counter in pop_list:
+                    mini_container.polygons.append(container.sigma.pop(counter - pop_helper))
+                    pop_helper += 1
                 # mini_container.plot_container()
-            mini_container.current_right_boundary = mini_container.polygons[-1].max_x
+            mini_container.height = mini_container_y_border
+            mini_container.current_right_boundary = mini_container_x_border
             mini_container_array.append(mini_container)
-            #             if plot==True:
-            #                 title = "Mini-Container {} (hc_{})".format(box_counter, container.hc.i)
-            #                 mini_container.plot_container(title)
-            title = "Mini-Container {} (hc_{})".format(box_counter, container.hc.i)
+            title = "Mini-Container {} heigth:{} (hc_{})".format(box_counter, mini_container.height, container.hc.i)
             mini_container_plot.append(mini_container.plot_container(title=title, render=False, background_c=b_color))
             box_counter += 1
             background_counter += 1
-        if len(copy_container.sigma) > 0:
-            mini_container = Mini_Container(max_width_mini_container, copy_container.y_boundary,
-                                            copy_container.hc.w_max, copy_container.hc.i)
+        if len(container.sigma) > 0:  # für die letzte box die eventuell kürzer ist
+            mini_container_y_border = 0
+            mini_container_x_border = 0
+            mini_container = Mini_Container(max_width_mini_container, container.y_boundary,
+                                            container.hc.w_max, container.hc.i)
             translation_flag = True
-            while len(copy_container.sigma) > 0 and copy_container.sigma[0].min_x < box_width * box_counter:
-                if translation_flag:
-                    translation = copy_container.sigma[0].min_x
-                    translation_flag = False
-                copy_container.sigma[0].translation(-translation, 0)
-                mini_container.polygons.append(copy_container.sigma.pop(0))
-                # mini_container.plot_container()
-            mini_container.current_right_boundary = mini_container.polygons[-1].max_x
+            pop_list2 = []
+            for counter, polygon in enumerate(container.sigma):
+                if polygon.min_x < (box_width * box_counter):
+                    if translation_flag:
+                        translation = container.sigma[counter].min_x
+                        translation_flag = False
+                    container.sigma[counter].translation(-translation, 0)
+                    pop_list2.append(counter)
+                    if mini_container_y_border < container.sigma[counter].max_y:
+                        mini_container_y_border = container.sigma[counter].max_y
+                    if mini_container_x_border < container.sigma[counter].max_x:
+                        mini_container_x_border = container.sigma[counter].max_x
+
+            if pop_list2 != []:
+                pop_helper2 = 0
+                for counter in pop_list2:
+                    mini_container.polygons.append(container.sigma.pop(counter - pop_helper2))
+                    pop_helper2 += 1
+            mini_container.height = mini_container_y_border
+            mini_container.current_right_boundary = mini_container_x_border
             mini_container_array.append(mini_container)
-            # if plot==True:
             title = "Mini-Container {} (hc_{})".format(box_counter, container.hc.i)
             # mini_container.plot_container(title)
             mini_container_plot.append(mini_container.plot_container(title=title, render=False))
@@ -764,6 +837,89 @@ def pack_mini_containers(container_array, plot_steps=False):
         return mini_container_array
 
 
+# def pack_mini_containers2(container_array, plot_steps=False):
+#     mini_container_array = []
+#     plot_steps_helper_tuples = []
+
+#     colors = itertools.cycle(palette)
+#     background_color_list = [next(colors)]
+#     for container in container_array:
+#         mini_container_plot = []
+#         copy_container = container  # nochmal schauen ob der Schritt nötig ist bzw. ob nur ein Pointer kopiert wird statt eine deepcopy
+#         box_width = 2.214 * copy_container.hc.w_max
+#         box_width_helper = 0
+
+#         box_counter = 1
+#         # print("container boundarys",copy_container.x_boundary)
+#         while box_width_helper < copy_container.x_boundary:
+#             container.box_boundarys_x_values.append(box_width_helper) # füllen den Container mit Box Grenzen (wichtig fürs Ploten des Containers)
+#             box_width_helper += box_width
+#             background_color_list.append(next(colors))
+#         container_plot = copy_container.plot_container(copy_container.sigma, render=False,
+#                                                        background_c_list=background_color_list)    # will added to the plots
+#         max_width_mini_container = box_width + copy_container.hc.w_max # maximale breite der Mini-Container (c+1)*w_max
+#         background_counter = 0
+
+#         # Boxen -> Miniboxen
+#         while len(copy_container.sigma) > 0 and (box_width * box_counter) < (copy_container.x_boundary):
+#             b_color = background_color_list[background_counter]
+#             mini_container = Mini_Container(max_width_mini_container, (copy_container.y_boundary),
+#                                             copy_container.hc.w_max, copy_container.hc.i)
+#             translation_flag = True
+#             mini_container_y_border=0
+#             mini_container_x_border=0
+#             while len(copy_container.sigma) > 0 and (copy_container.sigma[0].min_x) < (box_width * box_counter):
+#                 if translation_flag:
+#                     translation = copy_container.sigma[0].min_x
+#                     translation_flag = False
+#                 copy_container.sigma[0].translation(-translation, 0)
+#                 if mini_container_y_border < copy_container.sigma[0].max_y:
+#                     mini_container_y_border = copy_container.sigma[0].max_y
+#                 if mini_container_x_border < copy_container.sigma[0].max_x:
+#                     mini_container_x_border = copy_container.sigma[0].max_x
+#                 mini_container.polygons.append(copy_container.sigma.pop(0))
+#                 # mini_container.plot_container()
+#             mini_container.height = mini_container_y_border
+#             mini_container.current_right_boundary = mini_container_x_border
+#             mini_container_array.append(mini_container)
+#             #             if plot==True:
+#             #                 title = "Mini-Container {} (hc_{})".format(box_counter, container.hc.i)
+#             #                 mini_container.plot_container(title)
+#             title = "Mini-Container {} heigth:{} (hc_{})".format(box_counter,mini_container.height, container.hc.i)
+#             mini_container_plot.append(mini_container.plot_container(title=title, render=False, background_c=b_color))
+#             box_counter += 1
+#             background_counter += 1
+#         if len(copy_container.sigma) > 0:
+#             mini_container_y_border=0
+#             mini_container_x_border=0
+#             mini_container = Mini_Container(max_width_mini_container, copy_container.y_boundary,
+#                                             copy_container.hc.w_max, copy_container.hc.i)
+#             translation_flag = True
+#             while len(copy_container.sigma) > 0 and copy_container.sigma[0].min_x < box_width * box_counter:
+#                 if translation_flag:
+#                     translation = copy_container.sigma[0].min_x
+#                     translation_flag = False
+#                 copy_container.sigma[0].translation(-translation, 0)
+#                 if mini_container_y_border < copy_container.sigma[0].max_y:
+#                     mini_container_y_border = copy_container.sigma[0].max_y
+#                 if mini_container_x_border < copy_container.sigma[0].max_x:
+#                     mini_container_x_border = copy_container.sigma[0].max_x
+#                 mini_container.polygons.append(copy_container.sigma.pop(0))
+#                 # mini_container.plot_container()
+#             mini_container.height = mini_container_y_border
+#             mini_container.current_right_boundary = mini_container_x_border
+#             mini_container_array.append(mini_container)
+#             # if plot==True:
+#             title = "Mini-Container {} (hc_{})".format(box_counter, container.hc.i)
+#             # mini_container.plot_container(title)
+#             mini_container_plot.append(mini_container.plot_container(title=title, render=False))
+#         plot_steps_helper_tuples.append((container_plot, mini_container_plot))
+#     if plot_steps == True:
+#         return (mini_container_array, plot_steps_helper_tuples)
+#     else:
+#         return mini_container_array
+
+
 def plot_mini_containers(plot_steps, render=True, plot_width=600, plot_height=600):
     plots = []
 
@@ -787,107 +943,492 @@ def plot_mini_containers(plot_steps, render=True, plot_width=600, plot_height=60
 class End_Container(object):
     def __init__(self, mini_container_array, angle=0):
         self.mini_containers = mini_container_array
-        self.polygons,self.max_width,self.max_height =self.pack_mini_containers()
-        self.container_area = self.container_area(self.mini_containers)
+        self.polygons, self.max_width, self.max_height = self.pack_mini_containers()
+        self.x_values_border, self.y_values_border = [0, 0, self.max_width, self.max_width, 0], [0, self.max_height,
+                                                                                                 self.max_height, 0, 0]
+        self.container_area = self.max_width * self.max_height
+        self.container_not_opt_area = self.container_not_opt_area(self.mini_containers)
         self.angle = angle
 
     def pack_mini_containers(self):
-        y_offset = self.mini_containers[0].height
-        polygons=[]
-        container_max_width =0
-        for mini_container in self.mini_containers[1:]:
+        #         y_offset = self.mini_containers[0].height
+        #         polygons=self.mini_containers[0].polygons
+        y_offset = 0
+        polygons = []
+        container_polygon_boundary_width = 0
+        for mini_container in self.mini_containers:
             for polygon in mini_container.polygons:
                 polygon.translation(0, y_offset)
             mini_container.y_offset = y_offset
             y_offset += mini_container.height
-            polygons= polygons+mini_container.polygons
-            if container_max_width < mini_container.max_width:
-                container_max_width = mini_container.max_width
-        border_points = [(0,0),(0,y_offset),(container_max_width,y_offset),(container_max_width,0)]
-        return (polygons,container_max_width,y_offset,)
-
-    def container_area(self, mini_containers):
-        container_area = 0
+            polygons = polygons + mini_container.polygons
+            # print(mini_container.current_right_boundary)
+            if container_polygon_boundary_width < mini_container.current_right_boundary:
+                container_polygon_boundary_width = mini_container.current_right_boundary
+        border_points = [(0, 0), (0, y_offset), (container_polygon_boundary_width, y_offset),
+                         (container_polygon_boundary_width, 0)]
+        return (polygons, container_polygon_boundary_width, y_offset,)
+
+    #     def pack_mini_containers(self):
+    #         y_offset = self.mini_containers[0].height
+    #         polygons=self.mini_containers[0].polygons
+    #         container_polygon_boundary_width =self.mini_containers[0].current_right_boundary
+    #         for mini_container in self.mini_containers[1:]:
+    #             for polygon in mini_container.polygons:
+    #                 polygon.translation(0, y_offset)
+    #             mini_container.y_offset = y_offset
+    #             y_offset += mini_container.height
+    #             polygons= polygons+mini_container.polygons
+    #             print(mini_container.current_right_boundary)
+    #             if container_polygon_boundary_width <  mini_container.current_right_boundary:
+    #                 container_polygon_boundary_width =  mini_container.current_right_boundary
+    #         border_points = [(0,0),(0,y_offset),(container_polygon_boundary_width,y_offset),(container_polygon_boundary_width,0)]
+    #         return (polygons,container_polygon_boundary_width,y_offset,)
+
+    def container_not_opt_area(self, mini_containers):
+        container_not_opt_area = 0
         for mini_container in mini_containers:
-            container_area += mini_container.max_width * mini_container.height
-        return container_area
+            container_not_opt_area += mini_container.max_width * mini_container.hc_height
+        return container_not_opt_area
 
-    def plot_container(self, title="", render=True):
+    def plot_polygons(self, title=""):
+        polygon_number = len(self.polygons)
+        #         x_data = self.x_values
+        #         y_data = self.y_values
+        TOOLTIPS = [("index", "$index"), ("(x,y)", "($x, $y)"), ]
+        if title == "":
+            title = 'End-Container-Polygons   area: {}   not-optimal-area: {}'.format(
+                (int(self.container_area / 10)) * 10, (int(self.container_not_opt_area / 10)) * 10)
+        fig = figure(title=title, x_axis_label='x', y_axis_label='y', tooltips=TOOLTIPS, toolbar_location="below")
+        colors = itertools.cycle(palette)
+        legend_items = []
         legend_polygons = []
+        for counter, polygon in enumerate(self.polygons):
+            color = next(colors)
+            x = polygon.x_values
+            y = polygon.y_values
+            legend_label = "Polygon {}".format(counter)
+            poly_fig = fig.line(x, y, color=color, line_width=2, muted_alpha=0.2)
+            circle_fig = fig.circle(x, y, color=color, line_width=2, muted_alpha=0.2, size=8)
+            legend_polygons.append((legend_label, [poly_fig, circle_fig]))
+        #         spine_x_values = [x[0] for x in self.spine]
+        #         spine_y_values = [x[1] for x in self.spine]
+        fig_border = fig.line(self.x_values_border, self.y_values_border, line_color="red", line_width=2,
+                              muted_alpha=0.2)
+
+        legend_items = legend_polygons
+        legend_items.append(("border", [fig_border]))
+        legend = Legend(items=legend_items)
+
+        fig.add_layout(legend, 'right')
+        fig.legend.click_policy = "mute"
+        #         if render:
+        #             return show(fig)
+        #         else:
+        return show(fig)
+
+    def plot_container(self, title="", plot_width=850, plot_height=700, solo_box_border=False, render=True):
+
+        legend_mini_containers = []
         legend_spine = []
         legend_lr = []
         legend_rl = []
+        legend_items = []
         # fig = plt.subplots(facecolor='w', edgecolor='k', figsize=(20,12), dpi=90)
         TOOLTIPS = [("index", "$index"), ("(x,y)", "($x, $y)"), ]
         if title == "":
-            title = 'End-Container  area:{}'.format((int(self.container_area/10))*10)
-        fig = figure(title=title, x_axis_label='x', y_axis_label='y', toolbar_location="below", tooltips=TOOLTIPS)
+            title = 'End-Container   area: {}   not-optimal-area: {}'.format((int(self.container_area / 10)) * 10, (
+                int(self.container_not_opt_area / 10)) * 10)
+        fig = figure(title=title, x_axis_label='x', y_axis_label='y', width=plot_width, height=plot_height,
+                     toolbar_location="below", tooltips=TOOLTIPS)
         y_offset = 0
         colors = itertools.cycle(palette)
         for counter, mini_container in enumerate(self.mini_containers):
             color = next(colors)
+            legend_polygons = []
             for polygon in mini_container.polygons:
                 # mapper = linear_cmap(field_name='x', palette=Viridis256 ,low=min(x) ,high=max(x))
                 source = ColumnDataSource(data=dict(x=polygon.x_values, y=polygon.y_values))
                 spine_x_values = [x[0] for x in polygon.spine]
                 spine_y_values = [x[1] for x in polygon.spine]
 
-                legend_label = "Mini-Container {} (hc{})".format(counter, mini_container.hc_i)
-                fig.line(x="x", y="y", line_width=2, line_color=color, muted_alpha=0.2, source=source,
-                         legend_label=legend_label)
+                # legend_label = "Mini-Container {} height:{} (hc{})".format(counter,int(mini_container.height), mini_container.hc_i)
+                fig_polygon = fig.line(x="x", y="y", line_width=2, line_color=color, muted_alpha=0.2, source=source)
                 # fig.circle(x="x",y="y",fill_color=linear_cmap(field_name='y', palette= 'Viridis256'),source=source, line_width=2, muted_alpha=0.2,size=8)
-                fig.circle(x="x", y="y", line_width=2, color=color, fill_color=color, muted_alpha=0.2, size=8,
-                           source=source, legend_label=legend_label)
+                fig_circle = fig.circle(x="x", y="y", line_width=2, color=color, fill_color=color, muted_alpha=0.2,
+                                        size=8,
+                                        source=source)
                 # ax.scatter(x, y, s=60)
-                fig.line(spine_x_values, spine_y_values, line_color="red", legend_label="Spine", line_width=2,
-                         muted_alpha=0.2)
-                fig.legend.click_policy = "mute"
-            color_box = BoxAnnotation(left=0, right=mini_container.max_width, bottom=mini_container.y_offset,
+                fig_spine = fig.line(spine_x_values, spine_y_values, line_color="red", line_width=2,
+                                     muted_alpha=0.2)
+                legend_spine.append(fig_spine)
+                legend_polygons = legend_polygons + [fig_polygon, fig_circle]
+
+            if solo_box_border:
+                mini_box_border = mini_container.current_right_boundary
+                fig.title.text = 'End-Container mini-containers with solo boundarys'
+            else:
+                mini_box_border = self.max_width
+            color_box = BoxAnnotation(left=0, right=mini_box_border, bottom=mini_container.y_offset,
                                       top=mini_container.y_offset + mini_container.height, fill_color=color,
                                       fill_alpha=0.1)
             fig.add_layout(color_box)
-            fig.line([0, mini_container.max_width, mini_container.max_width, 0, 0],
-                     [0 + y_offset, 0 + y_offset, mini_container.height + y_offset, mini_container.height + y_offset,
-                      0 + y_offset], line_color=color, muted_alpha=0.2, legend_label=legend_label)
+            fig_border = fig.line([0, mini_box_border, mini_box_border, 0, 0],
+                                  [0 + y_offset, 0 + y_offset, mini_container.height + y_offset,
+                                   mini_container.height + y_offset,
+                                   0 + y_offset], line_color=color, muted_alpha=0.2)
             y_offset += mini_container.height
+            legend_label = "Mini-Container {} height:{} (hc{})".format(counter, int(mini_container.height),
+                                                                       mini_container.hc_i)
+            legend_polygons.append(fig_border)
+            legend_mini_containers.append((legend_label, legend_polygons))
+        spine_legend = [("spine", legend_spine)]
+        legend_items = legend_items + legend_mini_containers + spine_legend
+        legend = Legend(items=legend_items)
+
+        fig.add_layout(legend, 'right')
+        fig.legend.click_policy = "mute"
         # mplcursors.cursor()
         if render:
             return show(fig)
         else:
             return fig
 
-def plot_polygons_in_single_plot(polygon_list, title="", render=True, border=None):
-    polygon_number = len(polygon_list)
-    #         x_data = self.x_values
-    #         y_data = self.y_values
-    TOOLTIPS = [("index", "$index"), ("(x,y)", "($x, $y)"), ]
-    #         if title=="":
-    #             title= 'height:{}  slope:{}'.format(height,slope)
-    #         else:
-    #             title= '{} height:{}  slope:{}'.format(title,height,slope)
-    fig = figure(title=title, x_axis_label='x', y_axis_label='y', tooltips=TOOLTIPS, toolbar_location="below")
-    colors = itertools.cycle(palette)
-    legend_items = []
-    legend_polygons = []
-    for counter, polygon in enumerate(polygon_list):
-        color = next(colors)
-        x = polygon.x_values
-        y = polygon.y_values
-        legend_label = "Polygon {}".format(counter)
-        poly_fig = fig.line(x, y, color=color, line_width=2, muted_alpha=0.2)
-        circle_fig = fig.circle(x, y, color=color, line_width=2, muted_alpha=0.2, size=8)
-        legend_polygons.append((legend_label, [poly_fig, circle_fig]))
-    #         spine_x_values = [x[0] for x in self.spine]
-    #         spine_y_values = [x[1] for x in self.spine]
-    if border != None:
-        fig_border = fig.line(border[0], border[1], line_color="red", line_width=2, muted_alpha=0.2)
+
+class Convex_Container(object):
+    def __init__(self, end_container, plots=False):
+        self.angle_0_end_container = deepcopy(end_container)
+        self.end_container_list = []  # Liste aller Endcontainer
+        self.end_container_polygons = deepcopy(end_container.polygons)  # die Polygone des endcontainers unrotiert
+        self.back_rotated_polygons_plots = []
+        self.container_plots = []
+        self.smallest_end_container, self.polygons, self.angle, self.area = self.find_convex_container(plots)
+        self.width = self.smallest_end_container.max_width
+        self.height = self.smallest_end_container.max_height
+        self.box_boundarys_x_values, self.box_boundarys_y_values = self.set_boundarys()
+
+    def find_convex_container(self, plot=False):
+        list_of_area = []
+        polygons = []
+
+        for angle in range(0, 360, 10):
+            polygons = self.rotate_polygons(self.end_container_polygons, -angle)
+            qs = height_classes(polygons)
+            containers = building_containers(qs)
+            mini_containers = pack_mini_containers(containers)
+            end_container = End_Container(mini_containers)
+            end_container.angle = angle
+            self.end_container_list.append(end_container)
+            list_of_area.append(end_container)
+            # if plot==True:
+
+            if plot:
+                title = 'End-Container   area: {} not-optimal-area: {} angle: {}'.format(
+                    truncate(end_container.container_area, 1), truncate(end_container.container_not_opt_area, 1),
+                    -end_container.angle)
+                self.container_plots.append(end_container.plot_container(render=False, title=title))
+
+                scp = end_container.polygons
+                back_rotated_polygons = self.rotate_polygons(scp, angle)
+                box_x_v = end_container.x_values_border
+                box_y_v = end_container.y_values_border
+                boundarys = list(zip(box_x_v, box_y_v))
+                x_values, y_values = self.rotate_points(boundarys, angle, split_x_y=True)
+                title2 = 'Convex-Container   area: {} not-optimal-area: {} angle: {}'.format(
+                    truncate(end_container.container_area, 1), truncate(end_container.container_not_opt_area, 1),
+                    -end_container.angle)
+                back_rotated_polygon_plot = plot_polygons_in_single_plot(back_rotated_polygons, render=False,
+                                                                         border=(x_values, y_values), title=title2)
+                self.back_rotated_polygons_plots.append(back_rotated_polygon_plot)
+            #
+            # area = end_container.container_area
+
+        sorted_container = sorted(list_of_area, key=lambda k: k.container_area)
+        smallest_container = sorted_container[0]
+        angle = smallest_container.angle
+        print("smallest poylgon", angle)
+        smallest_container_polygons = deepcopy(sorted_container[0].polygons)
+        back_rotated_polygons = self.rotate_polygons(smallest_container_polygons, angle)
+        return (smallest_container, back_rotated_polygons, angle, smallest_container.container_area)
+
+    def set_boundarys(self):
+        container = self.smallest_end_container
+        box_boundarys_x_values = [0, 0, self.width, self.width, 0]
+        box_boundarys_y_values = [0, self.height, self.height, 0, 0]
+        boundarys = list(zip(box_boundarys_x_values, box_boundarys_y_values))
+        x_values, y_values = self.rotate_points(boundarys, container.angle, split_x_y=True)
+        return (x_values, y_values)
+
+    #     def smallest_convex_container(self,convex_container_list):
+    #         sorted_container = sorted(convex_container_list,key=lambda k:k.container_area)
+    #         smallest_container=sorted_container[0]
+    #         return smallest_container
+
+    def rotate_polygons(self, polygons, angle):
+        rotated_polygons = []
+        for polygon in polygons:
+            rotated_polygons.append(self.create_rotated_polygon(polygon, angle))
+        return rotated_polygons
+
+    def rotate_points(self, point_list, angle, split_x_y=False):
+        x_values = []
+        y_values = []
+        angle = angle * math.pi / 180.0
+        cosp = math.cos(angle)
+        sinp = math.sin(angle)
+        if abs(cosp) < 2.5e-16:
+            cosp = 0.0
+        if abs(sinp) < 2.5e-16:
+            sinp = 0.0
+        for point in point_list:
+            point_x = (cosp * point[0]) - (sinp * point[1])
+            point_y = (sinp * point[0]) + (cosp * point[1])
+            x_values.append(point_x)
+            y_values.append(point_y)
+        if split_x_y:
+            return (x_values, y_values)
+        else:
+            return list(zip(x_values, y_values))
+
+    def create_rotated_polygon(self, polygon, angle):
+        # https://github.com/Toblerity/Shapely/blob/master/shapely/affinity.py hilfe aus zeile 160
+        rotated_shell = []
+        angle = angle * math.pi / 180.0
+        cosp = math.cos(angle)
+        sinp = math.sin(angle)
+        if abs(cosp) < 2.5e-16:
+            cosp = 0.0
+        if abs(sinp) < 2.5e-16:
+            sinp = 0.0
+        for vertex in polygon.shell:
+            vertex_x = (cosp * vertex[0]) - (sinp * vertex[1])
+            vertex_y = (sinp * vertex[0]) + (cosp * vertex[1])
+            rotated_shell.append((vertex_x, vertex_y))
+        return Polygon2(rotated_shell)
+
+    def plot_finding_cc_steps(self, render=True, colums=9, plot_width=500, plot_height=500):
+        grid = gridplot(self.container_plots, ncols=colums, plot_width=plot_width, plot_height=plot_height)
+        if render:
+            return show(grid)
+        else:
+            return grid
+
+    def plot_all_cc(self, render=True, colums=9, plot_width=500, plot_height=500):
+        grid = gridplot(self.back_rotated_polygons_plots, ncols=colums, plot_width=plot_width, plot_height=plot_height)
+        if render:
+            return show(grid)
+        else:
+            return grid
+
+    def plot_polygons(self, render=True, title=""):
+        polygon_number = len(self.polygons)
+        #         x_data = self.x_values
+        #         y_data = self.y_values
+        TOOLTIPS = [("index", "$index"), ("(x,y)", "($x, $y)"), ]
+        if title == "":
+            title = 'Convex Container   area: {} angle: {}'.format(int(self.smallest_end_container.container_area),
+                                                                   self.angle)
+        fig = figure(title=title, x_axis_label='x', y_axis_label='y', tooltips=TOOLTIPS, toolbar_location="below")
+        colors = itertools.cycle(palette)
+        legend_items = []
+        legend_polygons = []
+        for counter, polygon in enumerate(self.polygons):
+            color = next(colors)
+            x = polygon.x_values
+            y = polygon.y_values
+            legend_label = "Polygon {}".format(counter)
+            poly_fig = fig.line(x, y, color=color, line_width=2, muted_alpha=0.2)
+            circle_fig = fig.circle(x, y, color=color, line_width=2, muted_alpha=0.2, size=8)
+            legend_polygons.append((legend_label, [poly_fig, circle_fig]))
+        #         spine_x_values = [x[0] for x in self.spine]
+        #         spine_y_values = [x[1] for x in self.spine]
+        fig_border = fig.line(self.box_boundarys_x_values, self.box_boundarys_y_values, line_color="red", line_width=2,
+                              muted_alpha=0.2)
+
+        legend_items = legend_polygons
         legend_items.append(("border", [fig_border]))
-    legend_items = legend_items + legend_polygons
-    legend = Legend(items=legend_items)
-    legend.click_policy = "mute"
-    fig.add_layout(legend, 'right')
-    fig.legend.click_policy = "mute"
-    if render:
-        return show(fig)
+        legend = Legend(items=legend_items)
+        fig.add_layout(legend, 'right')
+        fig.legend.click_policy = "mute"
+        if render:
+            return show(fig)
+        else:
+            return fig
+
+        # x' = cos α * x - sin α * y
+
+
+# y' = sin α * x + cos α * y
+def rotate_polygons2(polygons, angle):
+    rotated_polygons = []
+    for polygon in polygons:
+        rotated_polygons.append(create_rotated_polygon2(polygon, angle))
+    return rotated_polygons
+
+
+def create_rotated_polygon2(polygon, angle):
+    # https://github.com/Toblerity/Shapely/blob/master/shapely/affinity.py hilfe aus zeile 160
+    rotated_shell = []
+    angle = angle * math.pi / 180.0
+    cosp = math.cos(angle)
+    sinp = math.sin(angle)
+    if abs(cosp) < 2.5e-16:
+        cosp = 0.0
+    if abs(sinp) < 2.5e-16:
+        sinp = 0.0
+    for vertex in polygon.shell:
+        vertex_x = (cosp * vertex[0]) - (sinp * vertex[1])
+        vertex_y = (sinp * vertex[0]) + (cosp * vertex[1])
+        rotated_shell.append((vertex_x, vertex_y))
+    return Polygon2(rotated_shell)
+
+
+# Zerlegen des Polygons
+
+def cut_polygon_into_polygons(polygon, number, plot=None):
+    list_polygons = [polygon]
+    plots = []
+    while number > 0:
+        list_helper = []
+        for polygon in list_polygons:
+            if plot == True:
+                cutted_polygons, polygon_plot = cut_polygon(polygon, True)
+                plots.append(polygon_plot)
+            else:
+                cutted_polygons = cut_polygon(polygon)
+            # print(cutted_polygons)
+            list_helper = list_helper + cutted_polygons
+        list_polygons = list_helper
+        number = number - 1
+    if plot == True:
+        return (list_polygons, plots)
     else:
-        return fig
\ No newline at end of file
+        return list_polygons
+
+
+def cut_polygon(polygon, plot=None):
+    polygon = polygon.shell  # polyog
+    number_vertices = len(polygon)
+    if number_vertices < 3:
+        raise ("Polygon has not enough vertices")
+    first_edge = numpy.random.randint(1, number_vertices)
+    second_edge = numpy.random.randint(1, number_vertices)
+    while first_edge == second_edge:
+        second_edge = numpy.random.randint(1, number_vertices)
+    # print(first_edge,second_edge)
+    if first_edge > second_edge:
+        first_edge, second_edge = second_edge, first_edge
+    vertex_1 = polygon[first_edge - 1]
+    vertex_2 = polygon[first_edge]
+    #     if second_edge == number_vertices:
+    #         vertex_3 = polygon[0]
+    #         vertex_4 = polygon[-1]
+    # else:
+    vertex_3 = polygon[second_edge - 1]
+    vertex_4 = polygon[second_edge]
+
+    def helper(vertex_1, vertex_2):
+        new_vertex = (0, 0)
+        if vertex_1[0] == vertex_2[0]:
+            low, high = vertex_1[1], vertex_2[1]
+            if low > high:
+                low, high = high, low
+            rand_number = numpy.random.uniform(low, high)
+            new_vertex = (vertex_1[0], rand_number)
+        elif vertex_1[1] == vertex_2[1]:
+            low, high = vertex_1[0], vertex_2[0]
+            if low > high:
+                low, high = high, low
+            rand_number = numpy.random.uniform(low, high)
+            new_vertex = (rand_number, vertex_1[1])
+        else:
+            # y = m*x+n
+            # n = y-m*x
+            slope = (vertex_1[1] - vertex_2[1]) / (vertex_1[0] - vertex_2[
+                0])  # m = y2-y1/x2-x1 Formel für die Geradensteigung mithilfe aus zwei verschiedenen Punkten der Geraden
+            n = vertex_1[1] - (slope * vertex_1[0])
+            low, high = vertex_1[1], vertex_2[1]
+            if low > high:
+                low, high = high, low
+            rand_number = numpy.random.uniform(low, high)
+            new_vertex_x = (rand_number - n) / slope  # x=(y-n)/m
+            new_vertex = (new_vertex_x, rand_number)
+        return new_vertex
+
+    new_vertex_1 = helper(vertex_1, vertex_2)
+    new_vertex_2 = helper(vertex_3, vertex_4)
+    polygon_1 = polygon[:first_edge] + [new_vertex_1] + [new_vertex_2] + polygon[second_edge:]
+    polygon_2 = [new_vertex_1] + polygon[first_edge:second_edge] + [new_vertex_2] + [new_vertex_1]
+    #  s = [1,2,5,6,7] ,s[6:] => []; daher können wir für den spezial Fall second_edge== vertices_number so vorgehen
+    if plot == True:
+        plot_fig = plot_polygons_in_single_plot([Polygon2(polygon_1), Polygon2(polygon_2)], render=False)
+        return ([Polygon2(polygon_1), Polygon2(polygon_2)], plot_fig)
+    else:
+        return [Polygon2(polygon_1), Polygon2(polygon_2)]
+
+# def plot_polygons2(polygon_list,title="",render=True, border=None):
+#         polygon_number = len(polygon_list)
+# #         x_data = self.x_values
+# #         y_data = self.y_values
+#         TOOLTIPS= [("index", "$index"),("(x,y)", "($x, $y)"),]
+# #         if title=="":
+# #             title= 'height:{}  slope:{}'.format(height,slope)
+# #         else:
+# #             title= '{} height:{}  slope:{}'.format(title,height,slope)
+#         fig = figure(title=title, x_axis_label='x', y_axis_label='y', tooltips=TOOLTIPS, toolbar_location="below")
+#         colors = itertools.cycle(palette)
+#         legend_items=[]
+#         legend_polygons=[]
+#         for counter,polygon in enumerate(polygon_list):
+#             color = next(colors)
+#             x= polygon.x_values
+#             y= polygon.y_values
+#             legend_label="Polygon {}".format(counter)
+#             poly_fig = fig.line(x,y,color=color,line_width=2, muted_alpha=0.2)
+#             circle_fig = fig.circle(x,y,color=color, line_width=2, muted_alpha=0.2,size=8)
+#             legend_polygons.append((legend_label, [poly_fig, circle_fig]))
+# #         spine_x_values = [x[0] for x in self.spine]
+# #         spine_y_values = [x[1] for x in self.spine]
+#         if border !=None:
+#             fig.line(border[0],border[1], line_color="red",legend_label="Border", line_width=2,muted_alpha=0.2)
+
+#         legend_items=legend_polygons
+#         legend = Legend(items=legend_items)
+#         legend.click_policy="mute"
+#         fig.add_layout(legend, 'right')
+#         fig.legend.click_policy="mute"
+#         if render:
+#             return show(fig)
+#         else:
+#             return fig
+# def plot_polygons2(polygon_list):
+#         polygon_number = len(polygon_list)
+#         fig, ax = plt.subplots(1,figsize=(9, 8), dpi= 80, facecolor='w', edgecolor='k')
+#         plt.tight_layout(pad=10, w_pad=10, h_pad=3)
+
+#         for polygon in polygon_list:
+#             x= polygon.x_values
+#             y= polygon.y_values
+#             for x_text, y_text in polygon.shell :
+#                 ax.text(x_text, y_text-(y_text*0.2), '({}, {})'.format(int(x_text*10)/10, int(y_text*10)/10),)
+#             ax.plot(x, y)
+#             ax.scatter(x, y, s=60)
+#             ax.set_title('A single plot')
+# ngon = numpy.random.randint(3,max_ngon+1)
+#     #ries=0
+#     max_rand= 1000
+
+#     #tries=tries+1
+#     polygon_points=[]
+#     while len(polygon_points)<ngon:
+
+
+#         x = numpy.random.randint(1,max_rand)
+#         y = numpy.random.randint(1,max_rand)
+# #             x = numpy.random.random()
+# #             y = numpy.random.random()
+#         while (x,y) in polygon_points:
+# #             x = numpy.random.random()
+# #             y = numpy.random.random()
+#             x = numpy.random.randint(1,max_rand)
+#             y = numpy.random.randint(1,max_rand)
\ No newline at end of file
diff --git a/mysite/plots/templates/plots/test.html b/mysite/plots/templates/plots/test.html
index 6309ac9f..974e89d2 100644
--- a/mysite/plots/templates/plots/test.html
+++ b/mysite/plots/templates/plots/test.html
@@ -24,18 +24,21 @@
         </script>
     </head>
     <body>
-    <form action="/hello/" target="_blank" method="post">
+
+
+        <div>
+            {{ response|safe }}
+            <form action="/test/"  method="post">
         {% csrf_token %}
-        <label for="your_name">Your name: </label>
+        <label for="your_name"></label>
     <input id="your_name" type="hidden" name="your_name" value="test">
-    <input type="submit" onclick="myFunction()" value="OK">
+    <input type="submit" onclick="myFunction()" value="Load Polygons">
     </form>
-    <p id="p1">Hello World!</p>
-        <div>
-            {{ response|safe }}
-
-
+            <!--{{response4|safe}}-->
         </div>
+
+            {{polygons_plot|safe}}
+            {{polygons_single_plot|safe}}
     </body>
 <script type="text/javascript">
 
diff --git a/mysite/plots/urls.py b/mysite/plots/urls.py
index 87e27c24..5314b36e 100644
--- a/mysite/plots/urls.py
+++ b/mysite/plots/urls.py
@@ -1,10 +1,11 @@
 from django.urls import path
-
+from plots.views import PolygonEditView
 from . import views
 
 urlpatterns = [
     path('plot/', views.index, name='index'),
     path('json/', views.get_json_view, name='index2'),
-    path('test/', views.test, name='index3'),
+    #path('test/', views.test, name='index3'),
     path('hello/', views.hello, name='index4'),
+    path('test/', PolygonEditView.as_view(), name='index4'),
 ]
\ No newline at end of file
diff --git a/mysite/plots/views.py b/mysite/plots/views.py
index 7f4ec534..c0427ebb 100644
--- a/mysite/plots/views.py
+++ b/mysite/plots/views.py
@@ -4,9 +4,13 @@ from django.shortcuts import render
 
 import json
 from django.shortcuts import render
+from django.views import View
+
 from plotly.offline import plot
+from django.http import HttpResponseRedirect
 import plots.polygon as poly
 from bokeh.embed import file_html
+from bokeh.models import BoxZoomTool
 from django.views.generic import TemplateView
 import matplotlib
 from django.http import JsonResponse
@@ -163,16 +167,64 @@ def test(request):
     # l1 = p.line("x", "y", source=source)
     # response = file_html(p, CDN, "my plot")
     # list =[1,2,3,4]
+    if request.method == "POST":
+        context={}
+        print(request.POST)
+        test = request.POST["your_name"]
+        dict_poly = json.loads(test)
+        print(dict_poly["x"])
+        print(dict_poly["y"])
+        polygon_list=[]
+        polygons_x_y_tuple = list(zip(dict_poly["x"],dict_poly["y"]))
+        # polygon_x_list = []
+        # polygon_y_list = []
+        for x,y in  polygons_x_y_tuple:
+            polygon_list.append(list(zip(x,y)))
+        # for x,y in polygons_x_y_tuple:
+        #     polygon_x_list.append(x)
+        #     polygon_y_list.append(y)
+        print(polygon_list)
+        real_polygons=[]
+        for polygon in polygon_list:
+
+            if len(polygon)<3:
+                continue
+            if polygon[0]!= polygon[-1]:
+                polygon.append(polygon[0])
+
 
+            polygon2 = poly.Polygon(polygon)
+            print("konkav",list(polygon2.exterior.coords))
+            polygon_parent_class = polygon2.convex_hull
+            polygon2 = poly.Polygon2(list(polygon_parent_class.exterior.coords))
+            print("convex",polygon2.shell)
+            real_polygons.append(polygon2)
+        # print(polygon_list)
+        # q = map(list, zip(*polygon_list))
+        # s=  json.loads(test)
+        # x = s["x"]
+        # y = s["y"]
+        # source = ColumnDataSource(data=dict(x=polygon_x_list, y=polygon_y_list),name='my-data-source')
+        # print(test)
+        plot = poly.plot_polygons_in_single_plot(real_polygons,render=False)
+        # plot = poly.plot_polygons(real_polygons,render=False)
+        # print(type(test))
+        # p = figure()
+        # p.multi_line("x", "y", source=source)
+        response2 = file_html(plot, CDN, "my plot")
+        context["response3"]=response2
+        return HttpResponseRedirect('/test/')
+    TOOLTIPS = [("index", "$index"), ("(x,y)", "($x{1.1}, $y{1.1})"), ]
     source = ColumnDataSource(data=dict(x=[],
                                        y=[]),
                              name='my-data-source')
+
     p = figure(x_range=(0, 10), y_range=(0, 10), width=400, height=400,
-               title='Poly Edit Tool')
+               title='Poly Edit Tool',tooltips=TOOLTIPS)
 
     p1 = p.patches("x", "y", fill_alpha=0.4,source=source, fill_color="red")
 
-    c1 = p.circle([], [], size=10, color='red')
+    c1 = p.circle([],[], size=10, color='red', )
 
     draw_tool = PolyDrawTool(renderers=[p1])
     edit_tool = PolyEditTool(renderers=[p1], vertex_renderer=c1)
@@ -230,4 +282,106 @@ def hello(request):
         # polygon = Polygon(polygon_points)
         # polygon_parent_class = polygon.convex_hull
         # polygon2 = Polygon2(list(polygon_parent_class.exterior.coords))
-        return HttpResponse(response)
\ No newline at end of file
+        return HttpResponse(response)
+
+class PolygonEditView(View):
+    context={}
+    polygons=[]
+    plot_min_x= 0
+    plot_max_x= 100
+    plot_min_y = 0
+    plot_max_y= 100
+    colum_data_x=[[]]
+    colum_data_y=[[]]
+    def get(self, request, *args, **kwargs):
+        TOOLTIPS = [("index", "$index"), ("(x,y)", "($x{1.1}, $y{1.1})"), ]
+        source = ColumnDataSource(data=dict(x=PolygonEditView.colum_data_x,
+                                            y=PolygonEditView.colum_data_y),
+                                  name='my-data-source')
+
+        p = figure(x_range=(PolygonEditView.plot_min_x, PolygonEditView.plot_max_x), y_range=(PolygonEditView.plot_min_y, PolygonEditView.plot_max_y), width=750, height=750,
+                   title='Poly Edit Tool', tooltips=TOOLTIPS)
+        p.aspect_ratio = 1
+        p1 = p.patches("x", "y", fill_alpha=0.4, source=source, fill_color="red")
+
+        c1 = p.circle([], [], size=10, color='red', )
+
+        draw_tool = PolyDrawTool(renderers=[p1])
+        edit_tool = PolyEditTool(renderers=[p1], vertex_renderer=c1)
+
+        p.add_tools(draw_tool, edit_tool)
+        p.toolbar.active_drag = edit_tool
+        response = file_html(p, CDN, "my plot")
+        PolygonEditView.context["response"]=response
+        return render(request, 'plots/test.html', PolygonEditView.context)
+
+    def post(self, request, *args, **kwargs):
+
+        test = request.POST["your_name"]
+        dict_poly = json.loads(test)
+        print(dict_poly["x"])
+        print(dict_poly["y"])
+        PolygonEditView.colum_data_x.clear()
+        PolygonEditView.colum_data_y.clear()
+
+        for poly_x in dict_poly["x"]:
+            PolygonEditView.colum_data_x.append(poly_x)
+        for poly_y in dict_poly["y"]:
+            PolygonEditView.colum_data_y.append(poly_y)
+
+
+        polygon_list=[]
+        polygons_x_y_tuple = list(zip(dict_poly["x"],dict_poly["y"]))
+        # polygon_x_list = []
+        # polygon_y_list = []
+        for x,y in  polygons_x_y_tuple:
+            polygon_list.append(list(zip(x,y)))
+        # for x,y in polygons_x_y_tuple:
+        #     polygon_x_list.append(x)
+        #     polygon_y_list.append(y)
+        print(polygon_list)
+        real_polygons=[]
+        polygon_max_x_list=[]
+        polygon_min_x_list = []
+        polygon_min_y_list = []
+        polygon_max_y_list=[]
+        for polygon in polygon_list:
+
+            if len(polygon)<3:
+                continue
+            if polygon[0]!= polygon[-1]:
+                polygon.append(polygon[0])
+
+
+            polygon2 = poly.Polygon(polygon)
+            print("konkav",list(polygon2.exterior.coords))
+            polygon_parent_class = polygon2.convex_hull
+            polygon2 = poly.Polygon2(list(polygon_parent_class.exterior.coords))
+            polygon_max_x_list.append(polygon2.max_x)
+            polygon_min_x_list.append(polygon2.min_x)
+            polygon_max_y_list.append(polygon2.max_y)
+            polygon_min_y_list.append(polygon2.min_y)
+            real_polygons.append(polygon2)
+        PolygonEditView.polygons = real_polygons
+
+        PolygonEditView.plot_max_y = max(polygon_max_y_list)
+
+        PolygonEditView.plot_min_y = min(polygon_min_y_list)
+
+        PolygonEditView.plot_max_x = max(polygon_max_x_list)
+
+        PolygonEditView.plot_min_x = min(polygon_min_x_list)
+
+
+        polygons_single_plot = poly.plot_polygons_in_single_plot(real_polygons,render=False)
+        plot = poly.plot_polygons(real_polygons,render=False)
+        # print(type(test))
+        # p = figure()
+        # p.multi_line("x", "y", source=source)
+        polygons_plot_html= file_html(plot, CDN, "my plot")
+        polygons_single_plot_html = file_html(polygons_single_plot, CDN, "single plot")
+        #self.polygons.append(response2)
+        PolygonEditView.context["polygons_plot"]= polygons_plot_html
+        PolygonEditView.context["polygons_single_plot"] = polygons_single_plot_html
+        return HttpResponseRedirect('/test/')
+
diff --git a/mysite/requirements/base.txt b/mysite/requirements/base.txt
index 25affeca..ef327b2d 100644
--- a/mysite/requirements/base.txt
+++ b/mysite/requirements/base.txt
@@ -6,4 +6,5 @@ mplcursors==0.3
 mpld3
 bokeh
 django-jquery
-django.js==0.8.1
\ No newline at end of file
+django.js==0.8.1
+pandas ==1.1.3
\ No newline at end of file
-- 
GitLab