Add basic visualization for topics

This commit is contained in:
Michał Romaszkin 2020-05-08 00:07:11 +02:00
parent 8e638e3037
commit ecb4b1148b
3 changed files with 111 additions and 6 deletions

View File

@ -1 +1 @@
{{ tempdata | json }}
<div #tree></div>

View File

@ -0,0 +1,5 @@
::ng-deep .link {
fill: none;
stroke: #000;
stroke-width: 2px;
}

View File

@ -1,4 +1,10 @@
import { Component, OnInit } from '@angular/core';
import {
Component,
OnInit,
ViewChild,
ElementRef,
AfterViewInit,
} from '@angular/core';
import { Router } from '@angular/router';
import * as d3 from 'd3';
@ -13,6 +19,7 @@ interface ForumData {
interface Discussion {
title: string;
id: string;
first_post: string;
posts: Array<Post>;
}
@ -20,6 +27,8 @@ interface Post {
author: string;
id: string;
message: string;
parent: string;
children?: Post[] | null;
}
@Component({
@ -27,14 +36,105 @@ interface Post {
templateUrl: './view-data.component.html',
styleUrls: ['./view-data.component.scss'],
})
export class ViewDataComponent implements OnInit {
export class ViewDataComponent implements OnInit, AfterViewInit {
@ViewChild('tree', { read: ElementRef })
private treeContainer: ElementRef;
data: ForumData;
tempdata: any;
constructor(private router: Router) {
const fetch = this.router.getCurrentNavigation()?.extras.state?.data;
this.data = JSON.parse(fetch);
console.log(this.data);
const fetch = JSON.parse(
this.router.getCurrentNavigation()?.extras.state?.data
);
this.data = fetch as ForumData;
}
makeHierarchy(): void {
const posts = this.data.discussions[0].posts;
const tree: Array<Post> = [];
const childOf = {} as any;
posts.forEach((item) => {
const { id, parent } = item;
childOf[id] = childOf[id] || [];
item.children = childOf[id];
if (parent !== '0') {
(childOf[parent] = childOf[parent] || []).push(item);
} else {
tree.push(item);
}
});
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 treemap = d3.tree<any>().size([width, height]);
const nodes = d3.hierarchy<any>(tree[0]);
treemap(nodes);
const element = this.treeContainer.nativeElement;
const tooltip = d3
.select(element)
.append('div')
.attr('class', 'tooltip')
.style('position', 'absolute')
.style('opacity', 0);
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');
const node = gNode.selectAll('g.nodes').data(nodes.descendants());
const nodeEnter = node.enter().append('g').classed('node', true);
gLink
.selectAll('g.links')
.data(nodes.links())
.enter()
.append('line')
.classed('link', true)
.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);
nodeEnter
.append('circle')
.attr('cx', (d: any) => d.x)
.attr('cy', (d: any) => d.y)
.attr('r', 25)
.style('fill', '#fff')
.style('stroke', '#ccc')
.on('mouseover', function (d) {
tooltip.transition().duration(200).style('opacity', 1);
tooltip
.html(`Wiadomość: ${d.data.message}`)
.style('left', `${d3.select(this).attr('cx')}px`)
.style('top', `${d3.select(this).attr('cy')}px`);
});
console.log(nodes.descendants());
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);
}
ngAfterViewInit(): void {
this.makeHierarchy();
}
ngOnInit(): void {}