1fb726d48Sopenharmony_ci/* 2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb726d48Sopenharmony_ci * You may obtain a copy of the License at 6fb726d48Sopenharmony_ci * 7fb726d48Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb726d48Sopenharmony_ci * 9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and 13fb726d48Sopenharmony_ci * limitations under the License. 14fb726d48Sopenharmony_ci */ 15fb726d48Sopenharmony_ci 16fb726d48Sopenharmony_ciimport { BaseElement, element } from '../../BaseElement'; 17fb726d48Sopenharmony_ciimport { LitChartColumnConfig } from './LitChartColumnConfig'; 18fb726d48Sopenharmony_ciimport { resizeCanvas } from '../helper'; 19fb726d48Sopenharmony_ciimport { getProbablyTime } from '../../../trace/database/logic-worker/ProcedureLogicWorkerCommon'; 20fb726d48Sopenharmony_ci 21fb726d48Sopenharmony_ciclass Pillar { 22fb726d48Sopenharmony_ci obj?: unknown; 23fb726d48Sopenharmony_ci xLabel?: string; 24fb726d48Sopenharmony_ci yLabel?: string; 25fb726d48Sopenharmony_ci type?: string; 26fb726d48Sopenharmony_ci root?: boolean; 27fb726d48Sopenharmony_ci bgFrame?: { 28fb726d48Sopenharmony_ci x: number; 29fb726d48Sopenharmony_ci y: number; 30fb726d48Sopenharmony_ci w: number; 31fb726d48Sopenharmony_ci h: number; 32fb726d48Sopenharmony_ci }; 33fb726d48Sopenharmony_ci frame?: { 34fb726d48Sopenharmony_ci x: number; 35fb726d48Sopenharmony_ci y: number; 36fb726d48Sopenharmony_ci w: number; 37fb726d48Sopenharmony_ci h: number; 38fb726d48Sopenharmony_ci }; 39fb726d48Sopenharmony_ci height?: number; 40fb726d48Sopenharmony_ci process?: boolean; 41fb726d48Sopenharmony_ci heightStep?: number; 42fb726d48Sopenharmony_ci centerX?: number; 43fb726d48Sopenharmony_ci centerY?: number; 44fb726d48Sopenharmony_ci color?: string; 45fb726d48Sopenharmony_ci hover?: boolean; 46fb726d48Sopenharmony_ci} 47fb726d48Sopenharmony_ci 48fb726d48Sopenharmony_ciinterface RLine { 49fb726d48Sopenharmony_ci label: string; 50fb726d48Sopenharmony_ci y: number; 51fb726d48Sopenharmony_ci} 52fb726d48Sopenharmony_ci 53fb726d48Sopenharmony_ci@element('lit-chart-column') 54fb726d48Sopenharmony_ciexport class LitChartColumn extends BaseElement { 55fb726d48Sopenharmony_ci private litChartColumnTipEL: HTMLDivElement | null | undefined; 56fb726d48Sopenharmony_ci litChartColumnCanvas: HTMLCanvasElement | undefined | null; 57fb726d48Sopenharmony_ci litChartColumnCtx: CanvasRenderingContext2D | undefined | null; 58fb726d48Sopenharmony_ci litChartColumnCfg: LitChartColumnConfig | null | undefined; 59fb726d48Sopenharmony_ci offset?: { x: number | undefined; y: number | undefined }; 60fb726d48Sopenharmony_ci data: Pillar[] = []; 61fb726d48Sopenharmony_ci rowLines: RLine[] = []; 62fb726d48Sopenharmony_ci 63fb726d48Sopenharmony_ci connectedCallback(): void { 64fb726d48Sopenharmony_ci super.connectedCallback(); 65fb726d48Sopenharmony_ci this.litChartColumnTipEL = this.shadowRoot!.querySelector<HTMLDivElement>('#tip'); 66fb726d48Sopenharmony_ci this.litChartColumnCanvas = this.shadowRoot!.querySelector<HTMLCanvasElement>('#canvas'); 67fb726d48Sopenharmony_ci this.litChartColumnCtx = this.litChartColumnCanvas!.getContext('2d', { alpha: true }); 68fb726d48Sopenharmony_ci resizeCanvas(this.litChartColumnCanvas!); 69fb726d48Sopenharmony_ci this.offset = { x: 60, y: 20 }; 70fb726d48Sopenharmony_ci this.litChartColumnCanvas!.onmouseout = (e): void => { 71fb726d48Sopenharmony_ci this.hideTip(); 72fb726d48Sopenharmony_ci this.data.forEach((it) => (it.hover = false)); 73fb726d48Sopenharmony_ci this.render(); 74fb726d48Sopenharmony_ci }; 75fb726d48Sopenharmony_ci this.litChartColumnCanvas!.onmousemove = (ev): void => { 76fb726d48Sopenharmony_ci let rect = this.getBoundingClientRect(); 77fb726d48Sopenharmony_ci let x = ev.pageX - rect.left; 78fb726d48Sopenharmony_ci let y = ev.pageY - rect.top; 79fb726d48Sopenharmony_ci this.data.forEach((it) => { 80fb726d48Sopenharmony_ci if (contains(it.bgFrame!, x, y)) { 81fb726d48Sopenharmony_ci it.hover = true; //@ts-ignore 82fb726d48Sopenharmony_ci this.litChartColumnCfg?.hoverHandler?.(it.obj.no); 83fb726d48Sopenharmony_ci } else { 84fb726d48Sopenharmony_ci it.hover = false; 85fb726d48Sopenharmony_ci } 86fb726d48Sopenharmony_ci }); 87fb726d48Sopenharmony_ci let pillars = this.data.filter((it) => it.hover); 88fb726d48Sopenharmony_ci if (this.litChartColumnCfg?.seriesField) { 89fb726d48Sopenharmony_ci if (pillars.length > 0) { 90fb726d48Sopenharmony_ci let titleEl = `<label>${this.litChartColumnCfg.xField}: ${pillars[0].xLabel}</label>`; 91fb726d48Sopenharmony_ci let messageEl = pillars.map((it) => `<label>${it.type}: ${it.yLabel}</label>`).join(''); 92fb726d48Sopenharmony_ci let sumEl = `<label>Total: ${pillars //@ts-ignore 93fb726d48Sopenharmony_ci .map((item) => item.obj[this.litChartColumnCfg?.yField!]) 94fb726d48Sopenharmony_ci .reduce((pre, current) => pre + current, 0)}</label>`; 95fb726d48Sopenharmony_ci let innerHtml = `<div class="tip-content">${titleEl}${messageEl}${sumEl}</div>`; 96fb726d48Sopenharmony_ci this.tipTypeShow(x, y, pillars, innerHtml); 97fb726d48Sopenharmony_ci } 98fb726d48Sopenharmony_ci } else { 99fb726d48Sopenharmony_ci if (pillars.length > 0) { 100fb726d48Sopenharmony_ci let title = `<label>${pillars[0].xLabel}:${pillars[0].yLabel}</label>`; 101fb726d48Sopenharmony_ci let innerHtml = `<div class="tip-content">${title}</div>`; 102fb726d48Sopenharmony_ci this.tipTypeShow(x, y, pillars, innerHtml); 103fb726d48Sopenharmony_ci } 104fb726d48Sopenharmony_ci } 105fb726d48Sopenharmony_ci 106fb726d48Sopenharmony_ci if (this.data.filter((it) => it.process).length === 0) { 107fb726d48Sopenharmony_ci this.render(); 108fb726d48Sopenharmony_ci } 109fb726d48Sopenharmony_ci }; 110fb726d48Sopenharmony_ci this.render(); 111fb726d48Sopenharmony_ci } 112fb726d48Sopenharmony_ci 113fb726d48Sopenharmony_ci private tipTypeShow(x: number, y: number, pillars: Pillar[], innerHtml: string): void { 114fb726d48Sopenharmony_ci if (x >= this.clientWidth - this.litChartColumnTipEL!.clientWidth) { 115fb726d48Sopenharmony_ci this.showTip( 116fb726d48Sopenharmony_ci x - this.litChartColumnTipEL!.clientWidth - 10, 117fb726d48Sopenharmony_ci y - 20, 118fb726d48Sopenharmony_ci this.litChartColumnCfg!.tip ? this.litChartColumnCfg!.tip(pillars) : innerHtml 119fb726d48Sopenharmony_ci ); 120fb726d48Sopenharmony_ci } else { 121fb726d48Sopenharmony_ci this.showTip(x + 10, y - 20, this.litChartColumnCfg!.tip ? this.litChartColumnCfg!.tip(pillars) : innerHtml); 122fb726d48Sopenharmony_ci } 123fb726d48Sopenharmony_ci } 124fb726d48Sopenharmony_ci 125fb726d48Sopenharmony_ci showHoverColumn(index: number): void { 126fb726d48Sopenharmony_ci this.data.forEach((it) => { 127fb726d48Sopenharmony_ci //@ts-ignore 128fb726d48Sopenharmony_ci if (it.obj.no === index) { 129fb726d48Sopenharmony_ci it.hover = true; 130fb726d48Sopenharmony_ci } else { 131fb726d48Sopenharmony_ci it.hover = false; 132fb726d48Sopenharmony_ci } 133fb726d48Sopenharmony_ci }); 134fb726d48Sopenharmony_ci let pillars = this.data.filter((it) => it.hover); 135fb726d48Sopenharmony_ci if (this.litChartColumnCfg?.seriesField) { 136fb726d48Sopenharmony_ci if (pillars.length > 0) { 137fb726d48Sopenharmony_ci let hoverData = pillars[0]; 138fb726d48Sopenharmony_ci let title = `<label>${this.litChartColumnCfg.xField}: ${pillars[0].xLabel}</label>`; 139fb726d48Sopenharmony_ci let msg = pillars.map((it) => `<label>${it.type}: ${it.yLabel}</label>`).join(''); 140fb726d48Sopenharmony_ci let sum = `<label>Total: ${pillars //@ts-ignore 141fb726d48Sopenharmony_ci .map((it) => it.obj[this.litChartColumnCfg?.yField!]) 142fb726d48Sopenharmony_ci .reduce((pre, current) => pre + current, 0)}</label>`; 143fb726d48Sopenharmony_ci let innerHtml = `<div class="tip-content">${title}${msg}${sum}</div>`; 144fb726d48Sopenharmony_ci this.showTip( 145fb726d48Sopenharmony_ci this.clientWidth / 2, 146fb726d48Sopenharmony_ci this.clientHeight / 2, 147fb726d48Sopenharmony_ci this.litChartColumnCfg!.tip ? this.litChartColumnCfg!.tip(pillars) : innerHtml 148fb726d48Sopenharmony_ci ); 149fb726d48Sopenharmony_ci } 150fb726d48Sopenharmony_ci } else { 151fb726d48Sopenharmony_ci if (pillars.length > 0) { 152fb726d48Sopenharmony_ci let hoverData = pillars[0]; 153fb726d48Sopenharmony_ci let title = `<label>${pillars[0].xLabel}:${pillars[0].yLabel}</label>`; 154fb726d48Sopenharmony_ci let innerHtml = `<div class="tip-content">${title}</div>`; 155fb726d48Sopenharmony_ci this.showTip( 156fb726d48Sopenharmony_ci this.clientWidth / 2, 157fb726d48Sopenharmony_ci this.clientHeight / 2, 158fb726d48Sopenharmony_ci this.litChartColumnCfg!.tip ? this.litChartColumnCfg!.tip(pillars) : innerHtml 159fb726d48Sopenharmony_ci ); 160fb726d48Sopenharmony_ci } 161fb726d48Sopenharmony_ci } 162fb726d48Sopenharmony_ci 163fb726d48Sopenharmony_ci if (this.data.filter((it) => it.process).length === 0) { 164fb726d48Sopenharmony_ci this.render(); 165fb726d48Sopenharmony_ci } 166fb726d48Sopenharmony_ci } 167fb726d48Sopenharmony_ci 168fb726d48Sopenharmony_ci initElements(): void { 169fb726d48Sopenharmony_ci new ResizeObserver((entries, observer) => { 170fb726d48Sopenharmony_ci entries.forEach((it) => { 171fb726d48Sopenharmony_ci resizeCanvas(this.litChartColumnCanvas!); 172fb726d48Sopenharmony_ci this.measure(); 173fb726d48Sopenharmony_ci this.render(false); 174fb726d48Sopenharmony_ci }); 175fb726d48Sopenharmony_ci }).observe(this); 176fb726d48Sopenharmony_ci } 177fb726d48Sopenharmony_ci 178fb726d48Sopenharmony_ci set config(litChartColumnConfig: LitChartColumnConfig | null | undefined) { 179fb726d48Sopenharmony_ci if (!litChartColumnConfig) { 180fb726d48Sopenharmony_ci return; 181fb726d48Sopenharmony_ci } 182fb726d48Sopenharmony_ci this.litChartColumnCfg = litChartColumnConfig; 183fb726d48Sopenharmony_ci this.measure(); 184fb726d48Sopenharmony_ci this.render(); 185fb726d48Sopenharmony_ci } 186fb726d48Sopenharmony_ci 187fb726d48Sopenharmony_ci set dataSource(litChartColumnArr: unknown[]) { 188fb726d48Sopenharmony_ci if (this.litChartColumnCfg) { 189fb726d48Sopenharmony_ci this.litChartColumnCfg.data = litChartColumnArr; 190fb726d48Sopenharmony_ci this.measure(); 191fb726d48Sopenharmony_ci this.render(); 192fb726d48Sopenharmony_ci } 193fb726d48Sopenharmony_ci } 194fb726d48Sopenharmony_ci 195fb726d48Sopenharmony_ci get dataSource(): unknown[] { 196fb726d48Sopenharmony_ci return this.litChartColumnCfg?.data || []; 197fb726d48Sopenharmony_ci } 198fb726d48Sopenharmony_ci 199fb726d48Sopenharmony_ci dataSort(): void { 200fb726d48Sopenharmony_ci if (!this.litChartColumnCfg!.notSort) { 201fb726d48Sopenharmony_ci this.litChartColumnCfg?.data.sort( 202fb726d48Sopenharmony_ci //@ts-ignore 203fb726d48Sopenharmony_ci (a, b) => b[this.litChartColumnCfg!.yField] - a[this.litChartColumnCfg!.yField] 204fb726d48Sopenharmony_ci ); 205fb726d48Sopenharmony_ci } 206fb726d48Sopenharmony_ci } 207fb726d48Sopenharmony_ci 208fb726d48Sopenharmony_ci haveSeriesField(): void { 209fb726d48Sopenharmony_ci //@ts-ignore 210fb726d48Sopenharmony_ci let maxValue = Math.max(...this.litChartColumnCfg!.data.map((it) => it[this.litChartColumnCfg!.yField])); 211fb726d48Sopenharmony_ci maxValue = Math.ceil(maxValue * 0.1) * 10; 212fb726d48Sopenharmony_ci let partWidth = (this.clientWidth - this.offset!.x!) / this.litChartColumnCfg!.data.length; 213fb726d48Sopenharmony_ci let partHeight = this.clientHeight - this.offset!.y!; 214fb726d48Sopenharmony_ci let gap = partHeight / 5; 215fb726d48Sopenharmony_ci let valGap = maxValue / 5; 216fb726d48Sopenharmony_ci for (let i = 0; i <= 5; i++) { 217fb726d48Sopenharmony_ci this.rowLines.push({ 218fb726d48Sopenharmony_ci y: gap * i, 219fb726d48Sopenharmony_ci label: 220fb726d48Sopenharmony_ci this.litChartColumnCfg!.removeUnit === true 221fb726d48Sopenharmony_ci ? `${maxValue - valGap * i}` 222fb726d48Sopenharmony_ci : `${getProbablyTime(maxValue - valGap * i)}`, 223fb726d48Sopenharmony_ci }); 224fb726d48Sopenharmony_ci } 225fb726d48Sopenharmony_ci this.dataSort(); 226fb726d48Sopenharmony_ci this.litChartColumnCfg?.data.forEach((litChartColumnItem, litChartColumnIndex, array) => { 227fb726d48Sopenharmony_ci this.data.push({ 228fb726d48Sopenharmony_ci color: this.litChartColumnCfg!.color(litChartColumnItem), 229fb726d48Sopenharmony_ci obj: litChartColumnItem, 230fb726d48Sopenharmony_ci root: true, //@ts-ignore 231fb726d48Sopenharmony_ci xLabel: litChartColumnItem[this.litChartColumnCfg!.xField], //@ts-ignore 232fb726d48Sopenharmony_ci yLabel: litChartColumnItem[this.litChartColumnCfg!.yField], 233fb726d48Sopenharmony_ci bgFrame: { 234fb726d48Sopenharmony_ci x: this.offset!.x! + partWidth * litChartColumnIndex, 235fb726d48Sopenharmony_ci y: 0, 236fb726d48Sopenharmony_ci w: partWidth, 237fb726d48Sopenharmony_ci h: partHeight, 238fb726d48Sopenharmony_ci }, 239fb726d48Sopenharmony_ci centerX: this.offset!.x! + partWidth * litChartColumnIndex + partWidth / 2, 240fb726d48Sopenharmony_ci centerY: 241fb726d48Sopenharmony_ci partHeight - //@ts-ignore 242fb726d48Sopenharmony_ci (litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue + //@ts-ignore 243fb726d48Sopenharmony_ci (litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue / 2, 244fb726d48Sopenharmony_ci frame: { 245fb726d48Sopenharmony_ci x: this.offset!.x! + partWidth * litChartColumnIndex + partWidth / 6, //@ts-ignore 246fb726d48Sopenharmony_ci y: partHeight - (litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue, 247fb726d48Sopenharmony_ci w: partWidth - partWidth / 3, //@ts-ignore 248fb726d48Sopenharmony_ci h: (litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue, 249fb726d48Sopenharmony_ci }, 250fb726d48Sopenharmony_ci height: 0, //@ts-ignore 251fb726d48Sopenharmony_ci heightStep: Math.ceil((litChartColumnItem[this.litChartColumnCfg!.yField] * partHeight) / maxValue / 60), 252fb726d48Sopenharmony_ci process: true, 253fb726d48Sopenharmony_ci }); 254fb726d48Sopenharmony_ci }); 255fb726d48Sopenharmony_ci } 256fb726d48Sopenharmony_ci 257fb726d48Sopenharmony_ci noSeriesField( 258fb726d48Sopenharmony_ci itemEl: unknown, 259fb726d48Sopenharmony_ci y: number, 260fb726d48Sopenharmony_ci initH: number, 261fb726d48Sopenharmony_ci maxValue: number, 262fb726d48Sopenharmony_ci partWidth: number, 263fb726d48Sopenharmony_ci partHeight: number, 264fb726d48Sopenharmony_ci reduceGroupIndex: number 265fb726d48Sopenharmony_ci ): void { 266fb726d48Sopenharmony_ci this.data.push({ 267fb726d48Sopenharmony_ci color: this.litChartColumnCfg!.color(itemEl), 268fb726d48Sopenharmony_ci obj: itemEl, 269fb726d48Sopenharmony_ci root: y === 0, //@ts-ignore 270fb726d48Sopenharmony_ci type: itemEl[this.litChartColumnCfg!.seriesField], //@ts-ignore 271fb726d48Sopenharmony_ci xLabel: itemEl[this.litChartColumnCfg!.xField], //@ts-ignore 272fb726d48Sopenharmony_ci yLabel: itemEl[this.litChartColumnCfg!.yField], 273fb726d48Sopenharmony_ci bgFrame: { 274fb726d48Sopenharmony_ci x: this.offset!.x! + partWidth * reduceGroupIndex, 275fb726d48Sopenharmony_ci y: 0, 276fb726d48Sopenharmony_ci w: partWidth, 277fb726d48Sopenharmony_ci h: partHeight, 278fb726d48Sopenharmony_ci }, 279fb726d48Sopenharmony_ci centerX: this.offset!.x! + partWidth * reduceGroupIndex + partWidth / 2, 280fb726d48Sopenharmony_ci centerY: 281fb726d48Sopenharmony_ci partHeight - 282fb726d48Sopenharmony_ci initH - //@ts-ignore 283fb726d48Sopenharmony_ci (itemEl[this.litChartColumnCfg!.yField] * partHeight) / maxValue + //@ts-ignore 284fb726d48Sopenharmony_ci (itemEl[this.litChartColumnCfg!.yField] * partHeight) / maxValue / 2, 285fb726d48Sopenharmony_ci frame: { 286fb726d48Sopenharmony_ci x: this.offset!.x! + partWidth * reduceGroupIndex + partWidth / 6, //@ts-ignore 287fb726d48Sopenharmony_ci y: partHeight - (itemEl[this.litChartColumnCfg!.yField] * partHeight) / maxValue - initH, 288fb726d48Sopenharmony_ci w: partWidth - partWidth / 3, //@ts-ignore 289fb726d48Sopenharmony_ci h: (itemEl[this.litChartColumnCfg!.yField] * partHeight) / maxValue, 290fb726d48Sopenharmony_ci }, 291fb726d48Sopenharmony_ci height: 0, //@ts-ignore 292fb726d48Sopenharmony_ci heightStep: Math.ceil((itemEl[this.litChartColumnCfg!.yField] * partHeight) / maxValue / 60), 293fb726d48Sopenharmony_ci process: true, 294fb726d48Sopenharmony_ci }); 295fb726d48Sopenharmony_ci } 296fb726d48Sopenharmony_ci 297fb726d48Sopenharmony_ci measure(): void { 298fb726d48Sopenharmony_ci if (!this.litChartColumnCfg) { 299fb726d48Sopenharmony_ci return; 300fb726d48Sopenharmony_ci } 301fb726d48Sopenharmony_ci this.data = []; 302fb726d48Sopenharmony_ci this.rowLines = []; 303fb726d48Sopenharmony_ci if (!this.litChartColumnCfg.seriesField) { 304fb726d48Sopenharmony_ci this.haveSeriesField(); 305fb726d48Sopenharmony_ci } else { 306fb726d48Sopenharmony_ci let reduceGroup = this.litChartColumnCfg!.data.reduce((pre, current, index, arr) => { 307fb726d48Sopenharmony_ci //@ts-ignore 308fb726d48Sopenharmony_ci (pre[current[this.litChartColumnCfg!.xField]] = pre[current[this.litChartColumnCfg!.xField]] || []).push( 309fb726d48Sopenharmony_ci current 310fb726d48Sopenharmony_ci ); 311fb726d48Sopenharmony_ci return pre; 312fb726d48Sopenharmony_ci }, {}); //@ts-ignore 313fb726d48Sopenharmony_ci let sums = Reflect.ownKeys(reduceGroup).map( 314fb726d48Sopenharmony_ci ( 315fb726d48Sopenharmony_ci k //@ts-ignore 316fb726d48Sopenharmony_ci ) => (reduceGroup[k] as unknown[]).reduce((pre, current) => pre + current[this.litChartColumnCfg!.yField], 0) 317fb726d48Sopenharmony_ci ); //@ts-ignore 318fb726d48Sopenharmony_ci let maxValue = Math.ceil(Math.max(...sums) * 0.1) * 10; //@ts-ignore 319fb726d48Sopenharmony_ci let partWidth = (this.clientWidth - this.offset!.x!) / Reflect.ownKeys(reduceGroup).length; 320fb726d48Sopenharmony_ci let partHeight = this.clientHeight - this.offset!.y!; 321fb726d48Sopenharmony_ci let gap = partHeight / 5; 322fb726d48Sopenharmony_ci let valGap = maxValue / 5; 323fb726d48Sopenharmony_ci for (let index = 0; index <= 5; index++) { 324fb726d48Sopenharmony_ci this.rowLines.push({ 325fb726d48Sopenharmony_ci y: gap * index, 326fb726d48Sopenharmony_ci label: `${getProbablyTime(maxValue - valGap * index)} `, 327fb726d48Sopenharmony_ci }); 328fb726d48Sopenharmony_ci } //@ts-ignore 329fb726d48Sopenharmony_ci Reflect.ownKeys(reduceGroup) 330fb726d48Sopenharmony_ci .sort( 331fb726d48Sopenharmony_ci (b, a) =>//@ts-ignore 332fb726d48Sopenharmony_ci (reduceGroup[a] as unknown[]).reduce((pre, cur) => pre + (cur[this.litChartColumnCfg!.yField] as number), 0) -//@ts-ignore 333fb726d48Sopenharmony_ci (reduceGroup[b] as unknown[]).reduce((pre, cur) => pre + (cur[this.litChartColumnCfg!.yField] as number), 0) 334fb726d48Sopenharmony_ci ) 335fb726d48Sopenharmony_ci .forEach((reduceGroupKey, reduceGroupIndex) => { 336fb726d48Sopenharmony_ci //@ts-ignore 337fb726d48Sopenharmony_ci let elements = reduceGroup[reduceGroupKey]; 338fb726d48Sopenharmony_ci let initH = 0; 339fb726d48Sopenharmony_ci elements.forEach((itemEl: unknown, y: number) => { 340fb726d48Sopenharmony_ci this.noSeriesField(itemEl, y, initH, maxValue, partWidth, partHeight, reduceGroupIndex); //@ts-ignore 341fb726d48Sopenharmony_ci initH += (itemEl[this.litChartColumnCfg!.yField] * partHeight) / maxValue; 342fb726d48Sopenharmony_ci }); 343fb726d48Sopenharmony_ci }); 344fb726d48Sopenharmony_ci } 345fb726d48Sopenharmony_ci } 346fb726d48Sopenharmony_ci 347fb726d48Sopenharmony_ci get config(): LitChartColumnConfig | null | undefined { 348fb726d48Sopenharmony_ci return this.litChartColumnCfg; 349fb726d48Sopenharmony_ci } 350fb726d48Sopenharmony_ci 351fb726d48Sopenharmony_ci render(ease: boolean = true): void { 352fb726d48Sopenharmony_ci if (!this.litChartColumnCanvas || !this.litChartColumnCfg) { 353fb726d48Sopenharmony_ci return; 354fb726d48Sopenharmony_ci } 355fb726d48Sopenharmony_ci this.litChartColumnCtx!.clearRect(0, 0, this.clientWidth, this.clientHeight); 356fb726d48Sopenharmony_ci this.drawLine(this.litChartColumnCtx!); 357fb726d48Sopenharmony_ci this.data?.forEach((it) => this.drawColumn(this.litChartColumnCtx!, it, ease)); 358fb726d48Sopenharmony_ci if (ease) { 359fb726d48Sopenharmony_ci if (this.data.filter((it) => it.process).length > 0) { 360fb726d48Sopenharmony_ci requestAnimationFrame(() => this.render(ease)); 361fb726d48Sopenharmony_ci } 362fb726d48Sopenharmony_ci } 363fb726d48Sopenharmony_ci } 364fb726d48Sopenharmony_ci 365fb726d48Sopenharmony_ci drawLine(c: CanvasRenderingContext2D): void { 366fb726d48Sopenharmony_ci c.strokeStyle = '#dfdfdf'; 367fb726d48Sopenharmony_ci c.lineWidth = 1; 368fb726d48Sopenharmony_ci c.beginPath(); 369fb726d48Sopenharmony_ci c.fillStyle = '#8c8c8c'; 370fb726d48Sopenharmony_ci this.rowLines.forEach((it, i) => { 371fb726d48Sopenharmony_ci c.moveTo(this.offset!.x!, it.y); 372fb726d48Sopenharmony_ci c.lineTo(this.clientWidth, it.y); 373fb726d48Sopenharmony_ci if (i === 0) { 374fb726d48Sopenharmony_ci c.fillText(it.label, this.offset!.x! - c.measureText(it.label).width - 2, it.y + 11); 375fb726d48Sopenharmony_ci } else { 376fb726d48Sopenharmony_ci c.fillText(it.label, this.offset!.x! - c.measureText(it.label).width - 2, it.y + 4); 377fb726d48Sopenharmony_ci } 378fb726d48Sopenharmony_ci }); 379fb726d48Sopenharmony_ci c.stroke(); 380fb726d48Sopenharmony_ci c.closePath(); 381fb726d48Sopenharmony_ci } 382fb726d48Sopenharmony_ci 383fb726d48Sopenharmony_ci drawColumn(c: CanvasRenderingContext2D, it: Pillar, ease: boolean): void { 384fb726d48Sopenharmony_ci if (it.hover) { 385fb726d48Sopenharmony_ci c.globalAlpha = 0.2; 386fb726d48Sopenharmony_ci c.fillStyle = '#999999'; 387fb726d48Sopenharmony_ci c.fillRect(it.bgFrame!.x, it.bgFrame!.y, it.bgFrame!.w, it.bgFrame!.h); 388fb726d48Sopenharmony_ci c.globalAlpha = 1.0; 389fb726d48Sopenharmony_ci } 390fb726d48Sopenharmony_ci c.fillStyle = it.color || '#ff0000'; 391fb726d48Sopenharmony_ci if (ease) { 392fb726d48Sopenharmony_ci if (it.height! < it.frame!.h) { 393fb726d48Sopenharmony_ci it.process = true; 394fb726d48Sopenharmony_ci c.fillRect(it.frame!.x, it.frame!.y + (it.frame!.h - it.height!), it.frame!.w, it.height!); 395fb726d48Sopenharmony_ci it.height! += it.heightStep!; 396fb726d48Sopenharmony_ci } else { 397fb726d48Sopenharmony_ci c.fillRect(it.frame!.x, it.frame!.y, it.frame!.w, it.frame!.h); 398fb726d48Sopenharmony_ci it.process = false; 399fb726d48Sopenharmony_ci } 400fb726d48Sopenharmony_ci } else { 401fb726d48Sopenharmony_ci c.fillRect(it.frame!.x, it.frame!.y, it.frame!.w, it.frame!.h); 402fb726d48Sopenharmony_ci it.process = false; 403fb726d48Sopenharmony_ci } 404fb726d48Sopenharmony_ci 405fb726d48Sopenharmony_ci c.beginPath(); 406fb726d48Sopenharmony_ci c.strokeStyle = '#d8d8d8'; 407fb726d48Sopenharmony_ci c.moveTo(it.centerX!, it.frame!.y + it.frame!.h!); 408fb726d48Sopenharmony_ci if (it.root) { 409fb726d48Sopenharmony_ci c.lineTo(it.centerX!, it.frame!.y + it.frame!.h + 4); 410fb726d48Sopenharmony_ci } 411fb726d48Sopenharmony_ci let xMetrics = c.measureText(it.xLabel!); 412fb726d48Sopenharmony_ci let xMetricsH = xMetrics.actualBoundingBoxAscent + xMetrics.actualBoundingBoxDescent; 413fb726d48Sopenharmony_ci let yMetrics = c.measureText(it.yLabel!); 414fb726d48Sopenharmony_ci let yMetricsH = yMetrics.fontBoundingBoxAscent + yMetrics.fontBoundingBoxDescent; 415fb726d48Sopenharmony_ci c.fillStyle = '#8c8c8c'; 416fb726d48Sopenharmony_ci if (it.root) { 417fb726d48Sopenharmony_ci c.fillText(it.xLabel!, it.centerX! - xMetrics.width / 2, it.frame!.y + it.frame!.h + 15); 418fb726d48Sopenharmony_ci } 419fb726d48Sopenharmony_ci c.fillStyle = '#fff'; 420fb726d48Sopenharmony_ci if (this.litChartColumnCfg?.label) { 421fb726d48Sopenharmony_ci if (yMetricsH < it.frame!.h) { 422fb726d48Sopenharmony_ci c.fillText( 423fb726d48Sopenharmony_ci // @ts-ignore 424fb726d48Sopenharmony_ci this.litChartColumnCfg!.label!.content ? this.litChartColumnCfg!.label!.content(it.obj) : it.yLabel!, 425fb726d48Sopenharmony_ci it.centerX! - yMetrics.width / 2, 426fb726d48Sopenharmony_ci it.centerY! + (it.frame!.h - it.height!) / 2 427fb726d48Sopenharmony_ci ); 428fb726d48Sopenharmony_ci } 429fb726d48Sopenharmony_ci } 430fb726d48Sopenharmony_ci c.stroke(); 431fb726d48Sopenharmony_ci c.closePath(); 432fb726d48Sopenharmony_ci } 433fb726d48Sopenharmony_ci 434fb726d48Sopenharmony_ci beginPath(stroke: boolean, fill: boolean): (fn: (c: CanvasRenderingContext2D) => void) => void { 435fb726d48Sopenharmony_ci return (fn: (c: CanvasRenderingContext2D) => void) => { 436fb726d48Sopenharmony_ci this.litChartColumnCtx!.beginPath(); 437fb726d48Sopenharmony_ci fn?.(this.litChartColumnCtx!); 438fb726d48Sopenharmony_ci if (stroke) { 439fb726d48Sopenharmony_ci this.litChartColumnCtx!.stroke(); 440fb726d48Sopenharmony_ci } 441fb726d48Sopenharmony_ci if (fill) { 442fb726d48Sopenharmony_ci this.litChartColumnCtx!.fill(); 443fb726d48Sopenharmony_ci } 444fb726d48Sopenharmony_ci this.litChartColumnCtx!.closePath(); 445fb726d48Sopenharmony_ci }; 446fb726d48Sopenharmony_ci } 447fb726d48Sopenharmony_ci 448fb726d48Sopenharmony_ci showTip(x: number, y: number, msg: string): void { 449fb726d48Sopenharmony_ci this.litChartColumnTipEL!.style.display = 'flex'; 450fb726d48Sopenharmony_ci this.litChartColumnTipEL!.style.top = `${y}px`; 451fb726d48Sopenharmony_ci this.litChartColumnTipEL!.style.left = `${x}px`; 452fb726d48Sopenharmony_ci this.litChartColumnTipEL!.innerHTML = msg; 453fb726d48Sopenharmony_ci } 454fb726d48Sopenharmony_ci 455fb726d48Sopenharmony_ci hideTip(): void { 456fb726d48Sopenharmony_ci this.litChartColumnTipEL!.style.display = 'none'; 457fb726d48Sopenharmony_ci } 458fb726d48Sopenharmony_ci 459fb726d48Sopenharmony_ci initHtml(): string { 460fb726d48Sopenharmony_ci return ` 461fb726d48Sopenharmony_ci <style> 462fb726d48Sopenharmony_ci :host { 463fb726d48Sopenharmony_ci display: flex; 464fb726d48Sopenharmony_ci flex-direction: column; 465fb726d48Sopenharmony_ci width: 100%; 466fb726d48Sopenharmony_ci height: 100%; 467fb726d48Sopenharmony_ci } 468fb726d48Sopenharmony_ci #tip{ 469fb726d48Sopenharmony_ci background-color: #f5f5f4; 470fb726d48Sopenharmony_ci border: 1px solid #fff; 471fb726d48Sopenharmony_ci border-radius: 5px; 472fb726d48Sopenharmony_ci color: #333322; 473fb726d48Sopenharmony_ci font-size: 8pt; 474fb726d48Sopenharmony_ci position: absolute; 475fb726d48Sopenharmony_ci min-width: max-content; 476fb726d48Sopenharmony_ci display: none; 477fb726d48Sopenharmony_ci top: 0; 478fb726d48Sopenharmony_ci left: 0; 479fb726d48Sopenharmony_ci pointer-events: none; 480fb726d48Sopenharmony_ci user-select: none; 481fb726d48Sopenharmony_ci padding: 5px 10px; 482fb726d48Sopenharmony_ci box-shadow: 0 0 10px #22ffffff; 483fb726d48Sopenharmony_ci /*transition: left;*/ 484fb726d48Sopenharmony_ci /*transition-duration: 0.3s;*/ 485fb726d48Sopenharmony_ci } 486fb726d48Sopenharmony_ci #root{ 487fb726d48Sopenharmony_ci position:relative; 488fb726d48Sopenharmony_ci } 489fb726d48Sopenharmony_ci .tip-content{ 490fb726d48Sopenharmony_ci display: flex; 491fb726d48Sopenharmony_ci flex-direction: column; 492fb726d48Sopenharmony_ci } 493fb726d48Sopenharmony_ci </style> 494fb726d48Sopenharmony_ci <div id="root"> 495fb726d48Sopenharmony_ci <canvas id="canvas"></canvas> 496fb726d48Sopenharmony_ci <div id="tip"></div> 497fb726d48Sopenharmony_ci </div>`; 498fb726d48Sopenharmony_ci } 499fb726d48Sopenharmony_ci} 500fb726d48Sopenharmony_ci 501fb726d48Sopenharmony_cifunction contains(rect: { x: number; y: number; w: number; h: number }, x: number, y: number): boolean { 502fb726d48Sopenharmony_ci return rect.x <= x && x <= rect.x + rect.w && rect.y <= y && y <= rect.y + rect.h; 503fb726d48Sopenharmony_ci} 504