UPDATE 2/2: add graph
This commit is contained in:
parent
ffca9a8a74
commit
b29ffd0605
@ -4,12 +4,10 @@ import { Post } from '../_interfaces/post';
|
||||
* Returns hierearchy-like array specified for D3 graph
|
||||
*/
|
||||
export default function makeHierarchy(data: Post[]) {
|
||||
console.log('In function!');
|
||||
const tree: Post[] = [];
|
||||
const childOf: any = {};
|
||||
data.forEach((element) => {
|
||||
const { id, parent } = element;
|
||||
console.log(parent);
|
||||
childOf[id] = childOf[id] || [];
|
||||
element.children = childOf[id];
|
||||
if (parent !== 0) {
|
||||
|
@ -0,0 +1 @@
|
||||
<div #tree></div>
|
@ -0,0 +1,5 @@
|
||||
::ng-deep .link {
|
||||
fill: none;
|
||||
stroke: #000;
|
||||
stroke-width: 2px;
|
||||
}
|
@ -1,9 +1,16 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
ViewChild,
|
||||
ElementRef,
|
||||
} from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { GetVisualizationDataService } from '../../_services/get-visualization-data.service';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { concatMap } from 'rxjs/operators';
|
||||
import { concatMap, finalize } from 'rxjs/operators';
|
||||
import { Post } from 'src/app/_interfaces/post';
|
||||
import * as d3 from 'd3';
|
||||
import maked3hierarchy from '../../_functions/maked3hierarchy';
|
||||
|
||||
@Component({
|
||||
@ -14,6 +21,9 @@ import maked3hierarchy from '../../_functions/maked3hierarchy';
|
||||
export class VisualizeForumComponent implements OnInit, OnDestroy {
|
||||
private subscription: Subscription;
|
||||
private data: Post[];
|
||||
private hierarchizedData: Post[];
|
||||
@ViewChild('tree', { read: ElementRef })
|
||||
private treeContainer: ElementRef;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
@ -24,12 +34,101 @@ export class VisualizeForumComponent implements OnInit, OnDestroy {
|
||||
this.subscription = this.route.params
|
||||
.pipe(concatMap((params) => this.getDataService.getDiscussion(params.id)))
|
||||
.subscribe((result) => {
|
||||
this.data = maked3hierarchy(result.posts);
|
||||
console.log(this.data);
|
||||
this.initializeData(result.posts);
|
||||
this.generateGraph();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
|
||||
private initializeData(data: Post[]): void {
|
||||
this.data = data;
|
||||
this.hierarchizedData = maked3hierarchy(data);
|
||||
}
|
||||
|
||||
private generateGraph(): void {
|
||||
/* ToDo: Add option to change sizes */
|
||||
const margin = { top: 50, right: 90, bottom: 30, left: 90 };
|
||||
const width = 660 - margin.left - margin.right;
|
||||
const height = 500 - margin.top - margin.bottom;
|
||||
|
||||
const hierarchizedNodes = d3.hierarchy<Post>(this.hierarchizedData[0]);
|
||||
d3.tree().size([width, height])(hierarchizedNodes);
|
||||
const element = this.treeContainer.nativeElement;
|
||||
|
||||
/* Clear previous graph */
|
||||
d3.select(element).select('svg').remove();
|
||||
|
||||
/* Create SVG */
|
||||
const svg = d3
|
||||
.select(element)
|
||||
.append('svg')
|
||||
.attr('width', width + margin.left + margin.right)
|
||||
.attr('height', height + margin.top + margin.bottom);
|
||||
|
||||
const group = svg
|
||||
.append('g')
|
||||
.attr('transform', `translate(${margin.left}, ${margin.top})`);
|
||||
|
||||
const gLink = group.append('g').attr('class', 'links');
|
||||
const gNode = group.append('g').attr('class', 'nodes');
|
||||
|
||||
/* Custom tooltip */
|
||||
const tooltip = d3
|
||||
.select(element)
|
||||
.append('div')
|
||||
.attr('class', 'tooltip')
|
||||
.style('position', 'absolute')
|
||||
.style('opacity', 0);
|
||||
|
||||
/* Select all nodes and pass data into them */
|
||||
const node = gNode
|
||||
.selectAll('g.nodes')
|
||||
.data(hierarchizedNodes.descendants());
|
||||
|
||||
/* Select all links and pass data into them */
|
||||
const link = gLink.selectAll('g.links').data(hierarchizedNodes.links());
|
||||
|
||||
/* 'Enter' into node, style it properly and create tooltip on hover */
|
||||
const nodeEnter = node.enter().append('g').classed('node', true);
|
||||
nodeEnter
|
||||
.append('circle')
|
||||
.attr('cx', (d: any) => d.x)
|
||||
.attr('cy', (d: any) => d.y)
|
||||
.attr('r', 25)
|
||||
.style('fill', '#fff')
|
||||
.style('stroke', '#ccc');
|
||||
|
||||
nodeEnter
|
||||
.append('text')
|
||||
.attr('x', (d: any) => d.x)
|
||||
.attr('y', (d: any) => d.y)
|
||||
.attr('text-anchor', 'middle')
|
||||
.text((d: any) => d.data.id);
|
||||
|
||||
nodeEnter
|
||||
.on('mouseover', (d) => {
|
||||
tooltip.transition().duration(400).style('opacity', 1);
|
||||
tooltip
|
||||
.html(`Wiadomość:<br> ${d.data.message}`)
|
||||
.style('width', '15rem')
|
||||
.style('background-color', '#fff')
|
||||
.style('border', '1px solid black')
|
||||
.style('left', `${d3.event.pageX + 40}px`)
|
||||
.style('top', `${d3.event.pageY - 10}px`);
|
||||
})
|
||||
.on('mouseout', function (d) {
|
||||
tooltip.transition().duration(400).style('opacity', 0);
|
||||
});
|
||||
|
||||
/* 'Enter' into links and style them properly */
|
||||
const linkEnter = link.enter().append('line').classed('link', true);
|
||||
linkEnter
|
||||
.attr('x1', (d: any) => d.source.x)
|
||||
.attr('y1', (d: any) => d.source.y)
|
||||
.attr('x2', (d: any) => d.target.x)
|
||||
.attr('y2', (d: any) => d.target.y);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user