风一更--软件开发--UI--Angular grid -- material table

target : angular material CSS-Grid table style


1.reference

 

2.practicial


 

2.practical


table attributes

1.整体:

 

2.details

 1. frozen 表头


3. 条件性的高亮某个单元格. 也可以借此在 table 的各个行定义中动态添加 class, 来设置行背景色,CSS 配合添加样式。

理想情况下,直接 class= css 样式类。 后面直接赋值 (使用特殊类绑定设置个别 CSS 类)《Angular 高级编程 4th》p218

在宿主元素现有的CSS 类成员身份基础之上进行控制,而不是完全替换它们。

N/A 单元格高亮显式:


2023-06-19 

mat-table  angular *ngFor let index,  odd event  first, last  内置

1.表格自动编号, 主要的作用在, 表格排序发生变化时,序号自动更新。

=====

编号注意 表格导航 标号的处理:

https://stackoverflow.com/questions/49648270/how-to-define-index-in-angular-material-table/49648620

https://www.cnblogs.com/keatkeat/p/11004658.html


2023-06-20

material mat-table, css style 记录,最终采用的结果如下

 table 在外部容器 windth 100%, 高度限定, 右侧有滑动条.

HTML 并不标准,与 material table mat-table 示例相比较

   

 

=============================================================================================== 

简单记录 无效的组合

----------

-------------------------

暂时先采用有效的 混合 HTML 标签.


2023-06-29

如果不需要高度限定,自由高度,可采用如下组合, 

1. dispaly: grid  , grid : auto

2. table


背景:表格 max-height 与 css grid template 一起使用时无法生效. 

探索记录:

1. 使用 angular material Mat table 可生效. 

同一个网格里的两个 块级元素 上下排布,居中对齐


差强人意的当前设计:

h2,h3 {
  margin: 1px 0 1px;
  border-bottom: 1px solid #8e3339;
}
.wrapper {
  width: 95%;
  max-width: 100em;
  margin: 0 auto;
}
.btn_config_op{
  margin: 0 0 0 1.5em;
}
.subcategory {
  margin-top: 1.5em;
  border-bottom: 1px solid #8E3339;
}
.grid-config {
  display: -webkit-grid;
  display: grid;
  -webkit-grid-template-rows : auto auto auto;
  grid-template-rows: auto auto auto;
  -webkit-grid-template-columns: 45% 1fr;
  grid-template-columns: 45% 1fr;
  grid-column-gap: .5em;
  grid-row-gap: .5em;
  margin: 0 -.375em;
}
.grid-config-base {
  -webkit-grid-row: 1/-1;
  grid-row: 1/-1;
  -webkit-grid-column: 1;
  grid-column: 1;
  padding: .175em;
  margin: 0 .375em .375em;
  background-color: #8E3339;
}
.grid-config-condition {
  -webkit-grid-row: 1;
  grid-row: 1;
  -webkit-grid-column: 2;
  grid-column: 2;
  padding: .175em;
  margin: 0 .375em .375em;
  background-color: skyblue;
}
.grid-config-comparison{
  -webkit-grid-row: 2;
  grid-row: 2;
  -webkit-grid-column:2;
  grid-column: 2;
  padding: .175em;
  margin: 0 .375em .375em;
  background-color: #FFC66D;
}
/********************************/
.mat-mdc-table{
  font-family: "Lucida Sans", Verdana, Arial, sans-serif;
  border-collapse: collapse;
  overflow: auto;
  max-height: 900px;
  width: 100%;
}
.mat-mdc-table .mat-mdc-row:nth-child(even){
  background-color: lightgray;
}

.mat-mdc-cell {
  word-break: break-word !important;
  font-size: xx-small;
}
.mat-column-index{
  border-right: 1px solid currentColor;
}
/*.mat-column-index{
  width: 35px;
  border-right: 1px solid currentColor;
  text-align: left;
}
.mat-column-partition{
  width:110px;
  text-align:left;
}
.mat-column-segment{
  width:150px;
  text-align:left;
}
.mat-column-valueType{
  width:120px;
}
.mat-mdc-table .mat-column-charName{
  max-width:100%
}*/
.mat-mdc-option{
  font-size: medium;
}
.grid-config article header {
  text-align: center;
  background-color: wheat;
}
.grid-config article header h3{
  font-style:  italic;
}
css
<!-- Toolbar-->
<header>
  <nav>
    <mat-toolbar color="primary">
      <button mat-icon-button class="app-icon" aria-label="app icon-button with menu  icon">
        <mat-icon>menu</mat-icon>
      </button>
      <span>Data process & analysis platform</span>
      <span class="app-spacer"></span>
      <button mat-icon-button class="app-icon home-icon" aria-label="app icon-button with  home icon"  routerLink="">
        <mat-icon aria-hidden="false" aria-label="app home icon" fontIcon="home">Home</mat-icon>
      </button>
      <button mat-icon-button class="app-icon" aria-label="app icon-button with share  icon">
        <mat-icon>share</mat-icon>
      </button>
    </mat-toolbar>
  </nav>
</header>

<ng-template cdk-portal #overlayConfig="cdkPortal">
  <mat-spinner color="accent"></mat-spinner>
</ng-template>

<!-- main -->
<main class="wrapper">
  <mat-toolbar>
    <mat-slide-toggle [(ngModel)]="configDefault">
      configuration default: {{configDefault}}
    </mat-slide-toggle>
    <span class="app-spacer"></span>
    <button class="btn_config_op" mat-stroked-button color="warn">
      Reset
    </button>
    <button class="btn_config_op" mat-stroked-button color="primary" (click)="submitConfig()" [disabled]="overlayRefConfig">
      Submit
    </button>
  </mat-toolbar>
  <section class="subcategory">

    <mat-sidenav-container [hasBackdrop]="true">
      <mat-sidenav disableClose [(opened)]="configDefault" ></mat-sidenav>
      <mat-sidenav-content>

        <div class="grid-config">

          <article class="grid-config-base">
            <header><h3>base</h3></header>
            <mat-table #tb_bases [dataSource]="configInit.bases" class="mat-elevation-z8"
                       cdkDropList id="tb_id_bases" [cdkDropListData]="configInit.bases"
                       [cdkDropListConnectedTo]="['tb_id_conditions','tb_id_comparisons']"
                       (cdkDropListDropped)="dragDropEventHandler($event)">

              <ng-container matColumnDef="index">
                <mat-header-cell *matHeaderCellDef>no.</mat-header-cell>
                <mat-cell *matCellDef="let cell;let index = index">{{index + 1}}</mat-cell>
              </ng-container>

              <ng-container matColumnDef="partition">
                <mat-header-cell *matHeaderCellDef>partition</mat-header-cell>
                <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.partition}}</mat-cell>
              </ng-container>

              <ng-container matColumnDef="segment">
                <mat-header-cell *matHeaderCellDef>segment</mat-header-cell>
                <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.segment}}</mat-cell>
              </ng-container>

              <ng-container matColumnDef="charName">
                <mat-header-cell *matHeaderCellDef>char name</mat-header-cell>
                <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.charName}}</mat-cell>
              </ng-container>

              <mat-header-row *matHeaderRowDef="metaColumns; sticky: true"></mat-header-row>
              <mat-row *matRowDef="let row; columns: metaColumns; let index = index" cdkDrag [cdkDragData]="row.data"></mat-row>
            </mat-table>
          </article>

          <article class="grid-config-condition">
            <header><h3>condition</h3></header>
            <mat-table #tb_conditions [dataSource]="configInit.conditions" class="mat-elevation-z8"
                       cdkDropList id="tb_id_conditions" [cdkDropListData]="configInit.conditions"
                       [cdkDropListConnectedTo]="['tb_id_bases']"
                       (cdkDropListDropped)="dragDropEventHandler($event)">
              <ng-container matColumnDef="index">
                <mat-header-cell *matHeaderCellDef>no.</mat-header-cell>
                <mat-cell *matCellDef="let cell;let index = index">{{index + 1}}</mat-cell>
              </ng-container>

              <ng-container matColumnDef="partition">
                <mat-header-cell *matHeaderCellDef>partition</mat-header-cell>
                <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.partition}}</mat-cell>
              </ng-container>

              <ng-container matColumnDef="segment">
                <mat-header-cell *matHeaderCellDef>segment</mat-header-cell>
                <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.segment}}</mat-cell>
              </ng-container>

              <ng-container matColumnDef="charName">
                <mat-header-cell *matHeaderCellDef>charName</mat-header-cell>
                <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.charName}}</mat-cell>
              </ng-container>

              <ng-container matColumnDef="valueType">
                <mat-header-cell *matHeaderCellDef>value type</mat-header-cell>
                <mat-cell *matCellDef="let cell;let index = index">{{cell.valueType}}</mat-cell>
              </ng-container>

              <mat-header-row *matHeaderRowDef="configColumns; sticky: true"></mat-header-row>
              <mat-row *matRowDef="let row; columns: configColumns;let index = index;" cdkDrag [cdkDragData]="row.data"></mat-row>

            </mat-table>
          </article>

          <article class="grid-config-comparison">
            <header><h3>comparison</h3></header>
            <mat-table #tb_comparisons [dataSource]="configInit.comparisons" class="mat-elevation-z8"
                       cdkDropList id="tb_id_comparisons" [cdkDropListData]="configInit.comparisons"
                       [cdkDropListConnectedTo]="['tb_id_bases']"
                       (cdkDropListDropped)="dragDropEventHandler($event)">
              <ng-container matColumnDef="index">
                <mat-header-cell *matHeaderCellDef>no.</mat-header-cell>
                <mat-cell *matCellDef="let cell;let index = index">{{index + 1}}</mat-cell>
              </ng-container>

              <ng-container matColumnDef="partition">
                <mat-header-cell *matHeaderCellDef>partition</mat-header-cell>
                <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.partition}}</mat-cell>
              </ng-container>

              <ng-container matColumnDef="segment">
                <mat-header-cell *matHeaderCellDef>segment</mat-header-cell>
                <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.segment}}</mat-cell>
              </ng-container>

              <ng-container matColumnDef="charName">
                <mat-header-cell *matHeaderCellDef>char name</mat-header-cell>
                <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.charName}}</mat-cell>
              </ng-container>

              <ng-container matColumnDef="valueType">
                <mat-header-cell *matHeaderCellDef>value type</mat-header-cell>
                <mat-cell *matCellDef="let cell">
                  <mat-select [(ngModel)]="cell.valueType" name="valueType">
                    <mat-option class="opt_valueType"  *ngFor="let val of valueOptions" [value]="val.value">
                      {{val.viewValue}}
                    </mat-option>
                  </mat-select>
                </mat-cell>
              </ng-container>

              <mat-header-row *matHeaderRowDef="configColumns; sticky: true"></mat-header-row>
              <mat-row *matRowDef="let row; columns: configColumns; let index = index;" cdkDrag [cdkDragData]="row.data"></mat-row>
            </mat-table>
          </article>
        </div>

      </mat-sidenav-content>
    </mat-sidenav-container>

    </section>
</main>
Html
import {Component, OnInit, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core';
import {
  ConfigAquaEdgeRegPerform,
  ConfigEntryAquaEdgeRegPerform
} from "../../model/config_aqua_edge_reg_perform/config_aqua_edge_reg_perform.model";
import {MatTable} from "@angular/material/table";
import {ActivatedRoute, Router} from "@angular/router";
import {ConfigAquaEdgeRegPerformRepository} from "../../model/config_aqua_edge_reg_perform/config_aqua_edge_reg_perform.repository";
import {ConfigAquaEdgeRegPerformRest} from "../../model/config_aqua_edge_reg_perform/config_aqua_edge_reg_perform.rest";
import {CdkOverlayOrigin, Overlay, OverlayConfig, OverlayRef} from "@angular/cdk/overlay";
import {CdkDragDrop, moveItemInArray, transferArrayItem} from "@angular/cdk/drag-drop";
import {TemplatePortal} from "@angular/cdk/portal";

interface valueEnum {
  value: string;
  viewValue: string;
}

@Component({
  selector: 'app-config-aqua-edge-reg-perform',
  templateUrl: './config-aqua-edge-reg-perform.component.html',
  styleUrls: ['./config-aqua-edge-reg-perform.component.css']
})
export class ConfigAquaEdgeRegPerformComponent implements OnInit{

  configDefault:boolean = true;

  // @ts-ignore
  configInit: ConfigAquaEdgeRegPerform;

  // overlay
  // @ts-ignore
  overlayRefConfig: OverlayRef = null;
  // @ts-ignore
  @ViewChild("overlayConfig", {static: false}) templatePortal: TemplatePortal;

  // table dropList config
  metaColumns: string[] = ['index','partition', 'segment', 'charName'];
  configColumns: string[] = ['index','partition', 'segment', 'charName', 'valueType'];

  // @ts-ignore
  @ViewChild('tb_bases') tb_bases: MatTable<ConfigEntryAquaEdgeRegPerform>;
  // @ts-ignore
  @ViewChild('tb_conditions') tb_conditions: MatTable<ConfigEntryAquaEdgeRegPerform>;
  // @ts-ignore
  @ViewChild('tb_comparisons') tb_comparisons: MatTable<ConfigEntryAquaEdgeRegPerform>;

  valueOptions: valueEnum[] = [
    {value: "STRING", viewValue: "String"},
    {value: "NUMBER", viewValue: "Number"}
  ];

  constructor(activatedRoute: ActivatedRoute,
              private configRepository: ConfigAquaEdgeRegPerformRepository,
              private configRest: ConfigAquaEdgeRegPerformRest,
              private router: Router,
              private overlay: Overlay) {
    activatedRoute.params.subscribe(res => {
      configRepository.handleInit(res);
      this.configInit = configRepository.configInit;
    })
  }

  ngOnInit(): void {
    }

  dragDropEventHandler(event: CdkDragDrop<any[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(
        event.container.data,
        event.previousIndex,
        event.currentIndex);
    } else {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex);
    }
    this.tb_bases.renderRows();
    this.tb_conditions.renderRows();
    this.tb_comparisons.renderRows();
  }

  backHome() {
    this.router.navigateByUrl("/home");
  }

  submitConfig() {
    this.openOverlay();
    this.applyConfig();
  }

  applyConfig() {
    let config: ConfigAquaEdgeRegPerform;
    if (this.configDefault) {
      config = this.buildDefaultConfig();
    } else {
      config = this.buildCustomizeConfig();
    }

    // @ts-ignore
    this.configRest.postConfig(config).subscribe(res => {
      this.handleConfigAppliedRes(res);
    });
  }

  buildDefaultConfig() {
    return new ConfigAquaEdgeRegPerform("default", [], [], []);
  }

  buildCustomizeConfig() {
    return new ConfigAquaEdgeRegPerform("customize",
      this.configInit.conditions,
      [],
      this.configInit.comparisons);
  }

  handleConfigAppliedRes(response: any) {
    if (response.statusCode === "NORMAL") {
      this.transferToReport(response);
      return;
    } else {
      alert(response.statusCode);
    }
  }

  private transferToReport(response: any) {
    const data = {
      data: JSON.stringify(response.data)
    };
    this.router.navigate(["/aqua-edge-regression-performance-report", data]);
  }

  // overlay
  openOverlay() {
    const config = new OverlayConfig();
    config.positionStrategy = this.overlay.position()
      .global().centerVertically().centerHorizontally();
    config.disposeOnNavigation = true;
    config.hasBackdrop = true;

    this.overlayRefConfig = this.overlay.create(config);
    this.overlayRefConfig.attach(this.templatePortal);
  }
}
ts

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

=============================================================================================== 

 
posted @ 2023-06-15 20:51  君子之行  阅读(54)  评论(0)    收藏  举报