evui 3.3.9 → 3.3.10

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.9",
3
+ "version": "3.3.10",
4
4
  "description": "A EXEM Library project",
5
5
  "author": "exem <dev_client@ex-em.com>",
6
6
  "license": "MIT",
@@ -20,6 +20,10 @@ import { onMounted, onBeforeUnmount, watch, onDeactivated } from 'vue';
20
20
  type: Object,
21
21
  default: null,
22
22
  },
23
+ selectedLabel: {
24
+ type: Object,
25
+ default: null,
26
+ },
23
27
  options: {
24
28
  type: Object,
25
29
  default: () => ({}),
@@ -38,6 +42,7 @@ import { onMounted, onBeforeUnmount, watch, onDeactivated } from 'vue';
38
42
  'dbl-click',
39
43
  'drag-select',
40
44
  'update:selectedItem',
45
+ 'update:selectedLabel',
41
46
  ],
42
47
  setup(props) {
43
48
  let evChart = {};
@@ -45,7 +50,8 @@ import { onMounted, onBeforeUnmount, watch, onDeactivated } from 'vue';
45
50
 
46
51
  const {
47
52
  eventListeners,
48
- selectInfo,
53
+ selectItemInfo,
54
+ selectLabelInfo,
49
55
  getNormalizedData,
50
56
  getNormalizedOptions,
51
57
  } = useModel();
@@ -66,7 +72,8 @@ import { onMounted, onBeforeUnmount, watch, onDeactivated } from 'vue';
66
72
  normalizedData,
67
73
  normalizedOptions,
68
74
  eventListeners,
69
- selectInfo,
75
+ selectItemInfo,
76
+ selectLabelInfo,
70
77
  );
71
78
  };
72
79
 
@@ -102,13 +109,15 @@ import { onMounted, onBeforeUnmount, watch, onDeactivated } from 'vue';
102
109
  }, { deep: true });
103
110
 
104
111
  await watch(() => props.selectedItem, (newValue) => {
105
- if (!newValue?.seriesID) {
106
- return;
107
- }
108
-
109
112
  const chartType = props.options?.type;
110
113
  evChart.selectItemByData(newValue, chartType);
111
114
  }, { deep: true });
115
+
116
+ await watch(() => props.selectedLabel, (newValue) => {
117
+ if (newValue.dataIndex) {
118
+ evChart.renderWithSelectLabel(newValue.dataIndex);
119
+ }
120
+ }, { deep: true });
112
121
  });
113
122
 
114
123
  onBeforeUnmount(() => {
@@ -14,7 +14,7 @@ import Pie from './plugins/plugins.pie';
14
14
  import Tip from './element/element.tip';
15
15
 
16
16
  class EvChart {
17
- constructor(target, data, options, listeners, defaultSelectInfo) {
17
+ constructor(target, data, options, listeners, defaultSelectItemInfo, defaultSelectLabelInfo) {
18
18
  Object.keys(Model).forEach(key => Object.assign(this, Model[key]));
19
19
  Object.assign(this, Title);
20
20
  Object.assign(this, Legend);
@@ -61,11 +61,12 @@ class EvChart {
61
61
  this.seriesList = {};
62
62
  this.lastTip = { pos: null, value: null };
63
63
  this.seriesInfo = {
64
- charts: { pie: [], bar: [], line: [], scatter: [] },
64
+ charts: { pie: [], bar: [], line: [], scatter: [], heatMap: [] },
65
65
  count: 0,
66
66
  };
67
67
 
68
- this.defaultSelectInfo = defaultSelectInfo;
68
+ this.defaultSelectItemInfo = defaultSelectItemInfo;
69
+ this.defaultSelectLabelInfo = defaultSelectLabelInfo;
69
70
  }
70
71
 
71
72
  /**
@@ -92,6 +93,7 @@ class EvChart {
92
93
 
93
94
  this.axesRange = this.getAxesRange();
94
95
  this.labelOffset = this.getLabelOffset();
96
+ this.initSelectedLabelInfo();
95
97
 
96
98
  this.drawChart();
97
99
 
@@ -146,11 +148,12 @@ class EvChart {
146
148
 
147
149
  /**
148
150
  * Draw each series
151
+ * @param {any} [hitInfo=undefined] from mousemove callback (object or undefined)
149
152
  *
150
153
  * @returns {undefined}
151
154
  */
152
155
  drawSeries(hitInfo) {
153
- const maxTip = this.options.maxTip;
156
+ const { maxTip, selectLabel } = this.options;
154
157
 
155
158
  const opt = {
156
159
  ctx: this.bufferCtx,
@@ -158,6 +161,7 @@ class EvChart {
158
161
  labelOffset: this.labelOffset,
159
162
  axesSteps: this.axesSteps,
160
163
  maxTipOpt: { background: maxTip.background, color: maxTip.color },
164
+ selectLabel: { option: selectLabel, selected: this.defaultSelectLabelInfo },
161
165
  };
162
166
 
163
167
  let showIndex = 0;
@@ -177,7 +181,7 @@ class EvChart {
177
181
  for (let jx = 0; jx < chartTypeSet.length; jx++) {
178
182
  const series = this.seriesList[chartTypeSet[jx]];
179
183
 
180
- if (chartType === 'line' || chartType === 'scatter') {
184
+ if (chartType === 'line' || chartType === 'scatter' || chartType === 'heatMap') {
181
185
  series.draw(opt);
182
186
  } else if (chartType === 'bar') {
183
187
  const { thickness, borderRadius } = this.options;
@@ -189,7 +193,7 @@ class EvChart {
189
193
  } else {
190
194
  const selectInfo = hitInfo
191
195
  ?? this.lastHitInfo
192
- ?? { sId: this.defaultSelectInfo?.seriesID };
196
+ ?? { sId: this.defaultSelectItemInfo?.seriesID };
193
197
 
194
198
  if (this.options.sunburst) {
195
199
  this.drawSunburst(selectInfo);
@@ -207,7 +211,7 @@ class EvChart {
207
211
  }
208
212
 
209
213
  /**
210
- * Draw Tip with hitInfo and defaultSelectInfo
214
+ * Draw Tip with hitInfo and defaultSelectItemInfo
211
215
  * @param hitInfo
212
216
  */
213
217
  drawTip(hitInfo) {
@@ -221,8 +225,8 @@ class EvChart {
221
225
  tipLocationInfo = hitInfo;
222
226
  } else if (this.lastHitInfo) {
223
227
  tipLocationInfo = this.lastHitInfo;
224
- } else if (this.defaultSelectInfo) {
225
- tipLocationInfo = this.getItem(this.defaultSelectInfo, false);
228
+ } else if (this.defaultSelectItemInfo) {
229
+ tipLocationInfo = this.getItem(this.defaultSelectItemInfo, false);
226
230
  } else {
227
231
  tipLocationInfo = null;
228
232
  }
@@ -281,11 +285,21 @@ class EvChart {
281
285
  */
282
286
  drawAxis(hitInfo) {
283
287
  this.axesX.forEach((axis, index) => {
284
- axis.draw(this.chartRect, this.labelOffset, this.axesSteps.x[index], hitInfo);
288
+ axis.draw(
289
+ this.chartRect,
290
+ this.labelOffset,
291
+ this.axesSteps.x[index],
292
+ hitInfo,
293
+ this.defaultSelectLabelInfo);
285
294
  });
286
295
 
287
296
  this.axesY.forEach((axis, index) => {
288
- axis.draw(this.chartRect, this.labelOffset, this.axesSteps.y[index]);
297
+ axis.draw(
298
+ this.chartRect,
299
+ this.labelOffset,
300
+ this.axesSteps.y[index],
301
+ hitInfo,
302
+ this.defaultSelectLabelInfo);
289
303
  });
290
304
  }
291
305
 
@@ -545,6 +559,7 @@ class EvChart {
545
559
  bar: [],
546
560
  line: [],
547
561
  scatter: [],
562
+ heatMap: [],
548
563
  },
549
564
  count: 0,
550
565
  };
@@ -604,6 +619,7 @@ class EvChart {
604
619
  this.axesY = this.createAxes('y', options.axesY);
605
620
  this.axesRange = this.getAxesRange();
606
621
  this.labelOffset = this.getLabelOffset();
622
+ this.initSelectedLabelInfo();
607
623
 
608
624
  this.render();
609
625
 
@@ -131,7 +131,13 @@ class Bar {
131
131
  }
132
132
 
133
133
  const barColor = item.dataColor || this.color;
134
- const isDownplay = this.state === 'downplay';
134
+
135
+ const selectLabelOption = param.selectLabel.option;
136
+ const selectedLabel = param.selectLabel.selected ?? { dataIndex: [] };
137
+
138
+ const isDownplay = selectLabelOption.use && selectLabelOption.useSeriesOpacity
139
+ ? selectedLabel.dataIndex.length && !selectedLabel.dataIndex.includes(index)
140
+ : this.state === 'downplay';
135
141
 
136
142
  if (typeof barColor !== 'string') {
137
143
  ctx.fillStyle = Canvas.createGradient(
@@ -0,0 +1,213 @@
1
+ import { merge } from 'lodash-es';
2
+ import Canvas from '../helpers/helpers.canvas';
3
+ import Util from '../helpers/helpers.util';
4
+ import { COLOR, HEAT_MAP_OPTION } from '../helpers/helpers.constant';
5
+
6
+ class HeatMap {
7
+ constructor(sId, opt, sIdx) {
8
+ const merged = merge({}, HEAT_MAP_OPTION, opt);
9
+ Object.keys(merged).forEach((key) => {
10
+ this[key] = merged[key];
11
+ });
12
+
13
+ ['color', 'pointFill', 'fillColor'].forEach((colorProp) => {
14
+ if (this[colorProp] === undefined) {
15
+ this[colorProp] = COLOR[sIdx];
16
+ }
17
+ });
18
+
19
+ this.colorAxis = this.createColorAxis(opt.colorOpt);
20
+ this.errorColor = opt.colorOpt.error;
21
+ this.borderColor = opt.colorOpt.border;
22
+
23
+ this.sId = sId;
24
+ this.data = [];
25
+ this.spaces = opt.spaces || { x: null, y: null };
26
+ this.size = {
27
+ w: 0,
28
+ h: 0,
29
+ };
30
+ this.valueOpt = {
31
+ max: 0,
32
+ interval: 0,
33
+ };
34
+ this.type = 'heatMap';
35
+ }
36
+
37
+ /**
38
+ * create series color axis
39
+ * @param colorOpt
40
+ * @returns {*[]}
41
+ */
42
+ createColorAxis(colorOpt) {
43
+ const colorAxis = [];
44
+ const { min, max, categoryCnt } = colorOpt;
45
+
46
+ const minColor = min.includes('#') ? Util.hexToRgb(min) : min;
47
+ const maxColor = max.includes('#') ? Util.hexToRgb(max) : max;
48
+
49
+ const [minR, minG, minB] = minColor.split(',');
50
+ const [maxR, maxG, maxB] = maxColor.split(',');
51
+
52
+ const unitR = Math.floor((minR - maxR) / (categoryCnt - 1));
53
+ const unitG = Math.floor((minG - maxG) / (categoryCnt - 1));
54
+ const unitB = Math.floor((minB - maxB) / (categoryCnt - 1));
55
+
56
+ for (let ix = 0; ix < categoryCnt; ix++) {
57
+ const r = +minR - (unitR * ix);
58
+ const g = +minG - (unitG * ix);
59
+ const b = +minB - (unitB * ix);
60
+
61
+ colorAxis.push({
62
+ id: `color#${ix}`,
63
+ value: `rgb(${r},${g},${b})`,
64
+ state: 'normal',
65
+ show: true,
66
+ });
67
+ }
68
+
69
+ return colorAxis;
70
+ }
71
+
72
+ getColorIndex(value) {
73
+ const existError = this.valueOpt.existError;
74
+ const maxIndex = this.colorAxis.length;
75
+ if (value < 0) {
76
+ return maxIndex - 1;
77
+ }
78
+
79
+ const colorIndex = Math.floor(value / this.valueOpt.interval);
80
+ if (colorIndex >= maxIndex) {
81
+ return existError ? maxIndex - 2 : maxIndex - 1;
82
+ }
83
+
84
+ return colorIndex;
85
+ }
86
+
87
+ drawItem(ctx, xp, yp) {
88
+ ctx.beginPath();
89
+ ctx.strokeRect(xp - this.size.w, yp + Math.SQRT2, this.size.w, this.size.h);
90
+ ctx.fillRect(xp - this.size.w, yp + Math.SQRT2, this.size.w, this.size.h);
91
+ ctx.closePath();
92
+ ctx.stroke();
93
+ }
94
+
95
+ draw(param) {
96
+ if (!this.show) {
97
+ return;
98
+ }
99
+
100
+ const { ctx, chartRect, labelOffset, axesSteps } = param;
101
+
102
+ const minmaxX = axesSteps.x[this.xAxisIndex];
103
+ const minmaxY = axesSteps.y[this.yAxisIndex];
104
+
105
+ const xArea = chartRect.chartWidth - (labelOffset.left + labelOffset.right);
106
+ const yArea = chartRect.chartHeight - (labelOffset.top + labelOffset.bottom);
107
+
108
+ const xsp = chartRect.x1 + labelOffset.left;
109
+ const ysp = chartRect.y2 - labelOffset.bottom;
110
+
111
+ this.size.w = Math.ceil(xArea / (this.spaces.x || (minmaxX.graphMax - minmaxX.graphMin)));
112
+ this.size.h = Math.floor(yArea / (this.spaces.y || (minmaxY.graphMax - minmaxY.graphMin)));
113
+
114
+ this.data.forEach((item) => {
115
+ item.xp = Canvas.calculateX(item.x, minmaxX.graphMin, minmaxX.graphMax, xArea, xsp);
116
+ item.yp = Canvas.calculateY(item.y, minmaxY.graphMin, minmaxY.graphMax, yArea, ysp);
117
+
118
+ const { xp, yp, o: value } = item;
119
+
120
+ if (xp !== null && yp !== null) {
121
+ const colorIndex = this.getColorIndex(value);
122
+ const opacity = this.colorAxis[colorIndex].state === 'downplay' ? 0.1 : 1;
123
+ item.dataColor = value < 0 ? this.errorColor : this.colorAxis[colorIndex].value;
124
+ item.cId = this.colorAxis[colorIndex].id;
125
+ if (this.colorAxis[colorIndex].show) {
126
+ ctx.strokeStyle = Util.colorStringToRgba(this.borderColor, opacity);
127
+ ctx.fillStyle = Util.colorStringToRgba(item.dataColor, opacity);
128
+ this.drawItem(ctx, xp, yp);
129
+ }
130
+ }
131
+ });
132
+ }
133
+
134
+ /**
135
+ *Returns items in range
136
+ * @param {object} params range values
137
+ *
138
+ * @returns {array}
139
+ */
140
+ findItems({ xsp, ysp, width, height }) {
141
+ const gdata = this.data;
142
+ const xep = xsp + width;
143
+ const yep = ysp + height;
144
+ return gdata.filter(seriesData =>
145
+ (xsp - 1 <= seriesData.xp && seriesData.xp <= xep + 1
146
+ && ysp - 1 <= seriesData.yp && seriesData.yp <= yep + 1));
147
+ }
148
+
149
+ /**
150
+ * Draw item highlight
151
+ * @param {object} item object for drawing series data
152
+ * @param {object} context canvas context
153
+ *
154
+ * @returns {undefined}
155
+ */
156
+ itemHighlight(item, context) {
157
+ const gdata = item.data;
158
+ const ctx = context;
159
+
160
+ const x = gdata.xp;
161
+ const y = gdata.yp;
162
+
163
+ ctx.save();
164
+ if (x !== null && y !== null) {
165
+ const color = gdata.dataColor;
166
+ ctx.strokeStyle = Util.colorStringToRgba(color, 1);
167
+ ctx.fillStyle = Util.colorStringToRgba(color, this.highlight.maxShadowOpacity);
168
+ this.drawItem(ctx, x, y);
169
+ }
170
+
171
+ ctx.restore();
172
+ }
173
+
174
+ /**
175
+ * Find graph item for tooltip
176
+ * @param {array} offset mouse position
177
+ *
178
+ * @returns {object} graph item
179
+ */
180
+ findGraphData(offset) {
181
+ const xp = offset[0];
182
+ const yp = offset[1];
183
+ const item = {
184
+ data: null,
185
+ hit: false,
186
+ color: null,
187
+ name: null,
188
+ };
189
+ const wSize = this.size.w;
190
+ const hSize = this.size.h;
191
+ const gdata = this.data;
192
+
193
+ const foundItem = gdata.find((data) => {
194
+ const x = data.xp;
195
+ const y = data.yp;
196
+
197
+ return (x - wSize <= xp)
198
+ && (xp <= x)
199
+ && (y <= yp)
200
+ && (yp <= y + hSize);
201
+ });
202
+
203
+ if (foundItem) {
204
+ item.data = foundItem;
205
+ item.color = foundItem.dataColor;
206
+ item.hit = true;
207
+ }
208
+
209
+ return item;
210
+ }
211
+ }
212
+
213
+ export default HeatMap;
@@ -27,7 +27,6 @@ class Pie {
27
27
  this.doughnutHoleSize = 0;
28
28
  this.startAngle = 0;
29
29
  this.endAngle = 0;
30
- this.slice = null;
31
30
  this.state = null;
32
31
  this.ctx = null;
33
32
  this.isSelect = false;
@@ -71,8 +70,6 @@ class Pie {
71
70
  }
72
71
 
73
72
  ctx.closePath();
74
-
75
- this.slice = slice;
76
73
  this.ctx = ctx;
77
74
  }
78
75
 
@@ -84,8 +81,19 @@ class Pie {
84
81
  */
85
82
  findGraphData([offsetX, offsetY]) {
86
83
  const item = { data: null, hit: false, color: null, index: -1 };
87
-
88
- if (this.show && this.ctx?.isPointInPath(this.slice, offsetX, offsetY)) {
84
+ const {
85
+ radius,
86
+ startAngle,
87
+ endAngle,
88
+ centerX,
89
+ centerY,
90
+ } = this;
91
+
92
+ const distance = Math.sqrt((offsetX - centerX) ** 2 + (offsetY - centerY) ** 2);
93
+ const radian = (2.5 * Math.PI) - Math.atan2((offsetX - centerX), (offsetY - centerY));
94
+ const isPointInPath = radius > distance && radian >= startAngle && radian <= endAngle;
95
+
96
+ if (this.show && isPointInPath) {
89
97
  item.type = this.type;
90
98
  item.data = this.data;
91
99
  item.hit = true;
@@ -14,9 +14,15 @@ const modules = {
14
14
  const isHorizontal = !!opt.horizontal;
15
15
  const maxTipOpt = opt.maxTip;
16
16
  const selTipOpt = opt.selectItem;
17
+ const labelTipOpt = opt.selectLabel;
17
18
  let maxArgs;
19
+ let isExistSelectedLabel;
18
20
 
19
- if (selTipOpt.use && tipLocationInfo) {
21
+ if (labelTipOpt.use && labelTipOpt.showTip) {
22
+ isExistSelectedLabel = this.drawLabelTip();
23
+ }
24
+
25
+ if (selTipOpt.use && tipLocationInfo && !isExistSelectedLabel) {
20
26
  const seriesInfo = this.seriesList[tipLocationInfo?.sId];
21
27
 
22
28
  if (!seriesInfo?.show) {
@@ -57,8 +63,7 @@ const modules = {
57
63
  this.lastHitInfo = tipLocationInfo;
58
64
  }
59
65
  }
60
-
61
- if (maxTipOpt.use) {
66
+ if (maxTipOpt.use && !isExistSelectedLabel) {
62
67
  const maxSID = this.minMax[isHorizontal ? 'x' : 'y'][0].maxSID;
63
68
  maxArgs = this.calculateTipInfo(this.seriesList[maxSID], 'max', null);
64
69
 
@@ -76,7 +81,8 @@ const modules = {
76
81
  /**
77
82
  * Calculate tip size and contents
78
83
  * @param {object} series series information (max series or selected series)
79
- * @param {string} tipType tip type [sel = user select, max = max value]
84
+ * @param {string} tipType tip type
85
+ * [sel = user select series, label = user select label, max = max value]
80
86
  * @param {object} hitInfo mouse hit information
81
87
  *
82
88
  * @returns {object} size and tip contents
@@ -220,6 +226,121 @@ const modules = {
220
226
  ctx.closePath();
221
227
  },
222
228
 
229
+ /**
230
+ * Draw Selected Label Tip
231
+ * @returns {boolean} Whether drew at least one tip
232
+ */
233
+ drawLabelTip() {
234
+ const opt = this.options;
235
+ const isHorizontal = !!opt.horizontal;
236
+ const labelTipOpt = opt.selectLabel;
237
+ const { dataIndex, data } = this.defaultSelectLabelInfo;
238
+ let drawTip = false;
239
+
240
+ if (dataIndex.length) {
241
+ drawTip = true;
242
+
243
+ const chartRect = this.chartRect;
244
+ const labelOffset = this.labelOffset;
245
+ const aPos = {
246
+ x1: chartRect.x1 + labelOffset.left,
247
+ x2: chartRect.x2 - labelOffset.right,
248
+ y1: chartRect.y1 + labelOffset.top,
249
+ y2: chartRect.y2 - labelOffset.bottom,
250
+ };
251
+
252
+ const labelAxes = this.options.horizontal ? this.axesY[0] : this.axesX[0];
253
+ const labelStartPoint = aPos[labelAxes.units.rectStart];
254
+ const labelEndPoint = aPos[labelAxes.units.rectEnd];
255
+ const labelGap = (labelEndPoint - labelStartPoint) / labelAxes.labels.length;
256
+
257
+ const valueAxes = this.options.horizontal ? this.axesX[0] : this.axesY[0];
258
+ const valueStartPoint = aPos[valueAxes.units.rectStart];
259
+
260
+ const offset = this.options.type === 'bar' ? 4 : 6;
261
+ const chartWidth = chartRect.chartWidth - (labelOffset.left + labelOffset.right);
262
+ const chartHeight = chartRect.chartHeight - (labelOffset.top + labelOffset.bottom);
263
+
264
+ dataIndex.forEach((idx, i) => {
265
+ const labelCenter = Math.round(labelStartPoint + (labelGap * idx));
266
+ let gp;
267
+ const dp = labelCenter + (labelGap / 2);
268
+ if (labelTipOpt.fixedPosTop) {
269
+ if (isHorizontal) {
270
+ gp = Canvas.calculateX(
271
+ this.axesRange.x[0].max,
272
+ this.axesRange.x[0].min,
273
+ this.axesRange.x[0].max,
274
+ chartWidth,
275
+ valueStartPoint);
276
+ gp += offset;
277
+ } else {
278
+ gp = Canvas.calculateY(
279
+ this.axesRange.y[0].max,
280
+ this.axesRange.y[0].min,
281
+ this.axesRange.y[0].max,
282
+ chartHeight,
283
+ valueStartPoint);
284
+ gp -= offset;
285
+ }
286
+ } else if (isHorizontal) {
287
+ const seriesList = Object.keys(data[i] ?? {});
288
+ const visibleSeries = seriesList.filter(sId => this.seriesList[sId].show);
289
+ const visibleValue = visibleSeries.map(sId => data[i][sId]);
290
+ const isExistGrp = seriesList.some(sId => this.seriesList[sId].isExistGrp);
291
+
292
+ let maxValue;
293
+ if (isExistGrp) {
294
+ maxValue = visibleValue.reduce((acc, v) => acc + v) ?? 0;
295
+ } else if (visibleValue.length) {
296
+ maxValue = Math.max(...visibleValue);
297
+ } else {
298
+ maxValue = this.axesRange.x[0].max;
299
+ }
300
+
301
+ gp = Canvas.calculateX(
302
+ maxValue,
303
+ this.axesRange.x[0].min,
304
+ this.axesRange.x[0].max,
305
+ chartWidth,
306
+ valueStartPoint);
307
+ gp += offset;
308
+ } else {
309
+ const seriesList = Object.keys(data[i] ?? {});
310
+ const visibleSeries = seriesList.filter(sId => this.seriesList[sId].show);
311
+ const visibleValue = visibleSeries.map(sId => data[i][sId]);
312
+ const isExistGrp = seriesList.some(sId => this.seriesList[sId].isExistGrp);
313
+
314
+ let maxValue;
315
+ if (isExistGrp) {
316
+ maxValue = visibleValue.reduce((acc, v) => acc + v) ?? 0;
317
+ } else if (visibleValue.length) {
318
+ maxValue = Math.max(...visibleValue);
319
+ } else {
320
+ maxValue = this.axesRange.y[0].max;
321
+ }
322
+
323
+ gp = Canvas.calculateY(
324
+ maxValue,
325
+ this.axesRange.y[0].min,
326
+ this.axesRange.y[0].max,
327
+ chartHeight,
328
+ valueStartPoint);
329
+ gp -= offset;
330
+ }
331
+
332
+ this.showTip({
333
+ context: this.bufferCtx,
334
+ x: isHorizontal ? gp : dp,
335
+ y: isHorizontal ? dp : gp,
336
+ opt: labelTipOpt,
337
+ isSamePos: false,
338
+ });
339
+ });
340
+ }
341
+
342
+ return drawTip;
343
+ },
223
344
  /**
224
345
  * Calculate x, y position to draw text tip
225
346
  * @param {object} param object for drawing text tip
@@ -128,6 +128,21 @@ export const PLOT_BAND_OPTION = {
128
128
  color: '#FAE59D',
129
129
  };
130
130
 
131
+ export const HEAT_MAP_OPTION = {
132
+ ...LINE_OPTION,
133
+ colorOpt: {
134
+ min: '#FFFFFF',
135
+ max: '#0052FF',
136
+ categoryCnt: 5,
137
+ border: '#FFFFFF',
138
+ error: '#FF0000',
139
+ },
140
+ spaces: {
141
+ x: 0,
142
+ y: 0,
143
+ },
144
+ };
145
+
131
146
 
132
147
  export const TIME_INTERVALS = {
133
148
  millisecond: {
@@ -3,6 +3,7 @@ import Scatter from '../element/element.scatter';
3
3
  import Bar from '../element/element.bar';
4
4
  import TimeBar from '../element/element.bar.time';
5
5
  import Pie from '../element/element.pie';
6
+ import HeatMap from '../element/element.heatmap';
6
7
 
7
8
  const modules = {
8
9
  /**
@@ -51,6 +52,9 @@ const modules = {
51
52
  } else if (type === 'pie') {
52
53
  this.seriesInfo.charts.pie.push(id);
53
54
  return new Pie(id, opt, index);
55
+ } else if (type === 'heatMap') {
56
+ this.seriesInfo.charts.heatMap.push(id);
57
+ return new HeatMap(id, opt, index);
54
58
  }
55
59
 
56
60
  return false;