我正在使用Tableau创建仪表板。我需要仪表板中D3的强大功能,因此我创建了创建Viz的Tableau Extension。这是使用Tableau Extensions API功能的JS的框架:
$(document).ready(function () {
console.log('were in again');
tableau.extensions.initializeAsync().then(function () {
// To get dataSource info, first get the dashboard.
const dashboard = tableau.extensions.dashboardContent.dashboard;
const worksheets = dashboard.worksheets;
let underlyingDataFetchPromises = [];
let dataObjects = {};
let worksheetNames = [];
// Save Promises to Array + Add Event Listeners
dashboard.worksheets.forEach(worksheet => {
worksheetNames.push(worksheet.name);
underlyingDataFetchPromises.push(worksheet.getUnderlyingDataAsync());
// add event listener too...
worksheet.addEventListener(tableau.TableauEventType.FilterChanged, (filterEvent) => {
clearChart();
drawChart(dataObjects.dataA, dataObjects.dataB);
});
});
// Maps dataSource id to dataSource so we can keep track of unique dataSources.
Promise.all(underlyingDataFetchPromises).then(fetchedData => {
// loop over the 2 fetchedData arrays [(1) dataA, (2) dataB]
fetchedData.forEach((dataTable, i) => {
let data = dataTable.data;
let columns = dataTable.columns;
let formattedData = formatData(data, columns);
dataObjects[worksheetNames[i]] = formattedData;
});
// currently requires worksheets named "dataA" and "dataB"... not flexible atm
drawChart(dataObjects.dataA, dataObjects.dataB);
});
}, function (err) {
// Something went wrong in initialization.
console.log('Error while Initializing: ' + err.toString());
});
});
cleanData()
和drawChart()
是我自己编写的用于绘制D3可视化效果的函数,它们正在起作用。我的事件处理程序在某种程度上可以“工作”,即在更改仪表板中的适配程序时可以正确触发它。
但是,我的问题是,当从eventListener中调用drawChart()
时,我的图表是用相同数据绘制的,而不是新数据由于切换了滤镜而导致的结果。我从本质上理解为什么会这样-eventListener不重新获取数据,仅重绘图表。
然后我的问题是,切换过滤器后,如何重新获取新数据以正确绘制我的视点?而且,是否有一个函数可以向我返回过滤器名称和值,可以用来改善扩展程序的功能?最好在此代码中使用JS中的所有仪表板筛选器和值。
在此先感谢您的帮助!
答案 0 :(得分:2)
以下代码刷新数据源“ ABC”并重新加载工作簿-
//The following code is used to refresh the data source
// Wrap everything in an anonymous function to avoid polluting the global namespace
function refreshMySql() {
$(document).ready(function() {
tableau.extensions.initializeAsync().then(function() {
// Since dataSource info is attached to the worksheet, we will perform
// one async call per worksheet to get every dataSource used in this
// dashboard. This demonstrates the use of Promise.all to combine
// promises together and wait for each of them to resolve.
let dataSourceFetchPromises = [];
// Maps dataSource id to dataSource so we can keep track of unique dataSources.
let dashboardDataSources = {};
// To get dataSource info, first get the dashboard.
const dashboard = tableau.extensions.dashboardContent.dashboard;
// Then loop through each worksheet and get its dataSources, save promise for later.
dashboard.worksheets.forEach(function(worksheet) {
dataSourceFetchPromises.push(worksheet.getDataSourcesAsync());
});
Promise.all(dataSourceFetchPromises).then(function(fetchResults) {
fetchResults.forEach(function(dataSourcesForWorksheet) {
dataSourcesForWorksheet.forEach(function(dataSource) {
if (!dashboardDataSources[dataSource.id]) { // We've already seen it, skip it.
dashboardDataSources[dataSource.id] = dataSource;
var datasourceName = dashboardDataSources[dataSource.id].name;
if (dashboardDataSources[dataSource.id].name == "ABC") {
refreshDataSource(dashboardDataSources[dataSource.id]);
console.log("refreshSql() was called for Datasource Name: 'ABC'");
}
}
});
});
});
}, function(err) {
// Something went wrong in initialization.
console.log('Error while Initializing: ' + err.toString());
});
});
// Refreshes the given dataSource.
function refreshDataSource(dataSource) {
dataSource.refreshAsync().then(function() {
//alert(dataSource.name + ': Refreshed Successfully');
console.log(dataSource.name + ': Refreshed Successfully');
});
}
}