jupyter-notebookf#deedle.net-interactive

How do I allow for copying data to clipboard from .NET Interactive (Polyglot) Notebooks?


I am working in .NET Interactive (aka Polyglot) Notebooks in F# (but I believe the same would apply to C#). In my code, I am running functions that ultimately produce an F# list of floating point values, or alternatively might be an F# list of tuples which contain floating point values.

When I ask the notebook to display the variable, it shows the first 20 values and says ".. (more)." Ideally, I would like to either be able to download this data by pressing a link next to the table that's displayed, or alternatively, run some function that can copy the full data to the clipboard - similar to Pandas' to_clipboard function.

Is there a way to do this?


Solution

  • If you want to create a cell that, when run, copies the contents of a data frame to a clipboard, you can do this using the TextCopy package. For testing, I used the following (including also Deedle and extension for nicely rendering frames):

    #i "nuget:https://www.myget.org/F/gregs-experimental-packages/api/v3/index.json"
    #r "nuget:Deedle"
    #r "nuget:Deedle.DotNet.Interactive.Extension,0.1.0-alpha9"
    #r "nuget:TextCopy"
    open Deedle
    

    Let's create a sample data frame and a function to get its contents as CSV string:

    let df = 
     Frame.ofRecords
      [ for i in 0 .. 100 -> {| Name = $"Joe {i}" |} ]
    
    let getFrameAsCsv (df:Frame<_, _>) = 
      let sb = System.Text.StringBuilder()
      use sw = new System.IO.StringWriter(sb)
      df.SaveCsv(sw)
      sb.ToString()
    

    To copy df to the clipboard, you can run:

    TextCopy.ClipboardService.SetText(getFrameAsCsv df)
    

    If you want to create a download link in the notebook output, this is also possible. You can use the HTML helper to output custom HTML and inside that, you can use the data: format to embed your CSV as a linked file in <a href=...> (as long as it is not too big):

    let csv = 
      System.Convert.ToBase64String
        (System.Text.UTF8Encoding.UTF8.GetBytes(getFrameAsCsv df))
    HTML($"<a href='data:text/csv;name=file.csv;base64,{csv}'>Download CSV</a>")