Commit 646ff488 authored by Qianwen's avatar Qianwen
Browse files

refine heatmap

parent edc10ee7
Pipeline #488730 passed with stages
in 3 minutes and 19 seconds
......@@ -56,7 +56,7 @@ import (
)
func main() {
err := agency.StartAgency(task_test)
err := agency.StartAgency(task)
if err != nil {
fmt.Println(err)
}
......@@ -116,6 +116,13 @@ func task(ag *agency.Agent) (err error) {
time.Sleep(10 * time.Second)
id := ag.GetAgentID()
// app logs
cnt := rand.Intn(10)
for i := 0; i < cnt; i++ {
ag.Logger.NewLog("app", "This is agent "+strconv.Itoa(id), "")
time.Sleep(2 * time.Second)
}
// sends 40 messages randomly to other agents
for i := 0; i < 40; i++ {
interval := rand.Intn(5)
......@@ -128,13 +135,6 @@ func task(ag *agency.Agent) (err error) {
ag.ACL.SendMessage(msg)
}
// app logs
cnt := rand.Intn(10)
for i := 0; i < cnt; i++ {
ag.Logger.NewLog("app", "This is agent "+strconv.Itoa(id), "")
time.Sleep(2 * time.Second)
}
// service
svc := schemas.Service{
Desc: "agent" + strconv.Itoa(id),
......
......@@ -167,7 +167,7 @@ func (stor *localStorage) addAgentLogMessage(log schemas.LogMessage) (err error)
stor.mas[log.MASID].msgCnt = make(map[[2]int]int)
}
recvStr := strings.Split(log.AdditionalData, ";")[1]
rec, _ := strconv.Atoi(strings.Split(recvStr, " ")[2])
rec, _ := strconv.Atoi(strings.Split(recvStr, " ")[1])
idx := [2]int{log.AgentID, rec}
stor.mas[log.MASID].msgCnt[idx] += 1
}
......
......@@ -263,10 +263,10 @@ svg {
fill: var(--light-primary-color);
}
text {
/* text {
fill: white;
color: var(--primary-color);
}
} */
.text-title {
font: bold 30px;
......@@ -401,9 +401,13 @@ ngx-charts-bubble-chart {
}
.heatmap{
/* .heatmap{
border: var(--light-primary-color) solid;
}
*/
.heatmap-legend{
background-color: red;
}
.xlabel {
font-size: 20px;
......
......@@ -147,10 +147,25 @@
</mat-form-field>
</div>
<div *ngIf="currState==='heatmap'">
<mat-form-field appearance="fill" class="between" style="width: 200px;">
<mat-label>Automatic partition?</mat-label>
<mat-select (selectionChange)="updatePartition($event.value)">
<mat-option value="Yes">Yes</mat-option>
<mat-option value="No">No</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field appearance="fill" [hidden]="autoPartition" style="width: 100px;">
<mat-label>Partitions</mat-label>
<input matInput (change)="getPartitionNum($event.target.value)" placeholder="5">
</mat-form-field>
</div>
<i class="fas fa-search fa-2x" (click)="onClickSearchButton()"></i>
</div>
<!-- agent selection for non-statistic conditions -->
<!-- agent selection for log and logSeries conditions -->
<div *ngIf="currState ==='log' || currState ==='logSeries'" class= "d-flex align-content-end">
<div class="agent-title">agents</div>
<div class="agents">
......@@ -295,8 +310,9 @@
</div>
</div>
<div class="d-flex justify-content-center">
<svg class="heatmap" *ngIf="currState==='heatmap'" width="600" height="600" >
<div *ngIf="currState==='heatmap'" class="d-flex justify-content-center">
<svg class="heatmap" width="1000" height="800" >
<rect class="grid" *ngFor="let grid of grids, index as i"
[attr.fill]="grid.color"
[attr.x]="grid.x * gridWidth"
......@@ -310,9 +326,32 @@
placement="top"
container="body"
></rect>
<rect *ngFor="let legend of colorPartitionEle, index as i"
[attr.x] = "700"
[attr.y]= "(legendWidth + 10) * i + 50"
[attr.width]="legendWidth"
[attr.height]="legendWidth"
[attr.fill]="legend"
></rect>
<text *ngFor="let text of colorLegendTexts, index as i"
[attr.x] = "750"
[attr.y]= "(legendWidth + 10) * i + 70"
[attr.fill]="gray"
> {{text[0]}}-{{text[1]}}</text>
<!-- <text class="xlabel" x="350" y="730"> agent ID of sender</text>
<text class="ylabel" x="-10" y="350"> agent ID of receiver</text> -->
</svg>
</div>
......
......@@ -100,6 +100,12 @@ export class LoggerComponent implements OnInit {
grids: any[] = [];
gridWidth: number = 4;
popoverFrequency: any = {};
autoPartition: boolean = false;
partitionNum: number = 5;
colorPartitionEle: string[] = [];
colorLegendTexts: number[][] = [];
legendWidth = 30;
constructor(
private loggerService: LoggerService,
......@@ -248,8 +254,10 @@ export class LoggerComponent implements OnInit {
this.drawLogs();
} else if (this.currState==="logSeries") {
this.drawSeries();
} else {
} else if (this.currState==="statistics") {
this.drawStatistics();
} else {
this.drawHeatmap();
}
}
......@@ -558,9 +566,25 @@ export class LoggerComponent implements OnInit {
this.drawHeatmap();
}
/************ convert the count of msg communication to color light ***************/
updatePartition(value: string) {
if (value === "Yes") {
this.autoPartition = true;
} else {
this.autoPartition = false;
}
}
getPartitionNum(value :string) {
const num = parseInt(value)
if (num !== NaN) {
this.partitionNum = num;
}
}
/************ convert the count of msg communication to color light ***************/
// form hsl(240, 100%, 90%) to hsl(240, 100%, 50%)
convertValueToColor(values: number[]): string[] {
autoConvertColor(values: number[]): string[] {
const maxVal = Math.max(...values);
const minVal = Math.min(...values);
let arrayColor: string[] = [];
......@@ -576,6 +600,43 @@ export class LoggerComponent implements OnInit {
return arrayColor;
}
getColorPartitionEle(): string[] {
// form hsl(240, 100%, 50%) to hsl(240, 100%, 90%)
let colors: string[] = [];
for (let i = 0; i < this.partitionNum; i++) {
let percent: number = 100 - i / (this.partitionNum - 1) * 40 - 10;
percent = Math.trunc(percent);
colors.push("hsl(240, 100%, " + percent.toString() + "%)");
}
return colors;
}
getColorLegendTexts(values: number[]): number[][] {
const quo: number = Math.floor(values.length / this.partitionNum)
const remainder: number = values.length % this.partitionNum
let res: number[][] = []
for (let i = 0; i < remainder; i++) {
res.push([values[i * (quo + 1)], values[(i + 1) * (quo + 1) - 1]])
}
for (let i = remainder; i < this.partitionNum; i++) {
res.push([values[i * quo + remainder], values[(i + 1) * quo + remainder - 1]])
}
return res;
}
manualConvertColor(idx: number, len: number): number {
const quo = Math.floor(len / this.partitionNum)
const remainder = len % this.partitionNum
if (Math.floor(idx / (quo + 1)) < remainder) {
return Math.floor(idx / (quo + 1));
} else {
return Math.floor((idx - remainder) / quo);
}
}
onEnterGrid(i: number){
this.popoverFrequency = {};
this.popoverFrequency.x = this.grids[i].x;
......@@ -593,15 +654,46 @@ export class LoggerComponent implements OnInit {
for (let i = 0; i < res.length; i++) {
values.push(parseInt(res[i].split("-")[2]))
}
this.gridColors = this.convertValueToColor(values);
this.grids = [];
for (let i = 0; i < res.length; i++) {
this.grids.push({
x: res[i].split("-")[0],
y: res[i].split("-")[1],
value: res[i].split("-")[2],
color: this.gridColors[i]
if (this.autoPartition) {
this.gridColors = this.autoConvertColor(values);
this.colorPartitionEle = [];
this.colorLegendTexts = [];
this.grids = [];
for (let i = 0; i < res.length; i++) {
this.grids.push({
x: res[i].split("-")[0],
y: res[i].split("-")[1],
value: res[i].split("-")[2],
color: this.gridColors[i]
})
}
} else {
this.grids = [];
this.gridColors = [];
const sortedSet: number[] = [...(new Set(values))].sort();
let mapIdx = new Map();
sortedSet.forEach((ele, idx) => {
mapIdx.set(ele, idx);
})
if (sortedSet.length < this.partitionNum) {
this.partitionNum = sortedSet.length;
}
this.colorPartitionEle = this.getColorPartitionEle();
this.colorLegendTexts = this.getColorLegendTexts(sortedSet);
console.log(this.colorLegendTexts)
console.log(this.colorPartitionEle)
for (const item of res) {
const idx = mapIdx.get(parseInt(item.split("-")[2]));
const color: string = this.colorPartitionEle[this.manualConvertColor(idx, sortedSet.length)];
this.gridColors.push(color)
this.grids.push({
x: item.split("-")[0],
y: item.split("-")[1],
value: item.split("-")[2],
color: color
})
}
}
})
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment