<commit_before>import React, { Component } from 'react';
import { connect } from 'react-redux';
import Dimensions from 'react-dimensions'

import * as d3 from 'd3';
import { map, groupBy, reduce, forEach, difference, find, uniq, remove, each, includes, assign } from 'lodash';
import moment from 'moment';

import { selectNodes, selectNode } from '../../modules/data/index';
import { normalize, fieldLocator } from '../../helpers/index';

class Graph extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            nodes: [],
            links: [],
            highlight_nodes: [],
            edges: [],
            queries: [],
            clusters: {},
            start: new Date(),
            time: 0,
            n: {
                id: 'test',
            },
            ticks: 0
        };

        const { containerHeight, containerWidth } = props;

        this.network = {
            graph: {
                nodes: [],
                links: [],
                highlight_nodes: [],
                selection: null,
                selectedNodes: [],
                tooltip: null,
                transform: d3.zoomIdentity
            },
            height: containerHeight,
            width: containerWidth,
            simulation: {},
            lines: {
                stroke: {
                    color: "#ccc",
                    thickness: 1
                }
            },
            nodes: {
                fill: {
                    color: "#333"
                },
                stroke: {
                    color: "#fff",
                    thickness: 3
                },
                sizeRange: [12, 30]
            },
            zoomed: function () {
                this.graph.transform = d3.event.transform;
            },
            setup: function (el) {
                this.render = this.render.bind(this);
                this.drawNode = this.drawNode.bind(this);
                this.drawLink = this.drawLink.bind(this);

                this.canvas = el;
                this.context = this.canvas.getContext('2d');
                var canvas = d3.select(this.canvas)

                canvas.on("mousedown", this.mousedown.bind(this))
                    .on("mousemove", this.mousemove.bind(this))
                    .on("mouseup", this.mouseup.bind(this))
                    .call(d3.drag()
                        .filter(() => {
                            return d3.event.altKey;
                        })
                        .subject(this.dragsubject.bind(this))
                        .on("start", this.dragstarted.bind(this))
                        .on("drag", this.dragged.bind(this))
                        .on("end", this.dragended.bind(this))
                    )
                    .call(d3.zoom()
                        .filter(() => {
                            return d3.event.altKey;
                        })
                        .scaleExtent([1 / 2, 8])
                        .on("zoom", this.zoomed.bind(this))
                    );

                this.simulation = d3.forceSimulation()
                    .stop()
                    .force("link", d3.forceLink().id(function (d) {
                        return d.id;
                    }))
                    .force("charge", d3.forceManyBody().strength(-100).distanceMax(300))
                    .force("center", d3.forceCenter(this.width / 2, this.height / 2))
                    .force("vertical", d3.forceY().strength(0.018))
                    .force("horizontal", d3.forceX().strength(0.006));

                this.render();
            },
            forceScale: function (node) {
                var scale = d3.scaleLog().domain(this.nodes.sizeRange).range(this.nodes.sizeRange.slice().reverse());
                return node.r + scale(node.r);
            },
            select: function (nodes) {
                this.graph.selectedNodes = nodes;
            },
            highlight: function (nodes) {
                this.graph.highlight_nodes = nodes;
            },
            updateNodes: function (graph) {
                var countExtent = d3.extent(graph.nodes, function (d) {
                        return d.connections;
                    }),
                    radiusScale = d3.scalePow().exponent(2).domain(countExtent).range(this.nodes.sizeRange);

                var newNodes = false;

                var that = this;

                // remove deleted nodes
                var removedNodes = difference(this.graph.nodes, graph.nodes);
                remove(this.graph.nodes, (n) => {
                    return find(removedNodes, {id: n});
                });

                each(graph.nodes, function (node) {
                    // todo(nl5887): cleanup
                    var n = find(that.graph.nodes, {id: node.id});
                    if (n) {
                        n = assign(n, node);
                        n = assign(n, {force: that.forceScale(n), r: radiusScale(n.connections)});
                        return;
                    }

                    let node2 = _.clone(node);
                    node2 = assign(node2, {force: that.forceScale(node2), r: radiusScale(node2.connections)});

                    that.graph.nodes.push(node2);

                    newNodes = true;
                });

                var removedLinks = difference(this.graph.links, graph.links);
                remove(this.graph.links, (link) => {
                    return find(removedLinks, (o) => {
                        return link.source.id == o.source && link.target.id == o.target;
                    });
                });

                each(graph.links, function (link) {
                    var n = find(that.graph.links, (o) => {
                        return o.source.id == link.source && o.target.id == link.target;
                    });

                    if (n) {
                        return;
                    }

                    that.graph.links.push({source: link.source, target: link.target});
                });


                this.graph.queries = graph.queries;

                if (!newNodes)
                    return;

                this.simulation
                    .nodes(this.graph.nodes);

                this.simulation.force("link")
                    .links(this.graph.links);

                this.simulation.alpha(0.3).restart();
            },
            render: function () {
                if (!this.graph) {
                    return false;
                }

                this.context.save();
                this.context.clearRect(0, 0, this.width, this.height);<commit_msg>fixed issue with deleting nodes<commit_after>import React, { Component } from 'react';
import { connect } from 'react-redux';
import Dimensions from 'react-dimensions'

import * as d3 from 'd3';
import { map, groupBy, reduce, forEach, difference, find, uniq, remove, each, includes, assign } from 'lodash';
import moment from 'moment';

import { selectNodes, selectNode } from '../../modules/data/index';
import { normalize, fieldLocator } from '../../helpers/index';

class Graph extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            nodes: [],
            links: [],
            highlight_nodes: [],
            edges: [],
            queries: [],
            clusters: {},
            start: new Date(),
            time: 0,
            n: {
                id: 'test',
            },
            ticks: 0
        };

        const { containerHeight, containerWidth } = props;

        this.network = {
            graph: {
                nodes: [],
                links: [],
                highlight_nodes: [],
                selection: null,
                queries: [],
                selectedNodes: [],
                tooltip: null,
                transform: d3.zoomIdentity
            },
            height: containerHeight,
            width: containerWidth,
            simulation: {},
            lines: {
                stroke: {
                    color: "#ccc",
                    thickness: 1
                }
            },
            nodes: {
                fill: {
                    color: "#333"
                },
                stroke: {
                    color: "#fff",
                    thickness: 3
                },
                sizeRange: [12, 30]
            },
            zoomed: function () {
                this.graph.transform = d3.event.transform;
            },
            setup: function (el) {
                this.render = this.render.bind(this);
                this.drawNode = this.drawNode.bind(this);
                this.drawLink = this.drawLink.bind(this);

                this.canvas = el;
                this.context = this.canvas.getContext('2d');
                var canvas = d3.select(this.canvas)

                canvas.on("mousedown", this.mousedown.bind(this))
                    .on("mousemove", this.mousemove.bind(this))
                    .on("mouseup", this.mouseup.bind(this))
                    .call(d3.drag()
                        .filter(() => {
                            return d3.event.altKey;
                        })
                        .subject(this.dragsubject.bind(this))
                        .on("start", this.dragstarted.bind(this))
                        .on("drag", this.dragged.bind(this))
                        .on("end", this.dragended.bind(this))
                    )
                    .call(d3.zoom()
                        .filter(() => {
                            return d3.event.altKey;
                        })
                        .scaleExtent([1 / 2, 8])
                        .on("zoom", this.zoomed.bind(this))
                    );

                this.simulation = d3.forceSimulation()
                    .stop()
                    .force("link", d3.forceLink().id(function (d) {
                        return d.id;
                    }))
                    .force("charge", d3.forceManyBody().strength(-100).distanceMax(300))
                    .force("center", d3.forceCenter(this.width / 2, this.height / 2))
                    .force("vertical", d3.forceY().strength(0.018))
                    .force("horizontal", d3.forceX().strength(0.006));

                this.render();
            },
            forceScale: function (node) {
                var scale = d3.scaleLog().domain(this.nodes.sizeRange).range(this.nodes.sizeRange.slice().reverse());
                return node.r + scale(node.r);
            },
            select: function (nodes) {
                this.graph.selectedNodes = nodes;
            },
            highlight: function (nodes) {
                this.graph.highlight_nodes = nodes;
            },
            updateNodes: function (graph) {
                var countExtent = d3.extent(graph.nodes, function (d) {
                        return d.connections;
                    }),
                    radiusScale = d3.scalePow().exponent(2).domain(countExtent).range(this.nodes.sizeRange);

                var newNodes = false;

                var that = this;

                // remove deleted nodes
                remove(this.graph.nodes, (n) => {
                    return !find(graph.nodes, (o) => {
                        return (o.id==n.id);
                    });
                });

                each(graph.nodes, function (node) {
                    // todo(nl5887): cleanup
                    var n = find(that.graph.nodes, {id: node.id});
                    if (n) {
                        n = assign(n, node);
                        n = assign(n, {force: that.forceScale(n), r: radiusScale(n.connections)});
                        return;
                    }

                    let node2 = _.clone(node);
                    node2 = assign(node2, {force: that.forceScale(node2), r: radiusScale(node2.connections)});

                    that.graph.nodes.push(node2);

                    newNodes = true;
                });

                remove(this.graph.links, (link) => {
                    return !find(graph.links, (o) => {
                        return (link.source.id == o.source && link.target.id == o.target);
                    });
                });

                each(graph.links, function (link) {
                    var n = find(that.graph.links, (o) => {
                        return o.source.id == link.source && o.target.id == link.target;
                    });

                    if (n) {
                        return;
                    }

                    that.graph.links.push({source: link.source, target: link.target});
                });

                this.graph.queries = graph.queries;

                if (!newNodes)
                    return;

                this.simulation
                    .nodes(this.graph.nodes);

                this.simulation.force("link")
                    .links(this.graph.links);

                this.simulation.alpha(0.3).restart();
            },
            render: function () {
                if (!this.graph) {
                    return false;
                }

                this.context.save();
                this.context.clearRect(0, 0, this.width, this.height);
{'fraction_non_alphanumeric': 0.1237638597542703, 'fraction_numerical': 0.00958945160323644, 'mean_word_length': 1.060030864197531, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 16, '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': '4804467', 'n_tokens_mistral': 3525, 'n_tokens_neox': 3194, 'n_words': 621}