Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

new d3

stage2/newd3.livemd

new d3

Mix.install([
  {:jason, "~> 1.4"},
  {:kino, "~> 0.10.0"}
])

Section

defmodule KinoD3.Cluster do
  use Kino.JS

  def new(html) do
    Kino.JS.new(__MODULE__, html)
  end

  asset "main.js" do
    """
    import "https://d3js.org/d3.v5.min.js";

    export function init(ctx, json) {
       	const chartid = document.createElement("div");
    	chartid.id = "out";
    	ctx.root.appendChild(chartid);
    	var obj = JSON.parse(json); 
        var root = d3.hierarchy(obj);
       var cluster = d3.cluster().size([250, 250])
       cluster(root);
       var g = d3.select('#out')
          .append("svg").attr("width", 600).attr("height", 600)
          .append("g").attr("transform", "translate(300, 300)");

       var link = g.selectAll(".link").data(root.links()).enter().append("path")
        .attr("class", "link").attr("fill", "none").attr("stroke", "#555")
        .attr("stroke-width", "1.5px").attr("opacity", "0.6")
        .attr("d", d3.linkRadial().angle(function(d) {
      		return (d.x + 90) * Math.PI / 180;
      	}).radius(function(d) {
      		return d.y;
      }));
     	var node = g.selectAll(".node").data(root.descendants()).enter().append("g")
          .attr("transform", function(d) {
       	return "rotate(" + (d.x) + ")translate(" + d.y + ")";
       })
       node.append("circle").attr("r", 8).attr("stroke", "steelblue")
          .attr("stroke-width", "1.5px").attr("fill", "white");
      	node.append("text").attr("dy", 3).attr("dx", function(d) {
      		return d.x < 90 || d.x > 270 ? 8 : -8;
      	}).style("text-anchor", function(d) {
       	return d.x < 90 || d.x > 270 ? "start" : "end";
      	}).attr("font-size", "200%").attr("transform", function(d) {
      		return d.x < 90 || d.x > 270 ? null : "rotate(180)";
      	}).text(function(d) {
       	return d.data.name;
       });
    }
    """
  end
end

"""
{
		"name": "A",
		"children": [{ 
			"name": "B" 
		}, {
			"name": "C",
			"children": [{ "name": "D" }, { "name": "E" }, { "name": "F" }]
		}, { 
			"name": "G" 
		}, {
			"name": "H",
			"children": [{ "name": "I" }, { "name": "J" }]
		}, { 
			"name": "K" 
		}, {
			"name": "L",
			"children": [{ "name": "M" }, { "name": "N" }]
		}, { 
			"name": "O" 
		}, { 
			"name": "P" 
		}]
	}
"""
|> Jason.decode!()
|> IO.inspect()
|> Jason.encode!()
|> KinoD3.Cluster.new()
%{
  "children" => [
    %{"name" => "B"},
    %{
      "children" => [%{"name" => "D"}, %{"name" => "E"}, %{"name" => "F"}],
      "name" => "C"
    },
    %{"name" => "G"},
    %{"children" => [%{"name" => "I"}, %{"name" => "J"}], "name" => "H"},
    %{"name" => "K"},
    %{"children" => [%{"name" => "M"}, %{"name" => "N"}], "name" => "L"},
    %{"name" => "O"},
    %{"name" => "P"}
  ],
  "name" => "A"
}
|> Jason.encode!()
|> KinoD3.Cluster.new()
defmodule KinoD3.Tree do
  use Kino.JS

  def new(html) do
    Kino.JS.new(__MODULE__, html)
  end

  asset "main.js" do
    """
    import "https://d3js.org/d3.v5.min.js";
    export function init(ctx, json) {
      const chartid = document.createElement("div");
    	chartid.id = "out";
    	ctx.root.appendChild(chartid);
    	var obj = JSON.parse(json); 
      var root = d3.hierarchy(obj);
      var tree = d3.tree().size([250, 250])
      tree(root);
      var g = d3.select('#out')
          .append("svg").attr("width", 600).attr("height", 600)
          .append("g").attr("transform", "translate(300, 300)");
      var link = g.selectAll(".link").data(root.descendants().slice(1))
        .enter().append("path").attr("class", "link").attr("fill", "none").attr("stroke", "#555")
        .attr("stroke-width", "1.5px").attr("opacity", "0.6")
        .attr("d", function(d) {
          return "M" + d.y + "," + d.x + "C" + (d.parent.y + 100) + "," + d.x +
            " " + (d.parent.y + 100) + "," + d.parent.x + " " + d.parent.y + "," + d.parent.x;
        });
      var node = g.selectAll(".node").data(root.descendants())
        .enter().append("g").attr("class", "node")
        .attr("transform", function(d) { 
          return "translate(" + d.y + "," + d.x + ")"; 
        })
      node.append("circle").attr("r", 8).attr("fill", "#999");
      node.append("text").attr("dy", 3).attr("x", function(d) { 
        return d.children ? -12 : 12; 
      }).style("text-anchor", function(d) { 
        return d.children ? "end" : "start"; 
      }).attr("font-size", "200%").text(function(d) { 
        return d.data.name; 
      });
    }
    """
  end
end

%{
  "children" => [
    %{"name" => "B"},
    %{
      "children" => [%{"name" => "D"}, %{"name" => "E"}, %{"name" => "F"}],
      "name" => "C"
    },
    %{"name" => "G"},
    %{"children" => [%{"name" => "I"}, %{"name" => "J"}], "name" => "H"},
    %{"name" => "K"},
    %{"children" => [%{"name" => "M"}, %{"name" => "N"}], "name" => "L"},
    %{"name" => "O"},
    %{"name" => "P"}
  ],
  "name" => "A"
}
|> Jason.encode!()
|> KinoD3.Tree.new()
"""
{
    "name": "A",
    "children": [
      { "name": "B", "value": 25 },
      {
        "name": "C",
        "children": [
          { "name": "D", "value": 10 },
          { "name": "E", "value": 15 },
          { "name": "F", "value": 10 }
        ]
      },
      { "name": "G", "value": 15 },
      {
        "name": "H",
        "children": [
          { "name": "I", "value": 20 },
          { "name": "J", "value": 10 }
        ]
      },
      { "name": "K", "value": 10 }
    ]
  }
"""
|> Jason.decode!()
|> IO.inspect()
defmodule KinoD3.Treemap do
  use Kino.JS

  def new(html) do
    Kino.JS.new(__MODULE__, html)
  end

  asset "main.js" do
    """
    import "https://d3js.org/d3.v5.min.js";
    export function init(ctx, json) {
      const chartid = document.createElement("div");
    	chartid.id = "out";
    	ctx.root.appendChild(chartid);
    	var obj = JSON.parse(json); 
      var root = d3.hierarchy(obj);
      root.sum(function(d) { 
        return d.value; 
      }).sort(function(a, b) { 
        return b.height - a.height || b.value - a.value; 
      }); 
      var treemap = d3.treemap().size([500, 500]).padding(1).round(true);
      treemap(root);
      var g = d3.select('#out')
        .append("svg").attr("width", 600).attr("height", 600)
        .selectAll(".node").data(root.leaves()).enter().append("g").attr("class", "node")
        .attr("transform", function(d) { 
          return "translate(" + d.x0 + "," + (d.y0) + ")"; 
        });
      g.append("rect").style("width", function(d) { 
        return d.x1 - d.x0; 
      }).style("height", function(d) { 
        return d.y1 - d.y0; 
      }).style("fill", function(d) {
        while(d.depth > 1) d = d.parent;
        return d3.schemeCategory10[parseInt(d.value % 7)];
      }).style("opacity", 0.6)
      g.append("text").attr("text-anchor", "start").attr("x", 5).attr("dy", 30)
        .attr("font-size", "150%").attr("class", "node-label").text(function(d) { 
          return d.data.name + " : " + d.value; 
        });
    }
    """
  end
end

%{
  "children" => [
    %{"name" => "B", "value" => 25},
    %{
      "children" => [
        %{"name" => "D", "value" => 10},
        %{"name" => "E", "value" => 15},
        %{"name" => "F", "value" => 10}
      ],
      "name" => "C"
    },
    %{"name" => "G", "value" => 15},
    %{
      "children" => [
        %{"name" => "I", "value" => 20},
        %{"name" => "J", "value" => 10}
      ],
      "name" => "H"
    },
    %{"name" => "K", "value" => 10}
  ],
  "name" => "A"
}
|> Jason.encode!()
|> KinoD3.Treemap.new()
defmodule KinoD3.Partition do
  use Kino.JS

  def new(html) do
    Kino.JS.new(__MODULE__, html)
  end

  asset "main.js" do
    """
    import "https://d3js.org/d3.v5.min.js";
    export function init(ctx, json) {
      const chartid = document.createElement("div");
    	chartid.id = "out";
    	ctx.root.appendChild(chartid);
    	var obj = JSON.parse(json); 
      var root = d3.hierarchy(obj);
      root.sum(function(d) { 
        return d.value; 
      }).sort(function(a, b) { 
        return b.height - a.height || b.value - a.value; 
      }); 
      var partition = d3.partition().size([400, 400]).padding(1).round(true);
      partition(root);
      var g = d3.select('#out')
          .append("svg").attr("width", 600).attr("height", 600)
          .selectAll(".node").data(root.descendants()).enter()
          .append("g").attr("class", "node").attr("transform", function(d) { 
            return "translate(" + d.y0 + "," + d.x0 + ")"; 
          }); 
      g.append("rect").style("width", function(d) { 
          return d.y1 - d.y0; 
        }).style("height", function(d) { 
          return d.x1 - d.x0; 
        }).style("fill", function(d) {
          while(d.depth > 1) 
            d = d.parent;
          if (d.depth == 0) 
            return "gray";
          return d3.schemeCategory10[parseInt(d.value % 7)];
        }).style("opacity", 0.6)
      g.append("text").attr("text-anchor", "start").attr("x", 5).attr("dy", 30)
        .attr("font-size", "150%").attr("class", "node-label")
        .text(function(d) { 
          return d.data.name + " : " + d.value; 
        });
    }
    """
  end
end

%{
  "children" => [
    %{"name" => "B", "value" => 25},
    %{
      "children" => [
        %{"name" => "D", "value" => 10},
        %{"name" => "E", "value" => 15},
        %{"name" => "F", "value" => 10}
      ],
      "name" => "C"
    },
    %{"name" => "G", "value" => 15},
    %{
      "children" => [
        %{"name" => "I", "value" => 20},
        %{"name" => "J", "value" => 10}
      ],
      "name" => "H"
    },
    %{"name" => "K", "value" => 10}
  ],
  "name" => "A"
}
|> Jason.encode!()
|> KinoD3.Partition.new()
defmodule KinoD3.Pack do
  use Kino.JS

  def new(html) do
    Kino.JS.new(__MODULE__, html)
  end

  asset "main.js" do
    """
    import "https://d3js.org/d3.v5.min.js";
    export function init(ctx, json) {
      const chartid = document.createElement("div");
    	chartid.id = "out";
    	ctx.root.appendChild(chartid);
    	var obj = JSON.parse(json); 
      var root = d3.hierarchy(obj);
      root.sum(function(d) { 
        return d.value; 
      });
      var pack = d3.pack().size([500, 500]).padding(1);
      pack(root);
      var node = d3.select('#out')
        .append("svg").attr("width", 600).attr("height", 600)
        .selectAll(".node").data(root.descendants()).enter()
        .append("g").attr("transform", function(d) { 
          return "translate(" + d.x + "," + (d.y) + ")"; 
        });
      var color = ["orange", "Khaki", "Ivory"];
      node.append("circle").attr("r", function(d) { 
        return d.r; 
      }).attr("stroke", "black").attr("fill", function(d) { 
        return color[d.depth]; 
      });
      node.append("text").style("text-anchor", function(d) { 
        return d.children ? "end" : "middle"; 
      }).attr("font-size", "150%").text(function(d) { 
        return d.children ? "" : d.data.name; 
      });
    }
    """
  end
end

%{
  "children" => [
    %{"name" => "B", "value" => 25},
    %{
      "children" => [
        %{"name" => "D", "value" => 10},
        %{"name" => "E", "value" => 15},
        %{"name" => "F", "value" => 10}
      ],
      "name" => "C"
    },
    %{"name" => "G", "value" => 15},
    %{
      "children" => [
        %{"name" => "I", "value" => 20},
        %{"name" => "J", "value" => 10}
      ],
      "name" => "H"
    },
    %{"name" => "K", "value" => 10}
  ],
  "name" => "A"
}
|> Jason.encode!()
|> KinoD3.Pack.new()