BookmarkSubscribeRSS Feed

Using the Data-Driven Content Object in Visual Analytics to Display Product Photos: Basics

Started ‎07-11-2023 by
Modified ‎11-20-2023 by
Views 1,856

This is the first part of a four part series that discusses how to display product photos in SAS Visual Analytics.

 

The data-driven content object in SAS Visual Analytics enables you to display your data in a custom third-party visualization within your Visual Analytics report. These third-party visualizations can be developed in any JavaScript charting framework, like D3.js, Google Charts, or CanvasJS. The visualization receives its data from Visual Analytics and can interact with filters, ranks, and actions in the same manner as other objects in your report. The data-driven content is not limited to unique or complex visualizations, however. You can use the data-driven content to present any content that can be displayed in an iFrame.

 

Scenario

 

Suppose you would like to display an image of a selected product in a report. Because the image is updated based on viewer selections, a data-driven content object is needed for this task. You can use this code to display images for any scenario: to show a picture of an employee, an office location, or even a state flag.

 

Requirements

 

To use the data-driven content object, you will need some knowledge of HTML, CSS, and JavaScript to create the file that will display the image. The file will also need to be hosted on a web server. In addition, if you want to send messages from the HTML file to Visual Analytics, SAS Viya must be accessed using the HTTPS protocol.

 

Note: For testing purposes I used the Five Server extension in Visual Studio Code to use my machine as a web server.

 

Steps

 

To create the visualization, follow these steps:

 

  1. Create a simple HTML page
  2. Add an event listener to execute JavaScript code when the HTML page is loaded and parsed
  3. Add sample data for debugging outside of Visual Analytics (optional)
  4. Declare variables
  5. Create a callback function to get the data from Visual Analytics
  6. Validate the data received from Visual Analytics (optional)
  7. Use the data received from Visual Analytics to add a photo to the web page

 

Note: In this post, I will discuss on the required pieces of code. Future posts will cover optional pieces.

Note: The entire code is available (via a link) at the end of this post.

 

Create a Simple HTML Page

 

I’ll start with a simple HTML page that contains a div (for the photo).

 

 

NB_1_niball_ddc_simple_html.png

Select any image to see a larger version.
Mobile users: To view the images, select the "Full" version at the bottom of the page.

 

A link is included to Bootstrap so special classes can be used to define the layout of the page and modify the content included in the page. These classes make it easier develop a responsive, mobile-first web page. In this example, Bootstrap will be used to display the image at 100% width, regardless of the screen size.

 

Script tags that reference the utilities from the SAS GitHub repository for third-party visualizations are included to help when creating the visualization. These utilities will be used in the JavaScript code to receive messages from Visual Analytics (using the setOnDataReceivedCallback function), send messages to Visual Analytics (using the postInstructionalMessage function), and validate the data received from Visual Analytics (using the validateRoles function).

 

A div is created with an id of photo to hold the image.

 

Note: For this example, I copied the utilities from the SAS GitHub repository for third party visualizations and stored them in a util folder where the web page is hosted. This is a best practice.

Note: Only the setOnDataReceivedCallback function is used in this example. The other functions will be explored in future posts.

 

Add an Event Listener

 

Inside the script tag (in the body), an event listener is added to execute a function when the HTML document is loaded and parsed. This is a best practice when working with JavaScript.

 

NB_2_niball_ddc_event_listener.png

 

Declare Variables

 

Inside the event listener function, several dynamic variables are created: vaMessage to hold the data passed from Visual Analytics to the third-party visualization and rowCount to hold the number of rows of data passed from Visual Analytics.

 

The rowCount variable will be used to determine if the viewer selects a product line. If they do, only one row will be passed from Visual Analytics and a picture of that product line will be displayed. If they do not, multiple rows will be passed from Visual Analytics and the company logo will be displayed.

 

NB_3_niball_ddc_declare_variables.png

 

This code also creates some selection variables that will be used to add the photo to the web page: photoDiv to hold the div for the photo and itemPhoto to hold the img element that will contain either the product image or the company logo.

 

Create a Callback Function

 

Next, create a callback function to get the data from Visual Analytics.

 

NB_4_niball_ddc_callback_function.png

 

The setOnDataReceivedCallback function (located in the messagingUtil.js file) creates a callback function that can be used to handle messages received from Visual Analytics. You must define a function (in this example, onDataReceived) that specifies what actions will be performed on the data received from Visual Analytics.

 

The onDataReceived function takes the data from Visual Analytics (messageFromVA) and initializes the dynamic variables: vaMessage contains the message in its entirety and rowCount contains the number of rows of data passed from Visual Analytics.

 

Add the Product Photo

 

After the data variables are initialized, code is added to include the product photo on the web page.

 

NB_5_niball_ddc_product_photo.png

 

The getElementById method is used to create an object that references the div in the body that has an id of photo. Then, the div is cleared (using the innerText property). Next, an if statement checks to see if the data passed from Visual Analytics contains one row (rowCount == 1). If it does, then a single product line is selected in the report. When this occurs, a new img element is created (using the createElement property), attributes of the element are modified (src and alt), and the element is added to the DOM (using the appendChild method).

 

The src attribute points to the image for the selected product line in the images folder. Note that the toLowerCase method is needed convert the product line passed from Visual Analytics (which is proper case) to the case used for the image file (which is in lower case). The alt attribute is the value of the selected product line. A Bootstrap class (img-fluid) is also added to the image to ensure the image takes up 100% of the width of the screen.

 

Testing

 

When the code is complete, you can test it in Visual Analytics. I added a page prompt to the report to select a product line and added a data-driven content object (that references the code) to the canvas.

 

NB_6_niball_ddc_options.png

 

Notice that Promo is selected in the drop-down list control.

 

Adding Product Line to the Variables role will send the selected product line to the third-party visualization. If one row is passed, an image for the selected product line will be displayed.

 

NB_7_niball_ddc_roles.png

 

If multiple rows are passed (nothing is selected in the drop-down list control), the company logo will be displayed.

 

NB_8_niball_ddc_companylogo.png

 

Considerations

 

This example is relatively simple because the data from Visual Analytics is only used when one row is passed to the visualization. If you are working on an example that requires the use of multiple rows, you will need to restructure the data from Visual Analytics into a two-dimensional array of objects so it can easily be referenced in your JavaScript code.

 

In addition, images don’t require any axes to display the data and Bootstrap is used to handle the responsiveness of the image for different screen sizes. In many cases, you will need to extend your code to create axes based on the scale of data assigned to the object and to redraw elements when the screen (or object) is resized. For examples on how to do this, see the samples in the SAS GitHub repository for third-party visualizations.

 

Summary

You can use this code to display images for any selected value in your report: a product, an employee, an office location, or even a state flag. In this example, we used a page prompt to filter the values, but it will even work with actions between objects. Suppose I have a report that contains a bar chart that filters the data-driven content object. When I select a product line (Plush), the image of that product line is displayed.

 

NB_9_niball_ddc_barchart.png

 

In the next part of this series, we will discuss how Visual Analytics communicates with the visualization and see how to validate the data passed from Visual Analytics

 

References

Documentation: Working with Data-Driven Content

Documentation: Programming Considerations for Data-Driven Visualizations

SAS GitHub repository for third-party visualizations

Book: Interactive Reports in SAS Visual Analytics

 

Code

 

Below is the code in its entirety. 

 

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>

<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

<!-- Utilities for DDC -->
<script type="text/javascript" src="util/messagingUtil.js"></script>
<script type="text/javascript" src="util/contentUtil.js"></script>
</head>
<body>
<!-- Container for Photo -->
<div class="container" id="photo">
</div>

<!-- Custom JavaScript -->
<script>

// Listening for HTML document completely loaded and parsed, best practice
document.addEventListener("DOMContentLoaded", function() {


/******************************* Declare variables ***************************************/

// Dynamic data variables
let vaMessage; // Data message from VA
let rowCount; // Number of rows passed from VA

// Selection variables
let photoDiv; // Div for photo
let itemPhoto; // Element for photo

/******************************* Setup Callback Functions ***************************************/
// Attach event for data message from VA
va.messagingUtil.setOnDataReceivedCallback(onDataReceived);

// Take action on received data
function onDataReceived(messageFromVA) {

// Initialize data variables
vaMessage = messageFromVA;
rowCount = messageFromVA.rowCount;

// Add photo to DOM
const photoDiv = document.getElementById("photo");
photoDiv.innerText = "";

// Display photo for selected item
if (
rowCount == 1
) {
itemPhoto = document.createElement("img");
itemPhoto.src="images/"+vaMessage.data[0][0].toLowerCase()+".jpg"; // check this!
itemPhoto.alt = vaMessage.data[0][0];
itemPhoto.classList.add("img-fluid");

photoDiv.appendChild(itemPhoto);
} else {
itemPhoto = document.createElement("img");
itemPhoto.src="images/insight_toys_logo.png";
itemPhoto.alt = "Insight Toys Logo";
itemPhoto.classList.add("img-fluid");

photoDiv.appendChild(itemPhoto);
};

};

});
</script>
</body>
</html>

 

Find more articles from SAS Global Enablement and Learning here.

Comments

Thanks!  Plan on giving this a try.

@lhartjordan I would love to see your end result!

Thanks for the information!

@melissa69 any time!

Thanks i will try it 

@Cayden Would love to see how it turns out!

Version history
Last update:
‎11-20-2023 10:34 AM
Updated by:
Contributors

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

Free course: Data Literacy Essentials

Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning  and boost your career prospects.

Get Started

Article Tags