In the first article of the series you saw how to embed a Web page that takes parameters from SAS Visual Analytics. Here you will see how you can easily modify the previous DDC HTML implementation to display images that dynamically change based on selections you make on the report.
The data table is the same used in the previous article, consisting of animal names and their corresponding image file names. We are assuming those image files have been made available in the Web Server and can be referenced via a relative path, such as ./AnimalImages/<image.png>.
Animal |
Image |
Bear |
icon-bear.png |
Cat |
icon-cat.png |
Chicken |
icon-chicken.png |
Cow |
icon-cow.png |
Deer |
icon-deer.png |
Dog |
icon-dog.png |
Duck |
icon-duck.png |
Elephant |
icon-elephant.png |
Frog |
icon-frog.png |
Giraffe |
icon-giraffe.png |
Goat |
icon-goat.png |
Horse |
icon-horse.png |
Koala |
icon-koala.png |
Lion |
icon-lion.png |
Monkey |
icon-monkey.png |
Mouse |
icon-mouse.png |
Panda |
icon-panda.png |
Pig |
icon-pig.png |
Rhino |
icon-rhino.png |
Observe that the image file names could have been easily derived from the animal names in this example, and that could have been done in the DDC implementation code with JavaScript or in SAS Visual Analytics via calculated item, using operators that manipulate strings. Anyway, you will not need to do that because it has been provided to you for convenience. This also allows you to explore a scenario that should be fairly common, especially when the image file name cannot be derived from other information that you have, like the animal name, so you really need this mapping or lookup table.
The idea is to select an animal name from the SAS Visual Analytics report and have the proper information passed to the DDC, to allow it to display the associated image. In this example, the information is the file name itself.
You will utilize a visualization object (a list table in this particular example) as the source of a filter action to select the animal, and a DDC object as the target. Using a control object (dropdown, list control, button bar, etc.) as the source of the filter action is also possible, and it doesn’t affect the DDC implementation at all, so for the purpose of this discussion they are the same.
Use of a control object to set a parameter and pass it to the DDC is also possible, but remember that parameters are set with the values of the selected items (animal name in this case), and the image name is not a perfect match, so a transformation would have to be done to go from the animal name stored in the parameter to the image name to be displayed. This is straight forward in this example, but it may not always be the case. If the image name cannot be derived, it must be provided to you in the source table. But how do you select one value (the animal name) and pass to the DDC a parameter set with a different value (the image name)? It is possible to set a parameter with a different/transformed value compared to the selected item, but at the time this article is being written, it requires some extra steps in SAS Visual Analytics, and the technique will be discussed at the end of this article.
To recap, this article will use a filter action from a visualization or a control object (it doesn’t matter) to filter the DDC, passing the image name to be displayed in the data portion of the JSON message.
This DDC example is available in GitHub, under samples/DynamicWebPagesAndImages. There you will find the following:
Using DDC to Display Dynamic Image Based on Filtered Data
In this example you will need two objects in SAS Visual Analytics:
Settings:
By assigning the column “image” to the DDC Role pane and defining the filter action, when the animal is selected in the source object, the data passed to the DDC object is filtered and the corresponding selected animal file name image is sent to the DDC implementation code in the data portion of the JSON message. For example, if Bear is selected from the list, this is the message sent to the DDC implementation:
In the first example of the previous DDC implementation you used an iframe to display the Wikipedia page. In this example, instead of an iframe, you will be using an img tag. The image’s src attribute is initially empty. It will be dynamically modified via JavaScript every time the DDC receives a new message from VA:
<div>
<img id="dynamic_img" src="">
</div>
The JavaScript portion is also very similar to the first example. The name of the callback function was changed to updateImage and whenever you have a valid, single image name in the data portion of the JSON message you can assign it to the image’s source:
va.messagingUtil.setOnDataReceivedCallback(updateImage);
function updateImage(vaMsgObj)
{
if (vaMsgObj && vaMsgObj.data && vaMsgObj.rowCount === 1) {
document.getElementById("dynamic_img").src="./AnimalImages/"+vaMsgObj.data[0][0];
}
else {
document.getElementById("dynamic_img").src="";
}
}
Every time you interact with the report and change the data values passed to the DDC, such as when you select a different animal from the list, the updateImage function gets called. It doesn’t display anything in case the image file is not found, or you don’t select any animal, or you select more than one animal, but it’s not hard to make small design changes, such as display a generic image by default if you want. Lastly, there are some styling changes necessary to display the image nicely. This is the overall HTML code:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://<your.web.server.host>/github/util/messagingUtil.js"></script>
<style>
html, body {
margin: 0px;
padding: 0px;
height: 100%;
width: 100%;
}
img {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
max-height: 100%;
max-width: 100%;
}
</style>
</head>
<body>
<div>
<img id="dynamic_img" src="">
</div>
<script>
"use strict";
va.messagingUtil.setOnDataReceivedCallback(updateImage);
function updateImage(vaMsgObj)
{
if (vaMsgObj && vaMsgObj.data && vaMsgObj.rowCount === 1) {
document.getElementById("dynamic_img").src="./AnimalImages/"+vaMsgObj.data[0][0];
}
else {
document.getElementById("dynamic_img").src="";
}
}
</script>
</body>
</html>
This HTML file is called ddc_DynamicImage.html in GitHub.
It is not covered here, but if the image files were hosted somewhere else than the Web Server hosting the DDC, the DDC could retrieve the image via URL with an HTTP request. Observe that you may need to configure SAS Viya to allow cross-domain references in this case.
Using DDC to Display Dynamic Image Based on Parameters
In this example you will explore the trick to set a parameter based on a different value that has been selected. In this example, we are talking about selecting the animal name and setting a parameter with the corresponding animal image file name.
You will need the following objects in SAS Visual Analytics:
Settings:
Every time an animal is selected, the hidden control object is filtered because of the filter action. The corresponding animal image file name is then automatically selected because the hidden drop-down list object is set as required and the file name is then assigned to the parameter associated with the object. The parameter is in turn passed to the DDC object that displays the image.
You may be asking yourself why to go through all these extra steps to be able to use parameters if you can accomplish the same results without parameters like it was done previously in this article. The most compelling reason for using parameters in this example is to be able to select the animal in one report page and display the image in another page, or to take advantage of selections made in control objects to be remembered from the last time you opened the report. If you don’t need any of that, then there is no apparent reason for adopting the solution that uses parameters.
The DDC implementation is not much different from the one used in the previous article:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://<your.web.server.host>/github/util/messagingUtil.js"></script>
<script type="text/javascript" src="http://<your.web.server.host>/github/util/contentUtil.js"></script>
<style>
html, body {
margin: 0px;
padding: 0px;
height: 100%;
width: 100%;
}
img {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
max-height: 100%;
max-width: 100%;
}
</style>
</head>
<body>
<div>
<img id="dynamic_img" src="">
</div>
<script>
"use strict";
va.messagingUtil.setOnDataReceivedCallback(updateImage);
function updateImage(vaMsgObj)
{
// Function getVAParameters returns the object: {<param_label_1>:<param_value_1>, ... , <param_label_n>:<param_value_n>}
// If <parameter_label> has multiple values, <param_value> is an array
var vaParameters = va.contentUtil.getVAParameters(vaMsgObj);
var imageName = vaParameters._image_name; // it will return undefined if the specific parameter doesn't exist
if (imageName && !Array.isArray(imageName)) {
document.getElementById("dynamic_img").src="./AnimalImages/"+imageName;
}
else {
document.getElementById("dynamic_img").src="";
}
}
</script>
</body>
</html>
This HTML file is called ddc_DynamicImage_WithVAParameter.html in GitHub.
In the next article you will be combining dynamic images and Web pages in the same DDC.
References
Learn More…
Github content is being updated. I'll let you know when it's ready.
GitHub content is ready!
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning and boost your career prospects.