#はじめに
本題とgifにあるように、フィルターの取りうる値を取得し、プルダウンメニューにセットしてその値を複数のフィルターに適用させるというある意味離れ業が必要だったので試してみました。
##フィルターの値の取得
今回の要件としてはダッシュボードのフィルターを使用せず、あるレポートのフィルターから値を持ってきてそれを自前のプルダウンにセットします。そのためフィルター部分のスタイルも自由自在になります。
手法としては、一度闇でレポートを取得します。そのため大きいレポートの場合は別のやり方を考えたほうがいいです。今回なぜフィルターのとり得る値を取得するのかというと、このレポートのフィルターにはアクセスフィルターがかかっており、ログインした人によってどの値が使用できるか動的に変更されるからです。
レポートを取得してから、そのフィルター名(今回はAthlete Region)を元にフィルターオブジェクトを変数にぶちこみます。
このオブジェクトのpossibleValuesには、まさにとり得る値が入っているので、その値を予めhtmlに側だけセットしているselectタグの中にoptionタグを追加していきます。参考はこちら(wiki)
let select = $('select.regionfilterList');
yellowfin.loadReport({
reportId: '02f3b19f-a5d1-4242-8495-2459ec9b8ec6',
}).then(report => {
let filters = report.filters;
let regionFilter = filters.getFilter('Athlete Region');
let possibleValues = regionFilter.possibleValues;
possibleValues.forEach(valueObject => {
let option = $('<option>')
.text(valueObject.value)
.val(valueObject.value);
select.append(option);
});
});
##ダッシュボードのフィルターへ値を設定・適用
今回はhtmlにあるただのbuttonをListenerとしてラジオボタンとプルダウンの値を取得して、もともと表示させるダッシュボードから反映するフィルターオブジェクトへ値をセットして適用していきます。取得した値をそれぞれ2つのフィルターに同じ値を設定します。もちろんshowGlobalContentContainerの値をfalseにすれば左側のフィルターも表示させないことができるのでhtml部分の疑似フォームだけでフィルターができることになります。
window.yellowfin.init().then(() => {
window.yellowfin.loadDashboard({
dashboardUUID: 'e5eac92a-c9c9-4f7e-a551-2960e9c22a39',
element: 'div#dashboard',
showGlobalContentContainer: true,//左側のフィルター表示
showFilters: false//上のバーのフィルターボタン表示
}).then(dashboard => {
window.dashboard = dashboard;
let filters = dashboard.filters;
let button = document.getElementById("button");
let gender1 = filters.getFilter('Gender1');
let gender2 = filters.getFilter('Gender2');
let region1 = filters.getFilter('Region1');
let region2 = filters.getFilter('Region2');
let select = $('select.regionfilterList');
button.addEventListener('click', (event) => {
let $gendervalue = $('input:radio[name="gender"]:checked').val();
let $regionvalue = $(".regionfilterList").val();
gender1.setValue($gendervalue);
gender2.setValue($gendervalue);
region1.setValue($regionvalue);
region2.setValue($regionvalue);
filters.applyFilters();
});
});
});
###html部分とスタイルとスクリプト(つまり全ソース)
左フィルターのスタイルをいい感じにしてもらったのでそれも合わせて残しておきます。
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
.contents {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
width: 1360px;
margin: 10px 0;
}
.input {
border: 1px solid #bbc0cd;
width: 260px;
height: 200px;
margin-bottom: 30px;
padding: 5px 10px;
text-align: left;
position: relative;
}
.output {
border: 1px solid #bbc0cd;
width: 1000px;
height: 700px;
margin-bottom: 30px;
padding: 5px 10px;
}
.regionfilterList {
width: 200px;
height: 36px;
padding: 5px;
margin: 10px 0px;
border: 1px solid #DBDDE5;
border-radius: 18px;
background-color: #FFF;
box-shadow: nooe;
font-size: 16px;
}
#button {
width: 120px;
height: 36px;
color: #FFF;
background-color: #717684;
border: 2px solid #717684;
border-radius: 18px;
z-index: 4;
opacity: 1.0;
cursor: pointer;
position: absolute;
right: 5px;
bottom: 10px;
}
#button:hover {
opacity: 0.5;
}
</style>
</head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript" src="http://localhost:8940/JsAPI/v3"></script>
<body>
<h1>サンプル</h1>
<div class="contents">
<div class="input">
<div>性別:
<input type="radio" name="gender" value="Male">男性
<input type="radio" name="gender" value="Female">女性
</div>
<div>地域:
<select class="regionfilterList" name="region">
<option selected disabled hidden>Region</option>
</select>
</div>
<button id="button" name="action" on-click="none">Apply</button>
</div>
<div id="dashboard" class="output"></div>
<script>
window.yellowfin.init().then(() => {
window.yellowfin.loadDashboard({
dashboardUUID: 'e5eac92a-c9c9-4f7e-a551-2960e9c22a39',
element: 'div#dashboard',
showGlobalContentContainer: true,//左側のフィルター表示
showFilters: false//上のバーのフィルターボタン表示
}).then(dashboard => {
window.dashboard = dashboard;
let filters = dashboard.filters;
let button = document.getElementById("button");
let gender1 = filters.getFilter('Gender1');
let gender2 = filters.getFilter('Gender2');
let region1 = filters.getFilter('Region1');
let region2 = filters.getFilter('Region2');
let select = $('select.regionfilterList');
yellowfin.loadReport({
reportId: '02f3b19f-a5d1-4242-8495-2459ec9b8ec6',
}).then(report => {
let filters = report.filters;
let regionFilter = filters.getFilter('Athlete Region');
let possibleValues = regionFilter.possibleValues;
possibleValues.forEach(valueObject => {
let option = $('<option>')
.text(valueObject.value)
.val(valueObject.value);
select.append(option);
});
});
button.addEventListener('click', (event) => {
let $gendervalue = $('input:radio[name="gender"]:checked').val();
let $regionvalue = $(".regionfilterList").val();
gender1.setValue($gendervalue);
gender2.setValue($gendervalue);
region1.setValue($regionvalue);
region2.setValue($regionvalue);
filters.applyFilters();
});
});
});
</script>
</body>
</html>