Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

Revision 08a8fb349e580560cdc785d0860cc423c288eca8 authored by Changjian Chen on 20 May 2024, 01:45:34 UTC, committed by Changjian Chen on 20 May 2024, 01:45:34 UTC
update README
1 parent 90f314b
  • Files
  • Changes
  • 5b23d0f
  • /
  • src
  • /
  • plugins
  • /
  • render_text_tree.js
Raw File Download

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • revision
  • directory
  • content
revision badge
swh:1:rev:08a8fb349e580560cdc785d0860cc423c288eca8
directory badge
swh:1:dir:d810d13a526521471406fb682b82d7b4a0267eab
content badge
swh:1:cnt:aa8dd8e0547784c018abd5c8a5423a0508f5affb

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • revision
  • directory
  • content
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
render_text_tree.js
import * as d3 from "d3";
import * as Global from "./global";
import { exit_type } from "./layout_text";
import {tree_process} from "../plugins/tree_data_helper"

const TextTree = function(parent) {
  let that = this;
  that.parent = parent;

  that.tree_node_group = that.parent.tree_node_group;
  that.rest_node_group = that.parent.rest_node_group;

  // text position
  that.text_height = that.parent.text_height;

  // node width
  that.max_text_width = that.parent.max_text_width;

  // detection result layout
  that.layout_width = that.parent.layout_width;
  that.layout_height = that.parent.layout_height;
  that.node_width = that.parent.node_width;
  that.layer_height = that.parent.layer_height;

  // bar size
  that.bar_width = that.parent.bar_width;
  that.bar_height = that.parent.bar_height;
  that.rounded_r = that.parent.rounded_r;

  that.editing_state = false;
  that.merge_action = null;
  that.target_node = null;
  that.focus_node_for_edit = null;
  that.highlight_fixed = false;

  that.parent.svg.select("defs").remove();
  that.defs = that.parent.svg
    .append("defs");
  that.defs
    .append("pattern")
    .attr("id", "edit-svg-icon")
    .attr("viewBox", "0 0 20 20")
    .attr("width", "100%")
    .attr("height", "100%")
    .append("svg")
    .attr("viewBox", "0 0 1024 1024")
    .attr("width", "20px")
    .attr("height", "20px")
    .append("path")
    .attr(
      "d",
      "M800 128.992c-24.512 0-48.512 9.504-67.008 28L416 472.992l-7.008 7.008-1.984 10.016-22.016 112-9.984 46.976 47.008-9.984 112-22.016 9.984-1.984 7.008-7.008 316-316.992A94.976 94.976 0 0 0 800 128.96z m0 62.016c7.488 0 14.88 3.84 22.016 10.976 14.24 14.272 14.24 29.76 0 44L512 556.032l-55.008 11.008 11.008-55.008 310.016-310.016c7.104-7.104 14.496-10.976 21.984-10.976zM128 256v640h640V473.984l-64 64V832H192V320h294.016l64-64z"
    )
    .style("fill", "rgb(114,114,114)");

    that.radialGradient = that.defs
        .append("radialGradient")
        .attr("id", "button-gradient")
        .attr("cx", "50%")
        .attr("cy", "50%")
        .attr("r", "40%")
        .attr("fx", "50%")
        .attr("fy", "50%");
    that.radialGradient.append("stop")
        .attr("offset", "0%")
        .style("stop-opacity", 0.5)
        .style("stop-color", "lightgrey");
    that.radialGradient.append("stop")
        .attr("offset", "100%")
        .style("stop-opacity", 1)
        .style("stop-color", "darkgrey");

  that.panel_info = [
    { x: -1, y: -1, name: "absorb" },
    { x: 0, y: -1, name: "join" },
    { x: -1, y: 0, name: "collapse" },
    { x: 0, y: 0, name: "cancel" },
  ];

  that.textClickHandler = function(evt) {
    that.highlight_fixed = true;
    window.d3 = d3;
    // if (document.querySelector("#overlay") !== null) return; // kludgy singleton approach
    that.text_element = d3.select(evt.target.parentElement).select("text");
    that.selected_input_data = that.text_element.data()[0];
    let bbox = that.text_element.node().getBoundingClientRect();
    const value = that.selected_input_data.full_name;
    let wrapper = d3
      .select("#wrapper")
      .append("div")
      .attr("id", "overlay")
      // .style("top", (that.parent.tree_node_group_y + that.selected_input_data.y + 6) + "px")
      // .style("left", (that.parent.tree_node_group_x + that.selected_input_data.x + that.layer_height / 2 + 12) + "px")
      .style("top", bbox.top + "px")
      .style("left", bbox.left + "px")
      .append("div")
      .attr("id", "obg")
      .style("display", "flex");
    // wrapper.append("span")
    //     .attr("id", "edit-title")
    //     .text("Edit node name");
    that.input = wrapper
      .append("input")
      .attr("id", "edit-input")
      .attr("type", "text")
      .attr("text-align", "middle")
      // .attr("data-src", data.id)
      // .attr("data-maxtextwidth", value.length)
      .style("max-width", that.get_text_length(value) + 20 + "px")
      .attr("value", value);
  };

  that.parent.svg.on("click", () => {
    that.highlight_fixed = false;
    that.dehighlight();
    if (that.input === undefined) return;
    that.selected_input_data.name = that.input.node().value;
    that.selected_input_data.full_name = that.selected_input_data.name;
    let text = that.wrap(that.selected_input_data.name);
    if (text.length !== that.selected_input_data.name.length) {
      that.selected_input_data.name = text + "...";
    }
    console.log(
      "edited name",
      that.selected_input_data.full_name,
      that.selected_input_data.id
    );
    that.parent.set_name_edit_history({
      id: that.selected_input_data.id,
      name: that.selected_input_data.full_name,
    });
    d3.select(".tree-node#id-" + that.selected_input_data.id)
      .select("text")
      .text(that.selected_input_data.name);
    d3.select(".tree-node#id-" + that.selected_input_data.id)
      .select("title")
      .text(that.selected_input_data.full_name);
    d3.select("#overlay").remove();
    that.input = undefined;
  });

  that.change_selected_flag = function(d, flag) {
    console.log("change selected flag", d.selected_flag, flag);
    that.create_ani = 0;
    that.remove_ani = 0;
    that.update_ani /= 2;
    d.selected_flag = flag;
    that.parent.set_selected_flag(that.parent.tree);
    console.log("change selected flag after", d.selected_flag, flag);
  };

  that.set_animation_time = function() {
    // animation
    that.create_ani = that.parent.create_ani;
    that.update_ani = that.parent.update_ani;
    that.remove_ani = that.parent.remove_ani;
  };
  that.set_animation_time();

  that.set_focus_node = function(nodes) {
    that.parent.set_focus_node(nodes);
  };

  that.fetch_word = function() {
    that.parent.$store.dispatch("fetch_word");
  };

  that.fetch_image = function() {
    that.parent.$store.dispatch("fetch_image");
  };

  that.set_selected_node = function(node) {
    that.parent.set_selected_node(node);
  };

  that.sub_component_update = function(nodes, rest_nodes) {
    // update state
    that.tree_node_group_x = that.parent.tree_node_group_x;
    that.tree_node_group_y = that.parent.tree_node_group_y;
    that.expand_tree = that.parent.expand_tree;

    that.get_text_length = function(text) {
      let self = that.tree_node_group
        .append("text")
        .attr("id", "temp")
        .attr("class", "node-name")
        .attr("text-anchor", "start")
        .attr("font-size", "18px");
      self.text(text);
      let textLength = self.node().getComputedTextLength();
      that.tree_node_group.select("#temp").remove();
      return textLength;
    };

    (that.wrap = function(text) {
      let self = that.tree_node_group
        .append("text")
        .attr("id", "temp")
        .attr("class", "node-name")
        .attr("text-anchor", "start")
        .attr("font-size", "18px");
      self.text(text);
      let textLength = self.node().getComputedTextLength();
      if (textLength < that.max_text_width - 30 - 5) {
        that.tree_node_group.select("#temp").remove();
        return text;
      }
      self.text(text + "...");
      textLength = self.node().getComputedTextLength();
      // console.log("wrap text", text);
      while (textLength > that.max_text_width - 30 - 2 * 5 && text.length > 0) {
        text = text.slice(0, -1);
        self.text(text + "...");
        textLength = self.node().getComputedTextLength();
      }
      that.tree_node_group.select("#temp").remove();
      return text;
    }),
      (that.node_wrap = function(node) {
        let text = node.full_name;
        text = that.wrap(text);
        if (text.length === node.full_name.length) {
          node.name = text;
        } else {
          node.name = text + "...";
        }
      });
    nodes.forEach(that.node_wrap);

    // update view
    that.e_nodes = that.tree_node_group
      .selectAll(".tree-node")
      .data(nodes, (d) => d.id);

    that.e_rest_nodes = that.rest_node_group
      .selectAll(".rest-tree-node")
      .data(rest_nodes, (d) => d.id);

    that.create();
    that.update();
    that.remove();

    // that.tree_node_group
    //     .selectAll(".tree-node").select("text").each(that.wrap); // dirty manner

    that.set_animation_time();
  };

  that.create = function() {
    that.node_create();
    that.rest_node_create();
  };

  that.node_create = function() {
    let dragstarted = function() {
      that.highlight_fixed = true;
      let tag = d3.select(this).node().parentElement;
      tag = d3.select(tag);
      console.log("drag start", tag);
      that.timer = setTimeout(function(){
        that.focus_node_for_edit = tag.data()[0];
        that.tree_node_group
          .append("rect")
          .attr("id", "dragnode")
          .attr("rx", that.layer_height / 12)
          .attr("ry", that.layer_height / 12)
          .attr("x", tag.data()[0].x + that.layer_height / 4)
          .attr("y", tag.data()[0].y + (-that.layer_height * 0.8) / 2)
          .attr("height", that.layer_height * 0.8)
          .attr("width", () => {
            return that.max_text_width;
          })
          .style("pointer-events", "none")
          .style("stroke", "black")
          .style("fill", "white")
          .style("opacity", 0.5);
      }, 1)
    };

    let dragged = function(event) {
      that.editing_state = true;
      // d3.select(this)
      //     .attr("transform",
      //     "translate(" + event.x + ", " + event.y + ")");
      that.tree_node_group
        .select("#dragnode")
        .attr("x", event.x + that.layer_height / 4)
        .attr("y", event.y - that.layer_height * 0.4);
     that.tree_node_group
        .select("#merge-panel-g")
        .attr("transform",  "translate(" + (event.x + that.layer_height / 4 + that.max_text_width  + 5) 
        + ", " + (event.y - that.layer_height * 0.4 + that.layer_height * 0.8) + ")");
    };

    let dragended = function() {
      console.log("drag end");
      that.highlight_fixed = false;
      that.dehighlight();

      if (that.merge_action){
        if (that.merge_action === "join"){
          console.log("join");
        }
        else if (that.merge_action === "absorb"){
          console.log("absorb");
          let focus_node_parent = that.focus_node_for_edit.parent;
          that.focus_node_parent = focus_node_parent;
          let children_ids = focus_node_parent.all_children.map(d => d.id);
          let idx = children_ids.indexOf(that.focus_node_for_edit.id);
          focus_node_parent.all_children.splice(idx, 1);
          that.target_node.all_children.push(that.focus_node_for_edit);
          that.focus_node_for_edit.parent = that.target_node;
          that.focus_node_for_edit.depth = that.focus_node_for_edit.parent.depth + 1;
          console.log(that.focus_node_for_edit.name);
          console.log(that.target_node.name, that.target_node.all_children.map(d => d.name));
          console.log(focus_node_parent.name, focus_node_parent.all_children.map(d => d.name));
          tree_process(that.parent.tree);
          that.set_focus_node([that.focus_node_for_edit]);
        }
        else if (that.merge_action === "collapse"){
          console.log("collapse");
        }
    }

      that.editing_state = false;
      that.tree_node_group.select("#dragnode").remove();
      that.tree_node_group.selectAll("#merge-panel-g").remove();
      that.focus_node_for_edit = null;
      that.target_node = null;
      that.merge_action = null;
    };

    let drag = d3
      .drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended);

    // node circle
    let node_groups = that.e_nodes
      .enter()
      .append("g")
      .attr("class", "tree-node")
      .attr("id", (d) => "id-" + d.id)
      .attr("transform", (d) => "translate(" + d.x + ", " + d.y + ")");
    node_groups
      .transition()
      .duration(that.create_ani)
      .delay(that.remove_ani + that.update_ani)
      .style("opacity", 1);
    node_groups
      .append("title")
      .style("font-size", "0.835vw")
      .text((d) => d.full_name);
    node_groups
      .append("rect")
      .attr("class", "background")
      .attr("rx", that.layer_height / 12)
      .attr("ry", that.layer_height / 12)
      .attr("x", that.layer_height / 4)
      .attr("y", (-that.layer_height * 0.8) / 2)
      .attr("height", that.layer_height * 0.8)
      .attr("width", () => {
        return that.max_text_width;
      })
      // TODO:
      // .style("fill", d => d.selected_flag ? Global.DarkGray : "#EBEBF3")
      .style("fill", "#EBEBF3")
      .style("fill-opacity", 0)
      .call(drag)
      .on("mouseover", (ev) => {
        let element = d3.select(ev.toElement).node().parentElement;
        // element = d3.select(element);
        that.highlight(ev);
        if (that.editing_state) {
          console.log("dragged hover");
          if (!that.target_node){
              that.target_node = d3.select(ev.toElement).data()[0];
          }
          else{
            console.log("treggle ", that.target_node.id, element.id);
              if (that.target_node.id != element.id){
                console.log("treggle differnt target node");
                that.tree_node_group.selectAll("#merge-panel-g").remove();
                that.target_node = d3.select(ev.toElement).data()[0];
              }
          }
          that.PanelWidth = 40;
          that.PanelHeight = 40;
          that.ImageMargin = that.PanelWidth * 0.12;
          that.PanelMargin = 0;
          that.PanelOffset = 1;
          if (that.tree_node_group.selectAll("#merge-panel-g").node()) return;
          let is_leaf = d3.select(ev.toElement).data()[0].all_children.length == 0;
          console.log("is leaf", is_leaf);
          let panel = that.tree_node_group
            .append("g")
            .attr("id", "merge-panel-g")
            .attr("transform",  "translate(" + 0 + ", " + 0 + ")");
          panel
            .append("text")
            .attr("x", 0)
            .attr("y", 0)
            .attr("text-anchor", "start")
            .attr("font-size", "18px")
            .text("move to")
            .attr("display",  is_leaf ? "none":"block");
          panel.append("image")
            .attr("x", 0)
            .attr("y", -10)
            .attr("width", 10)
            .attr("xlink:href", that.parent.server_url + "/icon/" + "forbid")
            .attr("display", is_leaf ? "block":"none");
          if (!is_leaf){
              that.merge_action = "absorb";
          }
          else{
              that.merge_action = null;
          }
        
        }
      })
      .on("mouseout", () => {
        // that.hideTooltip();
        that.dehighlight();
        if (that.editing_state){
          console.log("that.merge_action", that.merge_action);
          setTimeout(() =>{
            if (!that.merge_action) {
                that.tree_node_group.select("#merge-panel-g").remove();
                that.target_node = null;
            }
          }, 2);
        }
      })
      .on("click", (ev, d) => {
        console.log("on click tree node");
        // that.change_selected_flag(d, !d.selected_flag);
        if (d.all_children.length && d.all_children.length > 0){
          that.set_focus_node([d]);
          return;
        }
        // TODO: double click
        let node = {
          full_name: d.full_name,
          id: d.id,
        };
        that.set_selected_node(node);

        d3.select(".loading-wordcloud-svg")
          .transition()
          .duration(1)
          .style("opacity", 1);
        Global.disable_global_interaction();
        that.fetch_word();
        that.fetch_image();
      })
      .transition()
      .duration(that.create_ani)
      .delay(that.remove_ani + that.update_ani)
      .style("fill-opacity", 1);

    // precision and recall
    let bars = node_groups
      .append("g")
      .attr("class", "node-bars")
      .style("pointer-events", "none")
      .attr(
        "transform",
        () =>
          "translate(" +
          (that.max_text_width - 15) +
          ", " +
          -(that.bar_height - that.rounded_r) / 2 +
          ")"
      );
    let individual_bar = bars
      .selectAll("g.bar")
      .data((d) => {
        let precision = {
          value: d.data.precision,
          color: "#c982ce",
          type: "precision",
        };
        let recall = {
          value: d.data.recall,
          color: "#4fa7ff",
          type: "recall",
        };
        return [precision, recall];
      })
      .enter()
      .append("g")
      .attr("class", "bar")
      .attr(
        "transform",
        (_, i) => "translate(" + i * (that.bar_width + 3) + ", " + 0 + ")"
      );
    individual_bar
      .append("rect")
      .attr("class", "bar-background")
      .attr("rx", that.rounded_r)
      .attr("ry", that.rounded_r)
      .attr("width", that.bar_width)
      .attr("height", that.bar_height)
      .style("fill", "none")
      .style("stroke", (d) => d.color)
      .style("stroke-width", 1);

    individual_bar
      .append("rect")
      .attr("class", (d) => "bar-value bar-" + d.type)
      .attr("rx", that.rounded_r)
      .attr("ry", that.rounded_r)
      .attr("width", that.bar_width)
      .attr("height", that.bar_height)
      .style("fill", (d) => d.color)
      .style("clip-path", (d) => {
        return `inset(${(1 - d.value) *
          that.bar_height}px ${0}px ${0}px ${0}px)`;
      });
    bars
      .style("opacity", 0)
      .transition()
      .duration(that.create_ani)
      .delay(that.remove_ani + that.update_ani)
      .style("opacity", 1);

    // edit icon
    node_groups
      .append("rect")
      .attr("class", "edit-icon")
      .attr("width", "15px")
      .attr("height", "15px")
      .attr("fill", "url(#edit-svg-icon)")
      .attr("x", that.layer_height / 4 + that.max_text_width - 1)
      .attr("y", (-that.layer_height * 0.8) / 2 - 2)
      .style("opacity", 0)
      .on("click", (ev) => {
        that.textClickHandler(ev);
        ev.stopPropagation();
      })
      .on("mouseover", (ev) => {
        that.highlight(ev);
      })
      .on("mouseout", () => {
        // that.hideTooltip();
        that.dehighlight();
      });

    node_groups
      .append("path")
      .attr("class", (d) => "icon icon-" + d.type)
      .attr("d", function(d) {
        return Global.node_icon(0, 0, d.type);
      })
      .style("fill", Global.GrayColor)
      .style("opacity", 0)
      .transition()
      .duration(that.create_ani)
      .delay(that.update_ani + that.remove_ani)
      .style("opacity", () => (that.expand_tree ? 1 : 0));

    node_groups
      .append("rect")
      .attr("class", (d) => "icon-background icon-bg-" + d.type)
      .attr("x", -8)
      .attr("y", -8)
      .attr("width", 16)
      .attr("height", 16)
      .style("fill", "white")
      .style("opacity", 0)
      .on("mouseover", (ev, d) => {
        that.icon_highlight(ev, d);
      })
      .on("mouseout", (ev, d) => {
        that.icon_dehighlight(ev, d);
      })
      .on("click", (ev, d) => {
        console.log("click icon", d.type, d);
        if (!that.expand_tree) return;
        // if (d.type > 0) return;
        console.log("click tree node", d.name);
        // that.highlight(ev, d, "rgb(211, 211, 229)");
        that.set_focus_node([d]);
      });

    // node name
    node_groups
      .append("text")
      .attr("class", "node-name")
      .text((d) => {
        return d.name;
      })
      .attr("text-anchor", "start")
      .attr("x", that.layer_height / 2 - 2)
      .attr("font-size", "18px")
      .style("fill", Global.DeepGray)
      .attr("dy", ".3em")
      .style("opacity", 0)
      .transition()
      .duration(that.create_ani)
      .delay(that.update_ani + that.remove_ani)
      .style("opacity", 1);
    // node_groups.append("foreignObject")
    //     .attr("x", that.layer_height / 2)
    //     .attr("y", -10)
    //     .attr("width", ( (that.max_text_width - 30) - 2 * 5))
    //     .attr("height", 20)
    //     .append("div")
    //     .append("input")
    //     .attr("value", d => d.name);

    // node link
    node_groups
      .append("path")
      .attr("class", "node-link")
      .attr("d", (d) => {
        return (
          "M" +
          d.link_x +
          ", " +
          d.link_top +
          " L " +
          d.link_x +
          ", " +
          d.link_bottom
        );
      })
      .style("stroke", Global.GrayColor)
      .style("stroke-width", 0.5)
      .style("opacity", 0)
      .transition()
      .duration(that.create_ani)
      .delay(that.update_ani + that.remove_ani)
      .style("opacity", 1);
  };

  that.rest_node_create = function() {
    let node_groups = that.e_rest_nodes
      .enter()
      .append("g")
      .attr("class", "rest-tree-node")
      .attr("id", (d) => "id-" + d.id)
      .attr("transform", (d) => "translate(" + d.x + ", " + d.y + ")")
      .style("opacity", 0)
      .on("click", (ev, d) => {
        console.log("set focus node");
        that.set_focus_node(d.rest_children);
      });
    node_groups
      .append("path")
      .attr("class", "icon")
      .attr("d", Global.node_icon(0, 0, 0))
      .attr("fill", Global.GrayColor);
    node_groups
      .selectAll("rest-node-rect")
      .data((d) => {
        console.log("rest node groups data", d);
        return d.rest_children;
      })
      .enter()
      .append("rect")
      .attr("class", "rest-node-rect")
      .attr("rx", that.layer_height / 12)
      .attr("ry", that.layer_height / 12)
      .attr("x", (d) => that.layer_height / 4 + d.x_delta)
      .attr("y", (d) => d.y_delta)
      .attr("height", that.layer_height * 0.6)
      .attr("width", () => {
        return that.max_text_width;
      })
      .style("fill", (d) =>
        d.last_rest_children ? "#EBEBF3" : "rgb(211, 211, 229)"
      )
      .style("stroke", "white")
      .style("stroke-width", 1);
    node_groups
      .transition()
      .duration((d) => {
        if (d.prev_vis) {
          // return that.remove_ani * 0.5;
          return that.create_ani;
        } else {
          return that.create_ani;
        }
      })
      .delay((d) => {
        if (d.prev_vis) {
          // return that.remove_ani * 0.5 + that.remove_ani;
          return that.remove_ani + that.update_ani;
        } else {
          return that.remove_ani + that.update_ani;
        }
      })
      .style("opacity", 1);
  };

  that.update = function() {
    that.node_update();
    that.rest_node_update();
  };

  that.node_update = function() {
    that.tree_node_group
      .transition()
      .duration(that.update_ani)
      .delay(that.remove_ani)
      .attr("transform", () => {
        return (
          "translate(" +
          that.tree_node_group_x +
          ", " +
          that.tree_node_group_y +
          ")"
        );
      });
    that.e_nodes
      .transition()
      .duration(that.update_ani)
      .delay(that.remove_ani)
      .attr("transform", (d) => "translate(" + d.x + ", " + d.y + ")");
    that.e_nodes
      .select("rect.background")
      .transition()
      .duration(that.update_ani)
      .delay(that.remove_ani)
      .attr("x", that.layer_height / 4)
      .attr("y", (-that.layer_height * 0.8) / 2)
      .attr("height", that.layer_height * 0.8)
      .attr("width", () => {
        // return Global.getTextWidth(d.data.name, "16px Roboto, sans-serif") + that.layer_height / 2;
        return that.max_text_width;
      })
      .style("fill", (d) => (d.selected_flag ? Global.DarkGray : "#EBEBF3"));

    if (that.focus_node) {
      that.tree_node_group
        .select("#id-" + that.focus_node[0].id)
        .select("rect.background")
        .transition()
        .duration(that.create_ani)
        .delay(that.remove_ani + that.update_ani + that.create_ani)
        .style("fill", "#EBEBF3");
    }

    that.e_nodes
      .select("path.icon")
      .transition()
      .duration(that.update_ani)
      .delay(that.remove_ani)
      .attr("d", function(d) {
        return Global.node_icon(0, 0, d.type);
      })
      .style("opacity", () => (that.expand_tree ? 1 : 0))
      .style("fill", Global.GrayColor);
    that.e_nodes
      .select("rect.icon-background")
      .attr("class", (d) => "icon-background icon-bg-" + d.type);

    // that.e_nodes
    //     .select("text")
    //     .transition()
    //     .duration(that.update_ani)
    //     .delay(that.remove_ani)
    //     .text((d) => d.name)
    //     .style("opacity", 1);

    that.e_nodes
      .select("path.node-link")
      .transition()
      .duration(that.update_ani)
      .delay(that.remove_ani)
      .attr("d", (d) => {
        return (
          "M" +
          d.link_x +
          ", " +
          d.link_top +
          " L " +
          d.link_x +
          ", " +
          d.link_bottom
        );
      });

    that.e_nodes
      .select("g.node-bars")
      .transition()
      .duration(that.update_ani)
      .delay(that.remove_ani)
      .style("pointer-event", "none")
      .attr(
        "transform",
        () =>
          "translate(" +
          (that.max_text_width - 15) +
          ", " +
          -(that.bar_height - that.rounded_r) / 2 +
          ")"
      );
    that.e_nodes
      .select("g.node-bars")
      .selectAll("g.bar")
      .data((d) => {
        let precision = {
          value: d.data.precision,
          color: "#c982ce",
          type: "precision",
        };
        let recall = {
          value: d.data.recall,
          color: "#4fa7ff",
          type: "recall",
        };
        return [precision, recall];
      })
      .attr(
        "transform",
        (_, i) => "translate(" + i * (that.bar_width + 3) + ", " + 0 + ")"
      )
      .selectAll(".bar-value")
      .style("clip-path", (d) => {
        return `inset(${(1 - d.value) *
          that.bar_height}px ${0}px ${0}px ${0}px)`;
      });
  };

  that.rest_node_update = function() {
    that.rest_node_group
      .transition()
      .duration(that.update_ani)
      .delay(that.remove_ani)
      .attr("transform", () => {
        let x = that.layer_height / 2;
        if (!that.expand_tree) {
          x = 0;
        }
        return (
          "translate(" +
          x +
          ", " +
          (that.text_height + that.layer_height / 2) +
          ")"
        );
      });
    that.e_rest_nodes
      .transition()
      .duration(that.update_ani)
      .delay(that.remove_ani)
      .attr("transform", (d) => "translate(" + d.x + ", " + d.y + ")");
    that.e_rest_nodes
      .selectAll("rest-node-rect")
      .attr("y", (d, i) => (-that.layer_height * 0.8) / 2 + i * 10)
      .attr("width", () => {
        return that.max_text_width;
      });
  };

  that.remove = function() {
    that.node_remove();
    that.rest_node_remove();
  };

  that.node_remove = function() {
    that.e_nodes.exit().attr("", (d) => {
      let [type, translate] = exit_type(d);
      d.exit_type = type;
      d.translate = translate;
      d.exit_duration = d.exit_type > 1 ? that.update_ani : that.remove_ani;
      d.exit_delay = d.exit_type > 1 ? that.remove_ani : 0;
    });
    that.e_nodes
      .exit()
      .transition()
      .duration((d) => d.exit_duration)
      .delay((d) => d.exit_delay)
      .attr("transform", (d) => d.translate + " scale(1, 0)")
      .style("opacity", 0)
      .remove();
  };

  that.rest_node_remove = function() {
    that.e_rest_nodes.exit().attr("", (d) => {
      let [type, translate] = exit_type(d.parent);
      d.exit_type = type;
      d.translate = translate;
      d.exit_duration = d.exit_type > 1 ? that.update_ani : that.remove_ani;
      d.exit_delay = d.exit_type > 1 ? that.remove_ani : 0;
      console.log(
        "rest_node_remove",
        d.exit_type,
        d.exit_duration,
        d.exit_delay,
        d.translate
      );
    });
    that.e_rest_nodes
      .exit()
      .transition()
      .duration((d) => d.exit_duration)
      .delay((d) => d.exit_delay)
      .attr("transform", (d) => d.translate + " scale(1, 0)")
      .style("opacity", 0)
      .remove();
  };

  // that.highlight = function(ev, d, color) {
  that.highlight = function(ev, color) {
    // console.log("highlight in tree");
    if (that.highlight_fixed) return;
    let self = d3.select(ev.target.parentElement);
    let d = self.data()[0];
    self.selectAll(".edit-icon").style("opacity", 1);
    // color = color || "rgb(219, 219, 233)";
    color = color || "#ffa953";
    that.tree_node_group
      .select("#id-" + d.id)
      .select("rect.background")
      // .style("fill", color);
      .style('stroke', color)
      .style("stroke-width", 2);
    if (Global.linked_highlight) that.connection_highlight(d);
  };

  // that.dehighlight = function(ev, d) {
  that.dehighlight = function() {
    if (that.highlight_fixed) return;
    // let self = d3.select(ev.target.parentElement);
    // let d = self.data()[0];
    that.tree_node_group
      .selectAll(".tree-node")
      .selectAll(".edit-icon")
      .style("opacity", 0);
    that.tree_node_group
      .selectAll(".tree-node")
      .select("rect.background")
      // .style("fill", "#EBEBF3");
      .style("stroke", "");
    for (let i = 0; i < that.parent.selected_node.node_ids.length; i++){
      let id = that.parent.selected_node.node_ids[i];
      d3.selectAll(`#id-${id}`)
          .selectAll(".background").style('stroke', "#ffa953")
          .style("stroke-width", 2);
    }
    if (Global.linked_highlight) that.connection_dehilight();
  };

  that.connection_highlight = function(node) {
    that.parent.connection_view.highlight_by_node(node);
  };

  that.connection_dehilight = function() {
    that.parent.connection_view.dehighlight();
  };

  that.icon_highlight = function(ev, d) {
    console.log("icon-highlight");
    // if (d.type > 0) return;
    that.tree_node_group
      .select("#id-" + d.id)
      .select("path.icon")
      .style("fill", "#1f1f1f");
  };

  that.icon_dehighlight = function(ev, d) {
    that.tree_node_group
      .select("#id-" + d.id)
      .select("path.icon")
      .style("fill", Global.GrayColor);
  };

  that.clean = function() {
    that.tree_node_group.selectAll(".tree-node").remove();
    that.rest_node_group.selectAll(".rest-tree-node").remove();
    // clean selected state
    for (let i = 0; i < that.parent.selected_node.node_ids.length; i++) {
      let tmp_node = {
        full_name: that.parent.selected_node.nodes[i].full_name,
        id: that.parent.selected_node.node_ids[i],
      };
      that.set_selected_node(tmp_node);
    }
  };
};

export default TextTree;
The diff you're trying to view is too large. Only the first 1000 changed files have been loaded.
Showing with 0 additions and 0 deletions (0 / 0 diffs computed)
swh spinner

Computing file changes ...

back to top

Software Heritage — Copyright (C) 2015–2025, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Content policy— Contact— JavaScript license information— Web API