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