diff --git a/DESCRIPTION b/DESCRIPTION
index 6718febc25..a0a0195742 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,6 +1,6 @@
Package: plotly
Title: Create Interactive Web Graphics via 'plotly.js'
-Version: 4.9.4.2
+Version: 4.9.4.3
Authors@R: c(person("Carson", "Sievert", role = c("aut", "cre"),
email = "cpsievert1@gmail.com", comment = c(ORCID = "0000-0002-4958-2844")),
person("Chris", "Parmer", role = "aut",
diff --git a/inst/htmlwidgets/plotly.js b/inst/htmlwidgets/plotly.js
index 6dc46fbb40..0690a2fe5b 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","catch","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 87a2d88d7e..a5f5aaff2c 100644
--- a/theSrc/scripts/widgetdefinition.js
+++ b/theSrc/scripts/widgetdefinition.js
@@ -179,7 +179,12 @@ const widgetDefinition = {
}
// Trigger plotly.js calls defined via `plotlyProxy()`
- plot.then(function() {
+ plot.catch(function() {
+ // Used by Displayr to determine when widget is ready to be snapshot for testing
+ graphDiv.setAttribute("rhtmlwidget-status", "ready");
+ }).then(function() {
+ // Used by Displayr to determine when widget is ready to be snapshot for testing
+ graphDiv.setAttribute("rhtmlwidget-status", "ready");
if (HTMLWidgets.shinyMode) {
Shiny.addCustomMessageHandler("plotly-calls", function(msg) {
var gd = document.getElementById(msg.id);