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
How can I combine two .csv file arrays to create one dataset? After the CSV files are loaded, the arrays are returned to this.files.
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;
}
}
}
from Combine Nodes & Links in D3 Force Graph After CSV is Parsed to make one Array (Angular & D3.JS)
No comments:
Post a Comment