2017-02-28 4 views
0

Ich erzeugte ein Streudiagramm im HTML-Format mit Plotly und einem generischen Datenframe. Ich bin mir bewusst, dass es möglich ist, bestimmte Datenpunkte (vor) zu markieren (mit einer anderen Farbe zum Beispiel), um den Plot HTML zu generieren. Ich frage mich jedoch, ob es möglich ist, der HTML-Datei ein Element hinzuzufügen, das es einem Benutzer ermöglichen würde, einen bestimmten Datenpunkt basierend auf seiner Textbezeichnung zu finden/hervorzuheben, nachdem das Diagramm erstellt wurde.Markieren/finden Sie Datenpunkte in plotly streuen aus dem Browser

Der Code, den ich verwenden, um den Datenrahmen und Streuung zu erzeugen:

tab <- data.frame(sample.id = pca$sample.id, 
        EV1 = pca$eigenvect[, 1], 
        EV2 = pca$eigenvect[, 2], 
        stringsAsFactors=F) 

p <- plot_ly(tab, x=tab$EV1, y=tab$EV2, text=tab$sample.id) 
p <- layout(p, title="PCA", xaxis=list(title="PC 1"), 
      yaxis=list(title="PC 2")) 

htmlwidgets::saveWidget(as.widget(p), paste(output_name, ".html", sep="")) 

Antwort

1

Soweit ich weiß, dass es in Plotly nicht eingebaute Funktionalität, aber Sie müssen nur ein paar Zeilen Code Javascript um die Funktionalität zu erhalten.

Plotly speichert die Daten in einem application/json Objekt in der HTML-Datei. Sie können die Daten über

var data = JSON.parse(document.querySelectorAll("script[type='application/json']")[0].innerHTML); 

Die Textelemente in

data.x.data[i].text[j] 

gespeichert sind, wo i die Spurennummer und j ist Punktnummer.

Jetzt brauchen wir ein Textfeld und eine Schaltfläche, wir htmltools zu diesem Zweck

p <- htmlwidgets::appendContent(p, htmltools::tags$input(id='inputText', value='Merc', ''), htmltools::tags$button(id='buttonSearch', 'Search')) 

sie fügen Sie einen eventlister auf die Schaltfläche, die eine hover event des ersten Punktes löst der ersten Spur verwenden können.

p <- htmlwidgets::appendContent(p, htmltools::tags$script(HTML(
    'document.getElementById("buttonSearch").addEventListener("click", function() 
    { 
    var myDiv = document.getElementsByClassName("js-plotly-plot")[0] 
    Plotly.Fx.hover(myDiv, [{curveNumber: 0, pointNumber: 0}]); 
    } 
) 
')))  

Und der ganze Code, der durch alle Beschriftungen sucht und löst ein Hover-Ereignis, wenn der eingegebene Text in dem Etikett zu finden ist.

enter image description here

library(plotly) 
library(htmlwidgets) 
library(htmltools) 

pcaCars <- princomp(mtcars, cor = TRUE) 
carsHC <- hclust(dist(pcaCars$scores), method = "ward.D2") 

carsDf <- data.frame(pcaCars$scores, "cluster" = factor(carsClusters)) 
carsClusters <- cutree(carsHC, k = 3) 

carsDf <- transform(carsDf, cluster_name = paste("Cluster", carsClusters)) 

p <- plot_ly(carsDf, x = ~Comp.1 , y = ~Comp.2, text = rownames(carsDf), 
      mode = "markers", color = ~cluster_name, marker = list(size = 11), type = 'scatter', mode = 'markers') 

p <- htmlwidgets::appendContent(p, htmltools::tags$input(id='inputText', value='Merc', ''), htmltools::tags$button(id='buttonSearch', 'Search')) 
p <- htmlwidgets::appendContent(p, htmltools::tags$script(HTML(
    'document.getElementById("buttonSearch").addEventListener("click", function() 
    {   
     var i = 0; 
    var j = 0; 
     var found = []; 
     var myDiv = document.getElementsByClassName("js-plotly-plot")[0] 
     var data = JSON.parse(document.querySelectorAll("script[type=\'application/json\']")[0].innerHTML); 
     for (i = 0 ;i < data.x.data.length; i += 1) { 
     for (j = 0; j < data.x.data[i].text.length; j += 1) { 
      if (data.x.data[i].text[j].indexOf(document.getElementById("inputText").value) !== -1) { 
      found.push({curveNumber: i, pointNumber: j}); 
      } 
     } 
     } 
     Plotly.Fx.hover(myDiv, found); 
    } 
);')))              

htmlwidgets::saveWidget(p, paste('pca', ".html", sep="")) 
p 

Die Umsetzung PCA wurde von here modifiziert.

+0

Ehrfürchtig. Das war genau das, was ich brauchte. Vielen Dank. – ODiogoSilva