{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "source": [ "[this doc on github](https://github.com/dotnet/interactive/tree/main/samples/notebooks/polyglot)\n", "\n", "# using d3js to create widgets\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "source": [ "Introducing a new command to push data to the js kernel" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "using Microsoft.DotNet.Interactive;\n", "using Microsoft.DotNet.Interactive.Commands;\n", "\n", "public class WidgetData : KernelCommand {\n", "\n", " public int[] Data {get;set;}\n", " public WidgetData(string targetKernelName = null) : base(targetKernelName?? \"javascript\") {\n", "\n", " }\n", "}" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "source": [ "register the command for serialization" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "var jsKernel = Kernel.Root.FindKernelByName(\"javascript\");\n", "jsKernel.RegisterCommandType();" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "source": [ "load 3djs using import" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "dotnet_interactive": { "language": "javascript" }, "polyglot_notebook": { "kernelName": "javascript" } }, "outputs": [], "source": [ "d3 = await import(\"https://cdn.jsdelivr.net/npm/d3@7/+esm\");" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "dotnet_interactive": { "language": "javascript" }, "polyglot_notebook": { "kernelName": "javascript" } }, "source": [ "adding the handler to the `javascript` kernel, this will use `d3js` to refresh the display" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "dotnet_interactive": { "language": "javascript" }, "polyglot_notebook": { "kernelName": "javascript" } }, "outputs": [], "source": [ "let jskernel = kernel.root.findKernelByName('javascript');\n", "\n", "jskernel.registerCommandHandler({commandType: 'WidgetData', handle: c => {\n", "\n", " const svg = d3.select(\"#d3_target\");\n", " const data = c.commandEnvelope.command.data;\n", " const scaleFactor = 0.9;\n", " const container = svg.select(\".container\");\n", " const colorMap = (d) => d3.interpolateWarm(d / 80);\n", " const p = container.selectAll(\".points\")\n", " .data(data, (d, i) => i);\n", "\n", " p.transition()\n", " .duration(2000)\n", " .style(\"fill\", d => colorMap(d))\n", " .attr(\"r\", d => Math.max(0, d * scaleFactor));\n", "\n", " p.enter()\n", " .append(\"circle\")\n", " .attr(\"class\", \"points\")\n", " .attr(\"cy\", 80)\n", " .attr(\"cx\", (d,i) => ((i) + 1) * 60)\n", " .transition()\n", " .duration(2000)\n", " .style(\"fill\", d => colorMap(d))\n", " .ease(d3.easeElasticOut.period(1.00))\n", " .attr(\"r\", d => Math.max(0, d * scaleFactor)),\n", "\n", " p.exit()\n", " .transition()\n", " .duration(1000)\n", " .attr(\"r\", 0)\n", " .remove();\n", "}});" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "dotnet_interactive": { "language": "javascript" }, "polyglot_notebook": { "kernelName": "javascript" } }, "source": [ "add the html placeholder" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "dotnet_interactive": { "language": "html" }, "polyglot_notebook": { "kernelName": "html" } }, "outputs": [ { "data": { "text/html": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "dotnet_interactive": { "language": "html" }, "polyglot_notebook": { "kernelName": "html" } }, "source": [ "setup the svg container with some svg effects" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "dotnet_interactive": { "language": "javascript" }, "polyglot_notebook": { "kernelName": "javascript" } }, "outputs": [], "source": [ "const svg = d3.select(\"#d3_target\");\n", "\n", "let defs = svg.append(\"defs\");\n", "\n", "let filter = defs.append(\"filter\").attr(\"id\", \"gooeyCodeFilter\");\n", "\n", "filter.append(\"feGaussianBlur\")\n", " .attr(\"in\", \"SourceGraphic\")\n", " .attr(\"stdDeviation\", \"10\")\n", " .attr(\"color-interpolation-filters\", \"sRGB\")\n", " .attr(\"result\", \"blur\");\n", "\n", "filter.append(\"feColorMatrix\")\n", " .attr(\"in\", \"blur\")\n", " .attr(\"mode\", \"matrix\")\n", " .attr(\"values\", \"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9\")\n", " .attr(\"result\", \"gooey\");\n", "\n", "d3.select(\"#d3_target\")\n", " .append(\"g\")\n", " .style(\"filter\", \"url(#gooeyCodeFilter)\")\n", " .classed(\"container\", true);" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "dotnet_interactive": { "language": "javascript" }, "polyglot_notebook": { "kernelName": "javascript" } }, "source": [ "generate data and send it to javscript using the new command" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "var rnd = new Random();\n", "\n", "for(var i = 0; i < 10; i++){\n", " await Task.Delay(1000);\n", " var limit = rnd.Next(4,12);\n", " var data = Enumerable.Range(1,limit).Select( t => rnd.Next(30, 80)).ToArray();\n", " await Kernel.Root.SendAsync(new WidgetData(\"javascript\"){\n", " Data = data\n", " });\n", "}" ] } ], "metadata": { "kernelspec": { "display_name": ".NET (C#)", "language": "C#", "name": ".net-csharp" }, "language_info": { "name": "polyglot-notebook" }, "polyglot_notebook": { "kernelInfo": { "defaultKernelName": "csharp", "items": [ { "aliases": [ "C#", "c#" ], "languageName": "C#", "name": "csharp" }, { "aliases": [ "F#", "f#" ], "languageName": "F#", "name": "fsharp" }, { "aliases": [], "languageName": "HTML", "name": "html" }, { "aliases": [ "js" ], "languageName": "JavaScript", "name": "javascript" }, { "aliases": [], "languageName": "KQL", "name": "kql" }, { "aliases": [], "languageName": "Mermaid", "name": "mermaid" }, { "aliases": [ "powershell" ], "languageName": "PowerShell", "name": "pwsh" }, { "aliases": [], "languageName": "SQL", "name": "sql" }, { "aliases": [], "name": "value" } ] } } }, "nbformat": 4, "nbformat_minor": 2 }