I'm working on an application where I am parsing a CSV file on the client-side in Angular and D3.JS to create a graph node and I have an issue where the .csv file rows are a large data set and it is considerably slowing down the application and crashing.
How can I limit the number of nodes and links so the application doesn't crash? The CSV Parser library I am using is NgxCsvParser.
client-parser.component
import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { NgxCsvParser } from 'ngx-csv-parser'; import { NgxCSVParserError } from 'ngx-csv-parser'; @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.scss'] }) export class LoginComponent implements OnInit { files: File[] = []; connections: any[] = []; header = true; nodes: any[] = []; links: any[] = []; constructor( public router: Router, private ngxCsvParser: NgxCsvParser ) {} ngOnInit(): void {} onSelect(event: { addedFiles: any; }) { this.files.push(...event.addedFiles); this.ngxCsvParser.parse(this.files[0], { header: this.header, delimiter: ',' }) .pipe().subscribe((result: Array < any > ) => { this.connections = result; this.nodes.push({ "firstName": "You", "lastName": "", "name": "You", "company": "" }); for (const source of this.connections) { const sourceName = source["First Name"] + " " + source["Last Name"]; this.links.push({ "source": "You", "target": sourceName }); this.nodes.push({ "firstName": source["First Name"], "lastName": source["Last Name"], "name": sourceName, "company": source["Company"] }); for (const target of this.connections) { const targetName = target["First Name"] + " " + target["Last Name"]; if (sourceName != targetName && source["Company"] == target["Company"]) { this.links.push({ "source": sourceName, "target": targetName }); } } const graph = { "nodes": this.nodes, "links": this.links } console.log(graph); localStorage.setItem('graph', JSON.stringify(graph)); } }, (error: NgxCSVParserError) => { console.log('Error', error); }); // this.router.navigateByUrl('/graph'); } onRemove(event: File) { console.log(event); this.files.splice(this.files.indexOf(event), 1); } } d3.component
import { Component, OnInit } from '@angular/core'; import * as d3 from 'd3'; import {Node} from '../d3/models/node'; import {Link} from '../d3/models/link'; @Component({ selector: 'app-graph', templateUrl: './graph.component.html', styleUrls: ['./graph.component.scss'] }) export class GraphComponent implements OnInit { constructor() { } ngOnInit() { const retrievedObject = localStorage.getItem('graph'); const graph = JSON.parse(retrievedObject); this.loadForceDirectedGraph(graph.nodes, graph.links); } loadForceDirectedGraph(nodes: Node[], links: Link[]) { const svg = d3.select('svg'); const width = +svg.attr('width'); const height = +svg.attr('height'); const color = d3.scaleOrdinal(d3.schemeBlues[9]); const simulation = d3.forceSimulation() .force('link', d3.forceLink().id((d: Node) => d.name))// the id of the node .force("charge", d3.forceManyBody().strength(-5).distanceMax(0.5 * Math.min(width, height))) .force('center', d3.forceCenter(width / 2, height / 2)); console.log(nodes, links); const link = svg.append('g') .attr('class', 'links') .selectAll('line') .data(links) .enter() .append('line') .attr('stroke-width', d => Math.sqrt(d.index)) .attr('stroke', 'black'); const node = svg.append('g') .attr('class', 'nodes') .selectAll('circle') .data(nodes) .enter() .append('circle') .attr('r', 8) .attr("fill", function(d) { return color(d.company); }) .call(d3.drag() .on('start', dragStarted) .on('drag', dragged) .on('end', dragEnded) ); node.append('text') .text((d) => d.company) .attr('x', 6) .attr('y', 3); node.append('title').text((d) => d.name); simulation .nodes(nodes) .on('tick', ticked); simulation.force<d3.ForceLink<any, any>>('link') .links(links); function ticked() { node .attr('cx', d => d.x) .attr('cy', d => d.y); link .attr('x1', d => d.source.x) .attr('y1', d => d.source.y) .attr('x2', d => d.target.x) .attr('y2', d => d.target.y); } function dragStarted(event) { if (!event.active) { simulation.alphaTarget(0.3).restart(); } event.subject.fx = event.subject.x; event.subject.fy = event.subject.y; } function dragged(event) { event.subject.fx = event.x; event.subject.fy = event.y; } function dragEnded(event) { if (!event.active) { simulation.alphaTarget(0); } event.subject.fx = null; event.subject.fy = null; } } } https://stackoverflow.com/questions/66880693/limit-number-of-nodes-links-in-d3-force-graph-after-csv-is-parsed-angular-d March 31, 2021 at 10:05AM
没有评论:
发表评论