Custom Domo App troubleshooting - Phoenix Chart

Options

Hi! I created an App using Phoenix Chart with Selectable Dimensions and Measures Brick template.

Additionally, I wanted to add extra filters to this App, since Dashboard filters can not be applied to this App.

I successfully added Date filters, and they seem working.

As a second part, I was trying to add a filter using one of the dimension values from dataset.

I tried a lot of options, but it does not want to work.

It looks like, issue in this line of code:

"if (selectedCampaigns.length > 0) {
query += &filter=${dimensions.CampaignName} IN (${selectedCampaigns.map(campaign => '${campaign}').join(',')});
}"

But it is odd, since I added another if statement for Date filters, and they are working fine:

' if (startDate && endDate) {
query += &filter=${dimensions.Date}>=${startDate}&filter=${dimensions.Date}<=${endDate};
}'

Is there something in custom DOMO Apps that I am missing? Why dimension filters are not applicable?

My full Javascript code:

// variables
var startDateSelector = document.getElementById('startDate');
var endDateSelector = document.getElementById('endDate');

var measures = {
Sessions: 'Sessions',
Spend: 'Spend',
};

var dimensions = {
CampaignName: 'CampaignName',
AdGroupName: 'AdGroupName',
MonthYear: 'MonthYear',
Date: 'Date',
};

var barType = "Horizontal"; // "Vertical", "Horizontal"
var totalSort = "Descending"; // "None", "Ascending", "Descending", "A-Z", "Z-A"
var suppressMinMaxAvgLines = true;
var valueFormat = "Default"; // "Currency", "Percentage", "Number"
var valDecimalPlaces = "Default"; // "None", ".0", ".00", ".000", ".0000", ".00000"
var dataLabelText = "%_VALUE"; // "%_VALUE"
var chartMargin = 20; // space to leave around chart (in pixels)
var enableFiltering = true; //set to false to disable page filtering (cardbus)

// Add an event listener to the date inputs
startDateSelector.addEventListener('change', getData);
endDateSelector.addEventListener('change', getData);

//Available globals
var domo = window.domo; // For more on domo.js: https://developer.domo.com/docs/dev-studio-guides/domo-js#domo.get
var datasets = window.datasets;
var DomoPhoenix = window.DomoPhoenix;
var chartContainer = document.getElementById('myDiv'); //get "myDiv" from the html tab

var measureColumnName = Object.keys(measures)[0];
var measureSelector = document.getElementById('measures');
populateSelector(measureSelector, measures, function(value){
measureColumnName = value;
getData();
});

var dimensionColumnName = Object.keys(dimensions)[0];
var dimensionSelector = document.getElementById('dimensions');
populateSelector(dimensionSelector, dimensions, function(value){
dimensionColumnName = value;
getData();
});

var campaigns = [];
var campaignSelector = document.getElementById('campaignFilter');

domo.get(/data/v1/${datasets[0]}?fields=${dimensions.CampaignName})
.then(function (data) {
// Extract unique campaign names from the data
campaigns = [...new Set(data.map(item => item[dimensions.CampaignName]))];

// Populate the 'Campaign Name' dropdown
populateSelector(campaignSelector, campaigns, function (value) {
  // Handle the selected campaign value, if needed
});

});

campaignSelector.addEventListener('change', getData);

getData();

function getData(){
// Form the data query: https://developer.domo.com/docs/dev-studio-guides/data-queries
var fields = [dimensionColumnName, measureColumnName];
var groupby = [dimensionColumnName];
var query = /data/v1/${datasets[0]}?fields=${fields.join()}&groupby=${groupby.join()};

var startDate = startDateSelector.value;
var endDate = endDateSelector.value;

// Get selected campaign names from the dropdown
var selectedCampaigns = Array.from(campaignSelector.selectedOptions, option => option.value);

if (startDate && endDate) {
query += &filter=${dimensions.Date}>=${startDate}&filter=${dimensions.Date}<=${endDate};
}

if (selectedCampaigns.length > 0) {
query += `&filter=${dimensions.CampaignName} IN (${selectedCampaigns.map(campaign => `'${campaign}'`).join(',')})`;
}

// Get the data and chart it
chartContainer.style.visibility = 'hidden';
domo.get(query).then(function(data) {
chartIt(data);
chartContainer.style.visibility = 'visible';
});
}

var chart = null;
var cardBus = new CardBus();
function chartIt(data) {
// Read more about data types and mappings here: https://domoapps.github.io/domo-phoenix/#/domo-phoenix/api
var columns = [
{
type: DomoPhoenix.DATA_TYPE.STRING,
name: dimensionColumnName,
mapping: DomoPhoenix.MAPPING.ITEM
},
{
type: DomoPhoenix.DATA_TYPE.DOUBLE,
name: measureColumnName,
mapping: DomoPhoenix.MAPPING.VALUE,
format: getValueFormat()
}
];
var phoenixData = {columns: columns, rows: data};
var chartType = (barType.toLowerCase() === "vertical")? DomoPhoenix.CHART_TYPE.BAR : DomoPhoenix.CHART_TYPE.HORIZ_BAR;
var size = getChartSize();
var propertyOverrides = {
total_sort: totalSort,
suppress_minmaxavg: suppressMinMaxAvgLines,
datalabel_text : dataLabelText && dataLabelText.length ? dataLabelText : undefined,
title_x : dimensions[dimensionColumnName],
title_y : measures[measureColumnName],
};

// Create the Phoenix Chart
chart = new DomoPhoenix.Chart(chartType, phoenixData, {
width: size.width,
height: size.height,
properties: propertyOverrides
});

// Remove any previous canvas element
chartContainer.firstChild && chartContainer.removeChild(chartContainer.firstChild);

// Append the canvas element to your div
chartContainer.appendChild(chart.canvas);
chartContainer.style.margin = ${chartMargin}px ${chartMargin}px 0;

// Handle click events
enableFiltering && cardBus.addChart(chart);

// Render the chart when you're ready for the user to see it
chart.render();
}

window.addEventListener && window.addEventListener('resize', function(){
var size = getChartSize();
chart && chart.resize(size.width, size.height);
});

///// Helper Functions /////////////////////
var dropdownBar = document.getElementById('dropdownBar');
function getChartSize(){
var barHeight = dropdownBar.offsetHeight;
return {
width: window.innerWidth - chartMargin * 2,
height: window.innerHeight - barHeight - chartMargin * 2,
}
}

function getValueFormat(){
var valFmt = '###,###';
if (valDecimalPlaces.toLowerCase() != 'default' && valDecimalPlaces.toLowerCase() != 'none')
valFmt += valDecimalPlaces;
if (valueFormat.toLowerCase() == 'currency')
valFmt = '$' + valFmt;
else if (valueFormat.toLowerCase() == 'percentage')
valFmt += '%';

return valFmt;
}

function populateSelector(selector, names, onChange) {
var options = Object.keys(names);
for(i = 0; i < options.length; i++) {
var key = options[i];
var opt = document.createElement('option');
opt.value = key;
opt.innerText = names[key];
selector.appendChild(opt);
}

selector.addEventListener('change', function() {
onChange(this.value);
});
}

function CardBus() {
var charts = [];

function triggerBus(srcChart, ev){
charts.forEach(chart => {
if(srcChart == chart){
var isHighlightEvent = ev.highlight !== undefined;
var isDrillEvent = ev.applyfilters !== undefined;
if(isHighlightEvent){
var filters = ev.highlight;
chart.highlight(filters);
}
if(isDrillEvent){
var filters = ev.applyfilters;
console && console.log("Drill event", filters);
if (filters != null){
for (var i=0; i < filters.length; i++){
filters[i].operator = filters[i].operand;
}
}
domo.filterContainer(filters);
}
}
})
}

function addChart(chart){
charts.push(chart);
chart.addEventListener('cardbus', (ev) => triggerBus(chart, ev));
}

return {
addChart: addChart,
triggerBus: triggerBus,
};
}

Answers

  • GrantStowell
    GrantStowell Domo Employee
    Options

    Hello @fromMinnesota, it looks like your question has stumped the community! I'd recommend reaching out to your customer success manager to see if they can help you find a working solution.

  • GrantSmith
    Options

    @fromMinnesota

    It looks like you may need to use square brackets instead of parenthesis with your in statement: https://developer.domo.com/portal/8s3y9eldnjq8d-data-api#operators

    It expects an array, which is denoted by square brackets. It's not the same as the SQL version of IN used with beast modes or formula tiles.

    **Was this post helpful? Click Agree or Like below**
    **Did this solve your problem? Accept it as a solution!**
  • fromMinnesota
    Options

    @GrantSmith i think, this is it!

    I was testing before holidays, and figured out that it was in my IN operation.

    Let me try brackets after the holidays, thanks!