MASARYK U N I V E R S I T Y FACULTY OF INFORMATICS Patrolling Games Map Editor Bachelor's Thesis PETR BALNAR Brno, Spring 2023 MASARYK U N I V E R S I T Y FACULTY OF INFORMATICS Patrolling Games Map Editor Bachelor's Thesis PETR BALNAR Advisor: Ing. Matěj Lang Department of Visual Informatics Brno, Spring 2023 Declaration Hereby I declare that this paper is my original authorial work, which I have worked out on my own. A l l sources, references, and literature used or excerpted during elaboration of this work are properly cited and listed in complete reference to the due source. Petr Balnar Advisor: Ing. Matěj Lang iii Acknowledgements I would like to thank my advisor Ing. Matěj Lang, for his helpful assistance, valuable tips and patience. His comments and consultations with him helped me to create this application faster and in a more intuitive way. M y thanks also goes to my consultant doc. RNDr. Vojtěch Řehák, Ph.D., the author of this topic, for introducing me to the topic, formulating the requirements, answering my questions and helping me to describe the parameters of some functions. Last but not least, I would also like to thank my roommate and friend Jirka for mutually motivating me to finish my work on time and exchanging tips, and my friend Patrik for his encouraging comments that helped relieve my stress. iv Abstract Creating maps for patrolling games is now a slow procedure due to manually creating a text file with a specified graph. The goal of this thesis is to develop a web graph editor for editing these maps to speed up this process. The thesis briefly outlines the concept of patrol games, defines the application requirements, explores existing solutions and tools, introduces the technologies used, and explains the controls and how the application works. Finally, the thesis discusses some possible future enhancements. In the resulting application, it will be possible to create a new graph from scratch or generate it by a predefined function, add nodes and edges to it and move them around, edit their parameters both individually and in bulk, download such a graph or upload an existing one. Keywords user interface, visualization, patrolling games, web application, graph editor, U X v Contents Introduction 1 1 Motivation and Requirements 2 1.1 Patrolling Security Games 2 1.1.1 Definition 2 1.1.2 Need for a Graph Editor 3 1.2 Application Requirements 3 2 Related tools 5 2.1 CS Academy 5 2.2 ZoomCharts 5 2.3 Graph Online 6 2.4 Comparison of the Tools with Requirements 6 3 Used Technologies 8 3.1 Python 8 3.2 H T M L 8 3.3 CSS 9 3.4 JavaScript 9 3.5 NetworkX 9 3.6 PyYAML 10 3.7 Geopy 10 3.8 Main Python Library Selection 10 3.8.1 Pyvis H 3.8.2 D3.js Python Wrappers 11 3.8.3 Dash Cytoscape 12 3.8.4 Comparison of Candidate Libraries 13 3.9 Other Dash Extensions 14 3.9.1 Dash Bootstrap Components 14 3.9.2 Dash Extensions 14 3.9.3 DashDAQ 14 4 Implementation 15 4.1 Design 15 4.1.1 User Interface 15 v i 4.1.2 Editor Controls 18 4.2 Python Part 20 4.2.1 Application Directory Structure 20 4.2.2 Graph-Generating Functions 21 4.2.3 Dash Callbacks 22 4.2.4 Application Architecture 23 4.2.5 Generating the Graph from Template 24 4.2.6 Loading and Saving the Graph 25 4.2.7 Adding and Removing Graph Elements 25 4.2.8 Modifying the Graph Attributes 25 4.3 Cytoscape Part 26 4.3.1 Adjustments for Adding and Removing Graph Elements 26 4.3.2 Positions of the Nodes 27 4.4 Limitations and Workarounds 27 4.4.1 Moving the Selected Nodes 27 4.4.2 Multi-User Usage 28 4.4.3 Drawing the Edges 28 4.4.4 JavaScript Issues 28 4.4.5 Switching between Directed and Undirected Graph 28 5 Future Work 30 Conclusion 31 A An appendix 32 A . l Electronic Attachments 32 A.2 Online Source Codes 32 Glossary 33 Bibliography 34 vii List of Tables 4.1 Final Editor Controls List of Figures 4.1 Default look of the application with D E M O node 16 4.2 Modal Menu with selected graph-generating function and fields for its parameters 17 4.3 Graph Element's Properties Editor sidebar when selected only one node 17 4.4 Graph Element's Properties Editor sidebar when selected elements with same attribute names and different values 18 ix Introduction All of us may find ourselves in a situation where we own several properties or buildings and have valuable and sensitive items in them that we would hate to have stolen or even destroyed, but we would not have enough security guards to pay to keep an eye on it all. These situations are what patrolling games deal with, specifically focusing on finding the ideal strategy and movement of our available guards to minimize the risk of successful theft or destruction of our valuables. These games are often modelled using graphs, where each node represents one of our protected objects, and the edges represent possible paths. However, such graphs are now often stored in a text file that must be written manually, which often takes a lot of time and effort. This thesis aims to simplify and speed up the process of manually creating a graph in a text file and, therefore, to develop a web application that allows the creating, editing, downloading and uploading of such a graph. This web graph editor is also the result of this thesis. First, I examined existing solutions and analyzed whether some could be used or adapted to the application's needs designed for this purpose. Based on this analysis, I decided to implement my application. I discuss a more detailed formulation of the motivation for this work and the client's requirements for my application in Chapter 1. In Chapter 2,1 then present my search for existing graph editors and analyze whether any of them could be used or adapted to the needs of a graph editor designed for editing patrol game maps. This analysis made it clear that a new application would need to be created to meet my client's requirements. I discuss the technologies, tools used and their selection in Chapter 3. The actual implementation of my application, including what approaches I took and what problems I encountered, is explained in Chapter 4. In the last Chapter 5,1 discuss plans and other features and possibilities for extending my application, which were out of the scope of this bachelor's thesis. 1 1 Motivation and Requirements Patrolling Games as a type of task in game theory is of great importance, especially when dealing with how to patrol different objects or places while editing maps for them is now quite tedious. As a result, in this chapter, I discussed the primary motivation for creating this thesis, for which I first defined the concept of security and patrolling security games (sometimes also referred to as patrolling games or PSG for short) and put them in the context of this work. Then, in the following sections, I focused on the formulation of requirements for the desired application based on the problems presented in the individual sections. 1.1 Patrolling Security Games 1.1.1 Definition Security games are characterized by two players (a defender and an attacker), where the defender tries to protect a set of targets from the attacker's intrusions by committing to a strategy. Players use resources available to them to achieve their goals, such as patrollers for defenders or intruders for attackers. The essential components of these games consist of several targets, each with a value that may be different for the two players, and a number of resources available for the attacker to intrude the targets and for the defender to protect them. In most situations, the defender cannot protect all targets simultaneously due to the lack of resources. This lack forces the defender to follow a strategy for adequate protection of targets. Furthermore, the attacker is assumed to be in the position where they can observe the defender and deduce their strategy, so they can decide the best time to initiate an attack (secretly and instantly) [1,2]. Patrolling security games (PSG) are variants of security games that focus on patrolling as a reference scenario. In patrolling games, the game is played on the underlying directed graph, with each vertex corresponding to distinguished locations and each vertex corresponding to possible moves of the defender. A common problem associated 2 i . MOTIVATION A N D REQUIREMENTS with these games is finding the optimal strategy for the defender to maximize the chance of detecting the attack [1, 2]. In real life, these types of games model situations where we have a set of distinguished locations that needs to be protected from attacks. Sometimes the consequences of a successful attack on one of these locations can be disastrous, and in many cases, it is not economically desirable to place a guard on each of these locations. However, if, for example, some of the locations are close to each other, only one patroller has to patrol them because he can get to each of these locations before the initiated attack is completed [2]. 1.1.2 Need for a Graph Editor As I mentioned earlier, patrolling games are played on maps that are typically modelled using graphs whose vertices and edges may also have various special attributes, and these are often represented by relational matrices or lists of vertices and edges in a text file that must be written manually. In my case, this graph representation I discussed above is an instance of the NetworkX library [3] for Python 1 , which allows adding various additional attributes to the graph's elements and which the client uses. However, creating this instance also requires manually writing all the graph parameters. This need for manual specification of graph parameters can be inconvenient and slow, especially regarding the position of nodes. Not to mention that the user cannot clearly view the graph and quickly and intuitively edit it instead of searching for a specific element in a text file and editing it there. Additionally, the user can make a mistake much more easily when editing a text file, either in syntax or by editing a different element than he or she intended, bringing us to the formulation of the requirements for my application. 1.2 Application Requirements Given the information above, I can now present the requirements from the client for my graph editor. 1. For more information about both of these technologies, see Chapter 3 3 i . MOTIVATION A N D REQUIREMENTS The main requirements were that the editor should allow a user to create a new graph, add and remove nodes and edges, edit their parameters, select multiple nodes or edges and edit them in bulk. A user could start a new graph or generate one using a predefined function, a function whose output is an instance of NetworkX Graph, or DiGraph, which is an oriented variant of Graph. I explained these functions more in Subsection 4.2.2. If a user wants to use this graphgenerating function, the editor will dynamically create an interface for specifying the function's parameters. The application should also have the capability of importing an existing graph from a file and exporting the created graph to a file. Initially, the file was supposed to be in NetworkX Y A M L format, but since NetworkX 2.6 and later versions do not support saving and reading from it [4], we agreed to save it in Y A M L format using the hardcoded graph generating function and its parameters, which is used in the project of the client. Emphasis was placed on the intuitiveness of the user interface and controls. In terms of the requirements for the type of application and the technologies used, one of them was to use Python, as the NetworkX library is written only for it, and also to make the application web-based, which is a standard solution nowadays. Other than that, there were no more technical requirements, and the choice of other technologies or tools was up to me. I discuss the actual selection and description of the technologies, libraries and tools used in Chapter 3. 4 2 Related tools In this chapter, I inspected and compared existing graph editing tools and included reasons why the existing tools are sufficient and why they are not for the application of the presented needs. A large number of existing graph editors may indicate that it should not be necessary to create another similar tool, but all the editors I found only fulfilled part of the requirements defined above. In the following few sections, I present the editors I found that were closest to the requirements for my application and discuss what needs they comply with and why they are not adequate. 2.1 CS Academy Graph Editor [5] from CS Academy provides the most intuitive interface and interaction of all found editors with a well-designed layout of UI elements. It also has a range of features allowing a user to create and edit graphs. These include adding nodes and edges to the graph, moving nodes around, editing node labels and edge cost, switching between directed and undirected graphs, and downloading the graph as a P N G or text file using Markup language. On the other hand, this editor is quite buggy, i.e. switching modes does not work correctly, or it allows drawing multiple same edges between nodes. It also does not support uploading a graph from a file. 2.2 ZoomCharts App from ZoomCharts [6] allows users to perform basic editing tasks such as creating nodes and edges, customizing a node's name or changing the graph layout to improve readability or aesthetics. Even though this application supports adding nodes and edges, they did not implement it intuitively. To produce a node, a user must click on one of the lateral buttons, and it creates a new node automatically in a predefined position by an internal algorithm, so if a user wants to add a new node in the exact position specified by him, he needs to create it and then move it there, which is inconvenient. The app also has some 5 2. RELATED TOOLS aspects locked behind a premium subscription, such as cloud saving or graph importing. One of the features that I could use for my purposes is exporting a graph into JSON format. 2.3 Graph Online Graph Online [7], created by team UnickSoft, is the most feature-rich I found. It supports all fundamental interactions such as adding and removing nodes and edges, renaming and changing the style of nodes, even exporting or importing a file with a graph or creating several types of matrices such as adjacency, incidence or distance matrices. Unfortunately, the application uses an outdated user interface (constantly switching between different modes) and controls where the user has to click between three buttons only to add and remove nodes and edges, along with the inability to modify the custom attributes of individual graph elements. As a file format for graphs, it uses an XML-based GraphML file format. GraphML [8] extended on it and was developed to standardize graph exchange and store format. At the same time, it retains the ability to be combined with other XML-based formats due to its X M L syntax. 2.4 Comparison of the Tools with Requirements The graph editing tools mentioned above meet some of my application requirements. However, they lack some of the features I require. They all have basic functionality for adding and removing nodes and edges, but for example, the ZoomCharts app has implemented this functionality in a not very intuitive and desirable way, not to mention that it has a graph import feature behind the paywall. The same applies to Graph Online, which has even more outdated controls than the ZoomCharts editor, although it provides the most functionality of all the applications mentioned. O n the other hand, the editor from CS Academy is controlled more naturally and includes similar options for node appearance, but it does not offer any functionality to upload a graph from a file and contains many bugs incompatible with the 6 2. RELATED TOOLS heavy usage of this editor. Most importantly, these tools cannot edit and add or remove custom parameters for nodes or edges. 7 3 Used Technologies The aim of this chapter is to describe the programming languages, technologies and libraries used in this project, along with the rationale for choosing the main library for my Python web application. For this justification, I have listed several candidates, and according to the features they provide, given my experience in Python and primarily JavaScript, I have chosen the best one. 3.1 Python Python is an interpreted, object-oriented programming language with clear syntax making development in this language faster than in other popular languages. It also supports more programming paradigms, such as procedural or functional programming [9]. I used Python 3.9.16 for my application because my client uses this version of Python in his project. It is also one of the versions supported by NetworkX and the last officially supported version of Python by my chosen main library. That was why I did not risk using version 3.10, even though the library should not have problems with it, according to this GitHub discussion [10]. M y editor would also be compatible with the previous version of Python (3.8) since all the libraries I use support it as well, but I use some new features in my application (more precisely, Type Hinting For Built-in Generic Types) that only came in Python 3.9 [11]. 3.2 HTML The acronym H T M L stands for Hyper Text Markup Language, the standard markup language used for creating Web pages. This language unified elements such as pictures, sounds or text so these elements are not distributed as fragmented collections. Web browsers are run to access and display H T M L documents stored on special web servers or local storage. It is often used with Cascading Style Sheets (CSS) and the scripting language JavaScript both of which I will introduce in subsequent sections [12]. 8 3. U S E D TECHNOLOGIES Nowadays, HTML5 is used mainly, which is the version of H T M L that I use in my application, and which was first released in 2008 but was not officially released until 2014 [13]. 3.3 CSS Style Sheets are used to manage the overall "look" of various documents, for example, backgrounds, fonts, and colours. CSS was defined for H T M L in 1996 as a draft proposal which quickly matured into a standard and began being used to adjust the appearance of Web pages, such as the position of H T M L elements beyond the aforementioned style attributes [12]. 3.4 JavaScript JavaScript (JS) is a scripting object-based programming language, one of the most used technologies in web development, with CSS and H T M L . JS offers functions and commands designed to control the browser's behaviour for the user, allowing developers to add interactivity and responsivity to their web and web applications. Developers often utilize various third-party frameworks and libraries, making working in JavaScript much easier and less time-consuming. In my project, I used the Python wrapper for this language1 , as I still needed to gain more experience in JavaScript. 3.5 NetworkX Open source Python package NetworkX serves for the creation, manipulation, and study of the structure, dynamics, and functions of complex graphs and networks. This package offers data structures for graphs, digraphs and multigraphs, many standard graph algorithms, and generators for various graphs and networks. The latest version of NetworkX when writing this thesis is 3.1, supporting Python versions from 3.8 to 3.11 [14]. 1. The m a i n library I chose i n the next few sections respectively 9 3. USED TECHNOLOGIES For purposes of my app, the NetworkX module handles internal graph representation and generates positions of nodes for graphs where these positions do not exist, more described in Chapter 4. 3.6 PyYAML Python's P y Y A M L is a Y A M L parser and emitter. It has a complete Y A M L 1.1 parser, Unicode support, pickle support, a competent extension API, and understandable error messages. In addition to supporting common Y A M L tags, P y Y A M L also offers Python-specific tags that let users represent any Python object [15]. 3.7 Geopy Geopy is a Python client for numerous well-liked geocoding web services [16]. In my project, only the client's predefined helper function distance for some graph-generating functions (which I will present in Chapter 4) uses this library. 3.8 Main Python Library Selection The candidate Python libraries presented below were chosen based on their intended use and the popularity of the underlying JavaScript libraries. To visualize various networks and graphs, I found the three most popular and used libraries, namely: • vis.j s—An interactive visualization library that runs in the browser, and its features are made to be simple to use, to allow for data manipulation and interaction, and to handle large amounts of dynamic data. It uses the Network component for graph visualization and graph editing [17]. • D3.js—A JavaScript library called D3.js allows users to manipulate documents using data. Utilizing H T M L , SVG, and CSS, D3 enables the user to make data come to life. With its focus on web standards, D3 combines robust visualization components with a data-driven approach to D O M manipulation, giving users access 10 3. USED TECHNOLOGIES to all the features of contemporary browsers without shackling them to a proprietary framework [18]. However, it is created for an arbitrary SVG instead of networks and graphs only. • Cytoscape.js—The open-source graph theory (also known as network) library Cytoscape.js, written in JS, can be employed for graph analysis and visualization. It makes it simple for the user to display and manipulate interactive, rich graphs. Cytoscape.js is effortless to integrate into apps because it allows user interaction with the graph, and enables the client to hook into user events. There are numerous helpful graph theory functions in the library as well [19]. I then found the corresponding Python Wrappers for these libraries, which I introduced in the subsequent subsections and determined which one was the best candidate for use in my application. 3.8.1 Pyvis Python Wrapper around vis.js library called Pyvis, developed by West Health Institute, is one of the candidates for building my editor app. It includes node and edge customization and allows the dragging, hovering, and selection of both nodes and edges. Adding and removing the nodes and edges is also possible out of the box using the Pyvis library. A big plus of this package is straightforward and comprehensive documentation for which they use Sphinx, a popular Python library for generating web documentation. However, it does not allow adjusting the app layout using custom H T M L and CSS elements within the editor as it is only a standalone Python wrapper library and editing additional custom attributes of graph elements [20]. Unfortunately, I did not find any straightforward workaround, so dealing with this issue would require non-trivial modification of the Pyvis source code. 3.8.2 D3.js Python Wrappers The first Python wrapper of D3.js I will introduce is d3graph, a library that creates a standalone and interactive force-directed network graph, allowing its manipulation and study of the structure, dynamics and 11 3. U S E D TECHNOLOGIES functions of complex networks and graphs. It takes an adjacency matrix as the input, where columns and indices are the nodes, whereas the elements with a value of one or larger are considered an edge. The output is a single H T M L file consisting of 4 parts (FIGURE) - CSS, D3 module, JavaScript to build the graph and the JSON file with the data, together forming the resulting interactive graph. As with Pyvis, another advantage is that the author has provided well-organized and complex documentation, again using the Sphinx library [21]. Even though it includes many features, features like adding elements to a graph interactively still need to be included here. Another Python library named d3py also wraps D3.js and can be used for plotting a graph, although it does not offer any interactivity, is not maintained and does not support Python 3 [22]. Therefore I do not consider this library as an option too. 3.8.3 Dash Cytoscape To properly understand Dash Cytoscape, I must first introduce the Dash library. Dash, developed by Plotly company and used by the client for a dashboard, is a Python framework for creating interactive web applications, which is written on top of Flask (micro web frame- work2 written in Python), React.js and Plotly.js. The crucial advantage of Dash is that it allows you to create data apps with pure Python, i.e. without deep knowledge of H T M L , CSS or JavaScript, along with its ability to add interactivity to your applications using its callback functions, which I will explain in more detail in Subsection 4.2.3. However, it also allows you to use custom H T M L or CSS elements in your app or create a custom component for Dash that will wrap and include functionalities of other JavaScript libraries [23, 24]. Moreover, this custom component is precisely what Dash Cytoscape is. Dash Cytoscape is an open source graph visualization component for Dash, wrapping Cytoscape.js and extending it. This component is designed for creating easily customizable, high-performance, interactive, and web-based networks or graphs. Deep integration with Dash layouts and callbacks is another feature that makes it possible to build robust networks or graphs using the extensive library of Dash com- 2. M i c r o framework does not require any other tools or inner libraries. 12 3. USED TECHNOLOGIES ponents as well as well-known computational biology and network science libraries like Biopython and, the above-mentioned, NetworkX. Dash Cytoscape library belongs between libraries with well-structured and understandable documentation [25]. 3.8.4 Comparison of Candidate Libraries I compared the candidate libraries presented above based on their features, their ability to modify the application's layout, whether they allow modification of graph element attributes, and whether they are part of a framework. A l l three introduced libraries have well-written documentation, feature static graph creation and allow for manipulation and visualization of the created graph. Pyvis and D3Graph include NetworkX integration, which makes it easier for developers to use and visualize NetworkX graphs and also features force-directed graphs by default, which is undesirable because the user does not have full control over the node positions. O n the other hand, Dash Cytoscape has no NetworkX integration. However, as part of the Dash framework, which allows the developer to customize the look and layout of the entire application (unlike the previous two libraries, which only generate canvas with created graph), it does not have force simulation enabled by default. It also allows you to customize or create new interactions with the graph using Dash framework callbacks. Neither library includes a native option to dynamically create a new graph or interactively add and remove nodes and edges. In Dash Cytoscape, though, this behaviour may be established using the previously mentioned callbacks. As for modifying, adding and removing graph element attributes, all the libraries mentioned are similar - all have attributes in graph elements that affect their appearance or behaviour but do not natively offer any option to add custom ones. For the D3Graph and Pyvis libraries, this would require editing the code of the libraries themselves, as this is handled here by class parameters. While Dash Cytoscape also has no particular attribute to serve as a user attribute, it does have individual elements represented as a Python dictionary, allowing the programmer to work around this limitation. 13 3. USED TECHNOLOGIES The final decision was also influenced by the fact that Cytoscape.js, which Dash Cytoscape wraps, focuses directly on working with graphs and their visualization and interaction, which includes a built-in Tenderer [19]. At the same time, VisJS or D3.js [17,18] allow the visualization of arbitrary data, i.e. both libraries can draw a general diagram but do not offer as many features or options for interacting with the graph and modifying it at runtime as Cytoscape.js. Considering each library's mentioned advantages and disadvantages, the Dash Cytoscape library and its framework Dash emerges as the best candidate. 3.9 Other Dash Extensions 3.9.1 Dash Bootstrap Components Dash's library of Bootstrap components, dash-bootstrap-components, makes it simpler to create responsive apps with intricate layouts that are consistently styled [26]. M y main reason for using this library is to improve the application's visual appearance and add some new functional elements to the application's layout, such as the Modal Menu. 3.9.2 Dash Extensions Dash Extensions aims to enhance the Dash programming experience with a set of utility functions, syntax extensions, and Dash components [27]. This module is one of the more important ones, allowing me to write several callbacks with identical output. For a further detailed explanation of this feature, see Chapter 4. 3.9.3 DashDAQ The rich set of controls included in Dash DAQ makes it easier to include data gathering and controls in Dash applications [28]. I solely use the Boolean Switch function that this library includes for my project because it produces better-looking boolean value alteration. 14 4 Implementation 4.1 Design As I stated in Chapter 1.1.2, the editor's design focused on the intuitiveness of the user interface and controls. I discuss the chosen user interface style, controls and present application architecture in the following subsections. 4.1.1 User Interface I chose a minimalistic style and layout for the UI to make it as easy as possible for the uninitiated user to understand everything immediately and a single style to make everything look consistent. The basic layout of the application is divided into two or three parts, respectively (see Figure 4.1). The first part is the primary sidebar, located on the page's left side, containing the application's main controls. I chose a grey background because it contrasts more with the other controls and the editor's canvas. I left the buttons and toggles in their default blue colour because blue and grey complement each other perfectly. These are aligned below each other, with small gaps between them to separate them better visually. This sidebar also opens the modal menu (see Figure 4.2), which is used to select the graph-generating function and specify its parameters, for which individual input fields and switches are generated with the parameter's name above them. The application's second and central part is the canvas editor itself. In contrast to the primary sidebar, the colour of the canvas is pure white, and the individual nodes and edges are again grey. If the user selects a node or edge, the elements are coloured blue to distinguish between selected and unselected elements (see Figure 4.3 or 4.4). Every edge has a small arrow directing to its target, or it looks only like a line depending on whether the graph is oriented. The editor can draw one edge in either direction if the graph is directed; otherwise, it allows to draw only one edge. Each node has a defined label above it, which the user can change to organize his graph better. This change can be made in the third part of the editor. 15 4. IMPLEMENTATION The user will only see the third part of the application when he selects some nodes or edges. After that, a sidebar appears, which is used to edit the node's label and especially to edit the selected elements' custom additional attributes - that is why it is also called "Graph Element's Properties Editor" in the heading (see Figure 4.3). Here the user will see a box to change the node name if they have selected only one, and below that, a pair of input fields, one beneath the other, representing the individual attributes. Under these pairs, there is a light blue button to confirm the editing of attributes or a label, a dropdown to select the attribute the user wants to remove, and a button to remove the attribute, which the user can click after selecting the attribute to be removed. Lastly, there is a dropdown for selecting the type of attribute to be added, a field for entering the name of the attribute to be added, and after selecting the attribute type, another field or switch appears beneath this field for entering its value. After entering the attribute's name, a button for adding the attribute will be available below this new field. For the buttons to remove or add an attribute, I chose red or green, respectively, because these colours are associated with removing or adding respectively. DEMO Figure 4.1: Default look of the application with D E M O node 16 4. IMPLEMENTATION 17 4. IMPLEMENTATION G 2 0 0 Figure 4.4: Graph Element's Properties Editor sidebar when selected elements with same attribute names and different values 4.1.2 Editor Controls The way the application is controlled has been the subject of several discussions for several reasons. Dash Cytoscape did not support adding and removing nodes and edges out of the box, so this feature had to be implemented in its own way, which I describe in more detail in Sections 4.2 and 4.3. I suggested adding and removing elements using dedicated buttons as the simplest way to implement a solution to this problem. However, this method would involve too much clicking, filling in fields and annoyance every time a node was added, not to mention the fact that the positions of nodes added in this way would have to be manually entered, randomly selected based on the proximity of other elements, or selected by clicking into a space in the application canvas, which was not possible because Dash Cytoscape did not have a callback to get the position of the click when the user clicked into a space. I solved this position problem during development and took inspiration from CS Graph Editor [5], which switched between the 18 4. IMPLEMENTATION Move, Draw and Delete modes for deleting and adding nodes. After a discussion with the supervisor, I redesigned the controls so that no extra modes were needed and the user could get by with classic controls like clicking the mouse and holding modification keys like Ctrl, Alt or Shift. This solution was in agreement with the advisor of the thesis, the most intuitive proposed control method, and it is very well described in Table 4.1 below. Controls using Right Mouse Button still need to be implemented and are only proposals for the future. Table 4.1: Final Editor Controls Controls Space Node Edge L M B Nothing / Unselect Select(Show props) Select(Show props) L M B + Drag Move canvas Move selected Move canvas D L M B A d d node Delete node Delete edge R M B (Context menu?) (Context menu?) (Context menu?) Ctrl + L M B + Drag Box Select Box Select Box Select Shift + L M B + Drag Box Select A d d Edge Box Select As for the rest of the application controls, the app at first glance only contains the switch between the oriented and non-oriented graph and the buttons for: • Creating a new graph—It deletes the current graph, resets the name generator, and clears the space in canvas for the new graph. • Uploading a graph from a YML file—Clicking on this button triggers file selection from the PC, and after a (YML) file with a graph is selected, it generates a graph from it. • Downloading the graph to a YML file—After clicking on this button, it prompts the user to download a graph.yml file with the saved graph. • Opening the menu with graph template functions—This button opens the modal menu with an interface for choosing the specific graph-generating function. After selecting one of the functions, the application creates different types of fields or switches depending on the parameter type, i.e. if the parameter is boolean, for specific parameters of the selected function. 19 4. IMPLEMENTATION I have already outlined the controls of the "Graph Element's Properties Editor" sidebar in the User Interface subsection. Here the user can modify, add or remove attributes of selected elements or even change the node label if the user has selected only one. If the user has selected more than one element, the sidebar will only display and allow editing of those elements in common. However, if any of these common attributes have different values, the sidebar will only allow editing the attribute name and display the number of unique values for that attribute across the selected elements (see Figure 4.4). The user does editing by modifying the corresponding fields, where the left input field is for the attribute name and the right is for its value. For the editing to propagate into the graph, the user must confirm the edit by pressing the "Confirm Edit" button, which will also update the dropdown used to select the attribute to remove. In order to remove an attribute, the user must first select the attribute from the dropdown mentioned above and then click on "Remove Attribute" to remove the selected attribute from the graph and sidebar. For adding an attribute, the last items of this sidebar are used, where the user first selects the value type in the dropdown, which creates the corresponding input field or switch after selecting the type. Then the user needs to fill in the name and value of the attribute, and the editor will add this attribute to the graph and the corresponding fields and dropdowns in the sidebar after clicking "Add Attribute". 4.2 Python Part The Python component of my work pertains to the actual application itself. This Section elaborates on the code's structure, provides a rationale for my development choices and illustrates the functioning of each feature on the Python side.1 4.2.1 Application Directory Structure The directory structure of my application is pretty straightforward. The root of the application's directory called map_editor contains a graph templates folder containing separate Python files for each graph- 1. C h a t G P T was used for adjusting formulation of this paragraph. 20 4. IMPLEMENTATION generating function and another folder with a helper function for the previously mentioned functions. I described these functions in more detail in Subsection 4.2.4. In the root directory of the application, there is also a Python file with the actual implementation of the application app.py, a text file for easier installation of the required libraries using pip requirements.txt, a file with type aliases used throughout the application type_aliases.py and a tar file with packed modified Dash Cytoscape module. 4.2.2 Graph-Generating Functions In my application context, graph-generating functions are functions whose output is any NetworkX Graph or DiGraph. Each such function is located in a separate Python file with the same name as the function in the graph_tetnplates directory. Each such file must contain only that particular function; helper functions must be located in a different file and directory, e.g. the "Square Subgraph" function uses the helper function distance, which is located in the appropriate file in the graphjielper subfolder - this is also the recommended directory for these helper functions. For a given graph-generating function to be displayed and part of the dropdown selection found in the modal menu for generating a graph from these functions, the function must be correctly typed and have a docstring similar to Google style. The required docstring format looks like this: """ Function name Args: Argument name - python_name: Argument d e s c r i p t i o n Returns: return_type: D e s c r i p t i o n of the r e t u r n value ii ti ti Functions that take some file or custom class instance as parameters are not supported yet. Allowed parameter types are: • int • float 21 4. IMPLEMENTATION • bool • diet • list • set • Optional variants of types listed above 4.2.3 Dash Callbacks For communication with the backend and thus also for creating interactions with the application, Dash provides so-called callback functions. These functions are automatically called by Dash whenever a property of a selected component, which is specified as Input for a given callback, changes to update another property of the component, which is set as Output for the given callback. Each callback must have at least one Output and one Input as parameters. In addition to the Input and Output parameters, a callback can have a State parameter that adds another parameter to the function; however, changing a property defined as a State parameter does not automatically call the callback - so it serves as a parameter with additional information. The appropriate decorator and its arguments are used to define a callback, e.g. if the Dash instance is in the app variable, the definition of such a callback might look like this: @ a p p . c a l l b a c k ( O u t p u t ( c o m p o n e n t _ i d = ' m y - o u t p u t ' , c o m p o n e n t _ p r o p e r t y = ' c h i l d r e n ' ) , I n p u t ( c o m p o n e n t _ i d = ' my - i n p u t ' , c o m p o n e n t _ p r o p e r t y = ' c h i l d r e n ' ) , S t a t e ( c o m p o n e n t _ i d = ' m y - o u t p u t ' , c o m p o n e n t _ p r o p e r t y = ' c h i l d r e n ' ) ) def e x a m p l e _ c a l l b a c k ( m y _ i n p u t , m y _ s t a t e ) : p a s s From the example code, we can see that each parameter, whether Output, Input, or State, is an instance of the corresponding class and that each of them needs two arguments, namely component_id and componentjproperty. The component_id is often included in the application 22 4. IMPLEMENTATION layout as an optional parameter, so if it is not specified, the component can be passed directly to the component_id argument. Dash will then automatically generate an ID for that particular component. In basic Dash, only one callback can write to one specific component property; thus, there can only be one specific Output to that component. This behaviour can cause clutter, chaos and non-modularity in the application code. For this problem, I used a solution from Dash Extensions, which provides a MultiplexerTransform that is turned on by inserting an argument when creating an instance of the DashProxy class, which is a special class provided by Dash Extensions that can recognize these new arguments, and then one specific Output can be targeted by multiple callbacks. However, there is now a solution for this problem from Dash since version 2.9, which adds a new flag, allow_duplicate, that also solves precisely this. However, this version was released only during the development of the application. Therefore I do not use the solution from Dash's side. 4.2.4 Application Architecture The application architecture is designed as a single module with a Dash application instance, several global variables and constants, callback functions and their helper functions. A l l the global variables I have in my application are instances of some wrapper or handler class whose methods I continue to use in my code, and I never change the instance to maintain a consistent state across the entire runtime. I resorted to using global variables for optimization and remembering some information from callbacks to use in future callbacks. However, this use of global variables has another drawback, which I will discuss in the Section 4.4. A l l functions in my project are typed, and I use mypy for type control. At the beginning of the application file, I define three classes extension of the ValueError DocError, Id_generator and Selected_items classes. The last two mentioned classes are the wrapper and handler classes, whose instances I initialize straightaway. Along with them, I also populate a dictionary with available functions for generating graphs from the graph_templates directory, which is further used to create a list of available functions in the corresponding dropdown. After these preparations, I already initialize the app using DashProxy with 23 4. IMPLEMENTATION specific parameters, i.e. with name needed to specify the unique path of the app for the underlying Flask web server, the external Bootstrap stylesheet whose style I use throughout the app, the already mentioned MultiplexerTransform and callback exception suppression, because in the app I define some callbacks for components that are not yet in the app layout at the moment. Afterwards, I define the layout of the application itself, which I have already introduced in Section 4.1, and then it comes to the individual functions and callbacks, which I will briefly introduce within the individual features in the following subsections. 4.2.5 Generating the Graph from Template Graph-Generating from the template was one of the features that was easier for implementation. For this feature, I just needed to define functions for creating input fields for the graph-generating function parameters and callback function for button click of the Generate Graph button. In functions for creating input fields, I used inspect module for getting docstring and types of specified functions to determine the correct input field types. The callback button click function was needed to handle more tasks - parse values from input fields, call the graph-generating function and convert the resulting graph into Cytoscape's format. I needed to parse only values that were lists or dictionaries, for which purpose I used ast module and its function literal_eval, which safely evaluates Python expression so the potential attacker can not inject malicious Python code into my application. I manually converted the NetworkX graph to the Cytoscape format I needed for my app because the NetworkX built-in function for this purpose converted it in a slightly different format, which I still needed to adjust. This approach allowed me more flexibility in the later phases of the development as I decided to store some additional attributes like positions or labels of the nodes in the NetworkX graph. The exception is the hardcoded graph-generating function, where filling in the parameters would be somewhat similar to manually writing a Y A M L file with the graph. This function is then reserved for reading a graph from a Y A M L file and saving it. 24 4. IMPLEMENTATION 4.2.6 Loading and Saving the Graph For loading and saving the graph, I reused some of the functions already defined for generating the graph from the template because the Y A M L file with the graph contains only parameters for specific graph-generating function hardcoded that allows defining arbitrary graphs. I used safejoad from the PyYAML module to parse the Y A M L file, which safely converts the Y A M L file into a dictionary. For the reverse direction, I first create a specific dictionary from the current graph, which I then use to convert to a Y A M L file using the dump function from the same module. 4.2.7 Adding and Removing Graph Elements The feature that allows users to add and remove graph elements took more work to implement as Dash Cytoscape in version 0.3.0 does not support tap events into space or generally double-click events. Therefore, I decided to modify Dash Cytoscape's code to add these events because the underlying Cytoscape.js library supports these. I elaborate on Dash Cytoscape's code modification in Section 4.3. After adding these events, I could quickly implement its usage for this feature. 4.2.8 Modifying the Graph Attributes One of the more challenging features for implementation was developing the ability to modify the graph element's attributes, as it involved many smaller tasks to solve. At first, I needed to propose a design and way of editing the element's properties, and I came up with a design that involved dropdowns and three main functional buttons. I chose this design because it was easier to implement from my point of view while still preserving the intuitiveness of the user interface. After consulting with the thesis advisor, we concluded that this design is not the most intuitive but remains intelligible and adequate. I address its future improvements in Chapter 5. The most important tasks were to create a properties editor sidebar with particular input fields for editing and adding functionality for the confirm, add and remove buttons. For these tasks, I extensively 25 4. IMPLEMENTATION used global variable handling selected elements. Therefore, this is one of the parts of my application most affected by the drawback of using a global variable, which I discussed in Section 4.4. 4.3 Cytoscape Part In the end, I could not avoid writing JavaScript code and had to resort to modifying the Dash Cytoscape library. Fortunately, the modifications involved were not complicated, and I could spot what to add or change where. I added most modifications to the main library file Cytoscape.react.js. Most of the other changes were due to the project being built, as many of the files in this library are auto-generated. However, before I started modifying the code, I tweaked the version of Dash that the library uses to increase compatibility with my application and avoid potential problems. The newer version did not make changes that would necessarily break compatibility with older versions. In addition to this change, I also changed the version number of Dash Cytoscape from 0.3.0 to 0.3.1 and updated the version of Cytoscape that Dash Cytoscape utilizes. 4.3.1 Adjustments for Adding and Removing Graph Elements I added the required events for this feature based on other events implementation in the handleCy method in the core file mentioned above. Namely, I added oneTap and dblTap events from Cytoscape.js for this feature. Nevertheless, these events are only for adding nodes; for connecting nodes with edges, I imported an extension of Cytoscape.js cytoscape-edgehandles, which adds functionality to draw edges between nodes using mouse drag. However, this extension directly modifies the underlying elements list in Cytoscape.js, so Dash Cytoscape did not see changes it made to the graph. Therefore, I have added additional events to pass information about the newly drawn edge to Dash Cytoscape to add that edge to its list, and at the same time, I delete that edge from the internal Cytoscape.js element list in these events, so I avoid having duplicate edges in the graph. 26 4. IMPLEMENTATION 4.3.2 Positions of the Nodes While testing my application, I discovered that if I change the positions of the nodes in the graph, it does not get updated in the elements list of Dash Cytoscape. This problem caused an inconsistency between the actual node positions and those saved in the graph file. I have not found an ideal solution for this problem, but I solved it with the position event Cytoscape.js provides. With this event, I can provide Dash Cytoscape information about the position change of the moved node, and if the user has more selected nodes, this position change can apply to them too. Nevertheless, I explained a few limitations of this solution in Section 4.4. 4.4 Limitations and Workarounds M y application still has several limitations found during my testing, for which I have not found a suitable solution without the need for workarounds or a solution that would not require more time to understand and implement because these issues were lower a priority than, for example, the actual implementation of the required features. I describe these and how to work around them in the following sub- sections. 4.4.1 Moving the Selected Nodes When the user tries to move a node that is not selected and has some nodes selected, the user expects that he will move only the unselected node. Nevertheless, because of my solution for not updating Dash Cytoscape's elements position, moving an unselected node while some nodes are selected causes those selected nodes to get moved too. This behaviour can be avoided by deselecting the nodes before moving a particular node. Also, there are some performance spikes caused by the nature of my solution for the problem mentioned above when moving nodes. 27 4. IMPLEMENTATION 4.4.2 Multi-User Usage Currently, if more clients would want to use the same app server, usage of global variables will cause inconsistencies between client sessions and weird behaviour across the app, namely when editing properties of graph elements, as I mentioned in Subsection 4.2.8, and possibly when adding new elements to the graph. Therefore, I do not recommend having more client sessions on one server on this app version. 4.4.3 Drawing the Edges Sometimes, when the user holds Shift and wants to draw an edge, the application will start drawing box selection. This behaviour happens when the user has clicked on a sidebar button just before the drawing or the app has lost window focus before drawing especially. Luckily, this behaviour only occurs once, and the next attempt to create an edge will be executed correctly, but it may recur if the situations described above occur. 4.4.4 JavaScript Issues I discovered weird behaviour if the user switches many times between functions in the dropdown list of graph-generating functions, some error of built-in JavaScript code occurs, and dynamic input field generation stops working. I have not detected any pattern regarding this issue or problems in my code. For this reason, I assume that it is a bug in Dash or Dash Bootstrap Components module. To workaround this issue, the user must close the modal menu with graph-generating functions, open it again and reset the value in the dropdown. If the issue persists, repeat these steps. 4.4.5 Switching between Directed and Undirected Graph If the user has drawn two edges in the opposite direction in the Directed mode of the graph and then switches to the Undirected mode, the editor will not remove any edge; thus, the graph will contain two undirected edges between the same nodes. This behaviour is not an 28 4. IMPLEMENTATION issue necessarily, but it could be confusing for some users, so that is the reason why I am mentioning it here. If users want to stay in the Undirected mode and have only one edge between the same nodes, they remove the excess edge. 29 5 Future Work The client suggested, and I also discussed with the advisor, other features that did not make it to the application's version in the appendix which can be worked on or polished in the future—some of which are: • Option for altering the graph layout dynamically—This lets the user alter the node position and graph layout by some existing algorithm besides manually repositioning the nodes. • Multi-node deletion—Another QoL feature would be deleting multiple selected nodes by pressing, i.e. Delete key. This possibility would be beneficial for more significant graph restructuring. • Better design of graph properties editor sidebar—As stated in the Subsection 4.2.8, the chosen design could be more intuitive. As a part of future work, I would redesign the properties editor more intuitively, i.e. next to the input fields for the properties would be a small cross and check button to remove or confirm editing of individual property instead of a dropdown, remove button and a large confirmation button to confirm editing of all properties. • Updating the length attribute of the edges—Edges in the graph often have len or length attributes. This feature suggested by the client would update this attribute based on the current nodes' positions so the information about it could be utilized later. 30 Conclusion The aim of this thesis was to simplify and speed up the process of manually creating a graph in a text file and, therefore, to develop a web application that allows the creating, editing, downloading and uploading of such a graph. I initially briefly explained the concept of patrolling games and defined the application's requirements and usage. The explanation of this concept was relatively short and abstract, as this is not the main topic of this thesis nor the field of my expertise. Afterwards, I researched and evaluated the existing graph editors and justified the need to implement a new one. In this chapter, I focused on introducing the editors I found and comparing their features with the defined requirements. The core of this thesis was to present the technologies and libraries used and the rationale for their integration into my application, to describe the functions, controls and implementation of the editor, and to discuss my development decisions. At the end of the thesis, I listed some possible future application improvements that could be worked on later in Chapter 5, i.e., the option for dynamically altering the graph layout would be nice. The resulting application is included in the map_editor.zip attachment together with a README.md explaining how to run and use the application. It features creating a graph (a completely new one or generated one using a graph-generating function) and its editing, i.e. it is possible to add and remove nodes and edges and modify their parameters. It also supports selecting multiple elements and editing them in bulk, loading an existing graph or saving it into a file. Therefore, the application meets the official requirements specified in the assignment. The client of this editor is doc. RNDr. Vojtěch Řehák, Ph.D., for whom it was developed in order to simplify and speed up the process of creating maps for patrol games. 31 A An appendix A.l Electronic Attachments • map_editor.zip: The archive containing the source code of Python part of the application and the application itself. • dash_cytoscape.zip: The archive containing the modified source code of Dash Cytoscape extension for Dash A.2 Online Source Codes The source code for my application can also be found on GitHub, namely: • Python part on https: //github. com/pitris90/map_editor • Dash Cytoscape part on https : //github. com/pitris90/dash-cytoscape 32 Glossary DLMB is an acronym for Double Left Mouse Button, referring to Double Left Mouse Button Click action 19 JSON is an acronym for JavaScript Object Notation. It is a lightweight text data format designed to be easily readable and writable by humans and easily generated and parsed by machines. It is language-independent but uses conventions from languages like C, C++, Java, Python, C# and many others [29, 30]. 6 LMB is an acronym for Left Mouse Button, referring to Single Left Mouse Button Click action 19 PNG is an acronym for Portable Network Graphics 5 QoL is an acronym for Quality of Life 30 RMB is an acronym for Right Mouse Button, referring to Single Right Mouse Button Click action 19 SVG is an acronym for Scalable Vector Graphics, which is a markup language and also a file format 10 UI is an acronym for User Interface 5 XML is an acronym for Extensible Markup Language, a markup language and file format which is easy to read for humans and machines that was designed with simplicity, generality and usability in mind across the Internet [31]. 6 YAML is a data serialization format made to be readable by humans and to work with scripting languages. Y A M L stands for Y A M L ain't markup language, a recursive acronym that underlines that Y A M L is for data rather than documents [32]. 4 33 Bibliography 1. BASILICO, Nicola; GATTI, Nicola; A M I G O N I , Francesco. Patrolling security games: Definition and algorithms for solving large instances with single patroller and single intruder. Artificial Intelligence. 2012, vol. 184-185, pp. 78-123. ISSN 0004-3702. Available from DOI: https : / / d o i . org/10 .1016/j . a r t i n t . 2012 .03 . 003. 2. KLAŠKA, David. Optimalizační metody pro řešení patrolovacích her. Brno, 2017. Available also from: https : / / i s . muni . c z / t h / ri84d/. Diplomová práce. Masarykova univerzita, Fakulta informatiky. Supervised by Tomáš BRÁZDIL. 3. HAGBERG, Aric A.; SCHULT, Daniel A.; SWART, Pieter J. Exploring Network Structure, Dynamics, and Function using NetworkX. In: VAROQUAUX, Gael; VAUGHT, Travis; M I L L M A N , Jarrod (eds.). Proceedings of the 7th Python in Science Conference. Pasadena, C A U S A , 2008,pp. 11-15. 4. ABHAYGOYAL, et al. NetworkX 2.6—NetworkX 2.6.2 documentation [online]. 2021-07-08. [visited on 2023-04-25]. Available from: https : //networkx . org/documentation/net workx-2 .6.2/ release/release_2.6.html. 5. Graph Editor [online]. CS Academy [visited on 2023-04-06]. Available from: https://csacademy.com/app/graph_editor/. 6. Graph Editor from ZoomCharts. Create, edit and share interactive graph data visualizations, [online]. ZoomCharts [visited on 2023- 04-06]. Available from: https : //apps . zoomcharts . com/graph- editor/. 7. Create Graph online and find shortest path or use other algorithm [online]. UnickSoft, 2023 [visited on 2023-04-25]. Available from: https://graphonline.ru/en/. 8. ULRIK BRANDES, et al. Graph Markup Language (GraphML) [online]. Roberto Tamassia (ed.): CRC Press, 2013 [visited on 2023-04-26]. Available from: https : / /cs . brown. edu/people/ rtamassi/gdhandbook/chapters/graphml.pdf. 34 BIBLIOGRAPHY 9. General Python FAQ - Python 3.11.3 documentation [online]. Wilmington: Python Software Foundation, 2023 [visited on 2023-05- 01]. Available from: https: //docs .python, org/3/f aq/general. html#what-is-python. 10. C H A N D R A , Tushar. [Feature Request] Python 3.10 support • Issue #1863 • plotly/dash [online]. San Francisco, 2021 [visited on 2023- 05-01]. Available from: https : //github . com/plotly/dash/ issues/1863. 11. L A N G A , Lukasz (ed.). What's New In Python 3.9 - Python 3.11.3 documentation [online]. Wilmington: Python Software Foundation, 2023 [visited on 2023-05-01]. Available from: https : //docs. python.org/3/whatsnew/3.9.html. 12. M U S C I A N O , Chuck; KENNEDY, Bill. HTML & XHTML: The Definitive Guide: The Definitive Guide." O'Reilly Media, Inc.", 2002. 13. TABARES-GUTIERREZ, Raul. Taking a Glance at the History of HTML5. EUBAS Proceedings. 2017, T351-66. 14. DEVELOPERS, NetworkX. NetworkX — NetworkX documentation [online]. 2023. [visited on 2023-05-01]. Available from: https : //networkx.org/. 15. TINA MÜLLER, et al. https://pyyaml.org [online]. The Y A M L Project, 2020 [visited on 2023-05-07]. Available from: https: / / pyyaml.org/. 16. CONTRIBUTORS, GeoPy. Welcome to GeoPy's documentation1 . GeoPy 2.3.0 documentation [online]. Geopy, 2018 [visited on 2023- 05-07]. Available from: https : //geopy. readthedocs . io/. 17. COMMUNITY, vis.js. vis.js [online]. 2022. [visited on 2023-05-07]. Available from: https: / / v i s j s. org/. 18. BOSTOCK, Mike. D3./s - Data-Driven Documents [online]. San Francisco: D3, 2021 [visited on 2023-05-07]. Available from: https://d3j s.org/. 19. FRANZ, Max; LOPES, Christian T; HUCK, Gerardo; DONG, Yue; SUMER, Onur; BADER, Gary D. Cytoscape.js: a graph theory library for visualisation and analysis. Bioinformatics [online]. 2015, vol. 32, no. 2, pp. 309-311 [visited on 2023-05-07]. ISSN 1367-4803. Available from DOI: 10.1093/bioinf ormatics/btv557. 35 BIBLIOGRAPHY 20. Interactive network visualizations - pyvis 0.1.3.1 documentation [online]. San Diego: West Health Institute, 2018 [visited on 2023- 05-03]. Available from: https : / / p y v i s . readthedocs . i o / e n / latest/index.html. 21. TASKESEN, Erdogan. D3Graph - digraph digraph documentation [online]. 2020. [visited on 2023-05-03]. Available from: https : //erdogant.github.io/d3graph/pages/html/index.html#. 22. DEWAR, Mike. GitHub - mikedewar/ d3py: a plottling library for python, based on D3 [online]. 2017. [visited on 2023-05-03]. Available from: https: //github. com/mikedewar/d3py. 23. Plotly: Thefront endfor ML and data science models [online]. Montreal: Plotly, 2023 [visited on 2023-05-06]. Available from: https: //plotly.com/dash/. 24. TOMAR, Anmol. Dashfor Beginners: Create Interactive Python Dashboards | by Anmol Tomar \ Towards Data Science [online]. Toronto: Towards Data Science, 2021 [visited on 2023-05-06]. Available from: https : / / towardsdatascience . com / dash - for - beginners - create-interactive-python-dashboards-338bfcb6ffa4. 25. XING H A N LU, et al. Dash Cytoscope \ Dashfor Python Documentation | Plotly [online]. Montreal: Plotly, 2019 [visited on 2023-05- 06]. Available from: https://dash.plotly.com/cytoscape. 26. T O M BEGLEY, et al. Dash Bootstrap Components [online]. Faculty, 2023 [visited on 2023-05-07]. Available from: https : / /dashbootstrap-components .opensource.faculty.ai/. 27. EMIL H A L D R U P ERIKSEN, et al. Dash Extensions [online], thedirtyfew, 2023 [visited on 2023-05-07]. Available from: https://www.dash-extensions.com/. 28. S H A M M A M A H HOSSAIN, et al. Dash DAQ \ Dash for Python Documentation \ Plotly [online]. Plotly, 2022 [visited on 2023-05- 07]. Available from: https://dash.plotly.com/dash-daq. 29. CROCKFORD, Douglas; MORNINGSTAR, Chip. Standard ECMA- 404 The JSON Data Interchange Syntax [online]. 2017-12. [visited on 2023-04-06]. Available from DOI: 10 .13140/RG . 2 . 2 . 28181. 14560. 36 BIBLIOGRAPHY 30. JSON [online]. JSON [visited on 2023-04-06]. Available from: https://www.json.org/json-en.html. 31. BRAY, Tim; PAOLI, Jean; SPERBERG-MCQUEEN, C. M.; MALER, Eve; YERGEAU, Francois. Extensible Markup Language (XML) 1.0 (Fifth Edition) [online]. 2008. [visited on 2023-04-26]. Available from: http: //www. w3. org/TR/REC-xml/. 32. INGY DOT NET, et al. The Official YAML Web Site [online]. The Y A M L Project, 2021 [visited on 2023-05-07]. Available from: https://yaml.org/. 37