<commit_before>let fileName = '../js/ssProject.json'; // '../js/sampleGraphData.json'

// TODO: If a root id is passed, then we should add a relationship from the project node to the selected id node
// TODO: Add the project name as the first node in the nodes list of JSON being given

// get the data
d3.json(fileName, function (error, graphData) {
  if (error) {
    console.log(error);
  }

  let passedID = 2142;  // Gets the passed parameter value from URL

  let width = 1000;
  let height = 800;

  // let nodes = {};
  let items = graphData.nodes;
  let itemRelations = graphData.edges;

  // Create a project node and add it to the items list
  let projectNode = { id: -1, name: graphData.name, image: '', type: -1 };
  items.unshift(projectNode);
  projectNode = items[0];

  // Append the SVG object to the body
  // Add a group element within it to encompass all the nodes - this fixes the chrome
  let svg = d3.select('body').append('svg')
    .attr('width', '100%')
    .attr('height', height)
    .call(d3.behavior.zoom().scaleExtent([1, 10])
      .on('zoom', function () {
        svg.attr('transform', 'translate(' + d3.event.translate + ')' + ' scale(' + d3.event.scale + ')');
      }))
    .on('dblclick.zoom', null)  // To remove the double click zoom function
    .append('g');

  // ============ build the arrows ================
  svg.append('svg:defs').selectAll('marker')
    .data(['end'])      // Different link/path types can be defined here
    .enter().append('svg:marker')    // This section adds in the arrows
    .attr('id', String)
    .attr('viewBox', '0 -5 10 10')
    .attr('refX', 25)
    .attr('refY', -1.5)
    .attr('markerWidth', 6)
    .attr('markerHeight', 6)
    .attr('orient', 'auto')
    .append('svg:path')
    .attr('d', 'M0,-5L10,0L0,5')
    .attr('class', 'arrow');

  let force = d3.layout.force()
    .size([width, height])
    .linkDistance(100)  // sets the target distance between linked nodes to the specified value
    .charge(-950)       // - value results in node repulsion, while + value results in node attraction
    .friction(0.5);     // closely approximates velocity decay

  updateGraph(passedID);  // Render the graph

  /*
   * Updates the graph visuals
   * @param rootId - This is the id of the element that is to be the root node coming off the project node
   */
  function updateGraph (rootId = -1) {
    // For each relationship, add the target to the source node
    itemRelations.forEach(function (relItem) {
      let srcNode = items.find(function (item) {
        return item.id === relItem.source;
      });

      // Set the relationship source and target values
      // Note - Use objects only and not just ids of the nodes
      relItem.source = srcNode;
      relItem.target = items.find(function (item) {
        return item.id === relItem.target;
      });

      // Check if downstream items array exists
      if (typeof srcNode.downstream === 'undefined') {
        srcNode.downstream = [];
      }
      srcNode.downstream.push(relItem.target);  // Add the target ID to list of downstream items

      // relItem.value = +relItem.type;
    });

    // Checks to see if a node id was passed
    if (rootId !== -1) {
      // Get the root item from the items list
      let rootItem = items.find(function (item) {
        return item.id === rootId;
      });
      // Add an edge from the project node to the passed node
      itemRelations.unshift({id: 0, source: projectNode, target: rootItem, type: -1});
    }

    // Set the force nodes, edges and start the graph
    force
      .nodes(graphData.nodes)
      .links(graphData.edges)
      .on('tick', tick)
      .start();

    // ============ edges combined with the arrows ===========
    let path = svg.append('svg:g').selectAll('path')
      .data(force.links())
      .enter().append('svg:path')
      .attr('class', thisPath => {
        let result = 'link';
        // Check the type and add a style according to type
        result = (thisPath.type === -1) ? result + ' link-dot' : result;
        result = (thisPath.type === 8) ? ' link-dash' : result;

        return result;
      })
      .attr('marker-end', 'url(#end)');

    // ============ Node Properties Definition ===========
    let node = svg.selectAll('.node')
      .data(force.nodes())
      .enter()
      .append('g')
      .attr('class', function (thisNode) {
        // Add projectRoot class if the node is the project node
        return thisNode.type === -1 ? 'node projectRoot' : 'node';<commit_msg>Added the rootNode as a downstream item to the project list<commit_after>let fileName = '../js/ssProject.json'; // '../js/sampleGraphData.json'

// TODO: If a root id is passed, then we should add a relationship from the project node to the selected id node
// TODO: Add the project name as the first node in the nodes list of JSON being given

// get the data
d3.json(fileName, function (error, graphData) {
  if (error) {
    console.log(error);
  }

  let passedID = 2142;  // Gets the passed parameter value from URL

  let width = 1000;
  let height = 800;

  // let nodes = {};
  let items = graphData.nodes;
  let itemRelations = graphData.edges;

  // Create a project node and add it to the items list
  let projectNode = { id: -1, name: graphData.name, image: '', type: -1 };
  items.unshift(projectNode);
  projectNode = items[0];

  // Append the SVG object to the body
  // Add a group element within it to encompass all the nodes - this fixes the chrome
  let svg = d3.select('body').append('svg')
    .attr('width', '100%')
    .attr('height', height)
    .call(d3.behavior.zoom().scaleExtent([1, 10])
      .on('zoom', function () {
        svg.attr('transform', 'translate(' + d3.event.translate + ')' + ' scale(' + d3.event.scale + ')');
      }))
    .on('dblclick.zoom', null)  // To remove the double click zoom function
    .append('g');

  // ============ build the arrows ================
  svg.append('svg:defs').selectAll('marker')
    .data(['end'])      // Different link/path types can be defined here
    .enter().append('svg:marker')    // This section adds in the arrows
    .attr('id', String)
    .attr('viewBox', '0 -5 10 10')
    .attr('refX', 25)
    .attr('refY', -1.5)
    .attr('markerWidth', 6)
    .attr('markerHeight', 6)
    .attr('orient', 'auto')
    .append('svg:path')
    .attr('d', 'M0,-5L10,0L0,5')
    .attr('class', 'arrow');

  let force = d3.layout.force()
    .size([width, height])
    .linkDistance(100)  // sets the target distance between linked nodes to the specified value
    .charge(-950)       // - value results in node repulsion, while + value results in node attraction
    .friction(0.5);     // closely approximates velocity decay

  updateGraph(passedID);  // Render the graph

  /*
   * Updates the graph visuals
   * @param rootId - This is the id of the element that is to be the root node coming off the project node
   */
  function updateGraph (rootId = -1) {
    // For each relationship, add the target to the source node
    itemRelations.forEach(function (relItem) {
      let srcNode = items.find(function (item) {
        return item.id === relItem.source;
      });

      // Set the relationship source and target values
      // Note - Use objects only and not just ids of the nodes
      relItem.source = srcNode;
      relItem.target = items.find(function (item) {
        return item.id === relItem.target;
      });

      // Check if downstream items array exists
      if (typeof srcNode.downstream === 'undefined') {
        srcNode.downstream = [];
      }
      srcNode.downstream.push(relItem.target);  // Add the target ID to list of downstream items

      // relItem.value = +relItem.type;
    });

    // Checks to see if a node id was passed
    if (rootId !== -1) {
      // Get the root item from the items list
      let rootItem = items.find(function (item) {
        return item.id === rootId;
      });
      // Add an edge from the project node to the passed node
      itemRelations.unshift({id: 0, source: projectNode, target: rootItem, type: -1});
      if (typeof projectNode.downstream === 'undefined') {
        projectNode.downstream = [rootItem];
      } else {
        projectNode.downstream.push(rootItem);
      }
    }

    // Set the force nodes, edges and start the graph
    force
      .nodes(graphData.nodes)
      .links(graphData.edges)
      .on('tick', tick)
      .start();

    // ============ edges combined with the arrows ===========
    let path = svg.append('svg:g').selectAll('path')
      .data(force.links())
      .enter().append('svg:path')
      .attr('class', thisPath => {
        let result = 'link';
        // Check the type and add a style according to type
        result = (thisPath.type === -1) ? result + ' link-dot' : result;
        result = (thisPath.type === 8) ? ' link-dash' : result;

        return result;
      })
      .attr('marker-end', 'url(#end)');

    // ============ Node Properties Definition ===========
    let node = svg.selectAll('.node')
      .data(force.nodes())
      .enter()
      .append('g')
      .attr('class', function (thisNode) {
        // Add projectRoot class if the node is the project node
        return thisNode.type === -1 ? 'node projectRoot' : 'node';
{'fraction_non_alphanumeric': 0.15305022634188403, 'fraction_numerical': 0.012933821944384565, 'mean_word_length': 2.556535070908394, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '801263', 'n_tokens_mistral': 2863, 'n_tokens_neox': 2731, 'n_words': 923}