From 744328633e9676ce62e57b5f38e5ec494a55ddb1 Mon Sep 17 00:00:00 2001 From: Justin Yap Date: Wed, 6 Oct 2021 13:04:46 +1100 Subject: [PATCH 1/4] Test callback --- theSrc/scripts/widgetdefinition.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/theSrc/scripts/widgetdefinition.js b/theSrc/scripts/widgetdefinition.js index 8f25d2fd78..9bbc64f47b 100644 --- a/theSrc/scripts/widgetdefinition.js +++ b/theSrc/scripts/widgetdefinition.js @@ -551,6 +551,10 @@ const widgetDefinition = { }); } } // end of selectionChange + + graphDiv.on("plotly_afterplot", function() { + console.log("-------------plotly done!-----------------------------------------------------"); + }); } // end of renderValue } From d09b2225fc1199fb3b538e6bfeae5ed1cddfe866 Mon Sep 17 00:00:00 2001 From: Justin Yap Date: Wed, 6 Oct 2021 13:14:12 +1100 Subject: [PATCH 2/4] Update compiled files --- inst/htmlwidgets/plotly.js | 2 +- inst/htmlwidgets/plotly.js.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/inst/htmlwidgets/plotly.js b/inst/htmlwidgets/plotly.js index d637157815..2a0776e2d3 100644 --- a/inst/htmlwidgets/plotly.js +++ b/inst/htmlwidgets/plotly.js @@ -1,2 +1,2 @@ -!function i(r,o,n){function a(e,t){if(!o[e]){if(!r[e]){var l="function"==typeof require&&require;if(!t&&l)return l(e,!0);if(s)return s(e,!0);throw(l=new Error("Cannot find module '"+e+"'")).code="MODULE_NOT_FOUND",l}l=o[e]={exports:{}},r[e][0].call(l.exports,function(t){return a(r[e][1][t]||t)},l,l.exports,i,r,o,n)}return o[e].exports}for(var s="function"==typeof require&&require,t=0;t"),d.legendgroup=d.legendgroup||p.join("
"),d._originalIndex=l,d._newIndex=this.gd._fullData.length+g.length,d._isCrosstalkTrace=!0,g.push(d))}if(0"),d.legendgroup=d.legendgroup||p.join("
"),d._originalIndex=l,d._newIndex=this.gd._fullData.length+g.length,d._isCrosstalkTrace=!0,g.push(d))}if(0 0) {\n var ev = JSON.stringify(event);\n for (var i = 0; i < selectionHistory.length; i++) {\n var sel = JSON.stringify(selectionHistory[i]);\n if (sel == ev) {\n return;\n }\n }\n }\n \n // accumulate history for persistent selection\n if (!x.highlight.persistent) {\n selectionHistory = [event];\n } else {\n selectionHistory.push(event);\n }\n crosstalk.var(\"plotlySelectionHistory\").set(selectionHistory);\n \n // do the actual updating of traces, frames, and the selectize widget\n traceManager.updateSelection(set, e.value);\n // https://github.com/selectize/selectize.js/blob/master/docs/api.md#methods_items\n if (x.selectize) {\n if (!x.highlight.persistent || e.value === null) {\n selectize.clear(true);\n }\n selectize.addItems(e.value, true);\n selectize.close();\n }\n }\n selection.on(\"change\", selectionChange);\n \n // Set a crosstalk variable selection value, triggering an update\n var turnOn = function(e) {\n if (e) {\n var selectedKeys = pointsToKeys(e.points);\n // Keys are group names, values are array of selected keys from group.\n for (var set in selectedKeys) {\n if (selectedKeys.hasOwnProperty(set)) {\n selection.set(selectedKeys[set].value, {sender: el});\n }\n }\n }\n };\n if (x.highlight.debounce > 0) {\n turnOn = debounce(turnOn, x.highlight.debounce);\n }\n graphDiv.on(x.highlight.on, turnOn);\n \n graphDiv.on(x.highlight.off, function turnOff(e) {\n // remove any visual clues\n removeBrush(el);\n // remove any selection history\n crosstalk.var(\"plotlySelectionHistory\").set(null);\n // trigger the actual removal of selection traces\n selection.set(null, {sender: el});\n });\n \n // register a callback for selectize so that there is bi-directional\n // communication between the widget and direct manipulation events\n if (x.selectize) {\n var selectizeID = Object.keys(x.selectize)[i];\n var items = x.selectize[selectizeID].items;\n var first = [{value: \"\", label: \"(All)\"}];\n var opts = {\n options: first.concat(items),\n searchField: \"label\",\n valueField: \"value\",\n labelField: \"label\",\n maxItems: 50\n };\n var select = $(\"#\" + selectizeID).find(\"select\")[0];\n var selectize = $(select).selectize(opts)[0].selectize;\n // NOTE: this callback is triggered when *directly* altering \n // dropdown items\n selectize.on(\"change\", function() {\n var currentItems = traceManager.groupSelections[set] || [];\n if (!x.highlight.persistent) {\n removeBrush(el);\n for (var i = 0; i < currentItems.length; i++) {\n selectize.removeItem(currentItems[i], true);\n }\n }\n var newItems = selectize.items.filter(function(idx) { \n return currentItems.indexOf(idx) < 0;\n });\n if (newItems.length > 0) {\n traceManager.updateSelection(set, newItems);\n } else {\n // Item has been removed...\n // TODO: this logic won't work for dynamically changing palette \n traceManager.updateSelection(set, null);\n traceManager.updateSelection(set, selectize.items);\n }\n });\n }\n } // end of selectionChange\n } // end of renderValue\n}\n\n/**\n * @param graphDiv The Plotly graph div\n * @param highlight An object with options for updating selection(s)\n */\nfunction TraceManager(graphDiv, highlight) {\n // The Plotly graph div\n this.gd = graphDiv;\n\n // Preserve the original data.\n // TODO: try using Lib.extendFlat() as done in \n // https://github.com/plotly/plotly.js/pull/1136 \n this.origData = JSON.parse(JSON.stringify(graphDiv.data));\n \n // avoid doing this over and over\n this.origOpacity = [];\n for (var i = 0; i < this.origData.length; i++) {\n this.origOpacity[i] = this.origData[i].opacity === 0 ? 0 : (this.origData[i].opacity || 1);\n }\n\n // key: group name, value: null or array of keys representing the\n // most recently received selection for that group.\n this.groupSelections = {};\n \n // selection parameters (e.g., transient versus persistent selection)\n this.highlight = highlight;\n}\n\nTraceManager.prototype.close = function() {\n // TODO: Unhook all event handlers\n};\n\nTraceManager.prototype.updateFilter = function(group, keys) {\n\n if (typeof(keys) === \"undefined\" || keys === null) {\n \n this.gd.data = JSON.parse(JSON.stringify(this.origData));\n \n } else {\n \n var traces = [];\n for (var i = 0; i < this.origData.length; i++) {\n var trace = this.origData[i];\n if (!trace.key || trace.set !== group) {\n continue;\n }\n var matchFunc = getMatchFunc(trace);\n var matches = matchFunc(trace.key, keys);\n \n if (matches.length > 0) {\n if (!trace._isSimpleKey) {\n // subsetArrayAttrs doesn't mutate trace (it makes a modified clone)\n trace = subsetArrayAttrs(trace, matches);\n }\n traces.push(trace);\n }\n }\n }\n \n this.gd.data = traces;\n Plotly.redraw(this.gd);\n \n // NOTE: we purposely do _not_ restore selection(s), since on filter,\n // axis likely will update, changing the pixel -> data mapping, leading \n // to a likely mismatch in the brush outline and highlighted marks\n \n};\n\nTraceManager.prototype.updateSelection = function(group, keys) {\n \n if (keys !== null && !Array.isArray(keys)) {\n throw new Error(\"Invalid keys argument; null or array expected\");\n }\n \n // if selection has been cleared, or if this is transient\n // selection, delete the \"selection traces\"\n var nNewTraces = this.gd.data.length - this.origData.length;\n if (keys === null || !this.highlight.persistent && nNewTraces > 0) {\n var tracesToRemove = [];\n for (var i = 0; i < this.gd.data.length; i++) {\n if (this.gd.data[i]._isCrosstalkTrace) tracesToRemove.push(i);\n }\n Plotly.deleteTraces(this.gd, tracesToRemove);\n this.groupSelections[group] = keys;\n } else {\n // add to the groupSelection, rather than overwriting it\n // TODO: can this be removed?\n this.groupSelections[group] = this.groupSelections[group] || [];\n for (var i = 0; i < keys.length; i++) {\n var k = keys[i];\n if (this.groupSelections[group].indexOf(k) < 0) {\n this.groupSelections[group].push(k);\n }\n }\n }\n \n if (keys === null) {\n \n Plotly.restyle(this.gd, {\"opacity\": this.origOpacity});\n \n } else if (keys.length >= 1) {\n \n // placeholder for new \"selection traces\"\n var traces = [];\n // this variable is set in R/highlight.R\n var selectionColour = crosstalk.group(group).var(\"plotlySelectionColour\").get() || \n this.highlight.color[0];\n\n for (var i = 0; i < this.origData.length; i++) {\n // TODO: try using Lib.extendFlat() as done in \n // https://github.com/plotly/plotly.js/pull/1136 \n var trace = JSON.parse(JSON.stringify(this.gd.data[i]));\n if (!trace.key || trace.set !== group) {\n continue;\n }\n // Get sorted array of matching indices in trace.key\n var matchFunc = getMatchFunc(trace);\n var matches = matchFunc(trace.key, keys);\n \n if (matches.length > 0) {\n // If this is a \"simple\" key, that means select the entire trace\n if (!trace._isSimpleKey) {\n trace = subsetArrayAttrs(trace, matches);\n }\n // reach into the full trace object so we can properly reflect the \n // selection attributes in every view\n var d = this.gd._fullData[i];\n \n /* \n / Recursively inherit selection attributes from various sources, \n / in order of preference:\n / (1) official plotly.js selected attribute\n / (2) highlight(selected = attrs_selected(...))\n */\n // TODO: it would be neat to have a dropdown to dynamically specify these!\n $.extend(true, trace, this.highlight.selected);\n \n // if it is defined, override color with the \"dynamic brush color\"\"\n if (d.marker) {\n trace.marker = trace.marker || {};\n trace.marker.color = selectionColour || trace.marker.color || d.marker.color;\n }\n if (d.line) {\n trace.line = trace.line || {};\n trace.line.color = selectionColour || trace.line.color || d.line.color;\n }\n if (d.textfont) {\n trace.textfont = trace.textfont || {};\n trace.textfont.color = selectionColour || trace.textfont.color || d.textfont.color;\n }\n if (d.fillcolor) {\n // TODO: should selectionColour inherit alpha from the existing fillcolor?\n trace.fillcolor = selectionColour || trace.fillcolor || d.fillcolor;\n }\n // attach a sensible name/legendgroup\n trace.name = trace.name || keys.join(\"
\");\n trace.legendgroup = trace.legendgroup || keys.join(\"
\");\n \n // keep track of mapping between this new trace and the trace it targets\n // (necessary for updating frames to reflect the selection traces)\n trace._originalIndex = i;\n trace._newIndex = this.gd._fullData.length + traces.length;\n trace._isCrosstalkTrace = true;\n traces.push(trace);\n }\n }\n \n if (traces.length > 0) {\n \n Plotly.addTraces(this.gd, traces).then(function(gd) {\n // incrementally add selection traces to frames\n // (this is heavily inspired by Plotly.Plots.modifyFrames() \n // in src/plots/plots.js)\n var _hash = gd._transitionData._frameHash;\n var _frames = gd._transitionData._frames || [];\n \n for (var i = 0; i < _frames.length; i++) {\n \n // add to _frames[i].traces *if* this frame references selected trace(s)\n var newIndices = [];\n for (var j = 0; j < traces.length; j++) {\n var tr = traces[j];\n if (_frames[i].traces.indexOf(tr._originalIndex) > -1) {\n newIndices.push(tr._newIndex);\n _frames[i].traces.push(tr._newIndex);\n }\n }\n \n // nothing to do...\n if (newIndices.length === 0) {\n continue;\n }\n \n var ctr = 0;\n var nFrameTraces = _frames[i].data.length;\n \n for (var j = 0; j < nFrameTraces; j++) {\n var frameTrace = _frames[i].data[j];\n if (!frameTrace.key || frameTrace.set !== group) {\n continue;\n }\n \n var matchFunc = getMatchFunc(frameTrace);\n var matches = matchFunc(frameTrace.key, keys);\n \n if (matches.length > 0) {\n if (!trace._isSimpleKey) {\n frameTrace = subsetArrayAttrs(frameTrace, matches);\n }\n var d = gd._fullData[newIndices[ctr]];\n if (d.marker) {\n frameTrace.marker = d.marker;\n }\n if (d.line) {\n frameTrace.line = d.line;\n }\n if (d.textfont) {\n frameTrace.textfont = d.textfont;\n }\n ctr = ctr + 1;\n _frames[i].data.push(frameTrace);\n }\n }\n \n // update gd._transitionData._frameHash\n _hash[_frames[i].name] = _frames[i];\n }\n \n });\n \n // dim traces that have a set matching the set of selection sets\n var tracesToDim = [],\n opacities = [],\n sets = Object.keys(this.groupSelections),\n n = this.origData.length;\n \n for (var i = 0; i < n; i++) {\n var opacity = this.origOpacity[i] || 1;\n // have we already dimmed this trace? Or is this even worth doing?\n if (opacity !== this.gd._fullData[i].opacity || this.highlight.opacityDim === 1) {\n continue;\n }\n // is this set an element of the set of selection sets?\n var matches = findMatches(sets, [this.gd.data[i].set]);\n if (matches.length) {\n tracesToDim.push(i);\n opacities.push(opacity * this.highlight.opacityDim);\n }\n }\n \n if (tracesToDim.length > 0) {\n Plotly.restyle(this.gd, {\"opacity\": opacities}, tracesToDim);\n // turn off the selected/unselected API\n Plotly.restyle(this.gd, {\"selectedpoints\": null});\n }\n \n }\n \n }\n};\n\n/* \nNote: in all of these match functions, we assume needleSet (i.e. the selected keys)\nis a 1D (or flat) array. The real difference is the meaning of haystack.\nfindMatches() does the usual thing you'd expect for \nlinked brushing on a scatterplot matrix. findSimpleMatches() returns a match iff \nhaystack is a subset of the needleSet. findNestedMatches() returns \n*/\n\nfunction getMatchFunc(trace) {\n return (trace._isNestedKey) ? findNestedMatches : \n (trace._isSimpleKey) ? findSimpleMatches : findMatches;\n}\n\n// find matches for \"flat\" keys\nfunction findMatches(haystack, needleSet) {\n var matches = [];\n haystack.forEach(function(obj, i) {\n if (obj === null || needleSet.indexOf(obj) >= 0) {\n matches.push(i);\n }\n });\n return matches;\n}\n\n// find matches for \"simple\" keys\nfunction findSimpleMatches(haystack, needleSet) {\n var match = haystack.every(function(val) {\n return val === null || needleSet.indexOf(val) >= 0;\n });\n // yes, this doesn't make much sense other than conforming \n // to the output type of the other match functions\n return (match) ? [0] : []\n}\n\n// find matches for a \"nested\" haystack (2D arrays)\nfunction findNestedMatches(haystack, needleSet) {\n var matches = [];\n for (var i = 0; i < haystack.length; i++) {\n var hay = haystack[i];\n var match = hay.every(function(val) { \n return val === null || needleSet.indexOf(val) >= 0; \n });\n if (match) {\n matches.push(i);\n }\n }\n return matches;\n}\n\nfunction isPlainObject(obj) {\n return (\n Object.prototype.toString.call(obj) === '[object Object]' &&\n Object.getPrototypeOf(obj) === Object.prototype\n );\n}\n\nfunction subsetArrayAttrs(obj, indices) {\n var newObj = {};\n Object.keys(obj).forEach(function(k) {\n var val = obj[k];\n\n if (k.charAt(0) === \"_\") {\n newObj[k] = val;\n } else if (k === \"transforms\" && Array.isArray(val)) {\n newObj[k] = val.map(function(transform) {\n return subsetArrayAttrs(transform, indices);\n });\n } else if (k === \"colorscale\" && Array.isArray(val)) {\n newObj[k] = val;\n } else if (isPlainObject(val)) {\n newObj[k] = subsetArrayAttrs(val, indices);\n } else if (Array.isArray(val)) {\n newObj[k] = subsetArray(val, indices);\n } else {\n newObj[k] = val;\n }\n });\n return newObj;\n}\n\nfunction subsetArray(arr, indices) {\n var result = [];\n for (var i = 0; i < indices.length; i++) {\n result.push(arr[indices[i]]);\n }\n return result;\n}\n\n// Convenience function for removing plotly's brush \nfunction removeBrush(el) {\n var outlines = el.querySelectorAll(\".select-outline\");\n for (var i = 0; i < outlines.length; i++) {\n outlines[i].remove();\n }\n}\n\n\n// https://davidwalsh.name/javascript-debounce-function\n\n// Returns a function, that, as long as it continues to be invoked, will not\n// be triggered. The function will be called after it stops being called for\n// N milliseconds. If `immediate` is passed, trigger the function on the\n// leading edge, instead of the trailing.\nfunction debounce(func, wait, immediate) {\n\tvar timeout;\n\treturn function() {\n\t\tvar context = this, args = arguments;\n\t\tvar later = function() {\n\t\t\ttimeout = null;\n\t\t\tif (!immediate) func.apply(context, args);\n\t\t};\n\t\tvar callNow = immediate && !timeout;\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(later, wait);\n\t\tif (callNow) func.apply(context, args);\n\t};\n};\n\nmodule.exports = widgetDefinition"]} \ No newline at end of file +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","theSrc/scripts/plotly.js","theSrc/scripts/widgetdefinition.js"],"names":["r","e","n","t","o","i","f","c","require","u","a","Error","code","p","exports","call","length","1","module","_widgetdefinition","HTMLWidgets","widget","_widgetdefinition2","default","widgetDefinition","name","type","initialize","el","width","height","resize","instance","autosize","Plotly","relayout","renderValue","x","lay","layout","crosstalk","var","set","highlight","window","PLOTLYENV","BASE_URL","base_url","persistent","onmousemove","event","shiftKey","persistentShift","graphDiv","document","getElementById","id","addPostRenderHandler","modebars","querySelectorAll","style","zIndex","selectize","dynamic","plotly","pickerDiv","flex","createElement","class","pickerInput","placeholder","pickerLabel","for","innerHTML","appendChild","ids","Object","keys","container","label","group","selectDiv","select","multiple","parentElement","insertBefore","picker","$","colors","color","opts","value","showColour","palette","allowedCols","join","colourpicker","changeDelay","grps","ctGroups","on","eventDataWithKey","eventData","undefined","hasOwnProperty","points","map","pt","obj","curveNumber","pointNumber","y","z","customdata","attrsToAttach","trace","data","_isSimpleKey","key","attr","Array","isArray","pointNumbers","idx","purge","plot","then","shinyMode","Shiny","addCustomMessageHandler","msg","gd","method","args","concat","apply","react","mapboxIDs","_fullLayout","_subplots","mapbox","_fitBounds","_subplot","fitBounds","bounds","options","eventClearMap","eventDataFunctionMap","legendEventData","d","legendgroup","legendgrps","traces","push","setInputValue","plotly_deselect","plotly_unhover","plotly_doubleclick","evt","input","source","priority","plotly_click","plotly_sunburstclick","plotly_hover","plotly_selected","plotly_selecting","plotly_brushed","range","lassoPoints","plotly_brushing","plotly_legendclick","plotly_legenddoubleclick","plotly_clickannotation","fullAnnotation","shinyEvents","eventDataPreProcessor","JSON","stringify","traceManager","TraceManager","allSets","curveIdx","newSet","indexOf","selection","SelectionHandle","FilterHandle","removeBrush","updateFilter","prototype","diff","this","filter","oldValue","selectionHistory","get","receiverID","plotlySelectionColour","ev","updateSelection","clear","addItems","close","selectizeID","turnOn","selectedKeys","keysBySet","keyFlat","ptNum","_isNestedKey","pointsToKeys","sender","debounce","func","wait","immediate","timeout","context","arguments","callNow","clearTimeout","setTimeout","off","items","searchField","valueField","labelField","maxItems","find","currentItems","groupSelections","removeItem","newItems","console","log","origData","parse","origOpacity","opacity","getMatchFunc","findNestedMatches","findSimpleMatches","findMatches","haystack","needleSet","matches","forEach","every","val","subsetArrayAttrs","indices","newObj","k","charAt","transform","toString","getPrototypeOf","arr","result","subsetArray","outlines","remove","matchFunc","redraw","nNewTraces","tracesToRemove","_isCrosstalkTrace","deleteTraces","restyle","selectionColour","_fullData","extend","selected","marker","line","textfont","fillcolor","_originalIndex","_newIndex","addTraces","_hash","_transitionData","_frameHash","_frames","newIndices","j","tr","ctr","nFrameTraces","frameTrace","tracesToDim","opacities","sets","opacityDim","selectedpoints"],"mappings":"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","file":"plotly.js","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i 0) {\n var ev = JSON.stringify(event);\n for (var i = 0; i < selectionHistory.length; i++) {\n var sel = JSON.stringify(selectionHistory[i]);\n if (sel == ev) {\n return;\n }\n }\n }\n \n // accumulate history for persistent selection\n if (!x.highlight.persistent) {\n selectionHistory = [event];\n } else {\n selectionHistory.push(event);\n }\n crosstalk.var(\"plotlySelectionHistory\").set(selectionHistory);\n \n // do the actual updating of traces, frames, and the selectize widget\n traceManager.updateSelection(set, e.value);\n // https://github.com/selectize/selectize.js/blob/master/docs/api.md#methods_items\n if (x.selectize) {\n if (!x.highlight.persistent || e.value === null) {\n selectize.clear(true);\n }\n selectize.addItems(e.value, true);\n selectize.close();\n }\n }\n selection.on(\"change\", selectionChange);\n \n // Set a crosstalk variable selection value, triggering an update\n var turnOn = function(e) {\n if (e) {\n var selectedKeys = pointsToKeys(e.points);\n // Keys are group names, values are array of selected keys from group.\n for (var set in selectedKeys) {\n if (selectedKeys.hasOwnProperty(set)) {\n selection.set(selectedKeys[set].value, {sender: el});\n }\n }\n }\n };\n if (x.highlight.debounce > 0) {\n turnOn = debounce(turnOn, x.highlight.debounce);\n }\n graphDiv.on(x.highlight.on, turnOn);\n \n graphDiv.on(x.highlight.off, function turnOff(e) {\n // remove any visual clues\n removeBrush(el);\n // remove any selection history\n crosstalk.var(\"plotlySelectionHistory\").set(null);\n // trigger the actual removal of selection traces\n selection.set(null, {sender: el});\n });\n \n // register a callback for selectize so that there is bi-directional\n // communication between the widget and direct manipulation events\n if (x.selectize) {\n var selectizeID = Object.keys(x.selectize)[i];\n var items = x.selectize[selectizeID].items;\n var first = [{value: \"\", label: \"(All)\"}];\n var opts = {\n options: first.concat(items),\n searchField: \"label\",\n valueField: \"value\",\n labelField: \"label\",\n maxItems: 50\n };\n var select = $(\"#\" + selectizeID).find(\"select\")[0];\n var selectize = $(select).selectize(opts)[0].selectize;\n // NOTE: this callback is triggered when *directly* altering \n // dropdown items\n selectize.on(\"change\", function() {\n var currentItems = traceManager.groupSelections[set] || [];\n if (!x.highlight.persistent) {\n removeBrush(el);\n for (var i = 0; i < currentItems.length; i++) {\n selectize.removeItem(currentItems[i], true);\n }\n }\n var newItems = selectize.items.filter(function(idx) { \n return currentItems.indexOf(idx) < 0;\n });\n if (newItems.length > 0) {\n traceManager.updateSelection(set, newItems);\n } else {\n // Item has been removed...\n // TODO: this logic won't work for dynamically changing palette \n traceManager.updateSelection(set, null);\n traceManager.updateSelection(set, selectize.items);\n }\n });\n }\n } // end of selectionChange\n\n graphDiv.on(\"plotly_afterplot\", function() {\n console.log(\"-------------plotly done!-----------------------------------------------------\");\n });\n } // end of renderValue\n}\n\n/**\n * @param graphDiv The Plotly graph div\n * @param highlight An object with options for updating selection(s)\n */\nfunction TraceManager(graphDiv, highlight) {\n // The Plotly graph div\n this.gd = graphDiv;\n\n // Preserve the original data.\n // TODO: try using Lib.extendFlat() as done in \n // https://github.com/plotly/plotly.js/pull/1136 \n this.origData = JSON.parse(JSON.stringify(graphDiv.data));\n \n // avoid doing this over and over\n this.origOpacity = [];\n for (var i = 0; i < this.origData.length; i++) {\n this.origOpacity[i] = this.origData[i].opacity === 0 ? 0 : (this.origData[i].opacity || 1);\n }\n\n // key: group name, value: null or array of keys representing the\n // most recently received selection for that group.\n this.groupSelections = {};\n \n // selection parameters (e.g., transient versus persistent selection)\n this.highlight = highlight;\n}\n\nTraceManager.prototype.close = function() {\n // TODO: Unhook all event handlers\n};\n\nTraceManager.prototype.updateFilter = function(group, keys) {\n\n if (typeof(keys) === \"undefined\" || keys === null) {\n \n this.gd.data = JSON.parse(JSON.stringify(this.origData));\n \n } else {\n \n var traces = [];\n for (var i = 0; i < this.origData.length; i++) {\n var trace = this.origData[i];\n if (!trace.key || trace.set !== group) {\n continue;\n }\n var matchFunc = getMatchFunc(trace);\n var matches = matchFunc(trace.key, keys);\n \n if (matches.length > 0) {\n if (!trace._isSimpleKey) {\n // subsetArrayAttrs doesn't mutate trace (it makes a modified clone)\n trace = subsetArrayAttrs(trace, matches);\n }\n traces.push(trace);\n }\n }\n }\n \n this.gd.data = traces;\n Plotly.redraw(this.gd);\n \n // NOTE: we purposely do _not_ restore selection(s), since on filter,\n // axis likely will update, changing the pixel -> data mapping, leading \n // to a likely mismatch in the brush outline and highlighted marks\n \n};\n\nTraceManager.prototype.updateSelection = function(group, keys) {\n \n if (keys !== null && !Array.isArray(keys)) {\n throw new Error(\"Invalid keys argument; null or array expected\");\n }\n \n // if selection has been cleared, or if this is transient\n // selection, delete the \"selection traces\"\n var nNewTraces = this.gd.data.length - this.origData.length;\n if (keys === null || !this.highlight.persistent && nNewTraces > 0) {\n var tracesToRemove = [];\n for (var i = 0; i < this.gd.data.length; i++) {\n if (this.gd.data[i]._isCrosstalkTrace) tracesToRemove.push(i);\n }\n Plotly.deleteTraces(this.gd, tracesToRemove);\n this.groupSelections[group] = keys;\n } else {\n // add to the groupSelection, rather than overwriting it\n // TODO: can this be removed?\n this.groupSelections[group] = this.groupSelections[group] || [];\n for (var i = 0; i < keys.length; i++) {\n var k = keys[i];\n if (this.groupSelections[group].indexOf(k) < 0) {\n this.groupSelections[group].push(k);\n }\n }\n }\n \n if (keys === null) {\n \n Plotly.restyle(this.gd, {\"opacity\": this.origOpacity});\n \n } else if (keys.length >= 1) {\n \n // placeholder for new \"selection traces\"\n var traces = [];\n // this variable is set in R/highlight.R\n var selectionColour = crosstalk.group(group).var(\"plotlySelectionColour\").get() || \n this.highlight.color[0];\n\n for (var i = 0; i < this.origData.length; i++) {\n // TODO: try using Lib.extendFlat() as done in \n // https://github.com/plotly/plotly.js/pull/1136 \n var trace = JSON.parse(JSON.stringify(this.gd.data[i]));\n if (!trace.key || trace.set !== group) {\n continue;\n }\n // Get sorted array of matching indices in trace.key\n var matchFunc = getMatchFunc(trace);\n var matches = matchFunc(trace.key, keys);\n \n if (matches.length > 0) {\n // If this is a \"simple\" key, that means select the entire trace\n if (!trace._isSimpleKey) {\n trace = subsetArrayAttrs(trace, matches);\n }\n // reach into the full trace object so we can properly reflect the \n // selection attributes in every view\n var d = this.gd._fullData[i];\n \n /* \n / Recursively inherit selection attributes from various sources, \n / in order of preference:\n / (1) official plotly.js selected attribute\n / (2) highlight(selected = attrs_selected(...))\n */\n // TODO: it would be neat to have a dropdown to dynamically specify these!\n $.extend(true, trace, this.highlight.selected);\n \n // if it is defined, override color with the \"dynamic brush color\"\"\n if (d.marker) {\n trace.marker = trace.marker || {};\n trace.marker.color = selectionColour || trace.marker.color || d.marker.color;\n }\n if (d.line) {\n trace.line = trace.line || {};\n trace.line.color = selectionColour || trace.line.color || d.line.color;\n }\n if (d.textfont) {\n trace.textfont = trace.textfont || {};\n trace.textfont.color = selectionColour || trace.textfont.color || d.textfont.color;\n }\n if (d.fillcolor) {\n // TODO: should selectionColour inherit alpha from the existing fillcolor?\n trace.fillcolor = selectionColour || trace.fillcolor || d.fillcolor;\n }\n // attach a sensible name/legendgroup\n trace.name = trace.name || keys.join(\"
\");\n trace.legendgroup = trace.legendgroup || keys.join(\"
\");\n \n // keep track of mapping between this new trace and the trace it targets\n // (necessary for updating frames to reflect the selection traces)\n trace._originalIndex = i;\n trace._newIndex = this.gd._fullData.length + traces.length;\n trace._isCrosstalkTrace = true;\n traces.push(trace);\n }\n }\n \n if (traces.length > 0) {\n \n Plotly.addTraces(this.gd, traces).then(function(gd) {\n // incrementally add selection traces to frames\n // (this is heavily inspired by Plotly.Plots.modifyFrames() \n // in src/plots/plots.js)\n var _hash = gd._transitionData._frameHash;\n var _frames = gd._transitionData._frames || [];\n \n for (var i = 0; i < _frames.length; i++) {\n \n // add to _frames[i].traces *if* this frame references selected trace(s)\n var newIndices = [];\n for (var j = 0; j < traces.length; j++) {\n var tr = traces[j];\n if (_frames[i].traces.indexOf(tr._originalIndex) > -1) {\n newIndices.push(tr._newIndex);\n _frames[i].traces.push(tr._newIndex);\n }\n }\n \n // nothing to do...\n if (newIndices.length === 0) {\n continue;\n }\n \n var ctr = 0;\n var nFrameTraces = _frames[i].data.length;\n \n for (var j = 0; j < nFrameTraces; j++) {\n var frameTrace = _frames[i].data[j];\n if (!frameTrace.key || frameTrace.set !== group) {\n continue;\n }\n \n var matchFunc = getMatchFunc(frameTrace);\n var matches = matchFunc(frameTrace.key, keys);\n \n if (matches.length > 0) {\n if (!trace._isSimpleKey) {\n frameTrace = subsetArrayAttrs(frameTrace, matches);\n }\n var d = gd._fullData[newIndices[ctr]];\n if (d.marker) {\n frameTrace.marker = d.marker;\n }\n if (d.line) {\n frameTrace.line = d.line;\n }\n if (d.textfont) {\n frameTrace.textfont = d.textfont;\n }\n ctr = ctr + 1;\n _frames[i].data.push(frameTrace);\n }\n }\n \n // update gd._transitionData._frameHash\n _hash[_frames[i].name] = _frames[i];\n }\n \n });\n \n // dim traces that have a set matching the set of selection sets\n var tracesToDim = [],\n opacities = [],\n sets = Object.keys(this.groupSelections),\n n = this.origData.length;\n \n for (var i = 0; i < n; i++) {\n var opacity = this.origOpacity[i] || 1;\n // have we already dimmed this trace? Or is this even worth doing?\n if (opacity !== this.gd._fullData[i].opacity || this.highlight.opacityDim === 1) {\n continue;\n }\n // is this set an element of the set of selection sets?\n var matches = findMatches(sets, [this.gd.data[i].set]);\n if (matches.length) {\n tracesToDim.push(i);\n opacities.push(opacity * this.highlight.opacityDim);\n }\n }\n \n if (tracesToDim.length > 0) {\n Plotly.restyle(this.gd, {\"opacity\": opacities}, tracesToDim);\n // turn off the selected/unselected API\n Plotly.restyle(this.gd, {\"selectedpoints\": null});\n }\n \n }\n \n }\n};\n\n/* \nNote: in all of these match functions, we assume needleSet (i.e. the selected keys)\nis a 1D (or flat) array. The real difference is the meaning of haystack.\nfindMatches() does the usual thing you'd expect for \nlinked brushing on a scatterplot matrix. findSimpleMatches() returns a match iff \nhaystack is a subset of the needleSet. findNestedMatches() returns \n*/\n\nfunction getMatchFunc(trace) {\n return (trace._isNestedKey) ? findNestedMatches : \n (trace._isSimpleKey) ? findSimpleMatches : findMatches;\n}\n\n// find matches for \"flat\" keys\nfunction findMatches(haystack, needleSet) {\n var matches = [];\n haystack.forEach(function(obj, i) {\n if (obj === null || needleSet.indexOf(obj) >= 0) {\n matches.push(i);\n }\n });\n return matches;\n}\n\n// find matches for \"simple\" keys\nfunction findSimpleMatches(haystack, needleSet) {\n var match = haystack.every(function(val) {\n return val === null || needleSet.indexOf(val) >= 0;\n });\n // yes, this doesn't make much sense other than conforming \n // to the output type of the other match functions\n return (match) ? [0] : []\n}\n\n// find matches for a \"nested\" haystack (2D arrays)\nfunction findNestedMatches(haystack, needleSet) {\n var matches = [];\n for (var i = 0; i < haystack.length; i++) {\n var hay = haystack[i];\n var match = hay.every(function(val) { \n return val === null || needleSet.indexOf(val) >= 0; \n });\n if (match) {\n matches.push(i);\n }\n }\n return matches;\n}\n\nfunction isPlainObject(obj) {\n return (\n Object.prototype.toString.call(obj) === '[object Object]' &&\n Object.getPrototypeOf(obj) === Object.prototype\n );\n}\n\nfunction subsetArrayAttrs(obj, indices) {\n var newObj = {};\n Object.keys(obj).forEach(function(k) {\n var val = obj[k];\n\n if (k.charAt(0) === \"_\") {\n newObj[k] = val;\n } else if (k === \"transforms\" && Array.isArray(val)) {\n newObj[k] = val.map(function(transform) {\n return subsetArrayAttrs(transform, indices);\n });\n } else if (k === \"colorscale\" && Array.isArray(val)) {\n newObj[k] = val;\n } else if (isPlainObject(val)) {\n newObj[k] = subsetArrayAttrs(val, indices);\n } else if (Array.isArray(val)) {\n newObj[k] = subsetArray(val, indices);\n } else {\n newObj[k] = val;\n }\n });\n return newObj;\n}\n\nfunction subsetArray(arr, indices) {\n var result = [];\n for (var i = 0; i < indices.length; i++) {\n result.push(arr[indices[i]]);\n }\n return result;\n}\n\n// Convenience function for removing plotly's brush \nfunction removeBrush(el) {\n var outlines = el.querySelectorAll(\".select-outline\");\n for (var i = 0; i < outlines.length; i++) {\n outlines[i].remove();\n }\n}\n\n\n// https://davidwalsh.name/javascript-debounce-function\n\n// Returns a function, that, as long as it continues to be invoked, will not\n// be triggered. The function will be called after it stops being called for\n// N milliseconds. If `immediate` is passed, trigger the function on the\n// leading edge, instead of the trailing.\nfunction debounce(func, wait, immediate) {\n\tvar timeout;\n\treturn function() {\n\t\tvar context = this, args = arguments;\n\t\tvar later = function() {\n\t\t\ttimeout = null;\n\t\t\tif (!immediate) func.apply(context, args);\n\t\t};\n\t\tvar callNow = immediate && !timeout;\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(later, wait);\n\t\tif (callNow) func.apply(context, args);\n\t};\n};\n\nmodule.exports = widgetDefinition"]} \ No newline at end of file From 6f7cc6a2a4bed5b27042f5227c1e8b99243303c4 Mon Sep 17 00:00:00 2001 From: Justin Yap Date: Wed, 6 Oct 2021 13:50:51 +1100 Subject: [PATCH 3/4] Add rhtmlwidget-status attribute --- inst/htmlwidgets/plotly.js | 2 +- inst/htmlwidgets/plotly.js.map | 2 +- theSrc/scripts/widgetdefinition.js | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/inst/htmlwidgets/plotly.js b/inst/htmlwidgets/plotly.js index 2a0776e2d3..5c12bb79f7 100644 --- a/inst/htmlwidgets/plotly.js +++ b/inst/htmlwidgets/plotly.js @@ -1,2 +1,2 @@ -!function i(r,o,n){function a(e,t){if(!o[e]){if(!r[e]){var l="function"==typeof require&&require;if(!t&&l)return l(e,!0);if(s)return s(e,!0);throw(l=new Error("Cannot find module '"+e+"'")).code="MODULE_NOT_FOUND",l}l=o[e]={exports:{}},r[e][0].call(l.exports,function(t){return a(r[e][1][t]||t)},l,l.exports,i,r,o,n)}return o[e].exports}for(var s="function"==typeof require&&require,t=0;t"),d.legendgroup=d.legendgroup||p.join("
"),d._originalIndex=l,d._newIndex=this.gd._fullData.length+g.length,d._isCrosstalkTrace=!0,g.push(d))}if(0"),g.legendgroup=g.legendgroup||p.join("
"),g._originalIndex=l,g._newIndex=this.gd._fullData.length+d.length,g._isCrosstalkTrace=!0,d.push(g))}if(0 0) {\n var ev = JSON.stringify(event);\n for (var i = 0; i < selectionHistory.length; i++) {\n var sel = JSON.stringify(selectionHistory[i]);\n if (sel == ev) {\n return;\n }\n }\n }\n \n // accumulate history for persistent selection\n if (!x.highlight.persistent) {\n selectionHistory = [event];\n } else {\n selectionHistory.push(event);\n }\n crosstalk.var(\"plotlySelectionHistory\").set(selectionHistory);\n \n // do the actual updating of traces, frames, and the selectize widget\n traceManager.updateSelection(set, e.value);\n // https://github.com/selectize/selectize.js/blob/master/docs/api.md#methods_items\n if (x.selectize) {\n if (!x.highlight.persistent || e.value === null) {\n selectize.clear(true);\n }\n selectize.addItems(e.value, true);\n selectize.close();\n }\n }\n selection.on(\"change\", selectionChange);\n \n // Set a crosstalk variable selection value, triggering an update\n var turnOn = function(e) {\n if (e) {\n var selectedKeys = pointsToKeys(e.points);\n // Keys are group names, values are array of selected keys from group.\n for (var set in selectedKeys) {\n if (selectedKeys.hasOwnProperty(set)) {\n selection.set(selectedKeys[set].value, {sender: el});\n }\n }\n }\n };\n if (x.highlight.debounce > 0) {\n turnOn = debounce(turnOn, x.highlight.debounce);\n }\n graphDiv.on(x.highlight.on, turnOn);\n \n graphDiv.on(x.highlight.off, function turnOff(e) {\n // remove any visual clues\n removeBrush(el);\n // remove any selection history\n crosstalk.var(\"plotlySelectionHistory\").set(null);\n // trigger the actual removal of selection traces\n selection.set(null, {sender: el});\n });\n \n // register a callback for selectize so that there is bi-directional\n // communication between the widget and direct manipulation events\n if (x.selectize) {\n var selectizeID = Object.keys(x.selectize)[i];\n var items = x.selectize[selectizeID].items;\n var first = [{value: \"\", label: \"(All)\"}];\n var opts = {\n options: first.concat(items),\n searchField: \"label\",\n valueField: \"value\",\n labelField: \"label\",\n maxItems: 50\n };\n var select = $(\"#\" + selectizeID).find(\"select\")[0];\n var selectize = $(select).selectize(opts)[0].selectize;\n // NOTE: this callback is triggered when *directly* altering \n // dropdown items\n selectize.on(\"change\", function() {\n var currentItems = traceManager.groupSelections[set] || [];\n if (!x.highlight.persistent) {\n removeBrush(el);\n for (var i = 0; i < currentItems.length; i++) {\n selectize.removeItem(currentItems[i], true);\n }\n }\n var newItems = selectize.items.filter(function(idx) { \n return currentItems.indexOf(idx) < 0;\n });\n if (newItems.length > 0) {\n traceManager.updateSelection(set, newItems);\n } else {\n // Item has been removed...\n // TODO: this logic won't work for dynamically changing palette \n traceManager.updateSelection(set, null);\n traceManager.updateSelection(set, selectize.items);\n }\n });\n }\n } // end of selectionChange\n\n graphDiv.on(\"plotly_afterplot\", function() {\n console.log(\"-------------plotly done!-----------------------------------------------------\");\n });\n } // end of renderValue\n}\n\n/**\n * @param graphDiv The Plotly graph div\n * @param highlight An object with options for updating selection(s)\n */\nfunction TraceManager(graphDiv, highlight) {\n // The Plotly graph div\n this.gd = graphDiv;\n\n // Preserve the original data.\n // TODO: try using Lib.extendFlat() as done in \n // https://github.com/plotly/plotly.js/pull/1136 \n this.origData = JSON.parse(JSON.stringify(graphDiv.data));\n \n // avoid doing this over and over\n this.origOpacity = [];\n for (var i = 0; i < this.origData.length; i++) {\n this.origOpacity[i] = this.origData[i].opacity === 0 ? 0 : (this.origData[i].opacity || 1);\n }\n\n // key: group name, value: null or array of keys representing the\n // most recently received selection for that group.\n this.groupSelections = {};\n \n // selection parameters (e.g., transient versus persistent selection)\n this.highlight = highlight;\n}\n\nTraceManager.prototype.close = function() {\n // TODO: Unhook all event handlers\n};\n\nTraceManager.prototype.updateFilter = function(group, keys) {\n\n if (typeof(keys) === \"undefined\" || keys === null) {\n \n this.gd.data = JSON.parse(JSON.stringify(this.origData));\n \n } else {\n \n var traces = [];\n for (var i = 0; i < this.origData.length; i++) {\n var trace = this.origData[i];\n if (!trace.key || trace.set !== group) {\n continue;\n }\n var matchFunc = getMatchFunc(trace);\n var matches = matchFunc(trace.key, keys);\n \n if (matches.length > 0) {\n if (!trace._isSimpleKey) {\n // subsetArrayAttrs doesn't mutate trace (it makes a modified clone)\n trace = subsetArrayAttrs(trace, matches);\n }\n traces.push(trace);\n }\n }\n }\n \n this.gd.data = traces;\n Plotly.redraw(this.gd);\n \n // NOTE: we purposely do _not_ restore selection(s), since on filter,\n // axis likely will update, changing the pixel -> data mapping, leading \n // to a likely mismatch in the brush outline and highlighted marks\n \n};\n\nTraceManager.prototype.updateSelection = function(group, keys) {\n \n if (keys !== null && !Array.isArray(keys)) {\n throw new Error(\"Invalid keys argument; null or array expected\");\n }\n \n // if selection has been cleared, or if this is transient\n // selection, delete the \"selection traces\"\n var nNewTraces = this.gd.data.length - this.origData.length;\n if (keys === null || !this.highlight.persistent && nNewTraces > 0) {\n var tracesToRemove = [];\n for (var i = 0; i < this.gd.data.length; i++) {\n if (this.gd.data[i]._isCrosstalkTrace) tracesToRemove.push(i);\n }\n Plotly.deleteTraces(this.gd, tracesToRemove);\n this.groupSelections[group] = keys;\n } else {\n // add to the groupSelection, rather than overwriting it\n // TODO: can this be removed?\n this.groupSelections[group] = this.groupSelections[group] || [];\n for (var i = 0; i < keys.length; i++) {\n var k = keys[i];\n if (this.groupSelections[group].indexOf(k) < 0) {\n this.groupSelections[group].push(k);\n }\n }\n }\n \n if (keys === null) {\n \n Plotly.restyle(this.gd, {\"opacity\": this.origOpacity});\n \n } else if (keys.length >= 1) {\n \n // placeholder for new \"selection traces\"\n var traces = [];\n // this variable is set in R/highlight.R\n var selectionColour = crosstalk.group(group).var(\"plotlySelectionColour\").get() || \n this.highlight.color[0];\n\n for (var i = 0; i < this.origData.length; i++) {\n // TODO: try using Lib.extendFlat() as done in \n // https://github.com/plotly/plotly.js/pull/1136 \n var trace = JSON.parse(JSON.stringify(this.gd.data[i]));\n if (!trace.key || trace.set !== group) {\n continue;\n }\n // Get sorted array of matching indices in trace.key\n var matchFunc = getMatchFunc(trace);\n var matches = matchFunc(trace.key, keys);\n \n if (matches.length > 0) {\n // If this is a \"simple\" key, that means select the entire trace\n if (!trace._isSimpleKey) {\n trace = subsetArrayAttrs(trace, matches);\n }\n // reach into the full trace object so we can properly reflect the \n // selection attributes in every view\n var d = this.gd._fullData[i];\n \n /* \n / Recursively inherit selection attributes from various sources, \n / in order of preference:\n / (1) official plotly.js selected attribute\n / (2) highlight(selected = attrs_selected(...))\n */\n // TODO: it would be neat to have a dropdown to dynamically specify these!\n $.extend(true, trace, this.highlight.selected);\n \n // if it is defined, override color with the \"dynamic brush color\"\"\n if (d.marker) {\n trace.marker = trace.marker || {};\n trace.marker.color = selectionColour || trace.marker.color || d.marker.color;\n }\n if (d.line) {\n trace.line = trace.line || {};\n trace.line.color = selectionColour || trace.line.color || d.line.color;\n }\n if (d.textfont) {\n trace.textfont = trace.textfont || {};\n trace.textfont.color = selectionColour || trace.textfont.color || d.textfont.color;\n }\n if (d.fillcolor) {\n // TODO: should selectionColour inherit alpha from the existing fillcolor?\n trace.fillcolor = selectionColour || trace.fillcolor || d.fillcolor;\n }\n // attach a sensible name/legendgroup\n trace.name = trace.name || keys.join(\"
\");\n trace.legendgroup = trace.legendgroup || keys.join(\"
\");\n \n // keep track of mapping between this new trace and the trace it targets\n // (necessary for updating frames to reflect the selection traces)\n trace._originalIndex = i;\n trace._newIndex = this.gd._fullData.length + traces.length;\n trace._isCrosstalkTrace = true;\n traces.push(trace);\n }\n }\n \n if (traces.length > 0) {\n \n Plotly.addTraces(this.gd, traces).then(function(gd) {\n // incrementally add selection traces to frames\n // (this is heavily inspired by Plotly.Plots.modifyFrames() \n // in src/plots/plots.js)\n var _hash = gd._transitionData._frameHash;\n var _frames = gd._transitionData._frames || [];\n \n for (var i = 0; i < _frames.length; i++) {\n \n // add to _frames[i].traces *if* this frame references selected trace(s)\n var newIndices = [];\n for (var j = 0; j < traces.length; j++) {\n var tr = traces[j];\n if (_frames[i].traces.indexOf(tr._originalIndex) > -1) {\n newIndices.push(tr._newIndex);\n _frames[i].traces.push(tr._newIndex);\n }\n }\n \n // nothing to do...\n if (newIndices.length === 0) {\n continue;\n }\n \n var ctr = 0;\n var nFrameTraces = _frames[i].data.length;\n \n for (var j = 0; j < nFrameTraces; j++) {\n var frameTrace = _frames[i].data[j];\n if (!frameTrace.key || frameTrace.set !== group) {\n continue;\n }\n \n var matchFunc = getMatchFunc(frameTrace);\n var matches = matchFunc(frameTrace.key, keys);\n \n if (matches.length > 0) {\n if (!trace._isSimpleKey) {\n frameTrace = subsetArrayAttrs(frameTrace, matches);\n }\n var d = gd._fullData[newIndices[ctr]];\n if (d.marker) {\n frameTrace.marker = d.marker;\n }\n if (d.line) {\n frameTrace.line = d.line;\n }\n if (d.textfont) {\n frameTrace.textfont = d.textfont;\n }\n ctr = ctr + 1;\n _frames[i].data.push(frameTrace);\n }\n }\n \n // update gd._transitionData._frameHash\n _hash[_frames[i].name] = _frames[i];\n }\n \n });\n \n // dim traces that have a set matching the set of selection sets\n var tracesToDim = [],\n opacities = [],\n sets = Object.keys(this.groupSelections),\n n = this.origData.length;\n \n for (var i = 0; i < n; i++) {\n var opacity = this.origOpacity[i] || 1;\n // have we already dimmed this trace? Or is this even worth doing?\n if (opacity !== this.gd._fullData[i].opacity || this.highlight.opacityDim === 1) {\n continue;\n }\n // is this set an element of the set of selection sets?\n var matches = findMatches(sets, [this.gd.data[i].set]);\n if (matches.length) {\n tracesToDim.push(i);\n opacities.push(opacity * this.highlight.opacityDim);\n }\n }\n \n if (tracesToDim.length > 0) {\n Plotly.restyle(this.gd, {\"opacity\": opacities}, tracesToDim);\n // turn off the selected/unselected API\n Plotly.restyle(this.gd, {\"selectedpoints\": null});\n }\n \n }\n \n }\n};\n\n/* \nNote: in all of these match functions, we assume needleSet (i.e. the selected keys)\nis a 1D (or flat) array. The real difference is the meaning of haystack.\nfindMatches() does the usual thing you'd expect for \nlinked brushing on a scatterplot matrix. findSimpleMatches() returns a match iff \nhaystack is a subset of the needleSet. findNestedMatches() returns \n*/\n\nfunction getMatchFunc(trace) {\n return (trace._isNestedKey) ? findNestedMatches : \n (trace._isSimpleKey) ? findSimpleMatches : findMatches;\n}\n\n// find matches for \"flat\" keys\nfunction findMatches(haystack, needleSet) {\n var matches = [];\n haystack.forEach(function(obj, i) {\n if (obj === null || needleSet.indexOf(obj) >= 0) {\n matches.push(i);\n }\n });\n return matches;\n}\n\n// find matches for \"simple\" keys\nfunction findSimpleMatches(haystack, needleSet) {\n var match = haystack.every(function(val) {\n return val === null || needleSet.indexOf(val) >= 0;\n });\n // yes, this doesn't make much sense other than conforming \n // to the output type of the other match functions\n return (match) ? [0] : []\n}\n\n// find matches for a \"nested\" haystack (2D arrays)\nfunction findNestedMatches(haystack, needleSet) {\n var matches = [];\n for (var i = 0; i < haystack.length; i++) {\n var hay = haystack[i];\n var match = hay.every(function(val) { \n return val === null || needleSet.indexOf(val) >= 0; \n });\n if (match) {\n matches.push(i);\n }\n }\n return matches;\n}\n\nfunction isPlainObject(obj) {\n return (\n Object.prototype.toString.call(obj) === '[object Object]' &&\n Object.getPrototypeOf(obj) === Object.prototype\n );\n}\n\nfunction subsetArrayAttrs(obj, indices) {\n var newObj = {};\n Object.keys(obj).forEach(function(k) {\n var val = obj[k];\n\n if (k.charAt(0) === \"_\") {\n newObj[k] = val;\n } else if (k === \"transforms\" && Array.isArray(val)) {\n newObj[k] = val.map(function(transform) {\n return subsetArrayAttrs(transform, indices);\n });\n } else if (k === \"colorscale\" && Array.isArray(val)) {\n newObj[k] = val;\n } else if (isPlainObject(val)) {\n newObj[k] = subsetArrayAttrs(val, indices);\n } else if (Array.isArray(val)) {\n newObj[k] = subsetArray(val, indices);\n } else {\n newObj[k] = val;\n }\n });\n return newObj;\n}\n\nfunction subsetArray(arr, indices) {\n var result = [];\n for (var i = 0; i < indices.length; i++) {\n result.push(arr[indices[i]]);\n }\n return result;\n}\n\n// Convenience function for removing plotly's brush \nfunction removeBrush(el) {\n var outlines = el.querySelectorAll(\".select-outline\");\n for (var i = 0; i < outlines.length; i++) {\n outlines[i].remove();\n }\n}\n\n\n// https://davidwalsh.name/javascript-debounce-function\n\n// Returns a function, that, as long as it continues to be invoked, will not\n// be triggered. The function will be called after it stops being called for\n// N milliseconds. If `immediate` is passed, trigger the function on the\n// leading edge, instead of the trailing.\nfunction debounce(func, wait, immediate) {\n\tvar timeout;\n\treturn function() {\n\t\tvar context = this, args = arguments;\n\t\tvar later = function() {\n\t\t\ttimeout = null;\n\t\t\tif (!immediate) func.apply(context, args);\n\t\t};\n\t\tvar callNow = immediate && !timeout;\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(later, wait);\n\t\tif (callNow) func.apply(context, args);\n\t};\n};\n\nmodule.exports = widgetDefinition"]} \ No newline at end of file +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","theSrc/scripts/plotly.js","theSrc/scripts/widgetdefinition.js"],"names":["r","e","n","t","o","i","f","c","require","u","a","Error","code","p","exports","call","length","1","module","_widgetdefinition","HTMLWidgets","widget","_widgetdefinition2","default","widgetDefinition","name","type","initialize","el","width","height","resize","instance","autosize","Plotly","relayout","renderValue","x","lay","layout","crosstalk","var","set","highlight","window","PLOTLYENV","BASE_URL","base_url","persistent","onmousemove","event","shiftKey","persistentShift","graphDiv","document","getElementById","id","setAttribute","addPostRenderHandler","modebars","querySelectorAll","style","zIndex","selectize","dynamic","plotly","pickerDiv","flex","createElement","class","pickerInput","placeholder","pickerLabel","for","innerHTML","appendChild","ids","Object","keys","container","label","group","selectDiv","select","multiple","parentElement","insertBefore","picker","$","colors","color","opts","value","showColour","palette","allowedCols","join","colourpicker","changeDelay","grps","ctGroups","on","eventDataWithKey","eventData","undefined","hasOwnProperty","points","map","pt","obj","curveNumber","pointNumber","y","z","customdata","attrsToAttach","trace","data","_isSimpleKey","key","attr","Array","isArray","pointNumbers","idx","purge","plot","then","shinyMode","Shiny","addCustomMessageHandler","msg","gd","method","args","concat","apply","react","mapboxIDs","_fullLayout","_subplots","mapbox","_fitBounds","_subplot","fitBounds","bounds","options","eventClearMap","eventDataFunctionMap","legendEventData","d","legendgroup","legendgrps","traces","push","setInputValue","plotly_deselect","plotly_unhover","plotly_doubleclick","evt","input","source","priority","plotly_click","plotly_sunburstclick","plotly_hover","plotly_selected","plotly_selecting","plotly_brushed","range","lassoPoints","plotly_brushing","plotly_legendclick","plotly_legenddoubleclick","plotly_clickannotation","fullAnnotation","shinyEvents","eventDataPreProcessor","JSON","stringify","traceManager","TraceManager","allSets","curveIdx","newSet","indexOf","selection","SelectionHandle","FilterHandle","removeBrush","updateFilter","prototype","diff","this","filter","oldValue","selectionHistory","get","receiverID","plotlySelectionColour","ev","updateSelection","clear","addItems","close","selectizeID","turnOn","selectedKeys","keysBySet","keyFlat","ptNum","_isNestedKey","pointsToKeys","sender","debounce","func","wait","immediate","timeout","context","arguments","callNow","clearTimeout","setTimeout","off","items","searchField","valueField","labelField","maxItems","find","currentItems","groupSelections","removeItem","newItems","origData","parse","origOpacity","opacity","getMatchFunc","findNestedMatches","findSimpleMatches","findMatches","haystack","needleSet","matches","forEach","every","val","subsetArrayAttrs","indices","newObj","k","charAt","transform","toString","getPrototypeOf","arr","result","subsetArray","outlines","remove","matchFunc","redraw","nNewTraces","tracesToRemove","_isCrosstalkTrace","deleteTraces","restyle","selectionColour","_fullData","extend","selected","marker","line","textfont","fillcolor","_originalIndex","_newIndex","addTraces","_hash","_transitionData","_frameHash","_frames","newIndices","j","tr","ctr","nFrameTraces","frameTrace","tracesToDim","opacities","sets","opacityDim","selectedpoints"],"mappings":"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","file":"plotly.js","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i 0) {\n var ev = JSON.stringify(event);\n for (var i = 0; i < selectionHistory.length; i++) {\n var sel = JSON.stringify(selectionHistory[i]);\n if (sel == ev) {\n return;\n }\n }\n }\n \n // accumulate history for persistent selection\n if (!x.highlight.persistent) {\n selectionHistory = [event];\n } else {\n selectionHistory.push(event);\n }\n crosstalk.var(\"plotlySelectionHistory\").set(selectionHistory);\n \n // do the actual updating of traces, frames, and the selectize widget\n traceManager.updateSelection(set, e.value);\n // https://github.com/selectize/selectize.js/blob/master/docs/api.md#methods_items\n if (x.selectize) {\n if (!x.highlight.persistent || e.value === null) {\n selectize.clear(true);\n }\n selectize.addItems(e.value, true);\n selectize.close();\n }\n }\n selection.on(\"change\", selectionChange);\n \n // Set a crosstalk variable selection value, triggering an update\n var turnOn = function(e) {\n if (e) {\n var selectedKeys = pointsToKeys(e.points);\n // Keys are group names, values are array of selected keys from group.\n for (var set in selectedKeys) {\n if (selectedKeys.hasOwnProperty(set)) {\n selection.set(selectedKeys[set].value, {sender: el});\n }\n }\n }\n };\n if (x.highlight.debounce > 0) {\n turnOn = debounce(turnOn, x.highlight.debounce);\n }\n graphDiv.on(x.highlight.on, turnOn);\n \n graphDiv.on(x.highlight.off, function turnOff(e) {\n // remove any visual clues\n removeBrush(el);\n // remove any selection history\n crosstalk.var(\"plotlySelectionHistory\").set(null);\n // trigger the actual removal of selection traces\n selection.set(null, {sender: el});\n });\n \n // register a callback for selectize so that there is bi-directional\n // communication between the widget and direct manipulation events\n if (x.selectize) {\n var selectizeID = Object.keys(x.selectize)[i];\n var items = x.selectize[selectizeID].items;\n var first = [{value: \"\", label: \"(All)\"}];\n var opts = {\n options: first.concat(items),\n searchField: \"label\",\n valueField: \"value\",\n labelField: \"label\",\n maxItems: 50\n };\n var select = $(\"#\" + selectizeID).find(\"select\")[0];\n var selectize = $(select).selectize(opts)[0].selectize;\n // NOTE: this callback is triggered when *directly* altering \n // dropdown items\n selectize.on(\"change\", function() {\n var currentItems = traceManager.groupSelections[set] || [];\n if (!x.highlight.persistent) {\n removeBrush(el);\n for (var i = 0; i < currentItems.length; i++) {\n selectize.removeItem(currentItems[i], true);\n }\n }\n var newItems = selectize.items.filter(function(idx) { \n return currentItems.indexOf(idx) < 0;\n });\n if (newItems.length > 0) {\n traceManager.updateSelection(set, newItems);\n } else {\n // Item has been removed...\n // TODO: this logic won't work for dynamically changing palette \n traceManager.updateSelection(set, null);\n traceManager.updateSelection(set, selectize.items);\n }\n });\n }\n } // end of selectionChange\n\n graphDiv.on(\"plotly_afterplot\", function() {\n // Used by Displayr to determine when widget is ready to be snapshot for testing\n graphDiv.setAttribute(\"rhtmlwidget-status\", \"ready\");\n });\n } // end of renderValue\n}\n\n/**\n * @param graphDiv The Plotly graph div\n * @param highlight An object with options for updating selection(s)\n */\nfunction TraceManager(graphDiv, highlight) {\n // The Plotly graph div\n this.gd = graphDiv;\n\n // Preserve the original data.\n // TODO: try using Lib.extendFlat() as done in \n // https://github.com/plotly/plotly.js/pull/1136 \n this.origData = JSON.parse(JSON.stringify(graphDiv.data));\n \n // avoid doing this over and over\n this.origOpacity = [];\n for (var i = 0; i < this.origData.length; i++) {\n this.origOpacity[i] = this.origData[i].opacity === 0 ? 0 : (this.origData[i].opacity || 1);\n }\n\n // key: group name, value: null or array of keys representing the\n // most recently received selection for that group.\n this.groupSelections = {};\n \n // selection parameters (e.g., transient versus persistent selection)\n this.highlight = highlight;\n}\n\nTraceManager.prototype.close = function() {\n // TODO: Unhook all event handlers\n};\n\nTraceManager.prototype.updateFilter = function(group, keys) {\n\n if (typeof(keys) === \"undefined\" || keys === null) {\n \n this.gd.data = JSON.parse(JSON.stringify(this.origData));\n \n } else {\n \n var traces = [];\n for (var i = 0; i < this.origData.length; i++) {\n var trace = this.origData[i];\n if (!trace.key || trace.set !== group) {\n continue;\n }\n var matchFunc = getMatchFunc(trace);\n var matches = matchFunc(trace.key, keys);\n \n if (matches.length > 0) {\n if (!trace._isSimpleKey) {\n // subsetArrayAttrs doesn't mutate trace (it makes a modified clone)\n trace = subsetArrayAttrs(trace, matches);\n }\n traces.push(trace);\n }\n }\n }\n \n this.gd.data = traces;\n Plotly.redraw(this.gd);\n \n // NOTE: we purposely do _not_ restore selection(s), since on filter,\n // axis likely will update, changing the pixel -> data mapping, leading \n // to a likely mismatch in the brush outline and highlighted marks\n \n};\n\nTraceManager.prototype.updateSelection = function(group, keys) {\n \n if (keys !== null && !Array.isArray(keys)) {\n throw new Error(\"Invalid keys argument; null or array expected\");\n }\n \n // if selection has been cleared, or if this is transient\n // selection, delete the \"selection traces\"\n var nNewTraces = this.gd.data.length - this.origData.length;\n if (keys === null || !this.highlight.persistent && nNewTraces > 0) {\n var tracesToRemove = [];\n for (var i = 0; i < this.gd.data.length; i++) {\n if (this.gd.data[i]._isCrosstalkTrace) tracesToRemove.push(i);\n }\n Plotly.deleteTraces(this.gd, tracesToRemove);\n this.groupSelections[group] = keys;\n } else {\n // add to the groupSelection, rather than overwriting it\n // TODO: can this be removed?\n this.groupSelections[group] = this.groupSelections[group] || [];\n for (var i = 0; i < keys.length; i++) {\n var k = keys[i];\n if (this.groupSelections[group].indexOf(k) < 0) {\n this.groupSelections[group].push(k);\n }\n }\n }\n \n if (keys === null) {\n \n Plotly.restyle(this.gd, {\"opacity\": this.origOpacity});\n \n } else if (keys.length >= 1) {\n \n // placeholder for new \"selection traces\"\n var traces = [];\n // this variable is set in R/highlight.R\n var selectionColour = crosstalk.group(group).var(\"plotlySelectionColour\").get() || \n this.highlight.color[0];\n\n for (var i = 0; i < this.origData.length; i++) {\n // TODO: try using Lib.extendFlat() as done in \n // https://github.com/plotly/plotly.js/pull/1136 \n var trace = JSON.parse(JSON.stringify(this.gd.data[i]));\n if (!trace.key || trace.set !== group) {\n continue;\n }\n // Get sorted array of matching indices in trace.key\n var matchFunc = getMatchFunc(trace);\n var matches = matchFunc(trace.key, keys);\n \n if (matches.length > 0) {\n // If this is a \"simple\" key, that means select the entire trace\n if (!trace._isSimpleKey) {\n trace = subsetArrayAttrs(trace, matches);\n }\n // reach into the full trace object so we can properly reflect the \n // selection attributes in every view\n var d = this.gd._fullData[i];\n \n /* \n / Recursively inherit selection attributes from various sources, \n / in order of preference:\n / (1) official plotly.js selected attribute\n / (2) highlight(selected = attrs_selected(...))\n */\n // TODO: it would be neat to have a dropdown to dynamically specify these!\n $.extend(true, trace, this.highlight.selected);\n \n // if it is defined, override color with the \"dynamic brush color\"\"\n if (d.marker) {\n trace.marker = trace.marker || {};\n trace.marker.color = selectionColour || trace.marker.color || d.marker.color;\n }\n if (d.line) {\n trace.line = trace.line || {};\n trace.line.color = selectionColour || trace.line.color || d.line.color;\n }\n if (d.textfont) {\n trace.textfont = trace.textfont || {};\n trace.textfont.color = selectionColour || trace.textfont.color || d.textfont.color;\n }\n if (d.fillcolor) {\n // TODO: should selectionColour inherit alpha from the existing fillcolor?\n trace.fillcolor = selectionColour || trace.fillcolor || d.fillcolor;\n }\n // attach a sensible name/legendgroup\n trace.name = trace.name || keys.join(\"
\");\n trace.legendgroup = trace.legendgroup || keys.join(\"
\");\n \n // keep track of mapping between this new trace and the trace it targets\n // (necessary for updating frames to reflect the selection traces)\n trace._originalIndex = i;\n trace._newIndex = this.gd._fullData.length + traces.length;\n trace._isCrosstalkTrace = true;\n traces.push(trace);\n }\n }\n \n if (traces.length > 0) {\n \n Plotly.addTraces(this.gd, traces).then(function(gd) {\n // incrementally add selection traces to frames\n // (this is heavily inspired by Plotly.Plots.modifyFrames() \n // in src/plots/plots.js)\n var _hash = gd._transitionData._frameHash;\n var _frames = gd._transitionData._frames || [];\n \n for (var i = 0; i < _frames.length; i++) {\n \n // add to _frames[i].traces *if* this frame references selected trace(s)\n var newIndices = [];\n for (var j = 0; j < traces.length; j++) {\n var tr = traces[j];\n if (_frames[i].traces.indexOf(tr._originalIndex) > -1) {\n newIndices.push(tr._newIndex);\n _frames[i].traces.push(tr._newIndex);\n }\n }\n \n // nothing to do...\n if (newIndices.length === 0) {\n continue;\n }\n \n var ctr = 0;\n var nFrameTraces = _frames[i].data.length;\n \n for (var j = 0; j < nFrameTraces; j++) {\n var frameTrace = _frames[i].data[j];\n if (!frameTrace.key || frameTrace.set !== group) {\n continue;\n }\n \n var matchFunc = getMatchFunc(frameTrace);\n var matches = matchFunc(frameTrace.key, keys);\n \n if (matches.length > 0) {\n if (!trace._isSimpleKey) {\n frameTrace = subsetArrayAttrs(frameTrace, matches);\n }\n var d = gd._fullData[newIndices[ctr]];\n if (d.marker) {\n frameTrace.marker = d.marker;\n }\n if (d.line) {\n frameTrace.line = d.line;\n }\n if (d.textfont) {\n frameTrace.textfont = d.textfont;\n }\n ctr = ctr + 1;\n _frames[i].data.push(frameTrace);\n }\n }\n \n // update gd._transitionData._frameHash\n _hash[_frames[i].name] = _frames[i];\n }\n \n });\n \n // dim traces that have a set matching the set of selection sets\n var tracesToDim = [],\n opacities = [],\n sets = Object.keys(this.groupSelections),\n n = this.origData.length;\n \n for (var i = 0; i < n; i++) {\n var opacity = this.origOpacity[i] || 1;\n // have we already dimmed this trace? Or is this even worth doing?\n if (opacity !== this.gd._fullData[i].opacity || this.highlight.opacityDim === 1) {\n continue;\n }\n // is this set an element of the set of selection sets?\n var matches = findMatches(sets, [this.gd.data[i].set]);\n if (matches.length) {\n tracesToDim.push(i);\n opacities.push(opacity * this.highlight.opacityDim);\n }\n }\n \n if (tracesToDim.length > 0) {\n Plotly.restyle(this.gd, {\"opacity\": opacities}, tracesToDim);\n // turn off the selected/unselected API\n Plotly.restyle(this.gd, {\"selectedpoints\": null});\n }\n \n }\n \n }\n};\n\n/* \nNote: in all of these match functions, we assume needleSet (i.e. the selected keys)\nis a 1D (or flat) array. The real difference is the meaning of haystack.\nfindMatches() does the usual thing you'd expect for \nlinked brushing on a scatterplot matrix. findSimpleMatches() returns a match iff \nhaystack is a subset of the needleSet. findNestedMatches() returns \n*/\n\nfunction getMatchFunc(trace) {\n return (trace._isNestedKey) ? findNestedMatches : \n (trace._isSimpleKey) ? findSimpleMatches : findMatches;\n}\n\n// find matches for \"flat\" keys\nfunction findMatches(haystack, needleSet) {\n var matches = [];\n haystack.forEach(function(obj, i) {\n if (obj === null || needleSet.indexOf(obj) >= 0) {\n matches.push(i);\n }\n });\n return matches;\n}\n\n// find matches for \"simple\" keys\nfunction findSimpleMatches(haystack, needleSet) {\n var match = haystack.every(function(val) {\n return val === null || needleSet.indexOf(val) >= 0;\n });\n // yes, this doesn't make much sense other than conforming \n // to the output type of the other match functions\n return (match) ? [0] : []\n}\n\n// find matches for a \"nested\" haystack (2D arrays)\nfunction findNestedMatches(haystack, needleSet) {\n var matches = [];\n for (var i = 0; i < haystack.length; i++) {\n var hay = haystack[i];\n var match = hay.every(function(val) { \n return val === null || needleSet.indexOf(val) >= 0; \n });\n if (match) {\n matches.push(i);\n }\n }\n return matches;\n}\n\nfunction isPlainObject(obj) {\n return (\n Object.prototype.toString.call(obj) === '[object Object]' &&\n Object.getPrototypeOf(obj) === Object.prototype\n );\n}\n\nfunction subsetArrayAttrs(obj, indices) {\n var newObj = {};\n Object.keys(obj).forEach(function(k) {\n var val = obj[k];\n\n if (k.charAt(0) === \"_\") {\n newObj[k] = val;\n } else if (k === \"transforms\" && Array.isArray(val)) {\n newObj[k] = val.map(function(transform) {\n return subsetArrayAttrs(transform, indices);\n });\n } else if (k === \"colorscale\" && Array.isArray(val)) {\n newObj[k] = val;\n } else if (isPlainObject(val)) {\n newObj[k] = subsetArrayAttrs(val, indices);\n } else if (Array.isArray(val)) {\n newObj[k] = subsetArray(val, indices);\n } else {\n newObj[k] = val;\n }\n });\n return newObj;\n}\n\nfunction subsetArray(arr, indices) {\n var result = [];\n for (var i = 0; i < indices.length; i++) {\n result.push(arr[indices[i]]);\n }\n return result;\n}\n\n// Convenience function for removing plotly's brush \nfunction removeBrush(el) {\n var outlines = el.querySelectorAll(\".select-outline\");\n for (var i = 0; i < outlines.length; i++) {\n outlines[i].remove();\n }\n}\n\n\n// https://davidwalsh.name/javascript-debounce-function\n\n// Returns a function, that, as long as it continues to be invoked, will not\n// be triggered. The function will be called after it stops being called for\n// N milliseconds. If `immediate` is passed, trigger the function on the\n// leading edge, instead of the trailing.\nfunction debounce(func, wait, immediate) {\n\tvar timeout;\n\treturn function() {\n\t\tvar context = this, args = arguments;\n\t\tvar later = function() {\n\t\t\ttimeout = null;\n\t\t\tif (!immediate) func.apply(context, args);\n\t\t};\n\t\tvar callNow = immediate && !timeout;\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(later, wait);\n\t\tif (callNow) func.apply(context, args);\n\t};\n};\n\nmodule.exports = widgetDefinition"]} \ No newline at end of file diff --git a/theSrc/scripts/widgetdefinition.js b/theSrc/scripts/widgetdefinition.js index 9bbc64f47b..130c45f072 100644 --- a/theSrc/scripts/widgetdefinition.js +++ b/theSrc/scripts/widgetdefinition.js @@ -58,6 +58,9 @@ const widgetDefinition = { } var graphDiv = document.getElementById(el.id); + + // Used by Displayr to determine when widget is ready to be snapshot for testing + graphDiv.setAttribute("rhtmlwidget-status", "not-ready"); // TODO: move the control panel injection strategy inside here... HTMLWidgets.addPostRenderHandler(function() { @@ -553,7 +556,8 @@ const widgetDefinition = { } // end of selectionChange graphDiv.on("plotly_afterplot", function() { - console.log("-------------plotly done!-----------------------------------------------------"); + // Used by Displayr to determine when widget is ready to be snapshot for testing + graphDiv.setAttribute("rhtmlwidget-status", "ready"); }); } // end of renderValue } From 00e6761d75639c54bb4d162a097434442dfea194 Mon Sep 17 00:00:00 2001 From: Justin Yap Date: Wed, 6 Oct 2021 14:58:43 +1100 Subject: [PATCH 4/4] wording change --- inst/htmlwidgets/plotly.js | 2 +- inst/htmlwidgets/plotly.js.map | 2 +- theSrc/scripts/widgetdefinition.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/inst/htmlwidgets/plotly.js b/inst/htmlwidgets/plotly.js index 5c12bb79f7..6dc46fbb40 100644 --- a/inst/htmlwidgets/plotly.js +++ b/inst/htmlwidgets/plotly.js @@ -1,2 +1,2 @@ -!function i(r,o,n){function a(e,t){if(!o[e]){if(!r[e]){var l="function"==typeof require&&require;if(!t&&l)return l(e,!0);if(s)return s(e,!0);throw(l=new Error("Cannot find module '"+e+"'")).code="MODULE_NOT_FOUND",l}l=o[e]={exports:{}},r[e][0].call(l.exports,function(t){return a(r[e][1][t]||t)},l,l.exports,i,r,o,n)}return o[e].exports}for(var s="function"==typeof require&&require,t=0;t"),g.legendgroup=g.legendgroup||p.join("
"),g._originalIndex=l,g._newIndex=this.gd._fullData.length+d.length,g._isCrosstalkTrace=!0,d.push(g))}if(0"),g.legendgroup=g.legendgroup||p.join("
"),g._originalIndex=l,g._newIndex=this.gd._fullData.length+d.length,g._isCrosstalkTrace=!0,d.push(g))}if(0 0) {\n var ev = JSON.stringify(event);\n for (var i = 0; i < selectionHistory.length; i++) {\n var sel = JSON.stringify(selectionHistory[i]);\n if (sel == ev) {\n return;\n }\n }\n }\n \n // accumulate history for persistent selection\n if (!x.highlight.persistent) {\n selectionHistory = [event];\n } else {\n selectionHistory.push(event);\n }\n crosstalk.var(\"plotlySelectionHistory\").set(selectionHistory);\n \n // do the actual updating of traces, frames, and the selectize widget\n traceManager.updateSelection(set, e.value);\n // https://github.com/selectize/selectize.js/blob/master/docs/api.md#methods_items\n if (x.selectize) {\n if (!x.highlight.persistent || e.value === null) {\n selectize.clear(true);\n }\n selectize.addItems(e.value, true);\n selectize.close();\n }\n }\n selection.on(\"change\", selectionChange);\n \n // Set a crosstalk variable selection value, triggering an update\n var turnOn = function(e) {\n if (e) {\n var selectedKeys = pointsToKeys(e.points);\n // Keys are group names, values are array of selected keys from group.\n for (var set in selectedKeys) {\n if (selectedKeys.hasOwnProperty(set)) {\n selection.set(selectedKeys[set].value, {sender: el});\n }\n }\n }\n };\n if (x.highlight.debounce > 0) {\n turnOn = debounce(turnOn, x.highlight.debounce);\n }\n graphDiv.on(x.highlight.on, turnOn);\n \n graphDiv.on(x.highlight.off, function turnOff(e) {\n // remove any visual clues\n removeBrush(el);\n // remove any selection history\n crosstalk.var(\"plotlySelectionHistory\").set(null);\n // trigger the actual removal of selection traces\n selection.set(null, {sender: el});\n });\n \n // register a callback for selectize so that there is bi-directional\n // communication between the widget and direct manipulation events\n if (x.selectize) {\n var selectizeID = Object.keys(x.selectize)[i];\n var items = x.selectize[selectizeID].items;\n var first = [{value: \"\", label: \"(All)\"}];\n var opts = {\n options: first.concat(items),\n searchField: \"label\",\n valueField: \"value\",\n labelField: \"label\",\n maxItems: 50\n };\n var select = $(\"#\" + selectizeID).find(\"select\")[0];\n var selectize = $(select).selectize(opts)[0].selectize;\n // NOTE: this callback is triggered when *directly* altering \n // dropdown items\n selectize.on(\"change\", function() {\n var currentItems = traceManager.groupSelections[set] || [];\n if (!x.highlight.persistent) {\n removeBrush(el);\n for (var i = 0; i < currentItems.length; i++) {\n selectize.removeItem(currentItems[i], true);\n }\n }\n var newItems = selectize.items.filter(function(idx) { \n return currentItems.indexOf(idx) < 0;\n });\n if (newItems.length > 0) {\n traceManager.updateSelection(set, newItems);\n } else {\n // Item has been removed...\n // TODO: this logic won't work for dynamically changing palette \n traceManager.updateSelection(set, null);\n traceManager.updateSelection(set, selectize.items);\n }\n });\n }\n } // end of selectionChange\n\n graphDiv.on(\"plotly_afterplot\", function() {\n // Used by Displayr to determine when widget is ready to be snapshot for testing\n graphDiv.setAttribute(\"rhtmlwidget-status\", \"ready\");\n });\n } // end of renderValue\n}\n\n/**\n * @param graphDiv The Plotly graph div\n * @param highlight An object with options for updating selection(s)\n */\nfunction TraceManager(graphDiv, highlight) {\n // The Plotly graph div\n this.gd = graphDiv;\n\n // Preserve the original data.\n // TODO: try using Lib.extendFlat() as done in \n // https://github.com/plotly/plotly.js/pull/1136 \n this.origData = JSON.parse(JSON.stringify(graphDiv.data));\n \n // avoid doing this over and over\n this.origOpacity = [];\n for (var i = 0; i < this.origData.length; i++) {\n this.origOpacity[i] = this.origData[i].opacity === 0 ? 0 : (this.origData[i].opacity || 1);\n }\n\n // key: group name, value: null or array of keys representing the\n // most recently received selection for that group.\n this.groupSelections = {};\n \n // selection parameters (e.g., transient versus persistent selection)\n this.highlight = highlight;\n}\n\nTraceManager.prototype.close = function() {\n // TODO: Unhook all event handlers\n};\n\nTraceManager.prototype.updateFilter = function(group, keys) {\n\n if (typeof(keys) === \"undefined\" || keys === null) {\n \n this.gd.data = JSON.parse(JSON.stringify(this.origData));\n \n } else {\n \n var traces = [];\n for (var i = 0; i < this.origData.length; i++) {\n var trace = this.origData[i];\n if (!trace.key || trace.set !== group) {\n continue;\n }\n var matchFunc = getMatchFunc(trace);\n var matches = matchFunc(trace.key, keys);\n \n if (matches.length > 0) {\n if (!trace._isSimpleKey) {\n // subsetArrayAttrs doesn't mutate trace (it makes a modified clone)\n trace = subsetArrayAttrs(trace, matches);\n }\n traces.push(trace);\n }\n }\n }\n \n this.gd.data = traces;\n Plotly.redraw(this.gd);\n \n // NOTE: we purposely do _not_ restore selection(s), since on filter,\n // axis likely will update, changing the pixel -> data mapping, leading \n // to a likely mismatch in the brush outline and highlighted marks\n \n};\n\nTraceManager.prototype.updateSelection = function(group, keys) {\n \n if (keys !== null && !Array.isArray(keys)) {\n throw new Error(\"Invalid keys argument; null or array expected\");\n }\n \n // if selection has been cleared, or if this is transient\n // selection, delete the \"selection traces\"\n var nNewTraces = this.gd.data.length - this.origData.length;\n if (keys === null || !this.highlight.persistent && nNewTraces > 0) {\n var tracesToRemove = [];\n for (var i = 0; i < this.gd.data.length; i++) {\n if (this.gd.data[i]._isCrosstalkTrace) tracesToRemove.push(i);\n }\n Plotly.deleteTraces(this.gd, tracesToRemove);\n this.groupSelections[group] = keys;\n } else {\n // add to the groupSelection, rather than overwriting it\n // TODO: can this be removed?\n this.groupSelections[group] = this.groupSelections[group] || [];\n for (var i = 0; i < keys.length; i++) {\n var k = keys[i];\n if (this.groupSelections[group].indexOf(k) < 0) {\n this.groupSelections[group].push(k);\n }\n }\n }\n \n if (keys === null) {\n \n Plotly.restyle(this.gd, {\"opacity\": this.origOpacity});\n \n } else if (keys.length >= 1) {\n \n // placeholder for new \"selection traces\"\n var traces = [];\n // this variable is set in R/highlight.R\n var selectionColour = crosstalk.group(group).var(\"plotlySelectionColour\").get() || \n this.highlight.color[0];\n\n for (var i = 0; i < this.origData.length; i++) {\n // TODO: try using Lib.extendFlat() as done in \n // https://github.com/plotly/plotly.js/pull/1136 \n var trace = JSON.parse(JSON.stringify(this.gd.data[i]));\n if (!trace.key || trace.set !== group) {\n continue;\n }\n // Get sorted array of matching indices in trace.key\n var matchFunc = getMatchFunc(trace);\n var matches = matchFunc(trace.key, keys);\n \n if (matches.length > 0) {\n // If this is a \"simple\" key, that means select the entire trace\n if (!trace._isSimpleKey) {\n trace = subsetArrayAttrs(trace, matches);\n }\n // reach into the full trace object so we can properly reflect the \n // selection attributes in every view\n var d = this.gd._fullData[i];\n \n /* \n / Recursively inherit selection attributes from various sources, \n / in order of preference:\n / (1) official plotly.js selected attribute\n / (2) highlight(selected = attrs_selected(...))\n */\n // TODO: it would be neat to have a dropdown to dynamically specify these!\n $.extend(true, trace, this.highlight.selected);\n \n // if it is defined, override color with the \"dynamic brush color\"\"\n if (d.marker) {\n trace.marker = trace.marker || {};\n trace.marker.color = selectionColour || trace.marker.color || d.marker.color;\n }\n if (d.line) {\n trace.line = trace.line || {};\n trace.line.color = selectionColour || trace.line.color || d.line.color;\n }\n if (d.textfont) {\n trace.textfont = trace.textfont || {};\n trace.textfont.color = selectionColour || trace.textfont.color || d.textfont.color;\n }\n if (d.fillcolor) {\n // TODO: should selectionColour inherit alpha from the existing fillcolor?\n trace.fillcolor = selectionColour || trace.fillcolor || d.fillcolor;\n }\n // attach a sensible name/legendgroup\n trace.name = trace.name || keys.join(\"
\");\n trace.legendgroup = trace.legendgroup || keys.join(\"
\");\n \n // keep track of mapping between this new trace and the trace it targets\n // (necessary for updating frames to reflect the selection traces)\n trace._originalIndex = i;\n trace._newIndex = this.gd._fullData.length + traces.length;\n trace._isCrosstalkTrace = true;\n traces.push(trace);\n }\n }\n \n if (traces.length > 0) {\n \n Plotly.addTraces(this.gd, traces).then(function(gd) {\n // incrementally add selection traces to frames\n // (this is heavily inspired by Plotly.Plots.modifyFrames() \n // in src/plots/plots.js)\n var _hash = gd._transitionData._frameHash;\n var _frames = gd._transitionData._frames || [];\n \n for (var i = 0; i < _frames.length; i++) {\n \n // add to _frames[i].traces *if* this frame references selected trace(s)\n var newIndices = [];\n for (var j = 0; j < traces.length; j++) {\n var tr = traces[j];\n if (_frames[i].traces.indexOf(tr._originalIndex) > -1) {\n newIndices.push(tr._newIndex);\n _frames[i].traces.push(tr._newIndex);\n }\n }\n \n // nothing to do...\n if (newIndices.length === 0) {\n continue;\n }\n \n var ctr = 0;\n var nFrameTraces = _frames[i].data.length;\n \n for (var j = 0; j < nFrameTraces; j++) {\n var frameTrace = _frames[i].data[j];\n if (!frameTrace.key || frameTrace.set !== group) {\n continue;\n }\n \n var matchFunc = getMatchFunc(frameTrace);\n var matches = matchFunc(frameTrace.key, keys);\n \n if (matches.length > 0) {\n if (!trace._isSimpleKey) {\n frameTrace = subsetArrayAttrs(frameTrace, matches);\n }\n var d = gd._fullData[newIndices[ctr]];\n if (d.marker) {\n frameTrace.marker = d.marker;\n }\n if (d.line) {\n frameTrace.line = d.line;\n }\n if (d.textfont) {\n frameTrace.textfont = d.textfont;\n }\n ctr = ctr + 1;\n _frames[i].data.push(frameTrace);\n }\n }\n \n // update gd._transitionData._frameHash\n _hash[_frames[i].name] = _frames[i];\n }\n \n });\n \n // dim traces that have a set matching the set of selection sets\n var tracesToDim = [],\n opacities = [],\n sets = Object.keys(this.groupSelections),\n n = this.origData.length;\n \n for (var i = 0; i < n; i++) {\n var opacity = this.origOpacity[i] || 1;\n // have we already dimmed this trace? Or is this even worth doing?\n if (opacity !== this.gd._fullData[i].opacity || this.highlight.opacityDim === 1) {\n continue;\n }\n // is this set an element of the set of selection sets?\n var matches = findMatches(sets, [this.gd.data[i].set]);\n if (matches.length) {\n tracesToDim.push(i);\n opacities.push(opacity * this.highlight.opacityDim);\n }\n }\n \n if (tracesToDim.length > 0) {\n Plotly.restyle(this.gd, {\"opacity\": opacities}, tracesToDim);\n // turn off the selected/unselected API\n Plotly.restyle(this.gd, {\"selectedpoints\": null});\n }\n \n }\n \n }\n};\n\n/* \nNote: in all of these match functions, we assume needleSet (i.e. the selected keys)\nis a 1D (or flat) array. The real difference is the meaning of haystack.\nfindMatches() does the usual thing you'd expect for \nlinked brushing on a scatterplot matrix. findSimpleMatches() returns a match iff \nhaystack is a subset of the needleSet. findNestedMatches() returns \n*/\n\nfunction getMatchFunc(trace) {\n return (trace._isNestedKey) ? findNestedMatches : \n (trace._isSimpleKey) ? findSimpleMatches : findMatches;\n}\n\n// find matches for \"flat\" keys\nfunction findMatches(haystack, needleSet) {\n var matches = [];\n haystack.forEach(function(obj, i) {\n if (obj === null || needleSet.indexOf(obj) >= 0) {\n matches.push(i);\n }\n });\n return matches;\n}\n\n// find matches for \"simple\" keys\nfunction findSimpleMatches(haystack, needleSet) {\n var match = haystack.every(function(val) {\n return val === null || needleSet.indexOf(val) >= 0;\n });\n // yes, this doesn't make much sense other than conforming \n // to the output type of the other match functions\n return (match) ? [0] : []\n}\n\n// find matches for a \"nested\" haystack (2D arrays)\nfunction findNestedMatches(haystack, needleSet) {\n var matches = [];\n for (var i = 0; i < haystack.length; i++) {\n var hay = haystack[i];\n var match = hay.every(function(val) { \n return val === null || needleSet.indexOf(val) >= 0; \n });\n if (match) {\n matches.push(i);\n }\n }\n return matches;\n}\n\nfunction isPlainObject(obj) {\n return (\n Object.prototype.toString.call(obj) === '[object Object]' &&\n Object.getPrototypeOf(obj) === Object.prototype\n );\n}\n\nfunction subsetArrayAttrs(obj, indices) {\n var newObj = {};\n Object.keys(obj).forEach(function(k) {\n var val = obj[k];\n\n if (k.charAt(0) === \"_\") {\n newObj[k] = val;\n } else if (k === \"transforms\" && Array.isArray(val)) {\n newObj[k] = val.map(function(transform) {\n return subsetArrayAttrs(transform, indices);\n });\n } else if (k === \"colorscale\" && Array.isArray(val)) {\n newObj[k] = val;\n } else if (isPlainObject(val)) {\n newObj[k] = subsetArrayAttrs(val, indices);\n } else if (Array.isArray(val)) {\n newObj[k] = subsetArray(val, indices);\n } else {\n newObj[k] = val;\n }\n });\n return newObj;\n}\n\nfunction subsetArray(arr, indices) {\n var result = [];\n for (var i = 0; i < indices.length; i++) {\n result.push(arr[indices[i]]);\n }\n return result;\n}\n\n// Convenience function for removing plotly's brush \nfunction removeBrush(el) {\n var outlines = el.querySelectorAll(\".select-outline\");\n for (var i = 0; i < outlines.length; i++) {\n outlines[i].remove();\n }\n}\n\n\n// https://davidwalsh.name/javascript-debounce-function\n\n// Returns a function, that, as long as it continues to be invoked, will not\n// be triggered. The function will be called after it stops being called for\n// N milliseconds. If `immediate` is passed, trigger the function on the\n// leading edge, instead of the trailing.\nfunction debounce(func, wait, immediate) {\n\tvar timeout;\n\treturn function() {\n\t\tvar context = this, args = arguments;\n\t\tvar later = function() {\n\t\t\ttimeout = null;\n\t\t\tif (!immediate) func.apply(context, args);\n\t\t};\n\t\tvar callNow = immediate && !timeout;\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(later, wait);\n\t\tif (callNow) func.apply(context, args);\n\t};\n};\n\nmodule.exports = widgetDefinition"]} \ No newline at end of file +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","theSrc/scripts/plotly.js","theSrc/scripts/widgetdefinition.js"],"names":["r","e","n","t","o","i","f","c","require","u","a","Error","code","p","exports","call","length","1","module","_widgetdefinition","HTMLWidgets","widget","_widgetdefinition2","default","widgetDefinition","name","type","initialize","el","width","height","resize","instance","autosize","Plotly","relayout","renderValue","x","lay","layout","crosstalk","var","set","highlight","window","PLOTLYENV","BASE_URL","base_url","persistent","onmousemove","event","shiftKey","persistentShift","graphDiv","document","getElementById","id","setAttribute","addPostRenderHandler","modebars","querySelectorAll","style","zIndex","selectize","dynamic","plotly","pickerDiv","flex","createElement","class","pickerInput","placeholder","pickerLabel","for","innerHTML","appendChild","ids","Object","keys","container","label","group","selectDiv","select","multiple","parentElement","insertBefore","picker","$","colors","color","opts","value","showColour","palette","allowedCols","join","colourpicker","changeDelay","grps","ctGroups","on","eventDataWithKey","eventData","undefined","hasOwnProperty","points","map","pt","obj","curveNumber","pointNumber","y","z","customdata","attrsToAttach","trace","data","_isSimpleKey","key","attr","Array","isArray","pointNumbers","idx","purge","plot","then","shinyMode","Shiny","addCustomMessageHandler","msg","gd","method","args","concat","apply","react","mapboxIDs","_fullLayout","_subplots","mapbox","_fitBounds","_subplot","fitBounds","bounds","options","eventClearMap","eventDataFunctionMap","legendEventData","d","legendgroup","legendgrps","traces","push","setInputValue","plotly_deselect","plotly_unhover","plotly_doubleclick","evt","input","source","priority","plotly_click","plotly_sunburstclick","plotly_hover","plotly_selected","plotly_selecting","plotly_brushed","range","lassoPoints","plotly_brushing","plotly_legendclick","plotly_legenddoubleclick","plotly_clickannotation","fullAnnotation","shinyEvents","eventDataPreProcessor","JSON","stringify","traceManager","TraceManager","allSets","curveIdx","newSet","indexOf","selection","SelectionHandle","FilterHandle","removeBrush","updateFilter","prototype","diff","this","filter","oldValue","selectionHistory","get","receiverID","plotlySelectionColour","ev","updateSelection","clear","addItems","close","selectizeID","turnOn","selectedKeys","keysBySet","keyFlat","ptNum","_isNestedKey","pointsToKeys","sender","debounce","func","wait","immediate","timeout","context","arguments","callNow","clearTimeout","setTimeout","off","items","searchField","valueField","labelField","maxItems","find","currentItems","groupSelections","removeItem","newItems","origData","parse","origOpacity","opacity","getMatchFunc","findNestedMatches","findSimpleMatches","findMatches","haystack","needleSet","matches","forEach","every","val","subsetArrayAttrs","indices","newObj","k","charAt","transform","toString","getPrototypeOf","arr","result","subsetArray","outlines","remove","matchFunc","redraw","nNewTraces","tracesToRemove","_isCrosstalkTrace","deleteTraces","restyle","selectionColour","_fullData","extend","selected","marker","line","textfont","fillcolor","_originalIndex","_newIndex","addTraces","_hash","_transitionData","_frameHash","_frames","newIndices","j","tr","ctr","nFrameTraces","frameTrace","tracesToDim","opacities","sets","opacityDim","selectedpoints"],"mappings":"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","file":"plotly.js","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i 0) {\n var ev = JSON.stringify(event);\n for (var i = 0; i < selectionHistory.length; i++) {\n var sel = JSON.stringify(selectionHistory[i]);\n if (sel == ev) {\n return;\n }\n }\n }\n \n // accumulate history for persistent selection\n if (!x.highlight.persistent) {\n selectionHistory = [event];\n } else {\n selectionHistory.push(event);\n }\n crosstalk.var(\"plotlySelectionHistory\").set(selectionHistory);\n \n // do the actual updating of traces, frames, and the selectize widget\n traceManager.updateSelection(set, e.value);\n // https://github.com/selectize/selectize.js/blob/master/docs/api.md#methods_items\n if (x.selectize) {\n if (!x.highlight.persistent || e.value === null) {\n selectize.clear(true);\n }\n selectize.addItems(e.value, true);\n selectize.close();\n }\n }\n selection.on(\"change\", selectionChange);\n \n // Set a crosstalk variable selection value, triggering an update\n var turnOn = function(e) {\n if (e) {\n var selectedKeys = pointsToKeys(e.points);\n // Keys are group names, values are array of selected keys from group.\n for (var set in selectedKeys) {\n if (selectedKeys.hasOwnProperty(set)) {\n selection.set(selectedKeys[set].value, {sender: el});\n }\n }\n }\n };\n if (x.highlight.debounce > 0) {\n turnOn = debounce(turnOn, x.highlight.debounce);\n }\n graphDiv.on(x.highlight.on, turnOn);\n \n graphDiv.on(x.highlight.off, function turnOff(e) {\n // remove any visual clues\n removeBrush(el);\n // remove any selection history\n crosstalk.var(\"plotlySelectionHistory\").set(null);\n // trigger the actual removal of selection traces\n selection.set(null, {sender: el});\n });\n \n // register a callback for selectize so that there is bi-directional\n // communication between the widget and direct manipulation events\n if (x.selectize) {\n var selectizeID = Object.keys(x.selectize)[i];\n var items = x.selectize[selectizeID].items;\n var first = [{value: \"\", label: \"(All)\"}];\n var opts = {\n options: first.concat(items),\n searchField: \"label\",\n valueField: \"value\",\n labelField: \"label\",\n maxItems: 50\n };\n var select = $(\"#\" + selectizeID).find(\"select\")[0];\n var selectize = $(select).selectize(opts)[0].selectize;\n // NOTE: this callback is triggered when *directly* altering \n // dropdown items\n selectize.on(\"change\", function() {\n var currentItems = traceManager.groupSelections[set] || [];\n if (!x.highlight.persistent) {\n removeBrush(el);\n for (var i = 0; i < currentItems.length; i++) {\n selectize.removeItem(currentItems[i], true);\n }\n }\n var newItems = selectize.items.filter(function(idx) { \n return currentItems.indexOf(idx) < 0;\n });\n if (newItems.length > 0) {\n traceManager.updateSelection(set, newItems);\n } else {\n // Item has been removed...\n // TODO: this logic won't work for dynamically changing palette \n traceManager.updateSelection(set, null);\n traceManager.updateSelection(set, selectize.items);\n }\n });\n }\n } // end of selectionChange\n\n graphDiv.on(\"plotly_afterplot\", function() {\n // Used by Displayr to determine when widget is ready to be snapshot for testing\n graphDiv.setAttribute(\"rhtmlwidget-status\", \"ready\");\n });\n } // end of renderValue\n}\n\n/**\n * @param graphDiv The Plotly graph div\n * @param highlight An object with options for updating selection(s)\n */\nfunction TraceManager(graphDiv, highlight) {\n // The Plotly graph div\n this.gd = graphDiv;\n\n // Preserve the original data.\n // TODO: try using Lib.extendFlat() as done in \n // https://github.com/plotly/plotly.js/pull/1136 \n this.origData = JSON.parse(JSON.stringify(graphDiv.data));\n \n // avoid doing this over and over\n this.origOpacity = [];\n for (var i = 0; i < this.origData.length; i++) {\n this.origOpacity[i] = this.origData[i].opacity === 0 ? 0 : (this.origData[i].opacity || 1);\n }\n\n // key: group name, value: null or array of keys representing the\n // most recently received selection for that group.\n this.groupSelections = {};\n \n // selection parameters (e.g., transient versus persistent selection)\n this.highlight = highlight;\n}\n\nTraceManager.prototype.close = function() {\n // TODO: Unhook all event handlers\n};\n\nTraceManager.prototype.updateFilter = function(group, keys) {\n\n if (typeof(keys) === \"undefined\" || keys === null) {\n \n this.gd.data = JSON.parse(JSON.stringify(this.origData));\n \n } else {\n \n var traces = [];\n for (var i = 0; i < this.origData.length; i++) {\n var trace = this.origData[i];\n if (!trace.key || trace.set !== group) {\n continue;\n }\n var matchFunc = getMatchFunc(trace);\n var matches = matchFunc(trace.key, keys);\n \n if (matches.length > 0) {\n if (!trace._isSimpleKey) {\n // subsetArrayAttrs doesn't mutate trace (it makes a modified clone)\n trace = subsetArrayAttrs(trace, matches);\n }\n traces.push(trace);\n }\n }\n }\n \n this.gd.data = traces;\n Plotly.redraw(this.gd);\n \n // NOTE: we purposely do _not_ restore selection(s), since on filter,\n // axis likely will update, changing the pixel -> data mapping, leading \n // to a likely mismatch in the brush outline and highlighted marks\n \n};\n\nTraceManager.prototype.updateSelection = function(group, keys) {\n \n if (keys !== null && !Array.isArray(keys)) {\n throw new Error(\"Invalid keys argument; null or array expected\");\n }\n \n // if selection has been cleared, or if this is transient\n // selection, delete the \"selection traces\"\n var nNewTraces = this.gd.data.length - this.origData.length;\n if (keys === null || !this.highlight.persistent && nNewTraces > 0) {\n var tracesToRemove = [];\n for (var i = 0; i < this.gd.data.length; i++) {\n if (this.gd.data[i]._isCrosstalkTrace) tracesToRemove.push(i);\n }\n Plotly.deleteTraces(this.gd, tracesToRemove);\n this.groupSelections[group] = keys;\n } else {\n // add to the groupSelection, rather than overwriting it\n // TODO: can this be removed?\n this.groupSelections[group] = this.groupSelections[group] || [];\n for (var i = 0; i < keys.length; i++) {\n var k = keys[i];\n if (this.groupSelections[group].indexOf(k) < 0) {\n this.groupSelections[group].push(k);\n }\n }\n }\n \n if (keys === null) {\n \n Plotly.restyle(this.gd, {\"opacity\": this.origOpacity});\n \n } else if (keys.length >= 1) {\n \n // placeholder for new \"selection traces\"\n var traces = [];\n // this variable is set in R/highlight.R\n var selectionColour = crosstalk.group(group).var(\"plotlySelectionColour\").get() || \n this.highlight.color[0];\n\n for (var i = 0; i < this.origData.length; i++) {\n // TODO: try using Lib.extendFlat() as done in \n // https://github.com/plotly/plotly.js/pull/1136 \n var trace = JSON.parse(JSON.stringify(this.gd.data[i]));\n if (!trace.key || trace.set !== group) {\n continue;\n }\n // Get sorted array of matching indices in trace.key\n var matchFunc = getMatchFunc(trace);\n var matches = matchFunc(trace.key, keys);\n \n if (matches.length > 0) {\n // If this is a \"simple\" key, that means select the entire trace\n if (!trace._isSimpleKey) {\n trace = subsetArrayAttrs(trace, matches);\n }\n // reach into the full trace object so we can properly reflect the \n // selection attributes in every view\n var d = this.gd._fullData[i];\n \n /* \n / Recursively inherit selection attributes from various sources, \n / in order of preference:\n / (1) official plotly.js selected attribute\n / (2) highlight(selected = attrs_selected(...))\n */\n // TODO: it would be neat to have a dropdown to dynamically specify these!\n $.extend(true, trace, this.highlight.selected);\n \n // if it is defined, override color with the \"dynamic brush color\"\"\n if (d.marker) {\n trace.marker = trace.marker || {};\n trace.marker.color = selectionColour || trace.marker.color || d.marker.color;\n }\n if (d.line) {\n trace.line = trace.line || {};\n trace.line.color = selectionColour || trace.line.color || d.line.color;\n }\n if (d.textfont) {\n trace.textfont = trace.textfont || {};\n trace.textfont.color = selectionColour || trace.textfont.color || d.textfont.color;\n }\n if (d.fillcolor) {\n // TODO: should selectionColour inherit alpha from the existing fillcolor?\n trace.fillcolor = selectionColour || trace.fillcolor || d.fillcolor;\n }\n // attach a sensible name/legendgroup\n trace.name = trace.name || keys.join(\"
\");\n trace.legendgroup = trace.legendgroup || keys.join(\"
\");\n \n // keep track of mapping between this new trace and the trace it targets\n // (necessary for updating frames to reflect the selection traces)\n trace._originalIndex = i;\n trace._newIndex = this.gd._fullData.length + traces.length;\n trace._isCrosstalkTrace = true;\n traces.push(trace);\n }\n }\n \n if (traces.length > 0) {\n \n Plotly.addTraces(this.gd, traces).then(function(gd) {\n // incrementally add selection traces to frames\n // (this is heavily inspired by Plotly.Plots.modifyFrames() \n // in src/plots/plots.js)\n var _hash = gd._transitionData._frameHash;\n var _frames = gd._transitionData._frames || [];\n \n for (var i = 0; i < _frames.length; i++) {\n \n // add to _frames[i].traces *if* this frame references selected trace(s)\n var newIndices = [];\n for (var j = 0; j < traces.length; j++) {\n var tr = traces[j];\n if (_frames[i].traces.indexOf(tr._originalIndex) > -1) {\n newIndices.push(tr._newIndex);\n _frames[i].traces.push(tr._newIndex);\n }\n }\n \n // nothing to do...\n if (newIndices.length === 0) {\n continue;\n }\n \n var ctr = 0;\n var nFrameTraces = _frames[i].data.length;\n \n for (var j = 0; j < nFrameTraces; j++) {\n var frameTrace = _frames[i].data[j];\n if (!frameTrace.key || frameTrace.set !== group) {\n continue;\n }\n \n var matchFunc = getMatchFunc(frameTrace);\n var matches = matchFunc(frameTrace.key, keys);\n \n if (matches.length > 0) {\n if (!trace._isSimpleKey) {\n frameTrace = subsetArrayAttrs(frameTrace, matches);\n }\n var d = gd._fullData[newIndices[ctr]];\n if (d.marker) {\n frameTrace.marker = d.marker;\n }\n if (d.line) {\n frameTrace.line = d.line;\n }\n if (d.textfont) {\n frameTrace.textfont = d.textfont;\n }\n ctr = ctr + 1;\n _frames[i].data.push(frameTrace);\n }\n }\n \n // update gd._transitionData._frameHash\n _hash[_frames[i].name] = _frames[i];\n }\n \n });\n \n // dim traces that have a set matching the set of selection sets\n var tracesToDim = [],\n opacities = [],\n sets = Object.keys(this.groupSelections),\n n = this.origData.length;\n \n for (var i = 0; i < n; i++) {\n var opacity = this.origOpacity[i] || 1;\n // have we already dimmed this trace? Or is this even worth doing?\n if (opacity !== this.gd._fullData[i].opacity || this.highlight.opacityDim === 1) {\n continue;\n }\n // is this set an element of the set of selection sets?\n var matches = findMatches(sets, [this.gd.data[i].set]);\n if (matches.length) {\n tracesToDim.push(i);\n opacities.push(opacity * this.highlight.opacityDim);\n }\n }\n \n if (tracesToDim.length > 0) {\n Plotly.restyle(this.gd, {\"opacity\": opacities}, tracesToDim);\n // turn off the selected/unselected API\n Plotly.restyle(this.gd, {\"selectedpoints\": null});\n }\n \n }\n \n }\n};\n\n/* \nNote: in all of these match functions, we assume needleSet (i.e. the selected keys)\nis a 1D (or flat) array. The real difference is the meaning of haystack.\nfindMatches() does the usual thing you'd expect for \nlinked brushing on a scatterplot matrix. findSimpleMatches() returns a match iff \nhaystack is a subset of the needleSet. findNestedMatches() returns \n*/\n\nfunction getMatchFunc(trace) {\n return (trace._isNestedKey) ? findNestedMatches : \n (trace._isSimpleKey) ? findSimpleMatches : findMatches;\n}\n\n// find matches for \"flat\" keys\nfunction findMatches(haystack, needleSet) {\n var matches = [];\n haystack.forEach(function(obj, i) {\n if (obj === null || needleSet.indexOf(obj) >= 0) {\n matches.push(i);\n }\n });\n return matches;\n}\n\n// find matches for \"simple\" keys\nfunction findSimpleMatches(haystack, needleSet) {\n var match = haystack.every(function(val) {\n return val === null || needleSet.indexOf(val) >= 0;\n });\n // yes, this doesn't make much sense other than conforming \n // to the output type of the other match functions\n return (match) ? [0] : []\n}\n\n// find matches for a \"nested\" haystack (2D arrays)\nfunction findNestedMatches(haystack, needleSet) {\n var matches = [];\n for (var i = 0; i < haystack.length; i++) {\n var hay = haystack[i];\n var match = hay.every(function(val) { \n return val === null || needleSet.indexOf(val) >= 0; \n });\n if (match) {\n matches.push(i);\n }\n }\n return matches;\n}\n\nfunction isPlainObject(obj) {\n return (\n Object.prototype.toString.call(obj) === '[object Object]' &&\n Object.getPrototypeOf(obj) === Object.prototype\n );\n}\n\nfunction subsetArrayAttrs(obj, indices) {\n var newObj = {};\n Object.keys(obj).forEach(function(k) {\n var val = obj[k];\n\n if (k.charAt(0) === \"_\") {\n newObj[k] = val;\n } else if (k === \"transforms\" && Array.isArray(val)) {\n newObj[k] = val.map(function(transform) {\n return subsetArrayAttrs(transform, indices);\n });\n } else if (k === \"colorscale\" && Array.isArray(val)) {\n newObj[k] = val;\n } else if (isPlainObject(val)) {\n newObj[k] = subsetArrayAttrs(val, indices);\n } else if (Array.isArray(val)) {\n newObj[k] = subsetArray(val, indices);\n } else {\n newObj[k] = val;\n }\n });\n return newObj;\n}\n\nfunction subsetArray(arr, indices) {\n var result = [];\n for (var i = 0; i < indices.length; i++) {\n result.push(arr[indices[i]]);\n }\n return result;\n}\n\n// Convenience function for removing plotly's brush \nfunction removeBrush(el) {\n var outlines = el.querySelectorAll(\".select-outline\");\n for (var i = 0; i < outlines.length; i++) {\n outlines[i].remove();\n }\n}\n\n\n// https://davidwalsh.name/javascript-debounce-function\n\n// Returns a function, that, as long as it continues to be invoked, will not\n// be triggered. The function will be called after it stops being called for\n// N milliseconds. If `immediate` is passed, trigger the function on the\n// leading edge, instead of the trailing.\nfunction debounce(func, wait, immediate) {\n\tvar timeout;\n\treturn function() {\n\t\tvar context = this, args = arguments;\n\t\tvar later = function() {\n\t\t\ttimeout = null;\n\t\t\tif (!immediate) func.apply(context, args);\n\t\t};\n\t\tvar callNow = immediate && !timeout;\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(later, wait);\n\t\tif (callNow) func.apply(context, args);\n\t};\n};\n\nmodule.exports = widgetDefinition"]} \ No newline at end of file diff --git a/theSrc/scripts/widgetdefinition.js b/theSrc/scripts/widgetdefinition.js index 130c45f072..87a2d88d7e 100644 --- a/theSrc/scripts/widgetdefinition.js +++ b/theSrc/scripts/widgetdefinition.js @@ -60,7 +60,7 @@ const widgetDefinition = { var graphDiv = document.getElementById(el.id); // Used by Displayr to determine when widget is ready to be snapshot for testing - graphDiv.setAttribute("rhtmlwidget-status", "not-ready"); + graphDiv.setAttribute("rhtmlwidget-status", "loading"); // TODO: move the control panel injection strategy inside here... HTMLWidgets.addPostRenderHandler(function() {