From fb21d5fdebe58d879c5d6e7a144de3987de3a347 Mon Sep 17 00:00:00 2001 From: Lingzi Date: Tue, 29 Mar 2022 11:26:55 +0800 Subject: [PATCH] fix bug --- .../customindex/customindex.component.html | 6 + .../customindex/customindex.component.spec.ts | 24 ++ .../customindex/customindex.component.ts | 45 ++++ .../customtable/customtable.component.html | 6 + .../customtable/customtable.component.spec.ts | 24 ++ .../customtable/customtable.component.ts | 45 ++++ .../customtable/driver/driver.component.html | 6 + .../driver/driver.component.spec.ts | 24 ++ .../customtable/driver/driver.component.ts | 45 ++++ .../customtable/owner/owner.component.html | 5 + .../customtable/owner/owner.component.spec.ts | 24 ++ .../customtable/owner/owner.component.ts | 45 ++++ .../dataindex/dataindex.component.html | 69 +++++ .../dataindex/dataindex.component.less | 0 .../dataindex/dataindex.component.spec.ts | 0 .../dataindex/dataindex.component.ts | 249 +++++++++++++++++ .../dataindex_line.component.html | 69 +++++ .../dataindex_line.component.less | 0 .../dataindex_line.component.spec.ts | 24 ++ .../dataindex_line.component.ts | 249 +++++++++++++++++ .../operationtable/curve/curve.component.html | 69 +++++ .../operationtable/curve/curve.component.less | 0 .../curve/curve.component.spec.ts | 24 ++ .../operationtable/curve/curve.component.ts | 249 +++++++++++++++++ .../operationtable.component.html | 46 ++++ .../operationtable.component.less | 11 + .../operationtable.component.spec.ts | 24 ++ .../operationtable.component.ts | 89 +++++++ .../operationtable/pie/pie.component.html | 1 + .../operationtable/pie/pie.component.less | 0 .../operationtable/pie/pie.component.spec.ts | 24 ++ .../operationtable/pie/pie.component.ts | 252 ++++++++++++++++++ .../dataindex/dataindex.component.html | 32 --- .../dataindex/dataindex.component.ts | 37 --- .../datatable/datatable-routing.module.ts | 15 +- src/app/routes/datatable/datatable.module.ts | 17 +- .../routes/datatable/services/data.service.ts | 30 +++ src/app/shared/shared-g2.module.ts | 3 +- 38 files changed, 1807 insertions(+), 75 deletions(-) create mode 100644 src/app/routes/datatable/components/customtable/customindex/customindex.component.html create mode 100644 src/app/routes/datatable/components/customtable/customindex/customindex.component.spec.ts create mode 100644 src/app/routes/datatable/components/customtable/customindex/customindex.component.ts create mode 100644 src/app/routes/datatable/components/customtable/customtable.component.html create mode 100644 src/app/routes/datatable/components/customtable/customtable.component.spec.ts create mode 100644 src/app/routes/datatable/components/customtable/customtable.component.ts create mode 100644 src/app/routes/datatable/components/customtable/driver/driver.component.html create mode 100644 src/app/routes/datatable/components/customtable/driver/driver.component.spec.ts create mode 100644 src/app/routes/datatable/components/customtable/driver/driver.component.ts create mode 100644 src/app/routes/datatable/components/customtable/owner/owner.component.html create mode 100644 src/app/routes/datatable/components/customtable/owner/owner.component.spec.ts create mode 100644 src/app/routes/datatable/components/customtable/owner/owner.component.ts create mode 100644 src/app/routes/datatable/components/dataindex/dataindex.component.html rename src/app/routes/datatable/{ => components}/dataindex/dataindex.component.less (100%) rename src/app/routes/datatable/{ => components}/dataindex/dataindex.component.spec.ts (100%) create mode 100644 src/app/routes/datatable/components/dataindex/dataindex.component.ts create mode 100644 src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.html create mode 100644 src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.less create mode 100644 src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.spec.ts create mode 100644 src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.ts create mode 100644 src/app/routes/datatable/components/operationtable/curve/curve.component.html create mode 100644 src/app/routes/datatable/components/operationtable/curve/curve.component.less create mode 100644 src/app/routes/datatable/components/operationtable/curve/curve.component.spec.ts create mode 100644 src/app/routes/datatable/components/operationtable/curve/curve.component.ts create mode 100644 src/app/routes/datatable/components/operationtable/operationtable.component.html create mode 100644 src/app/routes/datatable/components/operationtable/operationtable.component.less create mode 100644 src/app/routes/datatable/components/operationtable/operationtable.component.spec.ts create mode 100644 src/app/routes/datatable/components/operationtable/operationtable.component.ts create mode 100644 src/app/routes/datatable/components/operationtable/pie/pie.component.html create mode 100644 src/app/routes/datatable/components/operationtable/pie/pie.component.less create mode 100644 src/app/routes/datatable/components/operationtable/pie/pie.component.spec.ts create mode 100644 src/app/routes/datatable/components/operationtable/pie/pie.component.ts delete mode 100644 src/app/routes/datatable/dataindex/dataindex.component.html delete mode 100644 src/app/routes/datatable/dataindex/dataindex.component.ts create mode 100644 src/app/routes/datatable/services/data.service.ts diff --git a/src/app/routes/datatable/components/customtable/customindex/customindex.component.html b/src/app/routes/datatable/components/customtable/customindex/customindex.component.html new file mode 100644 index 00000000..56092666 --- /dev/null +++ b/src/app/routes/datatable/components/customtable/customindex/customindex.component.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/app/routes/datatable/components/customtable/customindex/customindex.component.spec.ts b/src/app/routes/datatable/components/customtable/customindex/customindex.component.spec.ts new file mode 100644 index 00000000..09bf44a2 --- /dev/null +++ b/src/app/routes/datatable/components/customtable/customindex/customindex.component.spec.ts @@ -0,0 +1,24 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; +import { DatatableCustomindexComponent } from './customindex.component'; + +describe('DatatableCustomindexComponent', () => { + let component: DatatableCustomindexComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ DatatableCustomindexComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DatatableCustomindexComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/routes/datatable/components/customtable/customindex/customindex.component.ts b/src/app/routes/datatable/components/customtable/customindex/customindex.component.ts new file mode 100644 index 00000000..7e720e39 --- /dev/null +++ b/src/app/routes/datatable/components/customtable/customindex/customindex.component.ts @@ -0,0 +1,45 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { STColumn, STComponent } from '@delon/abc/st'; +import { SFSchema } from '@delon/form'; +import { ModalHelper, _HttpClient } from '@delon/theme'; + +@Component({ + selector: 'app-datatable-customindex', + templateUrl: './customindex.component.html', +}) +export class DatatableCustomindexComponent implements OnInit { + url = `/user`; + searchSchema: SFSchema = { + properties: { + no: { + type: 'string', + title: '编号' + } + } + }; + @ViewChild('st') private readonly st!: STComponent; + columns: STColumn[] = [ + { title: '编号', index: 'no' }, + { title: '调用次数', type: 'number', index: 'callNo' }, + { title: '头像', type: 'img', width: '50px', index: 'avatar' }, + { title: '时间', type: 'date', index: 'updatedAt' }, + { + title: '', + buttons: [ + // { text: '查看', click: (item: any) => `/form/${item.id}` }, + // { text: '编辑', type: 'static', component: FormEditComponent, click: 'reload' }, + ] + } + ]; + + constructor(private http: _HttpClient, private modal: ModalHelper) { } + + ngOnInit(): void { } + + add(): void { + // this.modal + // .createStatic(FormEditComponent, { i: { id: 0 } }) + // .subscribe(() => this.st.reload()); + } + +} diff --git a/src/app/routes/datatable/components/customtable/customtable.component.html b/src/app/routes/datatable/components/customtable/customtable.component.html new file mode 100644 index 00000000..56092666 --- /dev/null +++ b/src/app/routes/datatable/components/customtable/customtable.component.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/app/routes/datatable/components/customtable/customtable.component.spec.ts b/src/app/routes/datatable/components/customtable/customtable.component.spec.ts new file mode 100644 index 00000000..980fc9d9 --- /dev/null +++ b/src/app/routes/datatable/components/customtable/customtable.component.spec.ts @@ -0,0 +1,24 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; +import { DatatableCustomtableComponent } from './customtable.component'; + +describe('DatatableCustomtableComponent', () => { + let component: DatatableCustomtableComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ DatatableCustomtableComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DatatableCustomtableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/routes/datatable/components/customtable/customtable.component.ts b/src/app/routes/datatable/components/customtable/customtable.component.ts new file mode 100644 index 00000000..292a9c25 --- /dev/null +++ b/src/app/routes/datatable/components/customtable/customtable.component.ts @@ -0,0 +1,45 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { STColumn, STComponent } from '@delon/abc/st'; +import { SFSchema } from '@delon/form'; +import { ModalHelper, _HttpClient } from '@delon/theme'; + +@Component({ + selector: 'app-datatable-customtable', + templateUrl: './customtable.component.html', +}) +export class DatatableCustomtableComponent implements OnInit { + url = `/user`; + searchSchema: SFSchema = { + properties: { + no: { + type: 'string', + title: '编号' + } + } + }; + @ViewChild('st') private readonly st!: STComponent; + columns: STColumn[] = [ + { title: '编号', index: 'no' }, + { title: '调用次数', type: 'number', index: 'callNo' }, + { title: '头像', type: 'img', width: '50px', index: 'avatar' }, + { title: '时间', type: 'date', index: 'updatedAt' }, + { + title: '', + buttons: [ + // { text: '查看', click: (item: any) => `/form/${item.id}` }, + // { text: '编辑', type: 'static', component: FormEditComponent, click: 'reload' }, + ] + } + ]; + + constructor(private http: _HttpClient, private modal: ModalHelper) { } + + ngOnInit(): void { } + + add(): void { + // this.modal + // .createStatic(FormEditComponent, { i: { id: 0 } }) + // .subscribe(() => this.st.reload()); + } + +} diff --git a/src/app/routes/datatable/components/customtable/driver/driver.component.html b/src/app/routes/datatable/components/customtable/driver/driver.component.html new file mode 100644 index 00000000..56092666 --- /dev/null +++ b/src/app/routes/datatable/components/customtable/driver/driver.component.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/app/routes/datatable/components/customtable/driver/driver.component.spec.ts b/src/app/routes/datatable/components/customtable/driver/driver.component.spec.ts new file mode 100644 index 00000000..6a2084a2 --- /dev/null +++ b/src/app/routes/datatable/components/customtable/driver/driver.component.spec.ts @@ -0,0 +1,24 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; +import { DatatableDriverComponent } from './driver.component'; + +describe('DatatableDriverComponent', () => { + let component: DatatableDriverComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ DatatableDriverComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DatatableDriverComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/routes/datatable/components/customtable/driver/driver.component.ts b/src/app/routes/datatable/components/customtable/driver/driver.component.ts new file mode 100644 index 00000000..f27f6788 --- /dev/null +++ b/src/app/routes/datatable/components/customtable/driver/driver.component.ts @@ -0,0 +1,45 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { STColumn, STComponent } from '@delon/abc/st'; +import { SFSchema } from '@delon/form'; +import { ModalHelper, _HttpClient } from '@delon/theme'; + +@Component({ + selector: 'app-datatable-driver', + templateUrl: './driver.component.html', +}) +export class DatatableDriverComponent implements OnInit { + url = `/user`; + searchSchema: SFSchema = { + properties: { + no: { + type: 'string', + title: '编号' + } + } + }; + @ViewChild('st') private readonly st!: STComponent; + columns: STColumn[] = [ + { title: '编号', index: 'no' }, + { title: '调用次数', type: 'number', index: 'callNo' }, + { title: '头像', type: 'img', width: '50px', index: 'avatar' }, + { title: '时间', type: 'date', index: 'updatedAt' }, + { + title: '', + buttons: [ + // { text: '查看', click: (item: any) => `/form/${item.id}` }, + // { text: '编辑', type: 'static', component: FormEditComponent, click: 'reload' }, + ] + } + ]; + + constructor(private http: _HttpClient, private modal: ModalHelper) { } + + ngOnInit(): void { } + + add(): void { + // this.modal + // .createStatic(FormEditComponent, { i: { id: 0 } }) + // .subscribe(() => this.st.reload()); + } + +} diff --git a/src/app/routes/datatable/components/customtable/owner/owner.component.html b/src/app/routes/datatable/components/customtable/owner/owner.component.html new file mode 100644 index 00000000..3a90b91b --- /dev/null +++ b/src/app/routes/datatable/components/customtable/owner/owner.component.html @@ -0,0 +1,5 @@ + + + + + diff --git a/src/app/routes/datatable/components/customtable/owner/owner.component.spec.ts b/src/app/routes/datatable/components/customtable/owner/owner.component.spec.ts new file mode 100644 index 00000000..8c518688 --- /dev/null +++ b/src/app/routes/datatable/components/customtable/owner/owner.component.spec.ts @@ -0,0 +1,24 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; +import { DatatableOwnerComponent } from './owner.component'; + +describe('DatatableOwnerComponent', () => { + let component: DatatableOwnerComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ DatatableOwnerComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DatatableOwnerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/routes/datatable/components/customtable/owner/owner.component.ts b/src/app/routes/datatable/components/customtable/owner/owner.component.ts new file mode 100644 index 00000000..af6bf032 --- /dev/null +++ b/src/app/routes/datatable/components/customtable/owner/owner.component.ts @@ -0,0 +1,45 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { STColumn, STComponent } from '@delon/abc/st'; +import { SFSchema } from '@delon/form'; +import { ModalHelper, _HttpClient } from '@delon/theme'; + +@Component({ + selector: 'app-datatable-owner', + templateUrl: './owner.component.html', +}) +export class DatatableOwnerComponent implements OnInit { + url = `/user`; + searchSchema: SFSchema = { + properties: { + no: { + type: 'string', + title: '编号' + } + } + }; + @ViewChild('st') private readonly st!: STComponent; + columns: STColumn[] = [ + { title: '编号', index: 'no' }, + { title: '调用次数', type: 'number', index: 'callNo' }, + { title: '头像', type: 'img', width: '50px', index: 'avatar' }, + { title: '时间', type: 'date', index: 'updatedAt' }, + { + title: '', + buttons: [ + // { text: '查看', click: (item: any) => `/form/${item.id}` }, + // { text: '编辑', type: 'static', component: FormEditComponent, click: 'reload' }, + ] + } + ]; + + constructor(private http: _HttpClient, private modal: ModalHelper) { } + + ngOnInit(): void { } + + add(): void { + // this.modal + // .createStatic(FormEditComponent, { i: { id: 0 } }) + // .subscribe(() => this.st.reload()); + } + +} diff --git a/src/app/routes/datatable/components/dataindex/dataindex.component.html b/src/app/routes/datatable/components/dataindex/dataindex.component.html new file mode 100644 index 00000000..3f148bfd --- /dev/null +++ b/src/app/routes/datatable/components/dataindex/dataindex.component.html @@ -0,0 +1,69 @@ + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+
+
+ + + +
+
+ + + +
+
+
+
+ + + + +
+
+ + + + +
+
\ No newline at end of file diff --git a/src/app/routes/datatable/dataindex/dataindex.component.less b/src/app/routes/datatable/components/dataindex/dataindex.component.less similarity index 100% rename from src/app/routes/datatable/dataindex/dataindex.component.less rename to src/app/routes/datatable/components/dataindex/dataindex.component.less diff --git a/src/app/routes/datatable/dataindex/dataindex.component.spec.ts b/src/app/routes/datatable/components/dataindex/dataindex.component.spec.ts similarity index 100% rename from src/app/routes/datatable/dataindex/dataindex.component.spec.ts rename to src/app/routes/datatable/components/dataindex/dataindex.component.spec.ts diff --git a/src/app/routes/datatable/components/dataindex/dataindex.component.ts b/src/app/routes/datatable/components/dataindex/dataindex.component.ts new file mode 100644 index 00000000..0881c73c --- /dev/null +++ b/src/app/routes/datatable/components/dataindex/dataindex.component.ts @@ -0,0 +1,249 @@ +import { Component, ElementRef, NgZone, OnInit, ViewChild } from '@angular/core'; +import { ModalHelper, _HttpClient } from '@delon/theme'; +import { G2MiniAreaClickItem, G2MiniAreaData } from '@delon/chart/mini-area'; +import { G2PieClickItem, G2PieComponent, G2PieData } from '@delon/chart/pie'; +import { format } from 'date-fns'; +import { DataService } from '../../services/data.service'; +import { Chart, registerShape, Util } from '@antv/g2'; +import { G2TimelineClickItem, G2TimelineData } from '@delon/chart/timeline'; + +@Component({ + selector: 'app-datatable-dataindex', + templateUrl: './dataindex.component.html', + styleUrls: ['./dataindex.component.less'] +}) +export class DatatableDataindexComponent implements OnInit { + @ViewChild('pie', { static: false }) pie!: G2PieComponent; + chartData: G2TimelineData[] = []; + visitData = this.genData(); + salesData = this.genData(); + salesPieData: G2PieData[] = []; + total = ''; + + constructor(private service: DataService, private ngZone: NgZone) { + + } + + ngOnInit(): void { + this.refreshPie(); + this.initLineData() + } + initLineData(){ + for (let i = 0; i < 20; i += 1) { + this.chartData.push({ + time: new Date().getTime() + 1000 * 60 * 60 * 24 * i, + y1: Math.floor(Math.random() * 100) + 1000, + y2: Math.floor(Math.random() * 100) + 10, + }); + } + } + private genData(): G2MiniAreaData[] { + const beginDay = new Date().getTime(); + const res: G2MiniAreaData[] = []; + for (let i = 0; i < 20; i += 1) { + res.push({ + x: format(new Date(beginDay + 1000 * 60 * 60 * 24 * i), 'yyyy-MM-dd'), + y: Math.floor(Math.random() * 100) + 10, + }); + } + return res; + } + + refresh(): void { + this.visitData = this.genData(); + } + refreshPie(): void { + const rv = (min: number = 0, max: number = 5000) => Math.floor(Math.random() * (max - min + 1) + min); + this.salesPieData = [ + { + x: '家用电器', + y: rv(), + }, + { + x: '食用酒水', + y: rv(), + }, + { + x: '个护健康', + y: rv(), + }, + { + x: '服饰箱包', + y: rv(), + }, + { + x: '母婴产品', + y: rv(), + }, + ]; + if (Math.random() > 0.5) { + this.salesPieData.push({ + x: '其他', + y: rv(), + }); + } + this.total = `¥ ${this.salesPieData.reduce((pre, now) => now.y + pre, 0).toFixed(2)}`; + if (this.pie) { + // 等待组件渲染 + setTimeout(() => { + console.log('a') + this.pie.changeData() + }); + } + } + + handleClick(data: G2MiniAreaClickItem): void { + this.service.msgSrv.info(`${data.item.x} - ${data.item.y}`); + } + format(val: number): string { + return `¥ ${val.toFixed(2)}`; + } + render(el: ElementRef): void { + this.ngZone.runOutsideAngular(() => this.init(el.nativeElement)); + } + private init(el: HTMLElement): void { + const data = [ + { item: '货源单', count: 40, percent: 0.4 }, + { item: '合同单', count: 21, percent: 0.21 }, + { item: '事例三', count: 17, percent: 0.17 }, + { item: '事例四', count: 13, percent: 0.13 }, + { item: '事例五', count: 9, percent: 0.09 }, + ]; + const chart = new Chart({ + container: el, + autoFit: true, + height: 400, + }); + // 新建一个 view 用来单独渲染Annotation + const innerView = chart.createView(); + chart.coordinate('theta', { + radius: 0.6, + innerRadius: 0.7, + }); + + chart.data(data); + + chart.scale('percent', { + formatter: val => { + val = val * 100 + '%'; + return val; + }, + }); + + chart.tooltip(false); + + // 声明需要进行自定义图例字段: 'item' + chart.legend('item', { + position: 'right', // 配置图例显示位置 + custom: true, // 关键字段,告诉 G2,要使用自定义的图例 + items: data.map((obj, index) => { + return { + name: obj.item, // 对应 itemName + value: obj.percent, // 对应 itemValue + marker: { + symbol: 'square', // marker 的形状 + style: { + r: 5, // marker 图形半径 + fill: chart.getTheme().colors10[index], // marker 颜色,使用默认颜色,同图形对应 + }, + }, // marker 配置 + }; + }), + itemValue: { + style: { + fill: '#999', + }, // 配置 itemValue 样式 + formatter: (val: any) => `${val * 100}%` // 格式化 itemValue 内容 + }, + }); + + chart + .interval() + .adjust('stack') + .position('percent') + .color('item') + .style({ + fillOpacity: 1, + stroke: 'white', + lineWidth: 8, + }) + .state({ + active: { + style: element => { + const shape = element.shape; + return { + lineWidth: 1, + stroke: 'white', + strokeOpacity: shape.attr('fillOpacity'), + }; + }, + }, + }); + + // 移除图例点击过滤交互 + chart.removeInteraction('legend-filter'); + chart.interaction('element-active'); + + chart.render(); + + // 监听 element 上状态的变化来动态更新 Annotation 信息 + chart.on('element:statechange', (ev: any) => { + const { state, stateStatus, element } = ev.gEvent.originalEvent; + + // 本示例只需要监听 active 的状态变化 + if (state === 'active') { + const data = element.getData(); + if (stateStatus) { + // 更新 Annotation + updateAnnotation(data); + } else { + // 隐藏 Annotation + clearAnnotation(); + } + } + }); + + // 绘制 annotation + let lastItem: any; + function updateAnnotation(data: any) { + if (data.item !== lastItem) { + innerView.annotation().clear(true); + innerView + .annotation() + .text({ + position: ['50%', '50%'], + content: data.item, + style: { + fontSize: 20, + fill: '#8c8c8c', + textAlign: 'center', + }, + offsetY: -20, + }) + .text({ + position: ['50%', '50%'], + content: data.count, + style: { + fontSize: 28, + fill: '#8c8c8c', + textAlign: 'center', + }, + offsetX: -10, + offsetY: 20, + }) + innerView.render(true); + lastItem = data.item; + } + } + + // 清空 annotation + function clearAnnotation() { + innerView.annotation().clear(true); + innerView.render(true); + lastItem = null; + } + + } +} + + diff --git a/src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.html b/src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.html new file mode 100644 index 00000000..3f148bfd --- /dev/null +++ b/src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.html @@ -0,0 +1,69 @@ + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+
+
+ + + +
+
+ + + +
+
+
+
+ + + + +
+
+ + + + +
+
\ No newline at end of file diff --git a/src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.less b/src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.less new file mode 100644 index 00000000..e69de29b diff --git a/src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.spec.ts b/src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.spec.ts new file mode 100644 index 00000000..cd009e56 --- /dev/null +++ b/src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.spec.ts @@ -0,0 +1,24 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; +import { DatatableDataindexComponent } from './dataindex.component'; + +describe('DatatableDataindexComponent', () => { + let component: DatatableDataindexComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ DatatableDataindexComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DatatableDataindexComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.ts b/src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.ts new file mode 100644 index 00000000..eb15c985 --- /dev/null +++ b/src/app/routes/datatable/components/dataindex/dataindex_line/dataindex_line.component.ts @@ -0,0 +1,249 @@ +import { Component, ElementRef, NgZone, OnInit, ViewChild } from '@angular/core'; +import { ModalHelper, _HttpClient } from '@delon/theme'; +import { G2MiniAreaClickItem, G2MiniAreaData } from '@delon/chart/mini-area'; +import { G2PieClickItem, G2PieComponent, G2PieData } from '@delon/chart/pie'; +import { format } from 'date-fns'; +import { DataindexService } from '../services/dataindex.service'; +import { Chart, registerShape, Util } from '@antv/g2'; +import { G2TimelineClickItem, G2TimelineData } from '@delon/chart/timeline'; + +@Component({ + selector: 'app-datatable-dataindex', + templateUrl: './dataindex.component.html', + styleUrls: ['./dataindex.component.less'] +}) +export class DatatableDataindexComponent implements OnInit { + @ViewChild('pie', { static: false }) pie!: G2PieComponent; + chartData: G2TimelineData[] = []; + visitData = this.genData(); + salesData = this.genData(); + salesPieData: G2PieData[] = []; + total = ''; + + constructor(private service: DataindexService, private ngZone: NgZone) { + + } + + ngOnInit(): void { + this.refreshPie(); + this.initLineData() + } + initLineData(){ + for (let i = 0; i < 20; i += 1) { + this.chartData.push({ + time: new Date().getTime() + 1000 * 60 * 60 * 24 * i, + y1: Math.floor(Math.random() * 100) + 1000, + y2: Math.floor(Math.random() * 100) + 10, + }); + } + } + private genData(): G2MiniAreaData[] { + const beginDay = new Date().getTime(); + const res: G2MiniAreaData[] = []; + for (let i = 0; i < 20; i += 1) { + res.push({ + x: format(new Date(beginDay + 1000 * 60 * 60 * 24 * i), 'yyyy-MM-dd'), + y: Math.floor(Math.random() * 100) + 10, + }); + } + return res; + } + + refresh(): void { + this.visitData = this.genData(); + } + refreshPie(): void { + const rv = (min: number = 0, max: number = 5000) => Math.floor(Math.random() * (max - min + 1) + min); + this.salesPieData = [ + { + x: '家用电器', + y: rv(), + }, + { + x: '食用酒水', + y: rv(), + }, + { + x: '个护健康', + y: rv(), + }, + { + x: '服饰箱包', + y: rv(), + }, + { + x: '母婴产品', + y: rv(), + }, + ]; + if (Math.random() > 0.5) { + this.salesPieData.push({ + x: '其他', + y: rv(), + }); + } + this.total = `¥ ${this.salesPieData.reduce((pre, now) => now.y + pre, 0).toFixed(2)}`; + if (this.pie) { + // 等待组件渲染 + setTimeout(() => { + console.log('a') + this.pie.changeData() + }); + } + } + + handleClick(data: G2MiniAreaClickItem): void { + this.service.msgSrv.info(`${data.item.x} - ${data.item.y}`); + } + format(val: number): string { + return `¥ ${val.toFixed(2)}`; + } + render(el: ElementRef): void { + this.ngZone.runOutsideAngular(() => this.init(el.nativeElement)); + } + private init(el: HTMLElement): void { + const data = [ + { item: '货源单', count: 40, percent: 0.4 }, + { item: '合同单', count: 21, percent: 0.21 }, + { item: '事例三', count: 17, percent: 0.17 }, + { item: '事例四', count: 13, percent: 0.13 }, + { item: '事例五', count: 9, percent: 0.09 }, + ]; + const chart = new Chart({ + container: el, + autoFit: true, + height: 400, + }); + // 新建一个 view 用来单独渲染Annotation + const innerView = chart.createView(); + chart.coordinate('theta', { + radius: 0.6, + innerRadius: 0.7, + }); + + chart.data(data); + + chart.scale('percent', { + formatter: val => { + val = val * 100 + '%'; + return val; + }, + }); + + chart.tooltip(false); + + // 声明需要进行自定义图例字段: 'item' + chart.legend('item', { + position: 'right', // 配置图例显示位置 + custom: true, // 关键字段,告诉 G2,要使用自定义的图例 + items: data.map((obj, index) => { + return { + name: obj.item, // 对应 itemName + value: obj.percent, // 对应 itemValue + marker: { + symbol: 'square', // marker 的形状 + style: { + r: 5, // marker 图形半径 + fill: chart.getTheme().colors10[index], // marker 颜色,使用默认颜色,同图形对应 + }, + }, // marker 配置 + }; + }), + itemValue: { + style: { + fill: '#999', + }, // 配置 itemValue 样式 + formatter: (val: any) => `${val * 100}%` // 格式化 itemValue 内容 + }, + }); + + chart + .interval() + .adjust('stack') + .position('percent') + .color('item') + .style({ + fillOpacity: 1, + stroke: 'white', + lineWidth: 8, + }) + .state({ + active: { + style: element => { + const shape = element.shape; + return { + lineWidth: 1, + stroke: 'white', + strokeOpacity: shape.attr('fillOpacity'), + }; + }, + }, + }); + + // 移除图例点击过滤交互 + chart.removeInteraction('legend-filter'); + chart.interaction('element-active'); + + chart.render(); + + // 监听 element 上状态的变化来动态更新 Annotation 信息 + chart.on('element:statechange', (ev: any) => { + const { state, stateStatus, element } = ev.gEvent.originalEvent; + + // 本示例只需要监听 active 的状态变化 + if (state === 'active') { + const data = element.getData(); + if (stateStatus) { + // 更新 Annotation + updateAnnotation(data); + } else { + // 隐藏 Annotation + clearAnnotation(); + } + } + }); + + // 绘制 annotation + let lastItem: any; + function updateAnnotation(data: any) { + if (data.item !== lastItem) { + innerView.annotation().clear(true); + innerView + .annotation() + .text({ + position: ['50%', '50%'], + content: data.item, + style: { + fontSize: 20, + fill: '#8c8c8c', + textAlign: 'center', + }, + offsetY: -20, + }) + .text({ + position: ['50%', '50%'], + content: data.count, + style: { + fontSize: 28, + fill: '#8c8c8c', + textAlign: 'center', + }, + offsetX: -10, + offsetY: 20, + }) + innerView.render(true); + lastItem = data.item; + } + } + + // 清空 annotation + function clearAnnotation() { + innerView.annotation().clear(true); + innerView.render(true); + lastItem = null; + } + + } +} + + diff --git a/src/app/routes/datatable/components/operationtable/curve/curve.component.html b/src/app/routes/datatable/components/operationtable/curve/curve.component.html new file mode 100644 index 00000000..3f148bfd --- /dev/null +++ b/src/app/routes/datatable/components/operationtable/curve/curve.component.html @@ -0,0 +1,69 @@ + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+
+
+ + + +
+
+ + + +
+
+
+
+ + + + +
+
+ + + + +
+
\ No newline at end of file diff --git a/src/app/routes/datatable/components/operationtable/curve/curve.component.less b/src/app/routes/datatable/components/operationtable/curve/curve.component.less new file mode 100644 index 00000000..e69de29b diff --git a/src/app/routes/datatable/components/operationtable/curve/curve.component.spec.ts b/src/app/routes/datatable/components/operationtable/curve/curve.component.spec.ts new file mode 100644 index 00000000..cd009e56 --- /dev/null +++ b/src/app/routes/datatable/components/operationtable/curve/curve.component.spec.ts @@ -0,0 +1,24 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; +import { DatatableDataindexComponent } from './dataindex.component'; + +describe('DatatableDataindexComponent', () => { + let component: DatatableDataindexComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ DatatableDataindexComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DatatableDataindexComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/routes/datatable/components/operationtable/curve/curve.component.ts b/src/app/routes/datatable/components/operationtable/curve/curve.component.ts new file mode 100644 index 00000000..aedbf57a --- /dev/null +++ b/src/app/routes/datatable/components/operationtable/curve/curve.component.ts @@ -0,0 +1,249 @@ +import { Component, ElementRef, NgZone, OnInit, ViewChild } from '@angular/core'; +import { ModalHelper, _HttpClient } from '@delon/theme'; +import { G2MiniAreaClickItem, G2MiniAreaData } from '@delon/chart/mini-area'; +import { G2PieClickItem, G2PieComponent, G2PieData } from '@delon/chart/pie'; +import { format } from 'date-fns'; +import { Chart, registerShape, Util } from '@antv/g2'; +import { G2TimelineClickItem, G2TimelineData } from '@delon/chart/timeline'; +import { DataService } from '../../../services/data.service'; + +@Component({ + selector: 'app-datatable-curve', + templateUrl: './curve.component.html', + styleUrls: ['./curve.component.less'] +}) +export class DatatableDataindexComponent implements OnInit { + @ViewChild('pie', { static: false }) pie!: G2PieComponent; + chartData: G2TimelineData[] = []; + visitData = this.genData(); + salesData = this.genData(); + salesPieData: G2PieData[] = []; + total = ''; + + constructor(private service: DataService, private ngZone: NgZone) { + + } + + ngOnInit(): void { + this.refreshPie(); + this.initLineData() + } + initLineData(){ + for (let i = 0; i < 20; i += 1) { + this.chartData.push({ + time: new Date().getTime() + 1000 * 60 * 60 * 24 * i, + y1: Math.floor(Math.random() * 100) + 1000, + y2: Math.floor(Math.random() * 100) + 10, + }); + } + } + private genData(): G2MiniAreaData[] { + const beginDay = new Date().getTime(); + const res: G2MiniAreaData[] = []; + for (let i = 0; i < 20; i += 1) { + res.push({ + x: format(new Date(beginDay + 1000 * 60 * 60 * 24 * i), 'yyyy-MM-dd'), + y: Math.floor(Math.random() * 100) + 10, + }); + } + return res; + } + + refresh(): void { + this.visitData = this.genData(); + } + refreshPie(): void { + const rv = (min: number = 0, max: number = 5000) => Math.floor(Math.random() * (max - min + 1) + min); + this.salesPieData = [ + { + x: '家用电器', + y: rv(), + }, + { + x: '食用酒水', + y: rv(), + }, + { + x: '个护健康', + y: rv(), + }, + { + x: '服饰箱包', + y: rv(), + }, + { + x: '母婴产品', + y: rv(), + }, + ]; + if (Math.random() > 0.5) { + this.salesPieData.push({ + x: '其他', + y: rv(), + }); + } + this.total = `¥ ${this.salesPieData.reduce((pre, now) => now.y + pre, 0).toFixed(2)}`; + if (this.pie) { + // 等待组件渲染 + setTimeout(() => { + console.log('a') + this.pie.changeData() + }); + } + } + + handleClick(data: G2MiniAreaClickItem): void { + this.service.msgSrv.info(`${data.item.x} - ${data.item.y}`); + } + format(val: number): string { + return `¥ ${val.toFixed(2)}`; + } + render(el: ElementRef): void { + this.ngZone.runOutsideAngular(() => this.init(el.nativeElement)); + } + private init(el: HTMLElement): void { + const data = [ + { item: '货源单', count: 40, percent: 0.4 }, + { item: '合同单', count: 21, percent: 0.21 }, + { item: '事例三', count: 17, percent: 0.17 }, + { item: '事例四', count: 13, percent: 0.13 }, + { item: '事例五', count: 9, percent: 0.09 }, + ]; + const chart = new Chart({ + container: el, + autoFit: true, + height: 400, + }); + // 新建一个 view 用来单独渲染Annotation + const innerView = chart.createView(); + chart.coordinate('theta', { + radius: 0.6, + innerRadius: 0.7, + }); + + chart.data(data); + + chart.scale('percent', { + formatter: val => { + val = val * 100 + '%'; + return val; + }, + }); + + chart.tooltip(false); + + // 声明需要进行自定义图例字段: 'item' + chart.legend('item', { + position: 'right', // 配置图例显示位置 + custom: true, // 关键字段,告诉 G2,要使用自定义的图例 + items: data.map((obj, index) => { + return { + name: obj.item, // 对应 itemName + value: obj.percent, // 对应 itemValue + marker: { + symbol: 'square', // marker 的形状 + style: { + r: 5, // marker 图形半径 + fill: chart.getTheme().colors10[index], // marker 颜色,使用默认颜色,同图形对应 + }, + }, // marker 配置 + }; + }), + itemValue: { + style: { + fill: '#999', + }, // 配置 itemValue 样式 + formatter: (val: any) => `${val * 100}%` // 格式化 itemValue 内容 + }, + }); + + chart + .interval() + .adjust('stack') + .position('percent') + .color('item') + .style({ + fillOpacity: 1, + stroke: 'white', + lineWidth: 8, + }) + .state({ + active: { + style: element => { + const shape = element.shape; + return { + lineWidth: 1, + stroke: 'white', + strokeOpacity: shape.attr('fillOpacity'), + }; + }, + }, + }); + + // 移除图例点击过滤交互 + chart.removeInteraction('legend-filter'); + chart.interaction('element-active'); + + chart.render(); + + // 监听 element 上状态的变化来动态更新 Annotation 信息 + chart.on('element:statechange', (ev: any) => { + const { state, stateStatus, element } = ev.gEvent.originalEvent; + + // 本示例只需要监听 active 的状态变化 + if (state === 'active') { + const data = element.getData(); + if (stateStatus) { + // 更新 Annotation + updateAnnotation(data); + } else { + // 隐藏 Annotation + clearAnnotation(); + } + } + }); + + // 绘制 annotation + let lastItem: any; + function updateAnnotation(data: any) { + if (data.item !== lastItem) { + innerView.annotation().clear(true); + innerView + .annotation() + .text({ + position: ['50%', '50%'], + content: data.item, + style: { + fontSize: 20, + fill: '#8c8c8c', + textAlign: 'center', + }, + offsetY: -20, + }) + .text({ + position: ['50%', '50%'], + content: data.count, + style: { + fontSize: 28, + fill: '#8c8c8c', + textAlign: 'center', + }, + offsetX: -10, + offsetY: 20, + }) + innerView.render(true); + lastItem = data.item; + } + } + + // 清空 annotation + function clearAnnotation() { + innerView.annotation().clear(true); + innerView.render(true); + lastItem = null; + } + + } +} + + diff --git a/src/app/routes/datatable/components/operationtable/operationtable.component.html b/src/app/routes/datatable/components/operationtable/operationtable.component.html new file mode 100644 index 00000000..d50b08b2 --- /dev/null +++ b/src/app/routes/datatable/components/operationtable/operationtable.component.html @@ -0,0 +1,46 @@ + + + + +
+ +
+ + + + + + +
+ + +
+ +
+
+ +
+ +
+ + +
+ +
+ + + + +
+ +
+
+
+
+
+ + + \ No newline at end of file diff --git a/src/app/routes/datatable/components/operationtable/operationtable.component.less b/src/app/routes/datatable/components/operationtable/operationtable.component.less new file mode 100644 index 00000000..6b4b1cba --- /dev/null +++ b/src/app/routes/datatable/components/operationtable/operationtable.component.less @@ -0,0 +1,11 @@ +.chooseBox{ + display: flex; +} +.timeBox{ + display: flex; + margin: 0 0 0 10px; +} +.dateBox{ + display: inline-block; + margin: 0 0 0 10px; +} \ No newline at end of file diff --git a/src/app/routes/datatable/components/operationtable/operationtable.component.spec.ts b/src/app/routes/datatable/components/operationtable/operationtable.component.spec.ts new file mode 100644 index 00000000..3b100f2c --- /dev/null +++ b/src/app/routes/datatable/components/operationtable/operationtable.component.spec.ts @@ -0,0 +1,24 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; +import { DatatableOperationtableComponent } from './operationtable.component'; + +describe('DatatableOperationtableComponent', () => { + let component: DatatableOperationtableComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ DatatableOperationtableComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DatatableOperationtableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/routes/datatable/components/operationtable/operationtable.component.ts b/src/app/routes/datatable/components/operationtable/operationtable.component.ts new file mode 100644 index 00000000..bfa13aea --- /dev/null +++ b/src/app/routes/datatable/components/operationtable/operationtable.component.ts @@ -0,0 +1,89 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { STColumn, STComponent } from '@delon/abc/st'; +import { DatePipe, _HttpClient } from '@delon/theme'; +import { DataService } from '../../services/data.service'; +import { differenceInCalendarDays } from 'date-fns'; + +@Component({ + selector: 'app-datatable-operationtable', + templateUrl: './operationtable.component.html', + styleUrls: ['./operationtable.component.less'], + providers: [DatePipe] + +}) +export class DatatableOperationtableComponent implements OnInit {; + type = 1; + mode = 'year'; + date: any = null; + defineDate = []; + time: any = [] + dateFormat = 'yyyy-MM-dd'; + today = new Date(); + @ViewChild('st') private readonly st!: STComponent; + columns: STColumn[] = [ + { title: '运营主体', index: 'networkTransporterName', className: 'text-center' }, + { title: '订单数', index: 'zsl', className: 'text-center' }, + { title: '应收金额', index: 'yingsje', className: 'text-center' }, + { title: '承运数', index: 'cys', className: 'text-center' }, + { title: '应付运费', index: 'yingfyf', className: 'text-center' }, + { title: '运量(吨)', index: 'yl', className: 'text-center' }, + { title: '待接单数', index: 'djd', className: 'text-center' }, + { title: '在途数', index: 'ysz', className: 'text-center' }, + { title: '运输完成', index: 'yswc', className: 'text-center' }, + { title: '已收金额', index: 'yisje', className: 'text-center' }, + { title: '已付运费', index: 'yifyf', className: 'text-center' } + ]; + /** + * 查询参数 + */ + get reqParams() { + if(this.mode === 'year') { + this.type = 1 + } else if(this.mode === 'month') { + this.type = 2 + } else if(this.mode === 'date') { + this.type = 3 + } else { + this.type = 4 + } + let params: any = { + time: this.time, + type: this.type + }; + + delete params._$expand; + return { ...params }; + } + + constructor(public service: DataService, private datePipe: DatePipe) { } + ngOnInit(): void { } + + changeData(){ + if(this.mode === 'year') { + this.dateFormat = 'yyyy' + } else if(this.mode === 'month') { + this.dateFormat = 'yyyy-MM' + } else { + this.dateFormat = 'yyyy-MM-dd' + } + } + onChange(result: any) { + if(this.mode === 'year') { + this.time = [this.datePipe.transform(this.date, 'yyyy') + '-01-01 00:00:00'] + } else if(this.mode === 'month') { + this.time = [this.datePipe.transform(this.date, 'yyyy-MM') + '-01 00:00:00'] + } else if(this.mode === 'date') { + this.time = [this.datePipe.transform(this.date, 'yyyy-MM-dd') + ' 00:00:00'] + } else{ + this.time = [this.datePipe.transform(this.defineDate[0], 'yyyy-MM-dd') + '00:00:00', this.datePipe.transform(this.defineDate[1], 'yyyy-MM-dd') + ' 00:00:00'] + } + this.st.reload({ ...this.reqParams }); + } + disabledDate = (current: Date): boolean => + // Can not select days before today and today + differenceInCalendarDays(current, this.today) > 0; + exportFun(){ + + } + +} diff --git a/src/app/routes/datatable/components/operationtable/pie/pie.component.html b/src/app/routes/datatable/components/operationtable/pie/pie.component.html new file mode 100644 index 00000000..0640a4d4 --- /dev/null +++ b/src/app/routes/datatable/components/operationtable/pie/pie.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/routes/datatable/components/operationtable/pie/pie.component.less b/src/app/routes/datatable/components/operationtable/pie/pie.component.less new file mode 100644 index 00000000..e69de29b diff --git a/src/app/routes/datatable/components/operationtable/pie/pie.component.spec.ts b/src/app/routes/datatable/components/operationtable/pie/pie.component.spec.ts new file mode 100644 index 00000000..cd009e56 --- /dev/null +++ b/src/app/routes/datatable/components/operationtable/pie/pie.component.spec.ts @@ -0,0 +1,24 @@ +import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; +import { DatatableDataindexComponent } from './dataindex.component'; + +describe('DatatableDataindexComponent', () => { + let component: DatatableDataindexComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ DatatableDataindexComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DatatableDataindexComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/routes/datatable/components/operationtable/pie/pie.component.ts b/src/app/routes/datatable/components/operationtable/pie/pie.component.ts new file mode 100644 index 00000000..1e69183a --- /dev/null +++ b/src/app/routes/datatable/components/operationtable/pie/pie.component.ts @@ -0,0 +1,252 @@ +import { Component, ElementRef, NgZone, OnInit, ViewChild } from '@angular/core'; +import { ModalHelper, _HttpClient } from '@delon/theme'; +import { G2MiniAreaClickItem, G2MiniAreaData } from '@delon/chart/mini-area'; +import { G2PieClickItem, G2PieComponent, G2PieData } from '@delon/chart/pie'; +import { format } from 'date-fns'; +import { Chart, registerShape, Util } from '@antv/g2'; +import { G2TimelineClickItem, G2TimelineData } from '@delon/chart/timeline'; +import { DataService } from '../../../services/data.service'; + +@Component({ + selector: 'app-opeationtable-pie', + templateUrl: './pie.component.html', + styleUrls: ['./pie.component.less'] +}) +export class OperationtablePieComponent implements OnInit { + @ViewChild('pie', { static: false }) pie!: G2PieComponent; + chartData: G2TimelineData[] = []; + visitData = this.genData(); + salesData = this.genData(); + salesPieData: G2PieData[] = []; + total = ''; + + constructor(private service: DataService, private ngZone: NgZone) { + + } + + ngOnInit(): void { + this.refreshPie(); + this.initLineData() + } + initLineData() { + for (let i = 0; i < 20; i += 1) { + this.chartData.push({ + time: new Date().getTime() + 1000 * 60 * 60 * 24 * i, + y1: Math.floor(Math.random() * 100) + 1000, + y2: Math.floor(Math.random() * 100) + 10, + }); + } + } + private genData(): G2MiniAreaData[] { + const beginDay = new Date().getTime(); + const res: G2MiniAreaData[] = []; + for (let i = 0; i < 20; i += 1) { + res.push({ + x: format(new Date(beginDay + 1000 * 60 * 60 * 24 * i), 'yyyy-MM-dd'), + y: Math.floor(Math.random() * 100) + 10, + }); + } + return res; + } + + refresh(): void { + this.visitData = this.genData(); + } + refreshPie(): void { + const rv = (min: number = 0, max: number = 5000) => Math.floor(Math.random() * (max - min + 1) + min); + this.salesPieData = [ + { + x: '家用电器', + y: rv(), + }, + { + x: '食用酒水', + y: rv(), + }, + { + x: '个护健康', + y: rv(), + }, + { + x: '服饰箱包', + y: rv(), + }, + { + x: '母婴产品', + y: rv(), + }, + ]; + if (Math.random() > 0.5) { + this.salesPieData.push({ + x: '其他', + y: rv(), + }); + } + this.total = `¥ ${this.salesPieData.reduce((pre, now) => now.y + pre, 0).toFixed(2)}`; + if (this.pie) { + // 等待组件渲染 + setTimeout(() => { + console.log('a') + this.pie.changeData() + }); + } + } + + handleClick(data: G2MiniAreaClickItem): void { + this.service.msgSrv.info(`${data.item.x} - ${data.item.y}`); + } + format(val: number): string { + return `¥ ${val.toFixed(2)}`; + } + render(el: ElementRef): void { + this.ngZone.runOutsideAngular(() => this.init(el.nativeElement)); + } + private init(el: HTMLElement): void { + const data = [ + { item: '货源单', count: 40, percent: 0.4 }, + { item: '合同单', count: 21, percent: 0.21 }, + { item: '事例三', count: 17, percent: 0.17 }, + { item: '事例四', count: 13, percent: 0.13 }, + { item: '事例五', count: 9, percent: 0.09 }, + ]; + const chart = new Chart({ + container: el, + autoFit: true, + height: 400, + }); + // 新建一个 view 用来单独渲染Annotation + const innerView = chart.createView(); + chart.coordinate('theta', { + radius: 0.6, + innerRadius: 0.7, + }); + + chart.data(data); + + chart.scale('percent', { + formatter: val => { + val = val * 100 + '%'; + return val; + }, + }); + + chart.tooltip(false); + + // 声明需要进行自定义图例字段: 'item' + chart.legend('item', { + position: 'right', // 配置图例显示位置 + custom: true, // 关键字段,告诉 G2,要使用自定义的图例 + items: data.map((obj, index) => { + return { + name: obj.item, // 对应 itemName + value: obj.percent, // 对应 itemValue + marker: { + symbol: 'square', // marker 的形状 + style: { + r: 5, // marker 图形半径 + fill: chart.getTheme().colors10[index], // marker 颜色,使用默认颜色,同图形对应 + }, + }, // marker 配置 + }; + }), + itemValue: { + style: { + fill: '#999', + }, // 配置 itemValue 样式 + formatter: (val: any) => `${val * 100}%` // 格式化 itemValue 内容 + }, + }); + + const interval = chart + .interval() + .adjust('stack') + .position('percent') + .color('item') + .style({ + fillOpacity: 1, + stroke: 'white', + lineWidth: 8, + }) + .state({ + active: { + style: element => { + const shape = element.shape; + return { + lineWidth: 1, + stroke: 'white', + strokeOpacity: shape.attr('fillOpacity'), + }; + }, + }, + }); + + // 移除图例点击过滤交互 + chart.removeInteraction('legend-filter'); + chart.interaction('element-active'); + + chart.render(); + // 默认选择 + interval.elements[0].setState('selected', true); + // 监听 element 上状态的变化来动态更新 Annotation 信息 + chart.on('element:statechange', (ev: any) => { + const { state, stateStatus, element } = ev.gEvent.originalEvent; + + // 本示例只需要监听 active 的状态变化 + if (state === 'active') { + const data = element.getData(); + if (stateStatus) { + // 更新 Annotation + updateAnnotation(data); + } else { + // 隐藏 Annotation + clearAnnotation(); + } + } + }); + + // 绘制 annotation + let lastItem: any; + function updateAnnotation(data: any) { + if (data.item !== lastItem) { + innerView.annotation().clear(true); + innerView + .annotation() + .text({ + position: ['50%', '50%'], + content: data.item, + style: { + fontSize: 20, + fill: '#8c8c8c', + textAlign: 'center', + }, + offsetY: -20, + }) + .text({ + position: ['50%', '50%'], + content: data.count, + style: { + fontSize: 28, + fill: '#8c8c8c', + textAlign: 'center', + }, + offsetX: -10, + offsetY: 20, + }) + innerView.render(true); + + + lastItem = data.item; + } + } + + // 清空 annotation + function clearAnnotation() { + innerView.annotation().clear(true); + innerView.render(true); + lastItem = null; + } + + } +} + + diff --git a/src/app/routes/datatable/dataindex/dataindex.component.html b/src/app/routes/datatable/dataindex/dataindex.component.html deleted file mode 100644 index ffa275ac..00000000 --- a/src/app/routes/datatable/dataindex/dataindex.component.html +++ /dev/null @@ -1,32 +0,0 @@ - - -
-
- - - - - -
-
- - - - - -
-
- - - - - -
-
- - - - - -
-
diff --git a/src/app/routes/datatable/dataindex/dataindex.component.ts b/src/app/routes/datatable/dataindex/dataindex.component.ts deleted file mode 100644 index b180b8a5..00000000 --- a/src/app/routes/datatable/dataindex/dataindex.component.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; -import { ModalHelper, _HttpClient } from '@delon/theme'; -import { G2MiniAreaClickItem, G2MiniAreaData } from '@delon/chart/mini-area'; -import { format } from 'date-fns'; - -@Component({ - selector: 'app-datatable-dataindex', - templateUrl: './dataindex.component.html', - styleUrls: ['./dataindex.component.less'] -}) -export class DatatableDataindexComponent implements OnInit { - visitData = this.genData(); - - constructor(private http: _HttpClient, private modal: ModalHelper) { } - - ngOnInit(): void { } - private genData(): G2MiniAreaData[] { - const beginDay = new Date().getTime(); - const res: G2MiniAreaData[] = []; - for (let i = 0; i < 20; i += 1) { - res.push({ - x: format(new Date(beginDay + 1000 * 60 * 60 * 24 * i), 'yyyy-MM-dd'), - y: Math.floor(Math.random() * 100) + 10, - }); - } - return res; - } - - refresh(): void { - this.visitData = this.genData(); - } - - handleClick(data: G2MiniAreaClickItem): void { - //this.msg.info(`${data.item.x} - ${data.item.y}`); - } - -} diff --git a/src/app/routes/datatable/datatable-routing.module.ts b/src/app/routes/datatable/datatable-routing.module.ts index 76a62af8..3f26a99f 100644 --- a/src/app/routes/datatable/datatable-routing.module.ts +++ b/src/app/routes/datatable/datatable-routing.module.ts @@ -1,10 +1,19 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; -import { DatatableDataindexComponent } from './dataindex/dataindex.component'; +import { DatatableCustomtableComponent } from './components/customtable/customtable.component'; +import { DatatableCustomindexComponent } from './components/customtable/customindex/customindex.component'; +import { DatatableOwnerComponent } from './components/customtable/owner/owner.component'; +import { DatatableDriverComponent } from './components/customtable/driver/driver.component'; +import { DatatableOperationtableComponent } from './components/operationtable/operationtable.component'; +import { DatatableDataindexComponent } from './components/dataindex/dataindex.component'; const routes: Routes = [ - - { path: 'dataindex', component: DatatableDataindexComponent }]; + { path: 'dataindex', component: DatatableDataindexComponent }, + { path: 'customtable', component: DatatableCustomtableComponent }, + { path: 'customindex', component: DatatableCustomindexComponent }, + { path: 'owner', component: DatatableOwnerComponent }, + { path: 'driver', component: DatatableDriverComponent }, + { path: 'operationtable', component: DatatableOperationtableComponent }]; @NgModule({ imports: [RouterModule.forChild(routes)], diff --git a/src/app/routes/datatable/datatable.module.ts b/src/app/routes/datatable/datatable.module.ts index f996d3b5..10668149 100644 --- a/src/app/routes/datatable/datatable.module.ts +++ b/src/app/routes/datatable/datatable.module.ts @@ -1,10 +1,23 @@ import { NgModule, Type } from '@angular/core'; import { SharedModule, SHARED_G2_MODULES } from '@shared'; import { DatatableRoutingModule } from './datatable-routing.module'; -import { DatatableDataindexComponent } from './dataindex/dataindex.component'; +import { DatatableCustomtableComponent } from './components/customtable/customtable.component'; +import { DatatableCustomindexComponent } from './components/customtable/customindex/customindex.component'; +import { DatatableOwnerComponent } from './components/customtable/owner/owner.component'; +import { DatatableDriverComponent } from './components/customtable/driver/driver.component'; +import { DatatableOperationtableComponent } from './components/operationtable/operationtable.component'; +import { DatatableDataindexComponent } from './components/dataindex/dataindex.component'; +import { OperationtablePieComponent } from './components/operationtable/pie/pie.component'; const COMPONENTS: Type[] = [ - DatatableDataindexComponent]; + DatatableDataindexComponent, + DatatableCustomtableComponent, + DatatableCustomindexComponent, + DatatableOwnerComponent, + DatatableDriverComponent, + DatatableOperationtableComponent, + OperationtablePieComponent +]; @NgModule({ imports: [ diff --git a/src/app/routes/datatable/services/data.service.ts b/src/app/routes/datatable/services/data.service.ts new file mode 100644 index 00000000..be36c9cf --- /dev/null +++ b/src/app/routes/datatable/services/data.service.ts @@ -0,0 +1,30 @@ +/* + * @Description : + * @Version : 1.0 + * @Author : Shiming + * @Date : 2021-12-27 10:30:56 + * @LastEditors : Shiming + * @LastEditTime : 2022-01-18 17:14:59 + * @FilePath : \\tms-obc-web\\src\\app\\routes\\account\\services\\account.service.ts + * Copyright (C) 2022 huzhenhong. All rights reserved. + */ + +import { Injectable, Injector } from '@angular/core'; +import { _HttpClient } from '@delon/theme'; +import { NzMessageService } from 'ng-zorro-antd/message'; +import { map } from 'rxjs/operators'; +import { BaseService } from 'src/app/shared/services/core/base.service'; +import { EAFileUtil } from 'src/app/shared/utils/file.util'; + +@Injectable({ + providedIn: 'root', +}) +export class DataService extends BaseService { + + // 查询运营报表 + $api_listOperationalReportPage = `/api/sdc/report/listOperationalReportPage`; + + constructor(public injector: Injector) { + super(injector); + } +} diff --git a/src/app/shared/shared-g2.module.ts b/src/app/shared/shared-g2.module.ts index 93863e08..10ea8fcc 100644 --- a/src/app/shared/shared-g2.module.ts +++ b/src/app/shared/shared-g2.module.ts @@ -3,6 +3,7 @@ import { G2MiniAreaModule } from '@delon/chart/mini-area'; import { G2PieModule } from '@delon/chart/pie'; import { G2TimelineModule } from '@delon/chart/timeline'; import { G2CardModule } from '@delon/chart/card'; +import { G2CustomModule } from '@delon/chart/custom'; -export const SHARED_G2_MODULES = [G2BarModule, G2PieModule, G2TimelineModule, G2MiniAreaModule, G2CardModule]; +export const SHARED_G2_MODULES = [G2BarModule, G2PieModule, G2TimelineModule, G2MiniAreaModule, G2CardModule, G2CustomModule];