UNPKG

@domoinc/multiline-chart

Version:

MultiLineChart - Domo Widget

375 lines (345 loc) 9.49 kB
if (!window.AutoWidgets) { var AutoWidgets = { widgetRegistry: [] }; } AutoWidgets.baseWidget = function(widget) { widget.dataName = function(dataName) { if (!arguments.length) return widget._dataName; var sampleData = widget.sampleData(); var key; var temp; var newName; var re; if (widget._dataName && sampleData) { for (key in sampleData) { temp = sampleData[key]; delete sampleData[key]; re = new RegExp(widget._dataName); if (re.test(key)) { newName = key.replace(re, dataName); sampleData[newName] = temp; sampleData[newName].name = newName; } } } widget._dataName = dataName; return widget; }; widget.renderWithData = function(d) { var data = d[widget.dataName()].data; widget.draw(data); return widget; }; widget.sampleData = function(data) { if (!arguments.length) return widget._dataSchema; var key; for (key in data) { data[key].data = data[key].defaultValue; } widget._dataSchema = data; // TEMPORARY // This allows widgets converted to the new platform to continue to work on Mason if (window.$badge) { createBadgeData(data); } return widget; }; // Can be overwritten in each widget widget.prepareForArtboard = function() { if (widget.base) { widget.base.selectAll('[id^=chartBounds]') .remove(); widget.base.insert('rect', ':first-child') .attr('id', 'chartBounds') .attr({ height: widget.c('height'), width: widget.c('width') }) .style('fill', 'none'); } }; widget.getWidgetContainer = function() { return widget.__container; }; widget.getSVG = function() { widget.prepareForArtboard(); return serialize(widget.getWidgetContainer()); }; function serialize(node) { var serializer = new XMLSerializer(); return serializer.serializeToString(node); } // TEMPORARY function createBadgeData(data) { var key; for (key in data) { $badge.data[key] = $badge.DataGrid(key, data[key]); } } return widget; }; AutoWidgets.findWidgets = function(container) { var widgets = []; var widget; var filters = prepareFilters(); for (var i = 0; i < AutoWidgets.widgetRegistry.length; i++) { var desc = AutoWidgets.widgetRegistry[i]; container.selectAll("[id^=" + desc[0] + "]") .each(function() { d3.select(this).attr('data-domo-link', this.parentNode.id); widget = desc[1](d3.select(this)); widget.__container = this.parentNode; addConfig(widget); addData(widget); widgets.push(widget); }); } document.body.style.visibility = 'visible'; widgets.renderAll = function() { for (var i = 0; i < widgets.length; i++) { renderWidget(widgets[i]); } window.addEventListener('message', function(event) { var message = JSON.parse(event.data); // send acknowledgement to prevent autorefresh var ack = JSON.stringify({ event: 'ack', alias: message.alias }); event.source.postMessage(ack, event.origin); // inform domo app which alias has been updated for (var i = 0; i < widgets.length; i++) { if (widgets[i].sampleData()[message.alias]){ renderWidget(widgets[i]); break; } } }); }; function renderWidget(widget) { var key; var requests = []; var data = {}; var req; var sampleData = widget.sampleData(); if (widget._notifier) { widget._notifier.showMessage(false); widget._notifier.clearSampleDataMessages(); } for (key in sampleData) { (function(k) { req = new Promise(function(resolve, reject) { d3.text('data/v1/' + k) .header('Accept', '*/*') .get(function(err, value) { if (err) { if (widget._notifier) { // widget._notifier.appendMessage(widget.config('chartName'), 'SAMPLE_DATA', 'Using Sample Data', widget._dataDefs, [widget.sampleData()[k].data]); } resolve(widget.sampleData()[k]); } else { var dataObj = widget.sampleData()[k]; var data = JSON.parse(value); dataObj = dataToArrays(data, dataObj); resolve(dataObj); } }); }) .then(function(value) { data[k] = value; }); requests.push(req); })(key); } Promise.all(requests) .then(function() { widget.renderWithData(applyAllFilters(widget, data)); }); } function dataToArrays(input, dataObj) { var data = []; var columns = dataObj.columnNames; input.map(function(obj) { var row = []; columns.map(function(col) { if (obj.hasOwnProperty(col)) { row.push(obj[col]); } else if (obj.hasOwnProperty(col.replace(/\s/g, ''))) { row.push(obj[col.replace(/\s/g, '')]); } else { row.push(''); } }); data.push(row); }); dataObj.data = data; return dataObj; } widgets.previewAll = function() { for (var i = 0; i < widgets.length; i++) { var widget = widgets[i]; if (widget._notifier) { widget._notifier.showMessage(false); } // TEMPORARY if (window.$badge) { renderWithMasonData(widget); } else { widget.renderWithData(applyAllFilters(widget, widget.sampleData())); } } }; function prepareFilters() { var filters = {}; _.map(AutoWidgets.configs, function(widget, name) { if (widget.categories.indexOf('Controls') >= 0) { var widgets = {}; _.map(widget.widgets, function(def, id) { var w = AutoWidgets.configs[id]; if (w) { var name = w.config.widgetName.value; widgets[name] = def; } }); if(widget.config) { filters[widget.config.widgetName.value] = { value: widget.value || [], widgets: widgets }; } } }); return filters; } // TEMPORARY function renderWithMasonData(widget) { var key; var data = {}; var dataName = widget.dataName(); var sampleData = widget.sampleData(); if (sampleData) { for (key in sampleData) { data[key] = {}; data[key].columnNames = $badge.data[key].columnNames; data[key].data = $badge.data[key].val(); } } else { data[dataName] = $badge.data[dataName]; data[dataName].data = data[dataName].val(); } widget.renderWithData(applyAllFilters(widget, data)); } function addConfig(widget) { if (AutoWidgets.configs) { var config = _.find(AutoWidgets.configs, function(d) { return d.config && d.config.widgetName.value === widget.dataName(); }); if (config) { // The configure pane currently uses configs differently than the preview // or live version, so this check makes them both work properly if (config.config) { config = config.config; } _.map(config, function(item, key) { if (widget._config[key]) { _.extend(widget._config[key], item); } }); } } } function addData(widget) { if (AutoWidgets.configs) { var config = _.find(AutoWidgets.configs, function(d) { return d.config && d.config.widgetName.value === widget.dataName(); }); if (config) { var data = config.data; var key; if (data) { for (key in data) { data[key].data = data[key].defaultValue; } widget.sampleData(data); } } } } AutoWidgets.filterChange = function(filterName, value) { var filter; var col; var data; var filteredData; if (filters[filterName]) { filter = filters[filterName]; filter.value = value; _.map(filter.widgets, function(widget) { if (widget.widget) { col = widget.column; data = widget.data; filteredData = applyAllFilters(widget.widget, data); widget.widget.renderWithData(filteredData); } }); } } function applyAllFilters(widget, data) { var filteredData = removeNullRows(data); var widgetName = widget.dataName(); var filterColumns; var tempFilterColumns; _.map(filters, function(filter, name) { if (filter.widgets[widgetName]) { filterColumns = {}; tempFilterColumns = filter.widgets[widgetName]; _.map(tempFilterColumns, function(ds, dsName) { if (dsName !== 'widget' && dsName !== 'data') { filterColumns[widgetName + dsName] = ds; } }); filter.widgets[widgetName].widget = widget; filter.widgets[widgetName].data = data; filteredData = filterData(filteredData, filterColumns, filter.value); } }); return filteredData; } function filterData(data, filterColumns, values) { if (!values || values.length === 0) { return data; } var result = {}; _.map(data, function(source, name) { result[name] = {}; result[name].columnNames = source.columnNames; if (filterColumns[name]) { result[name].data = _.filter(source.data, function(row){ return _.include(values, row[filterColumns[name].column]); }); } else { result[name].data = source.data; } }); return result; } function removeNullRows(data) { _.map(data, function(source) { source.data = _.filter(source.data, isNotNullRow); }); return data; } function isNotNullRow(row) { var isNull = true; _.map(row, function(cell) { if (cell !== null && cell !== '') { isNull = false; } }); return !isNull; } return widgets; }; AutoWidgets.register = function(svgName, chartFunction) { AutoWidgets.widgetRegistry.push([svgName, chartFunction]); };