diff --git a/code v.1.1 b/code v.1.1 new file mode 100644 index 0000000000000000000000000000000000000000..8d1a01eebf5e12e0e07592553477a50551a57c7b --- /dev/null +++ b/code v.1.1 @@ -0,0 +1,548 @@ +# GAPI chart generator v.1.1 +# W.Wojnowski 2021 + +# imports +from tkinter import * +from tkinter import ttk +from tkinter import filedialog +from matplotlib.patches import Ellipse +import matplotlib.pyplot as plt +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg +import webbrowser + +# start the program +root = Tk() + +# app title: +root.title('GAPI v.1.1') + +# default app size: +root.geometry('1300x700') +root.minsize(1300, 700) + +# configure the background +root.configure(bg='white', padx=8, pady=8) + +# create the small icon in the task bar: +root.iconbitmap('GAPI_icon.ico') +# root.iconbitmap(r'C:\Users\Admin\Dysk Google\GAPI_rev\GAPI_icon.ico') + +# create the menu +menu = Menu(root) + +# configure the menu: +root.config(menu=menu) +file_menu = Menu(menu) +menu.add_cascade(label='File', menu=file_menu) +file_menu.config(bg='white') + +# function for saving the image (raster or vector): +def saveImage(): + ftypes = [('PNG file', '.png'), ('SVG file', '.svg'), ('All files', '*')] + filename = filedialog.asksaveasfilename(filetypes=ftypes, defaultextension='.png') + # save the plot in the specified path; the 'tight' option removes the whitespace from around the figure: + plt.savefig(filename, bbox_inches='tight', dpi=300) + +# add the image save option to the file menu +file_menu.add_command(label='Save image', command=saveImage) + +# create a popup window with citation information (to be filled in at a later time) +def popup_bonus(): + win = Toplevel() + win.wm_title('Cite As') + root.iconbitmap('GAPI_icon.ico') + + + def callback(event): + webbrowser.open_new(event.widget.cget("text")) + + cite_label1 = Label(win, text="If you are using the GAPI chart generator in your research, please cite: \n" + "Lorem ipsum\n" + " Dolor sit amet", justify=LEFT) + cite_label1.grid(row=0, column=0, padx=8, pady=8) + + cite_label2 = Label(win, text=r'https://doi.org/someDOI', fg='blue', cursor='hand2', justify=LEFT) + cite_label2.grid(row=1, column=0, padx=8, pady=8) + cite_label2.bind('<Button-1>', callback) + + cite_label3 = Label(win, text='BibTeX entry:', justify=LEFT) + cite_label3.grid(row=2, column=0, padx=8, pady=8) + + cite_label4 = Label(win, + text='@article{AC:,\n' + 'author = {},\n' + 'title = {},\n' + 'journal = {},\n' + 'year = {2021},\n' + 'url = https://doi.org/someDOI\n' + '}', + wraplength=300, justify=LEFT, bg='white') + + cite_label4.grid(row=3, column=0, padx=8, pady=8) + +# add the 'About' option to the file menu +file_menu.add_command(label='About', command=popup_bonus) + +# configure the dropdown menu +dropdown_style = ttk.Style() +dropdown_style.theme_use('clam') +dropdown_style.configure("TMenubutton", background="white", width=20) +label_style = ttk.Style() +label_style.theme_use('clam') +label_style.configure('TLabel', background='white') + +# create a top frame to pack the banner +topFrame = Frame(root, padx=10, pady=10, bg='white', bd=1) +topFrame.pack(side=TOP, anchor=NW) +fig_canvas = Canvas(root, width=1000, heigh=60, bg='white', bd=0, highlightthickness=0) +fig_canvas.pack() +banner = PhotoImage(file='banner2.png') +fig_canvas.create_image(3, 2, anchor=NW, image=banner) + +# create three separate frames; left and middle for the interface, right for the graph. +leftFrame = Frame(root, bd=1, width=600, padx=10, pady=10, bg='white') +leftFrame.pack(side=LEFT, anchor=N) +leftFrame.columnconfigure(0, minsize=100) +leftFrame.columnconfigure(1, minsize=150) + +middleFrame = Frame(root, bd=1, width=600, padx=10, pady=10, bg='white') +middleFrame.pack(side=LEFT, anchor=N) +middleFrame.columnconfigure(0, minsize=100) +middleFrame.columnconfigure(1, minsize=150) + +rightFrame = Frame(root, width=600, height=600, padx=1, pady=1, bg='grey') +rightFrame.pack(side=RIGHT, anchor=N) +bottomFrame = Frame(root, bd=1).pack(side=BOTTOM, anchor=W) + +# Create the graph (figure) and the canvas +fig, ax = plt.subplots(figsize=(675.93 / 100, 642.84 / 100), dpi=100) # figsize/dpi +ax.axis('equal') + +c = FigureCanvasTkAgg(fig, master=rightFrame) +plot_widget = c.get_tk_widget() +plot_widget.pack(side=TOP) + +# remove the axes from the matplotlib graph +plt.axis('off') + +# create a common class for the shapes +class Polygon: + + def __init__(self, x, y, color, edgecolor, lw, canvas): + self.x = x + self.y = y + self.color = color + self.edgecolor = edgecolor + self.lw = lw + self.canvas = canvas + + plt.fill(self.x, self.y, facecolor=self.color, edgecolor=self.edgecolor, lw=self.lw) + + def polygonreload(self): + plt.fill(self.x, self.y, facecolor=self.color, edgecolor=self.edgecolor, lw=self.lw) + + # refresh the canvas with the graph: + ellipse_1.edgecolor=polygons[4].color + CenterEllipse.ellipsereload(ellipse_1) + self.canvas.draw() + +class CenterEllipse: + + def __init__(self, canvas, edgecolor, lw): + self.canvas = canvas + self.visible = False + self.edgecolor = edgecolor + self.lw = lw + + ellipse = Ellipse(xy=(337.96, 355.35), width=100, height=63, edgecolor=self.edgecolor, + fc='None', lw=self.lw, zorder=1, visible=self.visible) + ax.add_patch(ellipse) + + # the zorder parameter makes sure that the ellipse stays on top of the pentagon + def ellipsereload(self): + ellipse = Ellipse(xy=(337.96, 355.35), width=100, height=63, edgecolor=self.edgecolor, + fc='None', lw=self.lw, zorder=1, visible=self.visible) + ax.add_patch(ellipse) + self.canvas.draw() + # Polygon.polygonreload(polygons[4]) + + +class EllipseDropdown(): + + def __init__(self, master, options, label_text, row): + self.master = master + self.options = options + self.label_text = label_text, + self.row = row + self.var = StringVar(self.master) + self.var.set('n.a.') + + self.label = ttk.Label(self.master, text=label_text).grid(row=self.row, column=0, padx=8, sticky=W) + self.dropdown = ttk.OptionMenu(self.master, self.var, self.var.get(), *self.options.keys()) + self.dropdown.grid(row=self.row, column=1, padx=8, sticky=W) + + self.ellipse = CenterEllipse(c, edgecolor='black', lw=0.5) + + # monitor the changes done via the dropdown ('w' - 'write') to update + # the visibility of the ellipse + self.var.trace('w', self.change_dropdown) + + def change_dropdown(self, *args): + self.ellipse.visible = self.options[self.var.get()] + if self.options[self.var.get()] == False: + self.ellipse.lw = 0.9 + self.ellipse.edgecolor = polygons[4].color + else: + self.ellipse.lw = 0.5 + self.ellipse.edgecolor = 'black' + + Polygon.polygonreload(polygons[4]) + CenterEllipse.ellipsereload(self.ellipse) + + +class OptionsDropdown: + + def __init__(self, master, options, plgn, label_text, row, number): + + self.options = options + self.master = master + self.var = StringVar(self.master) + self.var.set('n.a.') + self.row = row + self.number = number + + self.label = ttk.Label(self.master, text=label_text).grid(row=self.row, column=0, padx=8, sticky=W) + self.dropdown = ttk.OptionMenu(self.master, self.var, self.var.get(), *self.options.keys()) + self.dropdown.grid(row=self.row, column=1, padx=8, sticky=W) + + self.shape = plgn + # monitor the changes done via the dropdown ('w' - 'write') to update + # the colour of the polygon + self.var.trace('w', self.change_dropdown) + + def change_dropdown(self, *args): + self.shape.color = colors[self.options[self.var.get()]] + + # make sure the sub-graph disappears entirely if the corresponding polygons are empty. + # the difference in LineWidth (lw) between the white and black lines is meant to prevent fanthom outlines. + + if polygons[0].color != 'white' or polygons[1].color != 'white' or polygons[2].color != 'white' or polygons[3].color != 'white': + polygons[0].edgecolor = 'black' + polygons[1].edgecolor = 'black' + polygons[2].edgecolor = 'black' + polygons[3].edgecolor = 'black' + polygons[0].lw = 0.5 + polygons[1].lw = 0.5 + polygons[2].lw = 0.5 + polygons[3].lw = 0.5 + else: + polygons[0].edgecolor = 'white' + polygons[1].edgecolor = 'white' + polygons[2].edgecolor = 'white' + polygons[3].edgecolor = 'white' + polygons[0].lw = 1.0 + polygons[1].lw = 1.0 + polygons[2].lw = 1.0 + polygons[3].lw = 1.0 + + if polygons[4].color != 'white': + polygons[4].edgecolor = 'black' + polygons[4].lw = 0.5 + else: + polygons[4].edgecolor = 'black' + polygons[4].lw = 0.5 + + if polygons[5].color != 'white' or polygons[6].color != 'white' or polygons[7].color != 'white': + polygons[5].edgecolor = 'black' + polygons[6].edgecolor = 'black' + polygons[7].edgecolor = 'black' + polygons[5].lw = 0.5 + polygons[6].lw = 0.5 + polygons[7].lw = 0.5 + else: + polygons[5].edgecolor = 'white' + polygons[6].edgecolor = 'white' + polygons[7].edgecolor = 'white' + polygons[5].lw = 1.0 + polygons[6].lw = 1.0 + polygons[7].lw = 1.0 + + if polygons[8].color != 'white' or polygons[9].color != 'white' or polygons[10].color != 'white': + polygons[8].edgecolor = 'black' + polygons[9].edgecolor = 'black' + polygons[10].edgecolor = 'black' + polygons[8].lw = 0.5 + polygons[9].lw = 0.5 + polygons[10].lw = 0.5 + else: + polygons[8].edgecolor = 'white' + polygons[9].edgecolor = 'white' + polygons[10].edgecolor = 'white' + polygons[8].lw = 1.0 + polygons[9].lw = 1.0 + polygons[10].lw = 1.0 + + if polygons[11].color != 'white' or polygons[12].color != 'white' or polygons[13].color != 'white' or polygons[14].color != 'white': + polygons[11].edgecolor = 'black' + polygons[12].edgecolor = 'black' + polygons[13].edgecolor = 'black' + polygons[14].edgecolor = 'black' + polygons[11].lw = 0.5 + polygons[12].lw = 0.5 + polygons[13].lw = 0.5 + polygons[14].lw = 0.5 + else: + polygons[11].edgecolor = 'white' + polygons[12].edgecolor = 'white' + polygons[13].edgecolor = 'white' + polygons[14].edgecolor = 'white' + polygons[11].lw = 1.0 + polygons[12].lw = 1.0 + polygons[13].lw = 1.0 + polygons[14].lw = 1.0 + + if polygons[15].color != 'white' or \ + polygons[16].color != 'white' or \ + polygons[17].color != 'white' or \ + polygons[18].color != 'white' or \ + polygons[19].color != 'white' or \ + polygons[20].color != 'white' or \ + polygons[21].color != 'white' or \ + polygons[22].color != 'white' or \ + polygons[23].color != 'white' or \ + polygons[24].color != 'white' or \ + polygons[25].color != 'white' or \ + polygons[26].color != 'white': + polygons[15].edgecolor = 'black' + polygons[16].edgecolor = 'black' + polygons[17].edgecolor = 'black' + polygons[18].edgecolor = 'black' + polygons[19].edgecolor = 'black' + polygons[20].edgecolor = 'black' + polygons[21].edgecolor = 'black' + polygons[22].edgecolor = 'black' + polygons[23].edgecolor = 'black' + polygons[24].edgecolor = 'black' + polygons[25].edgecolor = 'black' + polygons[26].edgecolor = 'black' + polygons[15].lw = 0.5 + polygons[16].lw = 0.5 + polygons[17].lw = 0.5 + polygons[18].lw = 0.5 + polygons[19].lw = 0.5 + polygons[20].lw = 0.5 + polygons[21].lw = 0.5 + polygons[22].lw = 0.5 + polygons[23].lw = 0.5 + polygons[24].lw = 0.5 + polygons[25].lw = 0.5 + polygons[26].lw = 0.5 + + else: + polygons[15].edgecolor = 'white' + polygons[16].edgecolor = 'white' + polygons[17].edgecolor = 'white' + polygons[18].edgecolor = 'white' + polygons[19].edgecolor = 'white' + polygons[20].edgecolor = 'white' + polygons[21].edgecolor = 'white' + polygons[22].edgecolor = 'white' + polygons[23].edgecolor = 'white' + polygons[24].edgecolor = 'white' + polygons[25].edgecolor = 'white' + polygons[26].edgecolor = 'white' + polygons[15].lw = 1.0 + polygons[16].lw = 1.0 + polygons[17].lw = 1.0 + polygons[18].lw = 1.0 + polygons[19].lw = 1.0 + polygons[20].lw = 1.0 + polygons[21].lw = 1.0 + polygons[22].lw = 1.0 + polygons[23].lw = 1.0 + polygons[24].lw = 1.0 + polygons[25].lw = 1.0 + polygons[26].lw = 1.0 + + if self.number in range(0, 4): + for i in range(0, 4): + Polygon.polygonreload(polygons[i]) + + elif self.number in range(5, 8): + for i in range(5, 8): + Polygon.polygonreload(polygons[i]) + + elif self.number in range(8, 11): + for i in range(8, 11): + Polygon.polygonreload(polygons[i]) + + elif self.number in range(11, 15): + for i in range(11, 15): + Polygon.polygonreload(polygons[i]) + + elif self.number in range(15, 27): + for i in range(15, 27): + Polygon.polygonreload(polygons[i]) + + else: + Polygon.polygonreload(polygons[self.number]) + + ell1.change_dropdown() + + + +# define the colors to be used in the graph +colors = { + 'white': 'white', + 'black': 'black', + 'green': '#00FF00', + 'yellow': '#FFFF00', + 'red': '#FF0000' + } + +''' +COORDINATES FOR THE POLYGONS +''' +# list of coordinates for the polygon vertices: +# e.g. polygon 1: [[x1, x2, x3], [y1, y2, y3]] +coords = [ + [[198.68, 122.79, 245.58], [389.89, 285.44, 245.54]], # p1 + [[245.58, 122.79, 61.40, 122.79], [245.54, 285.44, 200.94, 156.33]], # p2 + [[122.79, 23.45, 0.0, 61.40], [285.44, 317.72, 245.54, 200.94]], # p3 + [[198.68, 49.90, 23.45, 122.79], [389.89, 389.89, 317.72, 285.44]], # p4 + [[337.96, 215.17, 262.07, 413.85, 460.75], [484.46, 395.25, 250.90, 250.90, 395.25]], # p5 + [[204.98, 204.98, 327.77], [409.28, 538.39, 498.49]], # p6 + [[204.98, 82.19, 129.09, 204.98], [409.28, 498.49, 642.84, 538.39]], # p7 + [[204.98, 129.09, 280.87, 327.77], [538.39, 642.84, 642.84, 498.49]], # p8 + [[348.15, 470.94, 470.94], [498.49, 538.39, 409.28]], # p9 + [[470.94, 546.83, 395.05, 348.15], [538.39, 642.84, 642.84, 498.49]], # p10 + [[470.94, 593.73, 546.83, 470.94], [409.28, 498.49, 642.84, 538.39]], # p11 + [[477.24, 553.13, 430.34], [389.89, 285.44, 245.54]], # p12 + [[477.24, 553.13, 652.47, 629.02], [389.89, 285.44, 317.72, 389.89]], # p13 + [[652.47, 553.13, 614.52, 675.92], [317.72, 285.44, 200.94, 245.54]], # p14 + [[614.52, 553.13, 430.34, 553.13], [200.92, 285.44, 245.54, 156.33]], # p15 + + [[337.96, 262.07, 413.85], [144.35, 233.56, 233.56]], # p16 + [[413.85, 536.64, 337.96], [233.56, 144.35, 144.35]], # p17 + [[337.96, 536.44, 413.85], [144.35, 144.35, 55.14]], # p18 + + [[413.85, 363.26, 337.96], [55.14, 55.14, 144.35]], # p19 + [[337.96, 312.66, 363.26], [144.35, 55.14, 55.14]], # p20 + [[337.96, 262.07, 312.66], [144.35, 55.14, 55.14]], # p21 + + [[337.96, 221.14, 262.07], [144.35, 84.87, 55.14]], # p23 + [[337.96, 221.14, 180.21], [144.35, 84.87, 114.61]], # p24 + [[337.96, 180.21, 139.28], [144.35, 114.61, 144.35]], # p25 + + [[337.96, 139.28, 180.21], [144.35, 144.35, 174.09]], # p26 + [[337.96, 180.21, 221.14], [144.35, 174.09, 203.82]], # p27 + [[337.96, 221.14, 262.07], [144.35, 203.82, 233.56]], # p28 + +] + +# create the Polygon objects (parts of the graph) based on the list of coordinates +polygons = [] +ellipse_1 = CenterEllipse(c, 'None', 0.5) + +# generate the polygons: +for number in range(0, len(coords)): + polygons.append(Polygon(coords[number][0], coords[number][1], colors['white'], colors['white'], 1.0, c)) + +# the central polygon should always be visible: +polygons[4].edgecolor = 'black' +polygons[4].lw = 0.5 +Polygon.polygonreload(polygons[4]) + +label1 = ttk.Label(leftFrame, text='SAMPLE PREPARATION', font='Helvetica 9 bold').grid(row=1, column=0, columnspan=2, padx=30, sticky='ew') +label2 = ttk.Label(leftFrame, text='REAGENTS AND SOLVENTS', font='Helvetica 9 bold').grid(row=10, column=0, columnspan=2, padx=30, sticky='ew') +label3 = ttk.Label(leftFrame, text='INSTRUMENTATION', font='Helvetica 9 bold').grid(row=14, column=0, columnspan=2, padx=30, sticky='ew') +label4 = ttk.Label(leftFrame, text='METHOD TYPE', font='Helvetica 9 bold').grid(row=25, column=0, columnspan=2, padx=30, sticky='ew') +label5 = ttk.Label(middleFrame, text='YIELD AND CONDITIONS', font='Helvetica 9 bold').grid(row=0, column=0, columnspan=2, padx=30, sticky='ew') +label6 = ttk.Label(middleFrame, text='REAGENTS AND SOLVENTS', font='Helvetica 9 bold').grid(row=3, column=0, columnspan=2, padx=30, sticky='ew') +label7 = ttk.Label(middleFrame, text='INSTRUMENTATION', font='Helvetica 9 bold').grid(row=8, column=0, columnspan=2, padx=30, sticky='ew') +label8 = ttk.Label(middleFrame, text='WORKUP AND PURIFICATION', font='Helvetica 9 bold').grid(row=12, column=0, columnspan=2, padx=30, sticky='ew') + + +options = [ + {'n.a.': 'white', 'In-line': 'green', 'On-line or at-line': 'yellow', 'off-line': 'red'}, # 1 + {'n.a.': 'white', 'None': 'green', 'Chemical or physical': 'yellow', 'Physico-chemical': 'red'}, # 2 + {'n.a.': 'white', 'None': 'green', 'Required': 'red'}, # 3 + {'n.a.': 'white', 'None': 'green', 'Under normal conditions': 'yellow', 'Under special conditions': 'red'}, # 4 + {'n.a.': 'white', 'No sample preparation': 'green', 'Simple procedures': 'yellow', 'Extraction required': 'red'}, # 5 + {'n.a.': 'white', 'Nano-extraction': 'green', 'Micro-extraction': 'yellow', 'Macro-extraction': 'red'}, # 6 + {'n.a.': 'white', 'Solvent-free methods': 'green', 'Green solvents/reagents': 'yellow', 'Non-green solvents/reagents': 'red'}, # 7 + {'n.a.': 'white', 'None': 'green', 'Simple treatments': 'yellow', 'Advanced treatments': 'red'}, # 8 + {'n.a.': 'white', '< 10 mL (< 10 g)': 'green', '10-100 mL (10-100 g)': 'yellow', '> 100 mL (> 100 g)': 'red'}, # 9 + {'n.a.': 'white', 'Slightly toxic, slight irritant; NFPA health hazard score of 0 or 1. No special hazards.': 'green', # 10 + 'Moderately toxic; could cause temporary incapacitation; NFPA = 2 or 3.': 'yellow', + 'Serious injury on short-term exposure; known or suspected small animal carcinogen; NFPA = 4.': 'red'}, + {'n.a.': 'white', 'Highest NFPA flammability or instability score of 0 or 1. No special hazards.': 'green', # 11 + 'Highest NFPA flammability or instability score = 2 or 3, or a special hazard is used.': 'yellow', + 'Highest NFPA flammability or instability score of 4.': 'red'}, + {'n.a.': 'white', '<= 0.1 kWh per sample': 'green', '<= 1.5 kWh per sample': 'yellow', '> 1.5 kWh per sample': 'red'}, # 12 + {'n.a.': 'white', 'Hermetic sealing of the analytical process': 'green', 'Emission of vapours to the atmosphere': 'red'}, # 13 + {'n.a.': 'white', '< 1 mL (< 1 g)': 'green', '1-10 mL (1-10 g)': 'yellow', '> 10 mL (>10 g)': 'red'}, # 14 + {'n.a.': 'white', 'Recycling': 'green', 'Degradation, passivation': 'yellow', 'No treatment': 'red'}, # 15 + {'n.a.': False, 'Qualitative': False, 'Qualitative and quantitative': True}, # 0 + {'n.a.': 'white', '>=89%': 'green', '80-89%': 'yellow', '<=79%': 'red'}, # 16 (I) + {'n.a.': 'white', 'Room temp., < 1 h': 'green', 'Room temp., > 1 h, Heating, < 1 h, Cooling to 0°C': 'yellow', 'Heating, > 1 h \n Cooling < 0°C': 'red'}, + {'n.a.': 'white', 'Inexpensive< 10$': 'green', 'Expensive 10-50$': 'yellow', 'Very expensive': 'red'}, + {'n.a.': 'white', '< 10 mL (mg)': 'green', '10-100 mL (mg)': 'yellow', '> 100 mL (mg)': 'red'}, + + {'n.a.': 'white', 'Slightly toxic, slight irritant; NFPA health hazard score is 0 or 1': 'green', + 'Moderately toxic; could cause temporary incapacitation; NFPA = 2 or 3': 'yellow', + 'Serious injury on short term exposure; known or suspected small animal carcinogen; NFPA = 4': 'red'}, + {'n.a.': 'white', 'Highest NFPA flammability, instability score of 0 or 1. No special hazards ': 'green', + 'Highest NFPA flammability or instability score is 2 or 3, or a special hazard is used': 'yellow', + 'Highest NFPA flammability or instability score is 4': 'red'}, + {'n.a.': 'white', 'Common setup': 'green', 'Additional setups/instruments used': 'yellow', + 'Pressure equipment > 1atm; Glove box ': 'red'}, + {'n.a.': 'white', 'â¤0.1 kWh per sample': 'green', 'â¤1.5 kWh per sample': 'yellow', + '>1.5 kWh per sample': 'red'}, + {'n.a.': 'white', 'Hermetization of analytical proces': 'green', 'Emission of vapours to the atmosphere': 'red'}, + {'n.a.': 'white', 'None or simple proceses': 'green', 'Standard purification techniques': 'yellow', 'Advanced purification techniques': 'red'}, + {'n.a.': 'white', '>98%': 'green', '97-98%': 'yellow', '<97%': 'red'}, + {'n.a.': 'white', '<1 mL (<1 g)': 'green', '1-10 mL (1-10 g)': 'yellow', '>10 mL (<10 g)': 'red'}, + +] + +# create the drop-down menus (frame, dict. with options and values, polygon to be generated, +# label, pack row, polygon number). +select1 = OptionsDropdown(leftFrame, options[0], polygons[0], '1. Collection:', 2, 0) +select2 = OptionsDropdown(leftFrame, options[1], polygons[1], '2. Preservation:', 3, 1) +select3 = OptionsDropdown(leftFrame, options[2], polygons[2], '3. Transport:', 4, 2) +select4 = OptionsDropdown(leftFrame, options[3], polygons[3], '4. Storage:', 5, 3) +select5 = OptionsDropdown(leftFrame, options[4], polygons[4], '5. Type of method:', 6, 4) +select6 = OptionsDropdown(leftFrame, options[5], polygons[5], '6. Scale of extraction:', 7, 5) +select7 = OptionsDropdown(leftFrame, options[6], polygons[6], '7. Solvents/reagents used:', 8, 6) +select8 = OptionsDropdown(leftFrame, options[7], polygons[7], '8. Additional treatments:', 9, 7) +select9 = OptionsDropdown(leftFrame, options[8], polygons[8], '9. Amount:', 11, 8) +select10 = OptionsDropdown(leftFrame, options[9], polygons[9], '10. Health hazard:', 12, 9) +select11 = OptionsDropdown(leftFrame, options[10], polygons[10], '11. Safety hazard:', 13, 10) +select12 = OptionsDropdown(leftFrame, options[11], polygons[11], '12. Energy:', 15, 11) +select13 = OptionsDropdown(leftFrame, options[12], polygons[12], '13. Occupational hazard:', 16, 12) +select14 = OptionsDropdown(leftFrame, options[13], polygons[13], '14. Waste:', 17, 13) +select15 = OptionsDropdown(leftFrame, options[14], polygons[14], '15. Waste treatment:', 18, 14) + +select16 = OptionsDropdown(middleFrame, options[16], polygons[15], '16. Yield:', 1, 15) +select17 = OptionsDropdown(middleFrame, options[17], polygons[16], '17. Temperature/time:', 2, 16) +select18 = OptionsDropdown(middleFrame, options[18], polygons[17], '18. Price of reagents:', 4, 17) + +select19 = OptionsDropdown(middleFrame, options[19], polygons[18], '19. Amount:', 5, 18) +select20 = OptionsDropdown(middleFrame, options[20], polygons[19], '20. Health hazard:', 6, 19) +select21 = OptionsDropdown(middleFrame, options[21], polygons[20], '21. Safety hazard:', 7, 20) + +select22 = OptionsDropdown(middleFrame, options[22], polygons[21], '22. Technical setup :', 9, 21) +select23 = OptionsDropdown(middleFrame, options[23], polygons[22], '23. Energy:', 10, 22) +select24 = OptionsDropdown(middleFrame, options[24], polygons[23], '24. Occupational hazard:', 11, 23) + +select25 = OptionsDropdown(middleFrame, options[25], polygons[24], '25. End products workup, purification:', 13, 24) +select26 = OptionsDropdown(middleFrame, options[26], polygons[25], '26. Purity:', 14, 25) +select27 = OptionsDropdown(middleFrame, options[27], polygons[26], '27. Waste:', 15, 26) + +# create the central ellipse +ell1 = EllipseDropdown(leftFrame, options[15], 'Type of analysis:', row=26) + + +root.mainloop() +