{"id":3128,"date":"2025-08-04T01:18:46","date_gmt":"2025-08-04T05:18:46","guid":{"rendered":"https:\/\/blogs.mathworks.com\/graphics-and-apps\/?p=3128"},"modified":"2026-01-30T20:37:26","modified_gmt":"2026-01-31T01:37:26","slug":"creating-a-flight-tracking-dashboard-part-3-using-modular-application-development-principles-to-assemble-the-dashboard","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/graphics-and-apps\/2025\/08\/04\/creating-a-flight-tracking-dashboard-part-3-using-modular-application-development-principles-to-assemble-the-dashboard\/","title":{"rendered":"Creating a Flight Tracking Dashboard, Part 3: Using Modular Application Development Principles to Assemble the Dashboard"},"content":{"rendered":"<div class=\"rtcContent\">\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Are you ready to take your app building skills to the next level? This article walks through an advanced workflow for assembling a flight tracking dashboard. While the techniques covered are targeted for experienced MATLAB developers, they offer a powerful foundation for building scalable, professional-grade applications.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">In this article, you'll learn how to:<\/div>\r\n<ul style=\"margin: 10px 0px 20px;padding-left: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-size: 14px\">\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\">Structure your code using the model-view-controller (MVC) design pattern<\/li>\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\">Build modular, reusable UI components<\/li>\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\">Design a dynamic and customizable frontend using the GUI Layout Toolbox<\/li>\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\">Incorporate responsive theme support for light and dark themes<\/li>\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\">Package and deploy a dashboard as a standalone app or web app<\/li>\r\n<\/ul>\r\n\r\n<hr \/>\r\n\r\n<table style=\"background-color: #e2f0ff\">\r\n<tbody>\r\n<tr>\r\n<td style=\"width: 120px;padding: 3px;vertical-align: middle\"><img decoding=\"async\" loading=\"lazy\" class=\"alignleft wp-image-832\" src=\"https:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2024\/02\/kdeeley-150x150.jpg\" alt=\"\" width=\"110\" height=\"110\" \/><\/td>\r\n<td style=\"vertical-align: middle;padding: 3px\"><strong>Guest Writer: <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/2987674\">Ken Deeley<\/a>\r\n<\/strong>\r\n<div class=\"content\">\r\n<div class=\"SectionBlock first active\">\r\n<div class=\"SD57BF6401\">Ken is an application engineer in Cambridge, UK, supporting MathWorks users with their technical computing projects. Ken joined the MathWorks customer training team in 2011 after research work in mathematics with applications to motion planning for autonomous guided vehicle (AGV) robotics. Ken specializes in software development, machine learning, and financial applications, with a particular focus on graphics and app development. He enjoys training MathWorks users on best practices, working with customers on consulting projects, and capturing common customer workflows and requirements to inform future MathWorks development activities.<\/div>\r\n<\/div>\r\n<\/div><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<div class=\"rtcContent\">\r\n<div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">\r\n\r\n<a href=\"https:\/\/matlab.mathworks.com\/open\/github\/v1?repo=MATLAB-Graphics-and-App-Building\/matlab-gaab-blog-2024&amp;file=FlightTrackingDashboard\/FlightTrackingDashboard_Part3.mlx\" target=\"_blank\" rel=\"nofollow noopener\"><img decoding=\"async\" class=\"\" src=\"https:\/\/www.mathworks.com\/images\/responsive\/global\/open-in-matlab-online.svg\" alt=\"Open in MATLAB Online\" \/><\/a>\r\n\r\n<\/div>\r\n<div class=\"rtcContent\">\r\n<div id=\"H_701E9FF1\" style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><span style=\"font-weight: bold\">Overview<\/span><\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">In the <a href=\"https:\/\/blogs.mathworks.com\/graphics-and-apps\/2024\/07\/31\/creating-a-flight-tracking-dashboard-part-2-developing-an-aircraft-chart\/\" target=\"_blank\" rel=\"noopener\">second blog article<\/a> of this series, we saw how to develop a custom chart to encapsulate the 3D graphics and helper functions used to visualize the aircraft. We also discussed how a similar approach could be used to create a chart showing the current position of the aircraft on its flight route.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">In this article, we'll see how to assemble the flight tracking dashboard by developing a series of modular components. First, we'll develop classes to store and organize the flight data. These classes represent the backend of the dashboard. Next, we'll create a series of frontend components for visualizing and manipulating the flight data. This separation of concerns follows the <span style=\"font-weight: bold\">model-view-controller software architecture<\/span> pattern for application development, explained in more detail in this <a href=\"https:\/\/www.mathworks.com\/company\/technical-articles\/developing-matlab-apps-using-the-model-view-controller-pattern.html\">technical article<\/a> [1]. We will also make use of the latest release of <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/47982-gui-layout-toolbox\" target=\"_blank\" rel=\"noopener\">GUI Layout Toolbox<\/a> (which is now fully compatible with the JavaScript-based graphics system introduced in R2025a) to help organize the frontend components and allow the end user to configure the dashboard layout (see <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/add-ons.html\">instructions for Add-Ons<\/a> to install a toolbox).<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Finally, we'll assemble the various components into a dashboard application suitable for sharing with end users, and discuss the options available for deploying the dashboard, focusing on web deployment. By the end of this article, we'll have a fully functional dashboard for tracking flight data running as a web app.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">All the code used in this series of blog articles is available on <a href=\"https:\/\/github.com\/MATLAB-Graphics-and-App-Building\/flight-tracking-dashboard\">GitHub<\/a>.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><img decoding=\"async\" loading=\"lazy\" class=\"imageNode\" style=\"vertical-align: baseline;width: 972px;height: 522px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_1.png\" alt=\"\" width=\"972\" height=\"522\" \/><\/div>\r\n<div style=\"margin-bottom: 20px;padding-bottom: 4px\">\r\n<div style=\"margin: 0px;padding: 10px 0px 10px 5px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: bold;text-align: start\">Table of Contents<\/div>\r\n<ol>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_5ffd\">Create a storage class for the flight data.<\/a><\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_5416\">Create the application data model.<\/a><\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_712c\">Define a superclass for implementation of the views and controllers.<\/a><\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_8672\">Create views by aggregation with charts.<\/a><\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_072b\">Define class hierarchies to simplify view implementation.<\/a><\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_3a03\">Create a view of the flight path using a geoglobe object.<\/a><\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_9571\">Design reusable modular components for use within the views and controllers.<\/a><\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_24b6\">Use GUI Layout Toolbox layouts to develop a dynamic frontend.<\/a>\r\n<ol>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_3430\">Flexible layouts<\/a><\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_400a\">Card panels<\/a><\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_1ea1\">Box panels<\/a><\/li>\r\n<\/ol>\r\n<\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_69e4\">Provide theme support within the application.<\/a><\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_8fc8\">Assemble the dashboard.<\/a><\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_2d20\">Deploy the dashboard as a web app.<\/a><\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#TMP_3415\">Summary<\/a><\/li>\r\n \t<li style=\"line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: start\"><a href=\"#H_0926CC6D\">References<\/a><\/li>\r\n<\/ol>\r\n<\/div>\r\n<h2 id=\"TMP_5ffd\" style=\"margin: 3px 10px 5px 4px;padding: 0px;line-height: 25px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 20px;font-weight: bold;text-align: left\">Create a storage class for the flight data.<\/h2>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Our dashboard is designed to display flight data such as the position, altitude, and speed of the aircraft. These variables are all time series, so storing them in a <span style=\"font-family: monospace\">timetable<\/span> is a natural choice. We've created some (simulated) data representing a 1-hour flight between Glasgow and Stansted airports in the UK.<\/div>\r\n<div style=\"background-color: #f5f5f5;margin: 10px 15px 10px 0;min-width: 100%\">\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 4px 4px 0px 0px;padding: 6px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">tt = readtimetable( <span style=\"color: #a709f5\">\"FlightPath.csv\"<\/span> );<\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper outputs\">\r\n<div style=\"border-radius: 0px;padding: 0px 45px 4px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">disp( head( tt ) )<\/div>\r\n<div style=\"padding: 10px 0px 6px 17px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px;line-height: 17.234px\">\r\n<div class=\"inlineElement eoOutputWrapper disableDefaultGestureHandling embeddedOutputsTextElement\" style=\"width: 1146px;font-style: normal;font-size: 12px\" data-testid=\"output_0\">\r\n<div class=\" textElement eoOutputContent\" style=\"max-height: 261px;font-style: normal;font-size: 12px\" role=\"article\" data-previous-available-width=\"1109\" data-previous-scroll-height=\"164\" data-hashorizontaloverflow=\"false\">\r\n<table style=\"border-spacing: 0px;border-collapse: collapse\" cellspacing=\"0\">\r\n<thead>\r\n<tr>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 34px;text-align: left;font-weight: bold\" rowspan=\"1\"><\/th>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 140px;min-width: 140px;max-width: 140px;text-align: center;font-weight: bold\">Time<\/th>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 102px;min-width: 102px;max-width: 102px;text-align: center;font-weight: bold\">Latitude<\/th>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 110px;min-width: 110px;max-width: 110px;text-align: center;font-weight: bold\">Longitude<\/th>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 102px;min-width: 102px;max-width: 102px;text-align: center;font-weight: bold\">Airspeed<\/th>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 102px;min-width: 102px;max-width: 102px;text-align: center;font-weight: bold\">Altitude<\/th>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 82px;min-width: 82px;max-width: 82px;text-align: center;font-weight: bold\">Roll<\/th>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 82px;min-width: 82px;max-width: 82px;text-align: center;font-weight: bold\">Pitch<\/th>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 82px;min-width: 82px;max-width: 82px;text-align: center;font-weight: bold\">Yaw<\/th>\r\n<\/tr>\r\n<\/thead>\r\n<tbody>\r\n<tr>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 34px;border-width: 0px 1px 1px;border-style: solid;text-align: left;font-weight: bold\">1<\/th>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 140px;min-width: 140px;max-width: 140px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">30-Jun-2024 10:00:01<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">55.869<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 110px;min-width: 110px;max-width: 110px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">-4.4351<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0<\/td>\r\n<\/tr>\r\n<tr>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 34px;border-width: 0px 1px 1px;border-style: solid;text-align: left;font-weight: bold\">2<\/th>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 140px;min-width: 140px;max-width: 140px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">30-Jun-2024 10:00:02<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">55.868<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 110px;min-width: 110px;max-width: 110px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">-4.4337<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0.61752<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">36.677<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">-0.95973<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0.033343<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">-0.50273<\/td>\r\n<\/tr>\r\n<tr>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 34px;border-width: 0px 1px 1px;border-style: solid;text-align: left;font-weight: bold\">3<\/th>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 140px;min-width: 140px;max-width: 140px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">30-Jun-2024 10:00:03<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">55.867<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 110px;min-width: 110px;max-width: 110px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">-4.4322<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">1.235<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">73.354<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0.066685<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0.028237<\/td>\r\n<\/tr>\r\n<tr>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 34px;border-width: 0px 1px 1px;border-style: solid;text-align: left;font-weight: bold\">4<\/th>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 140px;min-width: 140px;max-width: 140px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">30-Jun-2024 10:00:04<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">55.866<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 110px;min-width: 110px;max-width: 110px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">-4.4308<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">1.8526<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">110.03<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0.10003<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0<\/td>\r\n<\/tr>\r\n<tr>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 34px;border-width: 0px 1px 1px;border-style: solid;text-align: left;font-weight: bold\">5<\/th>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 140px;min-width: 140px;max-width: 140px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">30-Jun-2024 10:00:05<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">55.865<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 110px;min-width: 110px;max-width: 110px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">-4.4294<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">2.4701<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">146.71<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">-0.12277<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0.13337<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0.16877<\/td>\r\n<\/tr>\r\n<tr>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 34px;border-width: 0px 1px 1px;border-style: solid;text-align: left;font-weight: bold\">6<\/th>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 140px;min-width: 140px;max-width: 140px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">30-Jun-2024 10:00:06<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">55.864<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 110px;min-width: 110px;max-width: 110px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">-4.428<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">3.0876<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">183.38<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0.16671<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">-0.64869<\/td>\r\n<\/tr>\r\n<tr>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 34px;border-width: 0px 1px 1px;border-style: solid;text-align: left;font-weight: bold\">7<\/th>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 140px;min-width: 140px;max-width: 140px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">30-Jun-2024 10:00:07<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">55.863<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 110px;min-width: 110px;max-width: 110px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">-4.4265<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">3.7051<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">220.06<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0.20006<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0<\/td>\r\n<\/tr>\r\n<tr>\r\n<th style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 6px 3px 3px;width: 34px;border-width: 0px 1px 1px;border-style: solid;text-align: left;font-weight: bold\">8<\/th>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 140px;min-width: 140px;max-width: 140px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">30-Jun-2024 10:00:08<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">55.862<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 110px;min-width: 110px;max-width: 110px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">-4.4251<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">4.3226<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 102px;min-width: 102px;max-width: 102px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">256.74<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0.2334<\/td>\r\n<td style=\"font-family: Arial, sans-serif;font-size: 12px;overflow: hidden;padding: 3px;width: 82px;min-width: 82px;max-width: 82px;border-width: 0px 1px 1px;border-style: solid;text-align: right\">0<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<div style=\"margin: 10px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Timetables are flexible and enable us to freely add and remove variables. We will add some derived variables to the timetable, such as the heading, climb rate, and slip. However, if our intention is to deploy an application to end users, we may want to limit the ways in which they can modify the application data, which is not possible using a standard MATLAB data type such as a timetable. On the other hand, using object-oriented programming means that we can provide read-only access to a data set, and guarantee that the timetable contains all the variables required for the application.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">We'll create a new class <span style=\"font-family: monospace\">FlightPathData<\/span> to store the timetable containing the flight data. We handle data input using the class constructor. This takes a filename as input and imports the data using <span style=\"font-family: monospace\">readtimetable<\/span>.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Note that a <span style=\"font-family: monospace\">FlightPathData<\/span> object can be constructed without entering a filename. In this case, the object will have empty properties. <span style=\"font-weight: bold\">It's good practice to support zero-input argument syntax for a data storage class<\/span>, because it means that it's easier to support arrays of objects. For example, we might need an object array if our application supports loading multiple datasets simultaneously.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">We construct a <span style=\"font-family: monospace\">FlightPathData<\/span> object from the file <span style=\"font-family: monospace\">FlightPath.csv<\/span> containing flight data.<\/div>\r\n<div style=\"background-color: #f5f5f5;margin: 10px 15px 10px 0;min-width: 100%\">\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 4px;padding: 6px 45px 4px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">FPD = FlightPathData( <span style=\"color: #a709f5\">\"FlightPath.csv\"<\/span> );<\/div>\r\n<\/div>\r\n<\/div>\r\n<h2 id=\"TMP_5416\" style=\"margin: 3px 10px 5px 4px;padding: 0px;line-height: 25px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 20px;font-weight: bold;text-align: left\">Create the application data model.<\/h2>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">The <span style=\"font-family: monospace\">FlightPathData<\/span> class provides data storage. For a modular application such as a dashboard, we also need the ability to maintain state information. Moreover, when the end user interacts with the dashboard controls, we need to notify other parts of the application of any changes. This information sharing is achieved through the use of <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/matlab_oop\/learning-to-use-events-and-listeners.html\">events and listeners<\/a>, which also avoids unnecessary coupling between different parts of the application. Since only handle classes can maintain state and issue events, we create a handle class wrapper <span style=\"font-family: monospace\">FlightDashboardModel<\/span> for our data storage class <span style=\"font-family: monospace\">FlightPathData<\/span>. The following diagram was generated using MATLAB's <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/classdiagramviewer.html\">Class Diagram Viewer<\/a> with the <span style=\"font-family: monospace\">FlightPathData<\/span> and <span style=\"font-family: monospace\">FlightDashboardModel<\/span> classes and enabling the \"Associations\" option.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><img decoding=\"async\" loading=\"lazy\" class=\"imageNode\" style=\"vertical-align: baseline;width: 653px;height: 404px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_2.png\" alt=\"\" width=\"653\" height=\"404\" \/><\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">We equip <span style=\"font-family: monospace\">FlightDashboardModel<\/span> with an <span style=\"font-family: monospace\">import<\/span> method for loading data from a file, and a <span style=\"font-family: monospace\">reset<\/span> method for removing the loaded data. We add the property <span style=\"font-family: monospace\">CurrentTime<\/span>, a scalar <span style=\"font-family: monospace\">datetime<\/span> value, to represent the state of the application. We equip the model with the events <span style=\"font-family: monospace\">CurrentTimeChanged<\/span> and <span style=\"font-family: monospace\">FlightDataChanged<\/span>. For more information about designing a model class, see [1].<\/div>\r\n<h2 id=\"TMP_712c\" style=\"margin: 3px 10px 5px 4px;padding: 0px;line-height: 25px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 20px;font-weight: bold;text-align: left\">Define a superclass for implementation of the views and controllers.<\/h2>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">The views and controllers that comprise the dashboard frontend have several things in common. First, they should all have a reference to the model (<span style=\"font-family: monospace\">FlightDashboardModel<\/span>), so that they can access and modify the application data and state during dashboard operation. Next, to respond dynamically to the model events <span style=\"font-family: monospace\">CurrentTimeChanged<\/span> and <span style=\"font-family: monospace\">FlightDataChanged<\/span>, the views and controllers should have listeners with corresponding callback functions <span style=\"font-family: monospace\">onCurrentTimeChanged<\/span> and <span style=\"font-family: monospace\">onFlightDataChanged<\/span>. All frontend components must implement these callbacks, but the concrete implementation will necessarily be different between the various views and controllers. We can enforce this behavioral contract by using <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/matlab_oop\/abstract-classes-and-interfaces.html\">abstract methods<\/a>.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">MATLAB's <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/matlab.ui.componentcontainer.componentcontainer-class.html\"><span style=\"font-family: monospace\">ComponentContainer<\/span><\/a> class provides a convenient means to implement frontend components. It equips each view and controller with a container object to hold the required graphics and control objects, provides standard public properties such as <span style=\"font-family: monospace\">Parent<\/span>, <span style=\"font-family: monospace\">Position<\/span>, <span style=\"font-family: monospace\">Units<\/span>, and <span style=\"font-family: monospace\">Visible<\/span>, and manages the component's lifecycle. On construction, we remove the autoparenting behavior of the component and ensure that it spans its parent by setting the following properties:<\/div>\r\n<ul style=\"margin: 10px 0px 20px;padding-left: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-size: 14px\">\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\"><span style=\"font-family: monospace\">Parent = []<\/span><\/li>\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\"><span style=\"font-family: monospace\">Units =<span style=\"color: #a709f5\"> \"normalized\"<\/span><\/span><\/li>\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\"><span style=\"font-family: monospace\">Position = [0, 0, 1, 1]<\/span><\/li>\r\n<\/ul>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Finally, we note that the R2024b release saw the introduction of <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/matlab_oop\/weak-reference-handles.html\">weak reference handles<\/a>. This enables a reference to an object to be created without interfering with the lifecycle of the underlying object. To avoid creating a strong reference cycle in the component via the object reference captured by the listener callback function handle, we create a weak reference to the component and access its <span style=\"font-family: monospace\">Handle<\/span> property in the callback function. From R2024b onwards, <span style=\"font-weight: bold\">avoiding unnecessary strong reference cycles is the recommended best practice<\/span> to help improve future code performance.<\/div>\r\n<div class=\"preformatted-matlab\" style=\"margin: 10px 3px 10px 55px;padding: 10px 10px 10px 5px\">\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">weakObj = matlab.lang.WeakReference( obj );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">obj.FlightDataChangedListener = listener( obj.Model, <span style=\"color: #a709f5\">\"FlightDataChanged\"<\/span>, @( s, e ) weakObj.Handle.onFlightDataChanged( s, e ) );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">obj.CurrentTimeChangedListener = listener( obj.Model, <span style=\"color: #a709f5\">\"CurrentTimeChanged\"<\/span>, @( s, e ) weakObj.Handle.onCurrentTimeChanged( s, e ) );<\/div>\r\n<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">See <span style=\"font-family: monospace\">FlightDashboardComponent<\/span> for full implementation details. This class is the common superclass for all of the dashboard's frontend components.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><img decoding=\"async\" loading=\"lazy\" class=\"imageNode\" style=\"vertical-align: baseline;width: 352px;height: 321px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_3.png\" alt=\"\" width=\"352\" height=\"321\" \/><\/div>\r\n<h2 id=\"TMP_8672\" style=\"margin: 3px 10px 5px 4px;padding: 0px;line-height: 25px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 20px;font-weight: bold;text-align: left\">Create views by aggregation with charts.<\/h2>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">In the <a href=\"https:\/\/blogs.mathworks.com\/graphics-and-apps\/2024\/07\/31\/creating-a-flight-tracking-dashboard-part-2-developing-an-aircraft-chart\/\">previous blog article<\/a> we saw how to encapsulate a related set of graphics objects and functions as a custom chart. <span style=\"font-weight: bold\">We can use charts as standalone objects<\/span> within scripts and functions, or embed them in a larger application. In this example, we'll create two views by aggregation [2] with charts that were created previously. Specifically,<\/div>\r\n<ul style=\"margin: 10px 0px 20px;padding-left: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-size: 14px\">\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\"><span style=\"font-family: monospace\">AircraftAttitudeView<\/span> is aggregated with the <span style=\"font-family: monospace\">AircraftChart<\/span>, and<\/li>\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\"><span style=\"font-family: monospace\">MapView<\/span> is aggregated with the <span style=\"font-family: monospace\">PositionChart<\/span>.<\/li>\r\n<\/ul>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Creating a view via aggregation with a chart is particularly simple: the view stores a reference to the chart as one of its private properties, and instantiates the chart in its <span style=\"font-family: monospace\">setup<\/span> method. When the view responds to model events through its implementation of the required listener callbacks, it updates the chart using the chart's public properties or methods.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><img decoding=\"async\" loading=\"lazy\" class=\"imageNode\" style=\"vertical-align: baseline;width: 945px;height: 646px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_4.png\" alt=\"\" width=\"945\" height=\"646\" \/><\/div>\r\n<h2 id=\"TMP_072b\" style=\"margin: 3px 10px 5px 4px;padding: 0px;line-height: 25px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 20px;font-weight: bold;text-align: left\">Define class hierarchies to simplify view implementation.<\/h2>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">We can identify two groups of views that share implementation details.<\/div>\r\n<ul style=\"margin: 10px 0px 20px;padding-left: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-size: 14px\">\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\">There are six views that display a specific flight instrument (airspeed, horizon, altitude, turn, heading, and climb rate). These share the same architecture, using a box panel (<span style=\"font-family: monospace\">uix.BoxPanel<\/span>) from <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/47982-gui-layout-toolbox\">GUI Layout Toolbox<\/a>, an intermediate <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/uigridlayout.html\">grid layout<\/a> and <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/uipanel.html\">panel<\/a>, and a <a href=\"https:\/\/www.mathworks.com\/help\/aerotbx\/flight-instruments.html\">flight instrument<\/a> component from <a href=\"https:\/\/www.mathworks.com\/products\/aerospace-toolbox.html\">Aerospace Toolbox<\/a>.<\/li>\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\">There are four views that use a text-based display to show the current value of a variable (time, latitude, longitude, and yaw). These views use the same graphics objects (an <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/axes.html\">axes<\/a>, <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/rectangle.html\">rectangle<\/a>, and <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/text.html\">text<\/a> box).<\/li>\r\n<\/ul>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">To share common code between multiple classes, we create a <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/matlab_oop\/hierarchies-of-classes-concepts.html\">class hierarchy<\/a>. This enables future modifications to the shared code to be made in a single location, rather than having to make the same change across a number of files.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">For the first group of views, we define a superclass <span style=\"font-family: monospace\">FlightInstrumentView<\/span> that contains the shared graphics objects and an abstract property <span style=\"font-family: monospace\">Instrument<\/span>. It's the responsibility of each subclass to define the appropriate flight instrument (e.g., using <a href=\"https:\/\/www.mathworks.com\/help\/aerotbx\/ug\/uiaeroairspeed.html\"><span style=\"font-family: monospace\">uiaeroairspeed<\/span><\/a> or <a href=\"https:\/\/www.mathworks.com\/help\/aerotbx\/ug\/uiaeroaltimeter.html\"><span style=\"font-family: monospace\">uiaeroaltimeter<\/span><\/a>).<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><img decoding=\"async\" loading=\"lazy\" class=\"imageNode\" style=\"vertical-align: baseline;width: 1061px;height: 585px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_5.png\" alt=\"\" width=\"1061\" height=\"585\" \/><\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">For example, we could create <span style=\"font-family: monospace\">AltitudeView<\/span> and <span style=\"font-family: monospace\">HorizonView<\/span> objects within the same layout. We use the <span style=\"font-family: monospace\">uix.HBox<\/span> component from GUI Layout Toolbox to create a horizontal layout.<\/div>\r\n<div style=\"background-color: #f5f5f5;margin: 10px 15px 10px 0;min-width: 100%\">\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 4px 4px 0px 0px;padding: 6px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">FDM = FlightDashboardModel( <span style=\"color: #a709f5\">\"FlightPath.csv\"<\/span> );<\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 0px;padding: 0px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\"><\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 0px;padding: 0px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">f = uifigure;<\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 0px;padding: 0px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">hb = uix.HBox(<span style=\"color: #a709f5\"> \"Parent\"<\/span>, f, <span style=\"color: #a709f5\">\"Padding\"<\/span>, 5,<span style=\"color: #a709f5\"> \"Spacing\"<\/span>, 5 );<\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 0px;padding: 0px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">AV = AltitudeView( FDM,<span style=\"color: #a709f5\"> \"Parent\"<\/span>, hb );<\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper outputs\">\r\n<div style=\"border-radius: 0px;padding: 0px 45px 4px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">HV = HorizonView( FDM, <span style=\"color: #a709f5\">\"Parent\"<\/span>, hb );<\/div>\r\n<div style=\"padding: 10px 0px 6px 17px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px;line-height: 17.234px\">\r\n<div class=\"inlineElement eoOutputWrapper disableDefaultGestureHandling embeddedOutputsFigure\" data-testid=\"output_1\">\r\n<div class=\"outputLayer selectedOutputDecorationLayer doNotExport\" aria-hidden=\"true\"><\/div>\r\n<div class=\"outputLayer activeOutputDecorationLayer doNotExport\" aria-hidden=\"true\"><\/div>\r\n<div class=\"outputLayer scrollableOutputDecorationLayer doNotExport\" aria-hidden=\"true\"><\/div>\r\n<div class=\"outputLayer navigationFocusLayer doNotExport\" role=\"application\" aria-hidden=\"false\"><\/div>\r\n<div class=\"figureElement eoOutputContent\" role=\"article\"><img decoding=\"async\" class=\"figureImage figureContainingNode\" style=\"width: 560px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_6.png\" \/><\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<div style=\"margin: 10px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Similarly, for the text-based views, we define a superclass <span style=\"font-family: monospace\">TextAreaView<\/span> to contain the shared graphics and a helper method <span style=\"font-family: monospace\">updateTextArea<\/span> that allows subclasses to modify the displayed text in response to model events. In this case, the shared graphics are encapsulated in a reusable component <span style=\"font-family: monospace\">RectangularTextArea<\/span> that we'll discuss in more detail in a later section.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><img decoding=\"async\" loading=\"lazy\" class=\"imageNode\" style=\"vertical-align: baseline;width: 937px;height: 564px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_7.png\" alt=\"\" width=\"937\" height=\"564\" \/><\/div>\r\n<h2 id=\"TMP_3a03\" style=\"margin: 3px 10px 5px 4px;padding: 0px;line-height: 25px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 20px;font-weight: bold;text-align: left\">Create a view of the flight path using a <span style=\"font-family: monospace\">geoglobe<\/span> object.<\/h2>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">In the <span style=\"font-family: monospace\">PositionChart<\/span> mentioned above, we plot the route and current position of the aircraft using <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/geoplot.html\"><span style=\"font-family: monospace\">geoplot<\/span><\/a> objects on a <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/geoaxes.html\"><span style=\"font-family: monospace\">geoaxes<\/span><\/a>. These graphics objects are available in base MATLAB. In addition, <a href=\"https:\/\/www.mathworks.com\/products\/mapping.html\">Mapping Toolbox<\/a> provides the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/geoplot.html\"><span style=\"font-family: monospace\">geoglobe<\/span><\/a> and <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2025a\/map\/ref\/geoplot3.html\"><span style=\"font-family: monospace\">geoplot3<\/span><\/a> visualization functions for visualizing lines and points on a 3D globe. We'll use these functions to create the <span style=\"font-family: monospace\">GlobeView<\/span> class. This provides an interactive view of the aircraft's current position and flight route on the globe, including terrain information.<\/div>\r\n<div style=\"background-color: #f5f5f5;margin: 10px 15px 10px 0;min-width: 100%\">\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 4px 4px 0px 0px;padding: 6px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">FDM = FlightDashboardModel( <span style=\"color: #a709f5\">\"FlightPath.csv\"<\/span> );<\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 0px;padding: 0px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\"><\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 0px;padding: 0px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">f = uifigure;<\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 0px 0px 4px 4px;padding: 0px 45px 4px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">GV = GlobeView( FDM,<span style=\"color: #a709f5\"> \"Parent\"<\/span>, f );<\/div>\r\n<\/div>\r\n<\/div>\r\n<div style=\"margin: 10px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><img decoding=\"async\" loading=\"lazy\" class=\"imageNode\" style=\"vertical-align: baseline;width: 562px;height: 452px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_8.png\" alt=\"\" width=\"562\" height=\"452\" \/><\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">If you have access to the <a href=\"https:\/\/www.mathworks.com\/products\/satellite-communications.html\">Satellite Communication Toolbox<\/a>, there are additional aircraft assets and map-based visualizations available for tracking applications. Here's an <a href=\"https:\/\/www.mathworks.com\/help\/satcom\/ug\/aircraft-ads-b-out-airport-and-satellite-connectivity.html\">example<\/a> [3] that shows communication links between an aircraft and a satellite constellation.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">The <span style=\"font-family: monospace\">GlobeView<\/span> class manages the geographic globe and two line objects created using the <span style=\"font-family: monospace\">geoplot3<\/span> function. One line object is used to plot the flight route, and the second is used to indicate the current position of the aircraft.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><img decoding=\"async\" loading=\"lazy\" class=\"imageNode\" style=\"vertical-align: baseline;width: 271px;height: 454px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_9.png\" alt=\"\" width=\"271\" height=\"454\" \/><\/div>\r\n<h2 id=\"TMP_9571\" style=\"margin: 3px 10px 5px 4px;padding: 0px;line-height: 25px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 20px;font-weight: bold;text-align: left\">Design reusable modular components for use within the views and controllers.<\/h2>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">To maximize code reuse between multiple applications, it's good practice to refactor out modular components (or <span style=\"font-style: italic\">widgets<\/span>) from views and controllers when developing the frontend. This avoids individual views and controllers becoming overly long or complicated and means that the same component can be reused within the same app or between different apps.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">We've already seen above that charts are good examples of reusable components - in our case, we can use <span style=\"font-family: monospace\">AircraftChart<\/span> and <span style=\"font-family: monospace\">PositionChart<\/span> as part of a script or function that we're writing, outside the context of an interactive application.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Two generic widgets in our dashboard are the playback controls for modifying the current time during the simulation, and the rectangular text area for displaying the current value of a flight variable.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">The class <span style=\"font-family: monospace\">PlaybackControls<\/span> creates the first widget. Since this uses user interface control objects, this class is derived from <span style=\"font-family: monospace\">ComponentContainer<\/span>.<\/div>\r\n<div style=\"background-color: #f5f5f5;margin: 10px 15px 10px 0;min-width: 100%\">\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 4px 4px 0px 0px;padding: 6px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">f = uifigure;<\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 0px;padding: 0px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">g = uigridlayout( f, [1, 1], <span style=\"color: #a709f5\">\"Padding\"<\/span>, 0 );<\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 0px;padding: 0px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">PC = PlaybackControls( <span style=\"color: #a709f5\">\"Parent\"<\/span>, g );<\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper outputs\">\r\n<div style=\"border-radius: 0px;padding: 0px 45px 4px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">f.Position(4) = 50;<\/div>\r\n<div style=\"padding: 10px 0px 6px 17px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px;line-height: 17.234px\">\r\n<div class=\"inlineElement eoOutputWrapper disableDefaultGestureHandling embeddedOutputsFigure\" data-testid=\"output_2\">\r\n<div class=\"outputLayer selectedOutputDecorationLayer doNotExport\" aria-hidden=\"true\"><\/div>\r\n<div class=\"outputLayer activeOutputDecorationLayer doNotExport\" aria-hidden=\"true\"><\/div>\r\n<div class=\"outputLayer scrollableOutputDecorationLayer doNotExport\" aria-hidden=\"true\"><\/div>\r\n<div class=\"outputLayer navigationFocusLayer doNotExport\" role=\"application\" aria-hidden=\"false\"><\/div>\r\n<div class=\"figureElement eoOutputContent\" role=\"article\"><img decoding=\"async\" class=\"figureImage figureContainingNode\" style=\"width: 560px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_10.png\" \/><\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<div style=\"margin: 10px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Likewise, the <span style=\"font-family: monospace\">RectangularTextArea<\/span> class defines the second reusable widget. This widget is reused in the dashboard across the second group of views in the class hierarchies discussed above. Since this widget uses an axes together with some axes children, we derive this class from <span style=\"font-family: monospace\">ChartContainer<\/span>. For further information about using <span style=\"font-family: monospace\">ChartContainer<\/span> and <span style=\"font-family: monospace\">ComponentContainer<\/span> to create modular components, see [4].<\/div>\r\n<div style=\"background-color: #f5f5f5;margin: 10px 15px 10px 0;min-width: 100%\">\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 4px 4px 0px 0px;padding: 6px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">f = uifigure;<\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper\">\r\n<div style=\"border-radius: 0px;padding: 0px 45px 0px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">g = uigridlayout( f, [1, 1], <span style=\"color: #a709f5\">\"Padding\"<\/span>, 0 );<\/div>\r\n<\/div>\r\n<div class=\"inlineWrapper outputs\">\r\n<div style=\"border-radius: 0px;padding: 0px 45px 4px 13px;line-height: 18.004px;min-height: 0px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace, Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px\">RTA = RectangularTextArea( <span style=\"color: #a709f5\">\"Parent\"<\/span>, g, <span style=\"color: #a709f5\">\"Value\"<\/span>, <span style=\"color: #a709f5\">\"Hello world\"<\/span> );<\/div>\r\n<div style=\"padding: 10px 0px 6px 17px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 14px;line-height: 17.234px\">\r\n<div class=\"inlineElement eoOutputWrapper disableDefaultGestureHandling embeddedOutputsFigure\" data-testid=\"output_3\">\r\n<div class=\"outputLayer selectedOutputDecorationLayer doNotExport\" aria-hidden=\"true\"><\/div>\r\n<div class=\"outputLayer activeOutputDecorationLayer doNotExport\" aria-hidden=\"true\"><\/div>\r\n<div class=\"outputLayer scrollableOutputDecorationLayer doNotExport\" aria-hidden=\"true\"><\/div>\r\n<div class=\"outputLayer navigationFocusLayer doNotExport\" role=\"application\" aria-hidden=\"false\"><\/div>\r\n<div class=\"figureElement eoOutputContent\" role=\"article\"><img decoding=\"async\" class=\"figureImage figureContainingNode\" style=\"width: 560px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_11.png\" \/><\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<div style=\"margin: 10px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">The rectangular text area is composed of an axes object, containing two children: a rectangle and a text box. The playback controls widget comprises play, pause, and stop buttons, with a label to display the current time, a slider to select the current time, and a spinner to control the playback rate.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><img decoding=\"async\" loading=\"lazy\" class=\"imageNode\" style=\"vertical-align: baseline;width: 454px;height: 892px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_12.png\" alt=\"\" width=\"454\" height=\"892\" \/><\/div>\r\n<h2 id=\"TMP_24b6\" style=\"margin: 3px 10px 5px 4px;padding: 0px;line-height: 25px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 20px;font-weight: bold;text-align: left\">Use GUI Layout Toolbox layouts to develop a dynamic frontend.<\/h2>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">To equip the dashboard with a dynamic interface, we use different layouts from <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/47982-gui-layout-toolbox\">GUI Layout Toolbox<\/a> to organize the views and controls.<\/div>\r\n<h3 id=\"TMP_3430\" style=\"margin: 15px 10px 5px 4px;padding: 0px;line-height: 20.4px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 17px;font-weight: bold;text-align: left\">Flexible layouts<\/h3>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><img decoding=\"async\" loading=\"lazy\" class=\"imageNode\" style=\"vertical-align: baseline;width: 280px;height: 210px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_13.gif\" alt=\"\" width=\"280\" height=\"210\" \/><\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Flexible layouts provide draggable dividers between the rows and columns in a grid. Layouts in this category are <span style=\"font-family: monospace\">uix.GridFlex<\/span>, <span style=\"font-family: monospace\">uix.HBoxFlex<\/span>, and <span style=\"font-family: monospace\">uix.VBoxFlex<\/span>.<\/div>\r\n<div class=\"preformatted-matlab\" style=\"margin: 10px 3px 10px 55px;padding: 10px 10px 10px 5px\">\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">FDM = FlightDashboardModel();<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\"><\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">f = uifigure( <span style=\"color: #a709f5\">\"AutoResizeChildren\"<\/span>, <span style=\"color: #a709f5\">\"off\"<\/span> );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">gf = uix.GridFlex( <span style=\"color: #a709f5\">\"Parent\"<\/span>, f, <span style=\"color: #a709f5\">\"Padding\"<\/span>, 15,<span style=\"color: #a709f5\"> \"Spacing\"<\/span>, 15 );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">V(1) = AirspeedView( FDM, <span style=\"color: #a709f5\">\"Parent\"<\/span>, gf );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">V(2) = TurnView( FDM, <span style=\"color: #a709f5\">\"Parent\"<\/span>, gf );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">V(3) = HorizonView( FDM, <span style=\"color: #a709f5\">\"Parent\"<\/span>, gf );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">V(4) = HeadingView( FDM,<span style=\"color: #a709f5\"> \"Parent\"<\/span>, gf );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">V(5) = AltitudeView( FDM,<span style=\"color: #a709f5\"> \"Parent\"<\/span>, gf );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">V(6) = ClimbRateView( FDM, <span style=\"color: #a709f5\">\"Parent\"<\/span>, gf );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">gf.Heights = [-1, -1];<\/div>\r\n<\/div>\r\n<h3 id=\"TMP_400a\" style=\"margin: 15px 10px 5px 4px;padding: 0px;line-height: 20.4px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 17px;font-weight: bold;text-align: left\">Card panels<\/h3>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><img decoding=\"async\" loading=\"lazy\" class=\"imageNode\" style=\"vertical-align: baseline;width: 280px;height: 210px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_14.gif\" alt=\"\" width=\"280\" height=\"210\" \/><\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">A card panel (<span style=\"font-family: monospace\">uix.CardPanel<\/span>) manages a stack of graphics objects, showing one object at a time and hiding the others.<\/div>\r\n<div class=\"preformatted-matlab\" style=\"margin: 10px 3px 10px 55px;padding: 10px 10px 10px 5px\">\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">FDM = FlightDashboardModel();<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\"><\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">f = uifigure( <span style=\"color: #a709f5\">\"AutoResizeChildren\"<\/span>, <span style=\"color: #a709f5\">\"off\"<\/span> );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">TAVD = TextAreaViewDisplay( FDM, <span style=\"color: #a709f5\">\"Parent\"<\/span>, f );<\/div>\r\n<\/div>\r\n<h3 id=\"TMP_1ea1\" style=\"margin: 15px 10px 5px 4px;padding: 0px;line-height: 20.4px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 17px;font-weight: bold;text-align: left\">Box panels<\/h3>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><img decoding=\"async\" loading=\"lazy\" class=\"imageNode\" style=\"vertical-align: baseline;width: 280px;height: 210px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_15.gif\" alt=\"\" width=\"280\" height=\"210\" \/><\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">A box panel (<span style=\"font-family: monospace\">uix.BoxPanel<\/span>) is a decorated standard panel equipped with additional callbacks (<span style=\"font-family: monospace\">MinimizeFcn<\/span>, <span style=\"font-family: monospace\">HelpFcn<\/span>, <span style=\"font-family: monospace\">DockFcn<\/span>, and <span style=\"font-family: monospace\">CloseRequestFcn<\/span>). Setting these callbacks places button controls in the top right of the title bar. In the flight dashboard we use the <span style=\"font-family: monospace\">MinimizeFcn<\/span> callback to allow an entire row of flight instruments to be expanded and collapsed.<\/div>\r\n<div class=\"preformatted-matlab\" style=\"margin: 10px 3px 10px 55px;padding: 10px 10px 10px 5px\">\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\"><span style=\"color: #0e00ff\">function<\/span> boxPanelExample()<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\"><\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">FDM = FlightDashboardModel();<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\"><\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">f = uifigure(<span style=\"color: #a709f5\"> \"AutoResizeChildren\"<\/span>, <span style=\"color: #a709f5\">\"off\"<\/span> );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">vb = uix.VBox( <span style=\"color: #a709f5\">\"Parent\"<\/span>, f );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">AltitudeView( FDM,<span style=\"color: #a709f5\"> \"Parent\"<\/span>, vb, <span style=\"color: #a709f5\">\"MinimizeFcn\"<\/span>, {@onPanelMinimized, 1} );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">HorizonView( FDM, <span style=\"color: #a709f5\">\"Parent\"<\/span>, vb, <span style=\"color: #a709f5\">\"MinimizeFcn\"<\/span>, {@onPanelMinimized, 2} );<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\"><\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0e00ff\">function<\/span> onPanelMinimized( s, ~, idx )<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\"><\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0s.Minimized = ~s.Minimized;<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\"><\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0e00ff\">if<\/span> s.Minimized<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0vb.Heights(idx) = 22;<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0e00ff\">else<\/span><\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0vb.Heights(idx) = -1;<\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0e00ff\">end<\/span> <span style=\"color: #008000\">% if<\/span><\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\"><\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\">\u00a0\u00a0\u00a0\u00a0<span style=\"color: #0e00ff\">end<\/span><span style=\"color: #008000\"> % onPanelMinimized<\/span><\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\"><\/div>\r\n<div style=\"border-radius: 0px;padding: 0px;line-height: 15.6px;min-height: 16px;font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;font-size: 12px\"><span style=\"color: #0e00ff\">end<\/span> <span style=\"color: #008000\">% boxPanelExample<\/span><\/div>\r\n<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><\/div>\r\n<h2 id=\"TMP_69e4\" style=\"margin: 3px 10px 5px 4px;padding: 0px;line-height: 25px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 20px;font-weight: bold;text-align: left\">Provide theme support within the application.<\/h2>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Support for themes in MATLAB graphics and apps was introduced in R2025a. When designing an application, it's good practice to ensure that the components are responsive to theme changes.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">We should ensure theme support at the level of each view and controller, as well as in the application launcher that managers the figure and figure-level controls. In a view or controller, theme support can be achieved by placing theme-responsive code in the <span style=\"font-family: monospace\">update<\/span> method. This suffices because the <span style=\"font-family: monospace\">update<\/span> method is called automatically whenever the theme changes.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">At the application launcher level, it may be necessary to use the figure's <span style=\"font-family: monospace\">ThemeChangedFcn<\/span> callback to respond to theme changes. However, by default, the app figure responds automatically to changes in the MATLAB Desktop theme.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">For the flight dashboard, we add a toolbar button to toggle between light and dark theme. The corresponding callback is simple: we set the figure's <span style=\"font-family: monospace\">Theme<\/span> property to either <span style=\"font-family: monospace\">\"light\"<\/span> or <span style=\"font-family: monospace\">\"dark\"<\/span>. The views and controllers then update accordingly.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\"><img decoding=\"async\" loading=\"lazy\" class=\"imageNode\" style=\"vertical-align: baseline;width: 150px;height: 89px\" src=\"http:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_16.png\" alt=\"\" width=\"150\" height=\"89\" \/><\/div>\r\n<h2 id=\"TMP_8fc8\" style=\"margin: 3px 10px 5px 4px;padding: 0px;line-height: 25px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 20px;font-weight: bold;text-align: left\">Assemble the dashboard.<\/h2>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">After developing the views and controllers that comprise the dashboard's frontend, the final step is to assemble them in the application launcher. This class has several responsibilities:<\/div>\r\n<ul style=\"margin: 10px 0px 20px;padding-left: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-size: 14px\">\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\">Check for software dependencies (in this case, GUI Layout Toolbox) and issue an alert if these are not installed.<\/li>\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\">Create the figure and any figure-level controls such as menus or toolbars.<\/li>\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\">Instantiate the model.<\/li>\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\">Define the top-level application layout (e.g., using <span style=\"font-family: monospace\">uigridlayout<\/span> or layouts from GUI Layout Toolbox).<\/li>\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\">Create the views and controllers that will be shown when the app starts.<\/li>\r\n \t<li style=\"margin-left: 56px;line-height: 21px;min-height: 0px;text-align: left\">Implement any menu or toolbar button callbacks.<\/li>\r\n<\/ul>\r\n<h2 id=\"TMP_2d20\" style=\"margin: 3px 10px 5px 4px;padding: 0px;line-height: 25px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 20px;font-weight: bold;text-align: left\">Deploy the dashboard as a web app.<\/h2>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Using <a href=\"https:\/\/www.mathworks.com\/products\/compiler.html\">MATLAB Compiler<\/a>, the dashboard could be deployed to end users as a standalone executable (.exe) or web app (.ctf). <a href=\"https:\/\/www.mathworks.com\/products\/matlab-web-app-server.html\">MATLAB Web App Server<\/a> enables enterprise deployment of web apps including authentication.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">Since we've built the application programmatically, if we need to deploy the dashboard as a web app, we need to create a simple App Designer wrapper. In App Designer, we create an app file <span style=\"font-family: monospace\">FlightDashboardApp<\/span> that contains only the figure. In the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/creating_guis\/app-designer-startup-function.html\">startup function<\/a> of the app, we call our application launcher, passing in the figure. We can then <a href=\"https:\/\/www.mathworks.com\/help\/compiler\/webapps\/create-and-deploy-a-web-app.html\">create a web app<\/a> interactively using the <span style=\"font-weight: bold\">Share<\/span> menu in App Designer, or programmatically using <a href=\"https:\/\/www.mathworks.com\/help\/compiler\/webapps\/compiler.build.webapparchive.html\" target=\"_blank\" rel=\"noopener\"><span style=\"font-family: monospace\">compiler.build.webAppArchive<\/span><\/a>.<\/div>\r\n<h2 id=\"TMP_3415\" style=\"margin: 3px 10px 5px 4px;padding: 0px;line-height: 25px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 20px;font-weight: bold;text-align: left\">Summary<\/h2>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">We've provided an overview of how the various components of the flight dashboard have been designed, with an emphasis on code modularity and reuse. We've also discussed how to assemble the dashboard as well as the options for deployment to end users.<\/div>\r\n<h2 id=\"H_0926CC6D\" style=\"margin: 3px 10px 5px 4px;padding: 0px;line-height: 25px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 20px;font-weight: bold;text-align: left\">References<\/h2>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">[1] <a href=\"https:\/\/www.mathworks.com\/company\/technical-articles\/developing-matlab-apps-using-the-model-view-controller-pattern.html\"><span style=\"font-style: italic\">Developing MATLAB Apps Using the Model-View-Controller Pattern<\/span><\/a>, Laura Dempsey and Ken Deeley (2023).<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">[2] <a href=\"https:\/\/en.wikipedia.org\/wiki\/Object_composition\"><span style=\"font-style: italic\">Object composition<\/span><\/a>, Wikipedia, accessed April 2025.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">[3] <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2025a\/satcom\/ug\/aircraft-ads-b-out-airport-and-satellite-connectivity.html\"><span style=\"font-style: italic\">Aircraft-to-Satellite Communication for ADS-B Out<\/span><\/a><span style=\"font-style: italic\">,<\/span> <a href=\"https:\/\/www.mathworks.com\/products\/satellite-communications.html\">Satellite Communications Toolbox<\/a>.<\/div>\r\n<div style=\"margin: 2px 10px 9px 4px;padding: 0px;line-height: 21px;min-height: 0px;font-family: Helvetica, Arial, sans-serif, Helvetica, Arial, sans-serif;font-style: normal;font-size: 14px;font-weight: 400;text-align: left\">[4] <a href=\"https:\/\/www.mathworks.com\/company\/newsletters\/articles\/creating-specialized-charts-with-matlab-object-oriented-programming.html\"><span style=\"font-style: italic\">Creating Specialized Charts with MATLAB Object-Oriented Programming<\/span><\/a>, Ken Deeley and David Sampson (2018).<\/div>\r\n&nbsp;\r\n\r\n<\/div>\r\n<script type=\"text\/javascript\">\r\n{ let css = '.eoOutputWrapper { width: calc(90vw - 10px) !important; } \/* Styling that is common to warnings and errors is in diagnosticOutput.css *\/.embeddedOutputsErrorElement {    min-height: 18px;    max-height: 550px;} .embeddedOutputsErrorElement .diagnosticMessage-errorType {    overflow: auto;} .embeddedOutputsErrorElement.activeOutput .eoOutputContent {    user-select: text;    -webkit-user-select: text;} .embeddedOutputsErrorElement.activeOutput .eoOutputContent button {    user-select: none;    -webkit-user-select: none;} .embeddedOutputsErrorElement .eoOutputContent ::selection {} .embeddedOutputsErrorElement.inlineElement {} .embeddedOutputsErrorElement.rightPaneElement {} \/* Styling that is common to warnings and errors is in diagnosticOutput.css *\/.embeddedOutputsWarningElement {    min-height: 18px;    max-height: 550px;} .embeddedOutputsWarningElement .diagnosticMessage-warningType {    overflow: auto;} .embeddedOutputsWarningElement.activeOutput .eoOutputContent {    user-select: text;    -webkit-user-select: text;} .embeddedOutputsWarningElement .eoOutputContent ::selection {} .embeddedOutputsWarningElement.inlineElement {} .embeddedOutputsWarningElement.rightPaneElement {} \/* Copyright 2015-2023 The MathWorks, Inc. *\/\/* In this file, styles are not scoped to rtcContainer since they could be in the Dojo Tooltip *\/.diagnosticMessage-wrapper {    font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;    font-size: 12px;} .diagnosticMessage-wrapper.diagnosticMessage-warningType {    \/*This fallback value will be used for appdesigner warnings*\/    color: var(--rtc-warning-output-color, var(--mw-color-matlabWarning));} .diagnosticMessage-wrapper.diagnosticMessage-warningType a {    \/*This fallback value will be used for appdesigner warnings*\/    color: var(--rtc-warning-output-color, var(--mw-color-matlabWarning));    text-decoration: underline;} .rtcThemeDefaultOverride .diagnosticMessage-wrapper.diagnosticMessage-warningType,.rtcThemeDefaultOverride .diagnosticMessage-wrapper.diagnosticMessage-warningType a {    color: var(--mw-color-matlabWarning) !important;} .diagnosticMessage-wrapper.diagnosticMessage-errorType {    \/*This fallback value will be used in appdesigner error tooltip text*\/    color: var(--rtc-error-output-color, var(--mw-color-matlabErrors));} .diagnosticMessage-wrapper.diagnosticMessage-errorType a {    \/*This fallback value will be used in appdesigner error tooltip text*\/    color: var(--rtc-error-output-color, var(--mw-color-matlabErrors));    text-decoration: underline;} .rtcThemeDefaultOverride .diagnosticMessage-wrapper.diagnosticMessage-errorType,.rtcThemeDefaultOverride .diagnosticMessage-wrapper.diagnosticMessage-errorType a {    color: var(--mw-color-matlabErrors) !important;} .diagnosticMessage-wrapper .diagnosticMessage-messagePart,.diagnosticMessage-wrapper .diagnosticMessage-causePart {    white-space: pre-wrap;} .diagnosticMessage-wrapper .diagnosticMessage-stackPart {    white-space: pre;} .embeddedOutputsTextElement,.embeddedOutputsVariableStringElement {    white-space: pre;    word-wrap:  initial;    min-height: 18px;    max-height: 550px;} .embeddedOutputsTextElement .textElement,.embeddedOutputsVariableStringElement .textElement {    overflow: auto;} .embeddedOutputsTextElement.activeOutput .eoOutputContent,.embeddedOutputsVariableStringElement.activeOutput .eoOutputContent {    user-select: text;    -webkit-user-select: text;} \/*embeddedOutputsTextElement has a different dom structure than embeddedOutputsVariableStringElement.Unlike variableString, the text output has both TEXT nodes and elements as children. Hence we needa selector for each.*\/.embeddedOutputsTextElement .eoOutputContent::selection,.embeddedOutputsTextElement .eoOutputContent ::selection,.embeddedOutputsVariableStringElement .eoOutputContent ::selection {} .textElement,.rtcDataTipElement .textElement {    padding-top: 2px;} .embeddedOutputsTextElement.inlineElement,.embeddedOutputsVariableStringElement.inlineElement {} .inlineElement .textElement {} .embeddedOutputsTextElement.rightPaneElement,.embeddedOutputsVariableStringElement.rightPaneElement {    min-height: 16px;} .rightPaneElement .textElement {    padding-top: 2px;    padding-left: 9px;}';\r\nlet head = document.head || document.getElementsByTagName('head')[0];\r\nlet style = document.createElement('style');\r\nhead.appendChild(style);\r\nstyle.type = 'text\/css';\r\nif (style.styleSheet) {\r\n    style.styleSheet.cssText = css;\r\n} else {\r\n    style.appendChild(document.createTextNode(css));\r\n}\r\n\r\n\r\n}<\/script>\r\n\r\n<\/div>\r\n<\/div>\r\n<\/div>","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/graphics-and-apps\/files\/2025\/07\/FlightTrackingDashboard_Part3.mlx-07-24-25_6.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>\r\nAre you ready to take your app building skills to the next level? This article walks through an advanced workflow for assembling a flight tracking dashboard. While the techniques covered are... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/graphics-and-apps\/2025\/08\/04\/creating-a-flight-tracking-dashboard-part-3-using-modular-application-development-principles-to-assemble-the-dashboard\/\">read more >><\/a><\/p>","protected":false},"author":198,"featured_media":3113,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[5,11,2],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/graphics-and-apps\/wp-json\/wp\/v2\/posts\/3128"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/graphics-and-apps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/graphics-and-apps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics-and-apps\/wp-json\/wp\/v2\/users\/198"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics-and-apps\/wp-json\/wp\/v2\/comments?post=3128"}],"version-history":[{"count":12,"href":"https:\/\/blogs.mathworks.com\/graphics-and-apps\/wp-json\/wp\/v2\/posts\/3128\/revisions"}],"predecessor-version":[{"id":3651,"href":"https:\/\/blogs.mathworks.com\/graphics-and-apps\/wp-json\/wp\/v2\/posts\/3128\/revisions\/3651"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics-and-apps\/wp-json\/wp\/v2\/media\/3113"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/graphics-and-apps\/wp-json\/wp\/v2\/media?parent=3128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics-and-apps\/wp-json\/wp\/v2\/categories?post=3128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics-and-apps\/wp-json\/wp\/v2\/tags?post=3128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}