When analyzing hierarchical data in SAS Visual Analytics, you can create hierarchies which give the end-user the opportunity to drill into the data and display the information based on the defined hierarchy. Another way to visualize hierarchical data is to use an organization chart, often referred to as an org chart. SAS Visual Analytics does not have an out-of-the-box object like an org chart, but you can use the Data-Driven Content object to leverage a custom-built visualization or a third-party open-source option.
The React component that will be created has a simple logic. It receives data from SAS Visual Analytic and transforms the set of data into a flattened tree. When displaying the report, the user sees the top element (parent) and its children. When the user clicks on a node, the node is selected, and the selection is passed back to SAS Visual Analytics to filter other objects in the report which might be linked to the Data-Driven Content object. In my custom org chart visualization, the user can drill up and down using arrows. The component has a breadcrumb which indicates where the user is in the data structure. Each node will also have a small badge indicating how many children nodes are bound to it.
Here is a demo to clarify the functionalities.
As you can see the choice has been made to use the org chart as a filter tool and not to display data in the object itself. There are good reasons for that related to how the Data-Driven Content (DDC) object works. The data set is passed to the DDC object as an array of data at the lowest level, a bit like a detailed table but aggregated based on the variable selection. As a result, it is complex or impossible to recreate the proper calculation in the Data-Driven Content object. For example, if a measure uses "average" as aggregation type, it is impossible to recreate the average for each level as the average of averages is rarely equal to an average calculated based on the detailed data. Recreating the averages for each level would imply passing the detailed data which is stored in the CAS table to the DDC object and calculating the average in the DDC object. For this reason, only the categories can be passed to the component I've created.
In this article, I will not cover how the DDC object works as there are many articles already covering the topic. If you are new to SAS Visual Analytics and especially to Data-Driven Content, I suggest you read one of my earlier articles or look for Data-Driven Content:
The application has been created using create-react-app. The structure is the one provided by the script. In addition to the default structure, a few folders have been created to define the different components, functions as well as interfaces which are used in the application.
Select any image to see a larger version.
Mobile users: To view the images, select the "Full" version at the bottom of the page.
The interfaces include the TypeScript interface's definitions. These interfaces are used to define the function signatures and store the information needed for TypeScript to enforce type checking. If you want to know more about interfaces in TypeScript, please refer to this documentation.
If you are not familiar with TypeScript, you may have noticed that some variables are defined with a question mark. This indicates that the variable is optional in the interface. As TypeScript will check the signature, TypeScript will transpile the code properly even if a variable is missing and marked as optional.
With the interfaces in place, we also need a few functions to handle the data received from the VA report and to send messages back to filter data in the report or to inform the user that the correct data has not been passed to the DDC object. The functions are:
This function will transform the array of data received from VA into a flattened tree which is used later to display the different nodes in the organizational chart. As you can see at the beginning, some interfaces are used to define new variables. As a result, when passing data from one function to the other, we are sure that the data type is correct, and that the data contains the expected set of variables.
This function identifies how many levels we have in the data received from VA. This is done by looping through the columns array provided by VA and checking the variable type. If the type is not string, then the process stops and sends a message to the end-user that "Only categorical variables are supported!".
This function is responsible for sending messages to VA. The message is defined as an interface and can have different content as defined in the interface. If the message variable is defined, it informs the user about something. If the selections is filled in, it will send the filter information to the VA report which will then filter dependent objects.
As we have seen above, the sendMessageToVA function can send a list of selected rows back to the VA report for filtering. This selection needs to be created and this is the role of this function. As the data used in the organization chart doesn't have the structure as the data received from VA, the selection list needs to be created by finding all the descendants from the selected node.
Now that you have seen the functions, it is interesting to check the different components in the user interface. We have two components and the application itself which will act as a wrapper for the other components.
The component uses the Card component from Material UI. Here, I've decided to define the INodeProps interface inside the component as it is specific to it and not used outside of the component. The definition may seem a bit long because it has a bit of logic to handle the display of the top and down arrows used for navigation in the tree. The cardStyle variable defines the style that is applied to the node if it is selected or not. It adds a border around the box to emphasize that it was selected.
This component is based on the Breadcrumbs component from Material UI. It appears in the top left of the application based on the level the user is currently in. It also gives the opportunity to navigate to a specific level when clicking on it.
This is the longest code in the application as it will group all the other components and functions. It also defines the interactions between the elements. I will focus here on the different important snippets and will not cover the import statements for example.
At the top of the App function, we are defining the states which are used to store data but also trigger updates to the user interface when they change.
The first useEffect is probably the most important as it is the one which defines the process to receive the data from the report and to build the data structure used to display the nodes in the organization chart. It defines an event listener which triggers the creation of the tree data as soon as the data is passed to the DDC object.
The second useEffect sets the information needed to display the interface when the data is loaded from VA.
The third useEffect handles the navigation in the tree. It is called whenever the top element in the chart is changing.
The fourth useEffect handles the selection process. When the selected node changes, it builds the selection which is then passed to the VA report using sendMessage function to filter dependent objects in the VA report.
The navigationHandler is the function which handles the navigation between the various levels.
The visualization part is the responsibility of the last bit of code.
This snippet uses the Box and Grid elements from Material UI. It defines how the elements should position on the screen. Please note that the positioning is dynamic based on the available space for the DDC object. It means that you may see more or less children nodes on a row depending on the DDC size.
This application is created using create-react-app. When you are developing the application, you can start the development server using npm start. As soon as you want to integrate with SAS Viya, you need to make sure that the development server is running on HTTPS. You should also make sure that the CORS and CSRF are properly configured for your environment. You can find information about CSRF and CORS in the following article: Configure Cross-Origin Resource Sharing for SAS Viya for REST API’s and web developments.
To deploy the application, you need to build the application using npm or yarn build commands. It will create a build folder on your project, and you can then deploy that folder into your preferred web server on the production environment. If you want to know how it can be done, please refer to the following article: Deploy a custom web application in the cloud for Data-Driven Content object in SAS Viya 4.
In this article, I tried to show you how you can use TypeScript, React, and Material UI to build a web application. The objective is clearly not to teach you to program for the web. The objective is to demonstrate how to proceed and that you can do it using different techniques. If you prefer to develop using Angular, Vue, jQuery or any other framework, it is also possible. You can use your preferred framework or no framework at all. The benefit of using a framework is that you can leverage the work that has been done by others before in such a way that you don’t need to waste a lot of time reinventing the wheel.
I hope you enjoyed reading this article. If you have ideas or requests for other custom visualizations, please don’t hesitate to share them as comments to this article. I will be happy to help you or guide you in the process of creating your own visualization.
Find more articles from SAS Global Enablement and Learning here.
Registration is open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.
If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website.
Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning and boost your career prospects.