evui 3.3.11 → 3.3.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evui",
3
- "version": "3.3.11",
3
+ "version": "3.3.12",
4
4
  "description": "A EXEM Library project",
5
5
  "author": "exem <dev_client@ex-em.com>",
6
6
  "license": "MIT",
@@ -44,15 +44,22 @@ class Line {
44
44
  return;
45
45
  }
46
46
 
47
- const { ctx, chartRect, labelOffset, axesSteps } = param;
47
+ const { ctx, chartRect, labelOffset, axesSteps, selectLabel } = param;
48
48
  const extent = this.extent[this.state];
49
-
50
- const fillOpacity = this.fillOpacity * extent.opacity;
49
+ const selectLabelOption = selectLabel.option;
50
+ const selectedLabel = selectLabel.selected;
51
+ const isExistSelectedLabel = selectLabelOption.use
52
+ && selectLabelOption.useSeriesOpacity
53
+ && selectedLabel.dataIndex?.length > 0;
54
+ const downplayOpacity = this.extent.downplay.opacity;
55
+
56
+ const fillOpacity = isExistSelectedLabel
57
+ ? this.fillOpacity * downplayOpacity : this.fillOpacity * extent.opacity;
51
58
  const lineWidth = this.lineWidth * extent.lineWidth;
52
59
 
53
60
  const getOpacity = (colorStr) => {
54
61
  const noneDownplayOpacity = colorStr.includes('rgba') ? Util.getOpacity(colorStr) : 1;
55
- return this.state === 'downplay' ? 0.1 : noneDownplayOpacity;
62
+ return this.state === 'downplay' || isExistSelectedLabel ? 0.1 : noneDownplayOpacity;
56
63
  };
57
64
 
58
65
  const mainColor = this.color;
@@ -165,14 +172,18 @@ class Line {
165
172
 
166
173
  ctx.fill();
167
174
  }
168
-
169
- if (this.point) {
175
+ if (this.point || isExistSelectedLabel) {
170
176
  ctx.strokeStyle = Util.colorStringToRgba(mainColor, mainColorOpacity);
171
- ctx.fillStyle = Util.colorStringToRgba(pointFillColor, pointFillColorOpacity);
177
+ const focusStyle = Util.colorStringToRgba(pointFillColor, 1);
178
+ const blurStyle = Util.colorStringToRgba(pointFillColor, pointFillColorOpacity);
172
179
 
173
- this.data.forEach((curr) => {
180
+ this.data.forEach((curr, i) => {
174
181
  if (curr.xp !== null && curr.yp !== null) {
175
- Canvas.drawPoint(ctx, this.pointStyle, this.pointSize, curr.xp, curr.yp);
182
+ ctx.fillStyle = isExistSelectedLabel && selectedLabel.dataIndex.includes(i)
183
+ ? focusStyle : blurStyle;
184
+ if (this.point || selectedLabel.dataIndex.includes(i)) {
185
+ Canvas.drawPoint(ctx, this.pointStyle, this.pointSize, curr.xp, curr.yp);
186
+ }
176
187
  }
177
188
  });
178
189
  }
@@ -250,7 +250,7 @@ const modules = {
250
250
  const opt = this.options;
251
251
  const isHorizontal = !!opt.horizontal;
252
252
  const labelTipOpt = opt.selectLabel;
253
- const { dataIndex, data } = this.defaultSelectLabelInfo;
253
+ const { dataIndex, data, label } = this.defaultSelectLabelInfo;
254
254
  let drawTip = false;
255
255
 
256
256
  if (dataIndex.length) {
@@ -264,86 +264,82 @@ const modules = {
264
264
  y1: chartRect.y1 + labelOffset.top,
265
265
  y2: chartRect.y2 - labelOffset.bottom,
266
266
  };
267
+ const labelAxes = isHorizontal ? this.axesY[0] : this.axesX[0];
268
+ const valueAxes = isHorizontal ? this.axesX[0] : this.axesY[0];
269
+ const valueAxesRange = isHorizontal ? this.axesRange.x[0] : this.axesRange.y[0];
270
+ const valuePositionCalcFunction = isHorizontal ? Canvas.calculateX : Canvas.calculateY;
271
+ const labelPositionCalcFunction = isHorizontal ? Canvas.calculateY : Canvas.calculateX;
267
272
 
268
- const labelAxes = this.options.horizontal ? this.axesY[0] : this.axesX[0];
269
- const labelStartPoint = aPos[labelAxes.units.rectStart];
270
- const labelEndPoint = aPos[labelAxes.units.rectEnd];
271
- const labelGap = (labelEndPoint - labelStartPoint) / labelAxes.labels.length;
272
-
273
- const valueAxes = this.options.horizontal ? this.axesX[0] : this.axesY[0];
274
- const valueStartPoint = aPos[valueAxes.units.rectStart];
275
-
276
- const offset = this.options.type === 'bar' ? 4 : 6;
277
273
  const chartWidth = chartRect.chartWidth - (labelOffset.left + labelOffset.right);
278
274
  const chartHeight = chartRect.chartHeight - (labelOffset.top + labelOffset.bottom);
275
+ const valueSpace = isHorizontal ? chartWidth : chartHeight;
276
+ const valueStartPoint = aPos[valueAxes.units.rectStart];
277
+ let offset = this.options.type === 'bar' ? 4 : 6;
278
+ offset *= isHorizontal ? 1 : -1;
279
+
280
+ const seriesList = Object.keys(this.seriesList ?? {});
281
+ const visibleSeries = seriesList.filter(sId => this.seriesList[sId].show);
282
+ const isExistGrp = seriesList.some(sId => this.seriesList[sId].isExistGrp);
283
+ const groups = this.data.groups?.[0] ?? [];
284
+
285
+ let gp;
286
+ let dp;
287
+ let value;
288
+ let labelStartPoint;
289
+ let labelEndPoint;
290
+ let labelGap;
291
+ let graphX;
292
+ let lineSeries;
293
+ let sizeObj;
294
+
295
+ if (labelAxes.labels) {
296
+ labelStartPoint = aPos[labelAxes.units.rectStart];
297
+ labelEndPoint = aPos[labelAxes.units.rectEnd];
298
+ labelGap = (labelEndPoint - labelStartPoint) / labelAxes.labels.length;
299
+ } else {
300
+ graphX = this.axesSteps.x[0];
301
+ lineSeries = seriesList.find(sId => this.seriesList[sId]?.type === 'line');
302
+ sizeObj = this.seriesList[lineSeries].size;
303
+ }
279
304
 
280
- dataIndex.forEach((idx, i) => {
281
- const labelCenter = Math.round(labelStartPoint + (labelGap * idx));
282
- let gp;
283
- const dp = labelCenter + (labelGap / 2);
305
+ data.forEach((selectedData, i) => {
284
306
  if (labelTipOpt.fixedPosTop) {
285
- if (isHorizontal) {
286
- gp = Canvas.calculateX(
287
- this.axesRange.x[0].max,
288
- this.axesRange.x[0].min,
289
- this.axesRange.x[0].max,
290
- chartWidth,
291
- valueStartPoint);
292
- gp += offset;
293
- } else {
294
- gp = Canvas.calculateY(
295
- this.axesRange.y[0].max,
296
- this.axesRange.y[0].min,
297
- this.axesRange.y[0].max,
298
- chartHeight,
299
- valueStartPoint);
300
- gp -= offset;
301
- }
302
- } else if (isHorizontal) {
303
- const seriesList = Object.keys(data[i] ?? {});
304
- const visibleSeries = seriesList.filter(sId => this.seriesList[sId].show);
305
- const visibleValue = visibleSeries.map(sId => data[i][sId]);
306
- const isExistGrp = seriesList.some(sId => this.seriesList[sId].isExistGrp);
307
-
308
- let maxValue;
309
- if (isExistGrp) {
310
- maxValue = visibleValue.reduce((acc, v) => acc + v) ?? 0;
311
- } else if (visibleValue.length) {
312
- maxValue = Math.max(...visibleValue);
313
- } else {
314
- maxValue = this.axesRange.x[0].max;
315
- }
316
-
317
- gp = Canvas.calculateX(
318
- maxValue,
319
- this.axesRange.x[0].min,
320
- this.axesRange.x[0].max,
321
- chartWidth,
322
- valueStartPoint);
323
- gp += offset;
307
+ value = valueAxesRange.max;
308
+ } else if (isExistGrp) {
309
+ const sumValue = visibleSeries.reduce((ac, sId) => (
310
+ groups.includes(sId) ? ac + (selectedData[sId]?.value ?? selectedData[sId]) : ac), 0);
311
+ const nonGroupValues = visibleSeries
312
+ .filter(sId => !groups.includes(sId))
313
+ .map(sId => selectedData[sId]?.value ?? selectedData[sId]);
314
+ value = Math.max(...nonGroupValues, sumValue);
315
+ } else if (visibleSeries.length) {
316
+ const visibleValue = visibleSeries
317
+ .map(sId => selectedData[sId]?.value ?? selectedData[sId]);
318
+ value = Math.max(...visibleValue);
324
319
  } else {
325
- const seriesList = Object.keys(data[i] ?? {});
326
- const visibleSeries = seriesList.filter(sId => this.seriesList[sId].show);
327
- const visibleValue = visibleSeries.map(sId => data[i][sId]);
328
- const isExistGrp = seriesList.some(sId => this.seriesList[sId].isExistGrp);
329
-
330
- let maxValue;
331
- if (isExistGrp) {
332
- maxValue = visibleValue.reduce((acc, v) => acc + v) ?? 0;
333
- } else if (visibleValue.length) {
334
- maxValue = Math.max(...visibleValue);
335
- } else {
336
- maxValue = this.axesRange.y[0].max;
337
- }
320
+ value = valueAxesRange.max;
321
+ }
322
+
323
+ if (labelAxes.labels) {
324
+ const labelCenter = Math.round(labelStartPoint + (labelGap * dataIndex[i]));
338
325
 
339
- gp = Canvas.calculateY(
340
- maxValue,
341
- this.axesRange.y[0].min,
342
- this.axesRange.y[0].max,
343
- chartHeight,
344
- valueStartPoint);
345
- gp -= offset;
326
+ dp = labelCenter + (labelGap / 2);
327
+ } else {
328
+ dp = labelPositionCalcFunction(
329
+ label[i],
330
+ graphX.graphMin,
331
+ graphX.graphMax,
332
+ chartWidth - sizeObj.comboOffset,
333
+ aPos.x1 + (sizeObj.comboOffset / 2),
334
+ );
346
335
  }
336
+ gp = valuePositionCalcFunction(
337
+ value,
338
+ valueAxesRange.min,
339
+ valueAxesRange.max,
340
+ valueSpace,
341
+ valueStartPoint);
342
+ gp += offset;
347
343
 
348
344
  this.showTip({
349
345
  context: this.bufferCtx,
@@ -699,8 +699,8 @@ const modules = {
699
699
  const index = Math.floor(((this.options.horizontal ? y : x) - startPoint) / labelGap);
700
700
  labelIndex = scale.labels.length > index ? index : -1;
701
701
  } else {
702
- hitInfo = this.getItemByPosition(offset, false);
703
- labelIndex = hitInfo.maxIndex;
702
+ hitInfo = this.getItemByPosition(offset, this.options.selectLabel.useApproximateValue);
703
+ labelIndex = hitInfo.maxIndex ?? -1;
704
704
  }
705
705
 
706
706
  return {
@@ -468,8 +468,12 @@ const modules = {
468
468
  */
469
469
  initSelectedLabelInfo() {
470
470
  const { use, limit } = this.options.selectLabel;
471
- const infoObj = this.defaultSelectLabelInfo;
472
- if (use && infoObj?.dataIndex) {
471
+
472
+ if (use) {
473
+ if (!this.defaultSelectLabelInfo) {
474
+ this.defaultSelectLabelInfo = { dataIndex: [] };
475
+ }
476
+ const infoObj = this.defaultSelectLabelInfo;
473
477
  infoObj.dataIndex.splice(limit);
474
478
  infoObj.label = infoObj.dataIndex.map(i => this.data.labels[i]);
475
479
  const dataEntries = Object.entries(this.data.data);
@@ -164,7 +164,7 @@ class Scale {
164
164
  *
165
165
  * @returns {undefined}
166
166
  */
167
- draw(chartRect, labelOffset, stepInfo, hitInfo, selectLabelInfo) {
167
+ draw(chartRect, labelOffset, stepInfo, hitInfo) {
168
168
  const ctx = this.ctx;
169
169
  const options = this.options;
170
170
  const aPos = {
@@ -239,12 +239,6 @@ class Scale {
239
239
  linePosition = labelCenter + aliasPixel;
240
240
  labelText = this.getLabelFormat(Math.min(axisMax, ticks[ix]));
241
241
 
242
- const isBlurredLabel = this.options?.selectLabel?.use
243
- && this.options?.selectLabel?.useLabelOpacity
244
- && (this.options.horizontal === (this.type === 'y'))
245
- && selectLabelInfo?.dataIndex?.length
246
- && !selectLabelInfo?.dataIndex?.includes(ix);
247
-
248
242
  const labelColor = this.labelStyle.color;
249
243
  let defaultOpacity = 1;
250
244
 
@@ -252,17 +246,14 @@ class Scale {
252
246
  defaultOpacity = Util.getOpacity(labelColor);
253
247
  }
254
248
 
255
- ctx.fillStyle = Util.colorStringToRgba(labelColor, isBlurredLabel ? 0.1 : defaultOpacity);
249
+ ctx.fillStyle = Util.colorStringToRgba(labelColor, defaultOpacity);
256
250
 
257
251
  let labelPoint;
258
252
 
259
253
  if (this.type === 'x') {
260
254
  labelPoint = this.position === 'top' ? offsetPoint - 10 : offsetPoint + 10;
261
255
  ctx.fillText(labelText, labelCenter, labelPoint);
262
- if (!isBlurredLabel
263
- && options?.selectItem?.showLabelTip
264
- && hitInfo?.label
265
- && !this.options?.horizontal) {
256
+ if (options?.selectItem?.showLabelTip && hitInfo?.label && !this.options?.horizontal) {
266
257
  const selectedLabel = this.getLabelFormat(
267
258
  Math.min(axisMax, hitInfo.label + (0 * stepValue)),
268
259
  );
@@ -84,6 +84,10 @@ export default {
84
84
  type: Object,
85
85
  default: () => ({}),
86
86
  },
87
+ isTree: {
88
+ type: Boolean,
89
+ default: false,
90
+ },
87
91
  },
88
92
  setup(props) {
89
93
  const ROW_DATA_INDEX = 2;
@@ -112,13 +116,18 @@ export default {
112
116
  return stores.value.store.length;
113
117
  }
114
118
  if (column.type === 'number' || column.type === 'float') {
115
- const columnValues = stores.value.store.map(rows => rows[ROW_DATA_INDEX][columnIndex]);
119
+ let columnValues = [];
120
+ if (props.isTree) {
121
+ columnValues = stores.value.store.map(node => node.data?.[column.field]);
122
+ } else {
123
+ columnValues = stores.value.store.map(row => row[ROW_DATA_INDEX][columnIndex]);
124
+ }
116
125
  switch (summaryType) {
117
126
  case 'sum':
118
127
  result = columnValues.reduce((prev, curr) => {
119
128
  const value = Number(curr);
120
129
  if (!Number.isNaN(value)) {
121
- return prev + curr;
130
+ return prev + value;
122
131
  }
123
132
  return prev;
124
133
  }, 0);
@@ -127,7 +136,7 @@ export default {
127
136
  result = columnValues.reduce((prev, curr) => {
128
137
  const value = Number(curr);
129
138
  if (!Number.isNaN(value)) {
130
- return prev + curr;
139
+ return prev + value;
131
140
  }
132
141
  return prev;
133
142
  }, 0) / columnValues.length;
@@ -180,8 +189,10 @@ export default {
180
189
  <style lang="scss" scoped>
181
190
  @import 'style/grid.scss';
182
191
  .grid-summary {
183
- background-color: #F8F9F9;
184
- border-bottom: 1px solid #CFCFCF;
192
+ @include evThemify() {
193
+ border-bottom: 1px solid evThemed('disabled');
194
+ background-color: evThemed('background-lighten');
195
+ }
185
196
  .non-border {
186
197
  border-bottom: none !important;
187
198
  }
@@ -190,7 +201,10 @@ export default {
190
201
  overflow: hidden;
191
202
  text-overflow: ellipsis;
192
203
  font-size: 14px;
193
- color: #737373;
204
+
205
+ @include evThemify() {
206
+ color: evThemed('font-color-base');
207
+ }
194
208
  }
195
209
  .column {
196
210
  &.number,
@@ -38,7 +38,7 @@ export const commonFunctions = () => {
38
38
  * @returns {number|string} 변환된 데이터
39
39
  */
40
40
  const getConvertValue = (column, value) => {
41
- let convertValue = value;
41
+ let convertValue = column.type === 'number' || column.type === 'float' ? Number(value) : value;
42
42
 
43
43
  if (column.type === 'number') {
44
44
  convertValue = numberWithComma(value);