55858fedabd0a942ed8639db3ea0fd5fcfd3104b chmalee Thu Feb 26 15:00:25 2026 -0800 Make hubApi wig table output behave like a bedgraph instead of having a top level key with the chromosome name that contains all the data, now there is a key with the trackName and then bedgraph like data of chrom,start,stop,value. Does not affect bigBed output which already worked this way. Clean up some missing 'let' declarations and fix some for loop logic in the download data in window feature, refs #36802,#36858 diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js index 435d1d773af..d8217da11f9 100644 --- src/hg/js/hgTracks.js +++ src/hg/js/hgTracks.js @@ -5659,61 +5659,68 @@ failedTrackDataRequest: function(msg) { msgJson = JSON.parse(msg); alert("Download failed. Error message: '" + msgJson.error); }, receiveTrackData: function(track, data) { downloadCurrentTrackData.downloadData[track] = data; }, convertJson: function(data, outType, withHeaders) { if (outType !== "tsv" && outType !== "csv") { alert("ERROR: incorrect output format option"); return null; } - outSep = outType === "tsv" ? '\t' : ','; + let outSep = outType === "tsv" ? '\t' : ','; // TODO: someday we will probably want to include some of these fields // for each track downloaded, perhaps as an option - ignoredKeys = new Set(["chrom", "dataTime", "dataTimeStamp", "downloadTime", "downloadTimeStamp", + let ignoredKeys = new Set(["chrom", "dataTime", "dataTimeStamp", "downloadTime", "downloadTimeStamp", "start", "end", "track", "trackType", "genome", "itemsReturned", "columnTypes", "bigDataUrl", "chromSize", "hubUrl"]); + let columnTypes; + let cleanData = {}; // first get rid of top level non track object keys _.each(data, function(val, key) { if (ignoredKeys.has(key)) { // squirrel away the columnTypes if requested if (key === "columnTypes") { columnTypes = data[key]; } - delete data[key]; + } else { + cleanData[key] = data[key]; } }); // now go through each track and format it correctly - str = ""; - _.each(data, function(val, track) { + let str = ""; + _.each(cleanData, function(val, track) { str += "track name=\"" + track + "\"\n"; if (withHeaders) { - headers = []; + let headers = []; + if (columnTypes) { for (let i of columnTypes[track]) { headers.push(i.name); } + if (headers.length) { str += headers.join(outSep) + "\n"; } - for (var row in val) { - for (var i = 0; i < val[row].length; i++) { - str += JSON.stringify(val[row][i]); - if (i < val[row].length) { str += outSep; } + } + } + for (let row of val) { + for (let i = 0; i < row.length; i++) { + str += JSON.stringify(row[i]); + if (i+1 < row.length) { str += outSep; } } str += "\n"; } str += "\n"; // extra new line after each track oh well }); return new Blob([str], {type: "text/plain"}); }, makeDownloadFile: function(key) { if (_.keys(downloadCurrentTrackData.currentRequests).length === 0) { // first stop the timer so we don't execute again clearInterval(downloadCurrentTrackData.intervalId); let outType = $("#outputFormat")[0].selectedOptions[0].value; let withHeaders = document.getElementById("downloadTrackHeaders").checked; var blob = null;