evui 3.1.38 → 3.1.42
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/dist/evui.common.js +2699 -970
- package/dist/evui.common.js.map +1 -1
- package/dist/evui.umd.js +2699 -970
- package/dist/evui.umd.js.map +1 -1
- package/dist/evui.umd.min.js +1 -1
- package/dist/evui.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/calendar/Calendar.vue +194 -82
- package/src/components/calendar/uses.js +457 -138
- package/src/components/chart/chart.core.js +27 -23
- package/src/components/chart/element/element.bar.js +28 -20
- package/src/components/chart/element/element.line.js +13 -0
- package/src/components/chart/helpers/helpers.constant.js +27 -0
- package/src/components/chart/helpers/helpers.util.js +2 -2
- package/src/components/chart/plugins/plugins.interaction.js +5 -5
- package/src/components/chart/plugins/plugins.legend.js +6 -3
- package/src/components/chart/plugins/plugins.tooltip.js +14 -1
- package/src/components/chart/scale/scale.js +520 -56
- package/src/components/chart/scale/scale.linear.js +8 -0
- package/src/components/chart/scale/scale.logarithmic.js +8 -0
- package/src/components/chart/scale/scale.step.js +148 -69
- package/src/components/chart/scale/scale.time.category.js +8 -0
- package/src/components/chart/scale/scale.time.js +8 -0
- package/src/components/chart/uses.js +2 -2
- package/src/components/contextMenu/MenuList.vue +1 -1
- package/src/components/datePicker/DatePicker.vue +91 -29
- package/src/components/datePicker/uses.js +231 -21
- package/src/components/grid/Grid.vue +15 -10
- package/src/components/tabs/Tabs.vue +12 -11
- package/src/components/treeGrid/TreeGrid.vue +56 -2
- package/src/components/treeGrid/TreeGridNode.vue +10 -1
- package/src/components/treeGrid/treeGrid.toolbar.vue +26 -0
- package/src/components/treeGrid/uses.js +66 -6
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
import Canvas from '@/components/chart/helpers/helpers.canvas';
|
|
1
2
|
import { defaultsDeep } from 'lodash-es';
|
|
2
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
AXIS_OPTION,
|
|
5
|
+
AXIS_UNITS,
|
|
6
|
+
PLOT_LINE_OPTION,
|
|
7
|
+
PLOT_LINE_LABEL_OPTION,
|
|
8
|
+
PLOT_BAND_OPTION,
|
|
9
|
+
} from '../helpers/helpers.constant';
|
|
3
10
|
import Util from '../helpers/helpers.util';
|
|
4
11
|
|
|
5
12
|
class Scale {
|
|
@@ -213,80 +220,537 @@ class Scale {
|
|
|
213
220
|
return;
|
|
214
221
|
}
|
|
215
222
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
223
|
+
if (this.labelStyle?.show) {
|
|
224
|
+
const labelGap = (endPoint - startPoint) / steps;
|
|
225
|
+
const ticks = [];
|
|
226
|
+
let labelCenter = null;
|
|
227
|
+
let linePosition = null;
|
|
220
228
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
let labelText;
|
|
226
|
-
for (let ix = 0; ix <= steps; ix++) {
|
|
227
|
-
ctx.beginPath();
|
|
228
|
-
ticks[ix] = axisMin + (ix * stepValue);
|
|
229
|
+
ctx.strokeStyle = this.gridLineColor;
|
|
230
|
+
ctx.lineWidth = 1;
|
|
231
|
+
aliasPixel = Util.aliasPixel(ctx.lineWidth);
|
|
229
232
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
+
let labelText;
|
|
234
|
+
for (let ix = 0; ix <= steps; ix++) {
|
|
235
|
+
ctx.beginPath();
|
|
236
|
+
ticks[ix] = axisMin + (ix * stepValue);
|
|
237
|
+
|
|
238
|
+
labelCenter = Math.round(startPoint + (labelGap * ix));
|
|
239
|
+
linePosition = labelCenter + aliasPixel;
|
|
240
|
+
labelText = this.getLabelFormat(Math.min(axisMax, ticks[ix]));
|
|
241
|
+
|
|
242
|
+
let labelPoint;
|
|
243
|
+
|
|
244
|
+
if (this.type === 'x') {
|
|
245
|
+
labelPoint = this.position === 'top' ? offsetPoint - 10 : offsetPoint + 10;
|
|
246
|
+
ctx.fillText(labelText, labelCenter, labelPoint);
|
|
247
|
+
if (options?.selectItem?.showLabelTip && hitInfo?.label && !this.options?.horizontal) {
|
|
248
|
+
const selectedLabel = this.getLabelFormat(
|
|
249
|
+
Math.min(axisMax, hitInfo.label + (0 * stepValue)),
|
|
250
|
+
);
|
|
251
|
+
if (selectedLabel === labelText) {
|
|
252
|
+
const height = Math.round(ctx.measureText(this.labelStyle?.fontSize).width);
|
|
253
|
+
Util.showLabelTip({
|
|
254
|
+
ctx: this.ctx,
|
|
255
|
+
width: Math.round(ctx.measureText(selectedLabel).width) + 10,
|
|
256
|
+
height,
|
|
257
|
+
x: labelCenter,
|
|
258
|
+
y: labelPoint + (height - 2),
|
|
259
|
+
borderRadius: 2,
|
|
260
|
+
arrowSize: 3,
|
|
261
|
+
text: labelText,
|
|
262
|
+
backgroundColor: options?.selectItem?.labelTipStyle?.backgroundColor,
|
|
263
|
+
textColor: options?.selectItem?.labelTipStyle?.textColor,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (ix !== 0 && this.showGrid) {
|
|
268
|
+
ctx.moveTo(linePosition, offsetPoint);
|
|
269
|
+
ctx.lineTo(linePosition, offsetCounterPoint);
|
|
270
|
+
}
|
|
271
|
+
} else {
|
|
272
|
+
labelPoint = this.position === 'left' ? offsetPoint - 10 : offsetPoint + 10;
|
|
273
|
+
ctx.fillText(labelText, labelPoint, labelCenter);
|
|
233
274
|
|
|
234
|
-
|
|
275
|
+
if (ix === steps) {
|
|
276
|
+
linePosition += 1;
|
|
277
|
+
}
|
|
235
278
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (options?.selectItem?.showLabelTip && hitInfo?.label && !this.options?.horizontal) {
|
|
240
|
-
const selectedLabel = this.getLabelFormat(
|
|
241
|
-
Math.min(axisMax, hitInfo.label + (0 * stepValue)),
|
|
242
|
-
);
|
|
243
|
-
if (selectedLabel === labelText) {
|
|
244
|
-
const height = Math.round(ctx.measureText(this.labelStyle?.fontSize).width);
|
|
245
|
-
Util.showLabelTip({
|
|
246
|
-
ctx: this.ctx,
|
|
247
|
-
width: Math.round(ctx.measureText(selectedLabel).width) + 10,
|
|
248
|
-
height,
|
|
249
|
-
x: labelCenter,
|
|
250
|
-
y: labelPoint + (height - 2),
|
|
251
|
-
borderRadius: 2,
|
|
252
|
-
arrowSize: 3,
|
|
253
|
-
text: labelText,
|
|
254
|
-
backgroundColor: options?.selectItem?.labelTipStyle?.backgroundColor,
|
|
255
|
-
textColor: options?.selectItem?.labelTipStyle?.textColor,
|
|
256
|
-
});
|
|
279
|
+
if (ix !== 0 && this.showGrid) {
|
|
280
|
+
ctx.moveTo(offsetPoint, linePosition);
|
|
281
|
+
ctx.lineTo(offsetCounterPoint, linePosition);
|
|
257
282
|
}
|
|
258
283
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
284
|
+
|
|
285
|
+
ctx.stroke();
|
|
286
|
+
ctx.closePath();
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Draw plot lines and plot bands
|
|
291
|
+
if (this.plotBands?.length || this.plotLines?.length) {
|
|
292
|
+
const xArea = chartRect.chartWidth - (labelOffset.left + labelOffset.right);
|
|
293
|
+
const yArea = chartRect.chartHeight - (labelOffset.top + labelOffset.bottom);
|
|
294
|
+
const padding = aliasPixel + 1;
|
|
295
|
+
const minX = aPos.x1 + padding;
|
|
296
|
+
const maxX = aPos.x2;
|
|
297
|
+
const minY = aPos.y1 + padding; // top
|
|
298
|
+
const maxY = aPos.y2; // bottom
|
|
299
|
+
|
|
300
|
+
this.plotBands?.forEach((plotBand) => {
|
|
301
|
+
if (!plotBand.from && !plotBand.to) {
|
|
302
|
+
return;
|
|
262
303
|
}
|
|
263
304
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
305
|
+
const mergedPlotBandOpt = defaultsDeep({}, plotBand, PLOT_BAND_OPTION);
|
|
306
|
+
const { from, to, label: labelOpt } = mergedPlotBandOpt;
|
|
307
|
+
|
|
308
|
+
this.setPlotBandStyle(mergedPlotBandOpt);
|
|
309
|
+
|
|
310
|
+
let fromPos;
|
|
311
|
+
let toPos;
|
|
312
|
+
if (this.type === 'x') {
|
|
313
|
+
fromPos = Canvas.calculateX(from ?? minX, axisMin, axisMax, xArea, minX);
|
|
314
|
+
toPos = Canvas.calculateX(to ?? maxX, axisMin, axisMax, xArea, minX);
|
|
315
|
+
this.drawXPlotBand(fromPos, toPos, minX, maxX, minY, maxY);
|
|
316
|
+
} else {
|
|
317
|
+
fromPos = Canvas.calculateY(from ?? axisMin, axisMin, axisMax, yArea, maxY);
|
|
318
|
+
toPos = Canvas.calculateY(to ?? axisMax, axisMin, axisMax, yArea, maxY);
|
|
319
|
+
this.drawYPlotBand(fromPos, toPos, minX, maxX, minY, maxY);
|
|
267
320
|
}
|
|
268
|
-
} else {
|
|
269
|
-
labelPoint = this.position === 'left' ? offsetPoint - 10 : offsetPoint + 10;
|
|
270
|
-
ctx.fillText(labelText, labelPoint, labelCenter);
|
|
271
321
|
|
|
272
|
-
if (
|
|
273
|
-
|
|
322
|
+
if (labelOpt.show) {
|
|
323
|
+
const labelOptions = this.getNormalizedLabelOptions(chartRect, labelOpt);
|
|
324
|
+
const textXY = this.getPlotBandLabelPosition(fromPos, toPos, labelOptions, maxX, minY);
|
|
325
|
+
this.drawPlotLabel(labelOptions, textXY);
|
|
274
326
|
}
|
|
275
327
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
328
|
+
ctx.restore();
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
this.plotLines?.forEach((plotLine) => {
|
|
332
|
+
if (!plotLine.value) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const mergedPlotLineOpt = defaultsDeep({}, plotLine, PLOT_LINE_OPTION);
|
|
337
|
+
const { value, label: labelOpt } = mergedPlotLineOpt;
|
|
338
|
+
|
|
339
|
+
this.setPlotLineStyle(mergedPlotLineOpt);
|
|
340
|
+
|
|
341
|
+
let dataPos;
|
|
342
|
+
if (this.type === 'x') {
|
|
343
|
+
dataPos = Canvas.calculateX(value, axisMin, axisMax, xArea, minX);
|
|
344
|
+
this.drawXPlotLine(dataPos, minX, maxX, minY, maxY);
|
|
345
|
+
} else {
|
|
346
|
+
dataPos = Canvas.calculateY(value, axisMin, axisMax, yArea, maxY);
|
|
347
|
+
this.drawYPlotLine(dataPos, minX, maxX, minY, maxY);
|
|
279
348
|
}
|
|
280
349
|
|
|
281
|
-
if (
|
|
282
|
-
|
|
283
|
-
|
|
350
|
+
if (labelOpt.show) {
|
|
351
|
+
const labelOptions = this.getNormalizedLabelOptions(chartRect, labelOpt);
|
|
352
|
+
const textXY = this.getPlotLineLabelPosition(dataPos, labelOptions, maxX, minY);
|
|
353
|
+
this.drawPlotLabel(labelOptions, textXY);
|
|
284
354
|
}
|
|
355
|
+
|
|
356
|
+
ctx.restore();
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Set plot line style
|
|
363
|
+
* @param {object} plotLine plotLine Options
|
|
364
|
+
*
|
|
365
|
+
* @returns {undefined}
|
|
366
|
+
*/
|
|
367
|
+
setPlotLineStyle(plotLine) {
|
|
368
|
+
const ctx = this.ctx;
|
|
369
|
+
const { color, lineWidth } = plotLine;
|
|
370
|
+
|
|
371
|
+
ctx.beginPath();
|
|
372
|
+
ctx.save();
|
|
373
|
+
ctx.lineWidth = lineWidth;
|
|
374
|
+
ctx.strokeStyle = color;
|
|
375
|
+
|
|
376
|
+
if (plotLine.segments) {
|
|
377
|
+
ctx.setLineDash(plotLine.segments);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Set plot band style
|
|
383
|
+
* @param {object} plotBand plotBand Options
|
|
384
|
+
*
|
|
385
|
+
* @returns {undefined}
|
|
386
|
+
*/
|
|
387
|
+
setPlotBandStyle(plotBand) {
|
|
388
|
+
const ctx = this.ctx;
|
|
389
|
+
const { color } = plotBand;
|
|
390
|
+
|
|
391
|
+
ctx.beginPath();
|
|
392
|
+
ctx.save();
|
|
393
|
+
ctx.fillStyle = color;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Draw X Plot band
|
|
398
|
+
* @param {number} fromDataX From data's X Position
|
|
399
|
+
* @param {number} toDataX To data's X Position
|
|
400
|
+
* @param {number} minX Min X Position
|
|
401
|
+
* @param {number} maxX Max X Position
|
|
402
|
+
* @param {number} minY Min Y Position
|
|
403
|
+
* @param {number} maxY Max Y Position
|
|
404
|
+
*
|
|
405
|
+
* @returns {undefined}
|
|
406
|
+
*/
|
|
407
|
+
drawXPlotBand(fromDataX, toDataX, minX, maxX, minY, maxY) {
|
|
408
|
+
const ctx = this.ctx;
|
|
409
|
+
|
|
410
|
+
const checkValidPosition = x => x || x > minX || x < maxX;
|
|
411
|
+
|
|
412
|
+
if (!checkValidPosition(fromDataX) || !checkValidPosition(toDataX)) {
|
|
413
|
+
ctx.closePath();
|
|
414
|
+
ctx.restore();
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
ctx.moveTo(fromDataX, minY);
|
|
419
|
+
ctx.lineTo(fromDataX, maxY);
|
|
420
|
+
ctx.lineTo(toDataX, maxY);
|
|
421
|
+
ctx.lineTo(toDataX, minY);
|
|
422
|
+
ctx.lineTo(fromDataX, minY);
|
|
423
|
+
|
|
424
|
+
ctx.stroke();
|
|
425
|
+
ctx.fill();
|
|
426
|
+
ctx.restore();
|
|
427
|
+
ctx.closePath();
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Draw X Plot line
|
|
432
|
+
* @param {object} dataX Data's X Position
|
|
433
|
+
* @param {number} minX Min X Position
|
|
434
|
+
* @param {number} maxX Max X Position
|
|
435
|
+
* @param {number} minY Min Y Position
|
|
436
|
+
* @param {number} maxY Max Y Position
|
|
437
|
+
*
|
|
438
|
+
* @returns {undefined}
|
|
439
|
+
*/
|
|
440
|
+
drawXPlotLine(dataX, minX, maxX, minY, maxY) {
|
|
441
|
+
const ctx = this.ctx;
|
|
442
|
+
|
|
443
|
+
if (!dataX || dataX < minX || dataX > maxX) {
|
|
444
|
+
ctx.closePath();
|
|
445
|
+
ctx.restore();
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
ctx.moveTo(dataX, maxY);
|
|
450
|
+
ctx.lineTo(dataX, minY);
|
|
451
|
+
|
|
452
|
+
ctx.stroke();
|
|
453
|
+
ctx.restore();
|
|
454
|
+
ctx.closePath();
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Draw Y Plot line
|
|
459
|
+
* @param {object} dataY Data's Y Position
|
|
460
|
+
* @param {number} minX Min X Position
|
|
461
|
+
* @param {number} maxX Max X Position
|
|
462
|
+
* @param {number} minY Min Y Position
|
|
463
|
+
* @param {number} maxY Max Y Position
|
|
464
|
+
*
|
|
465
|
+
* @returns {undefined}
|
|
466
|
+
*/
|
|
467
|
+
drawYPlotLine(dataY, minX, maxX, minY, maxY) {
|
|
468
|
+
const ctx = this.ctx;
|
|
469
|
+
|
|
470
|
+
if (!dataY || dataY > maxY || dataY < minY) {
|
|
471
|
+
ctx.closePath();
|
|
472
|
+
ctx.restore();
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
ctx.moveTo(minX, dataY);
|
|
477
|
+
ctx.lineTo(maxX, dataY);
|
|
478
|
+
|
|
479
|
+
ctx.stroke();
|
|
480
|
+
ctx.restore();
|
|
481
|
+
ctx.closePath();
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Draw Y Plot band
|
|
486
|
+
* @param {number} fromDataY From data's Y Position (bottom)
|
|
487
|
+
* @param {number} toDataY To data's Y Position (top)
|
|
488
|
+
* @param {number} minX Min X Position
|
|
489
|
+
* @param {number} maxX Max X Position
|
|
490
|
+
* @param {number} minY Min Y Position
|
|
491
|
+
* @param {number} maxY Max Y Position
|
|
492
|
+
*
|
|
493
|
+
* @returns {undefined}
|
|
494
|
+
*/
|
|
495
|
+
drawYPlotBand(fromDataY, toDataY, minX, maxX, minY, maxY) {
|
|
496
|
+
const ctx = this.ctx;
|
|
497
|
+
|
|
498
|
+
const checkValidPosition = y => y || y > minY || y < maxY;
|
|
499
|
+
|
|
500
|
+
if (!checkValidPosition(fromDataY) || !checkValidPosition(toDataY)) {
|
|
501
|
+
ctx.closePath();
|
|
502
|
+
ctx.restore();
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
ctx.moveTo(minX, fromDataY);
|
|
507
|
+
ctx.lineTo(minX, toDataY);
|
|
508
|
+
ctx.lineTo(maxX, toDataY);
|
|
509
|
+
ctx.lineTo(maxX, fromDataY);
|
|
510
|
+
ctx.lineTo(minX, fromDataY);
|
|
511
|
+
|
|
512
|
+
ctx.fill();
|
|
513
|
+
ctx.restore();
|
|
514
|
+
ctx.closePath();
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* get normalized options for plot label
|
|
519
|
+
* @param {object} chartRect chartRect
|
|
520
|
+
* @param {object} labelOpt plotLine Options
|
|
521
|
+
*
|
|
522
|
+
* @returns {object}
|
|
523
|
+
*/
|
|
524
|
+
getNormalizedLabelOptions(chartRect, labelOpt) {
|
|
525
|
+
const mergedLabelOpt = defaultsDeep({}, labelOpt, PLOT_LINE_LABEL_OPTION);
|
|
526
|
+
|
|
527
|
+
const ctx = this.ctx;
|
|
528
|
+
const { maxWidth } = mergedLabelOpt;
|
|
529
|
+
const fontSize = mergedLabelOpt.fontSize > 20 ? 20 : mergedLabelOpt.fontSize;
|
|
530
|
+
let label = mergedLabelOpt.text;
|
|
531
|
+
let labelWidth = maxWidth ?? ctx.measureText(label).width;
|
|
532
|
+
|
|
533
|
+
const plotLabelAreaWidth = this.type === 'y'
|
|
534
|
+
? chartRect.width - chartRect.chartWidth
|
|
535
|
+
: maxWidth ?? chartRect.width;
|
|
536
|
+
|
|
537
|
+
if (plotLabelAreaWidth < ctx.measureText(label).width && mergedLabelOpt.textOverflow === 'ellipsis') {
|
|
538
|
+
label = Util.truncateLabelWithEllipsis(mergedLabelOpt.text, plotLabelAreaWidth, ctx);
|
|
539
|
+
labelWidth = ctx.measureText(label).width;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
return {
|
|
543
|
+
label,
|
|
544
|
+
fontSize,
|
|
545
|
+
labelWidth,
|
|
546
|
+
labelBoxPadding: fontSize / 4,
|
|
547
|
+
labelHalfWidth: labelWidth / 2,
|
|
548
|
+
labelHalfHeight: fontSize / 2,
|
|
549
|
+
...mergedLabelOpt,
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Calculate position of plot band's label
|
|
555
|
+
* @param {object} fromPos from data position
|
|
556
|
+
* @param {object} toPos to data position
|
|
557
|
+
* @param {object} labelOpt label options
|
|
558
|
+
* @param {object} maxX max x position
|
|
559
|
+
* @param {object} minY min y position
|
|
560
|
+
*
|
|
561
|
+
* @returns {object}
|
|
562
|
+
*/
|
|
563
|
+
getPlotBandLabelPosition(fromPos, toPos, labelOpt, maxX, minY) {
|
|
564
|
+
const {
|
|
565
|
+
fontSize,
|
|
566
|
+
labelWidth,
|
|
567
|
+
labelHalfWidth,
|
|
568
|
+
labelHalfHeight,
|
|
569
|
+
labelBoxPadding,
|
|
570
|
+
textAlign,
|
|
571
|
+
verticalAlign,
|
|
572
|
+
} = labelOpt;
|
|
573
|
+
|
|
574
|
+
if (fontSize <= 0) {
|
|
575
|
+
return { textX: 0, textY: 0 };
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
let textX;
|
|
579
|
+
let textY;
|
|
580
|
+
|
|
581
|
+
if (this.type === 'x') {
|
|
582
|
+
textY = minY - labelBoxPadding - fontSize;
|
|
583
|
+
|
|
584
|
+
switch (textAlign) {
|
|
585
|
+
case 'left':
|
|
586
|
+
textX = fromPos + labelHalfWidth + labelBoxPadding;
|
|
587
|
+
break;
|
|
588
|
+
|
|
589
|
+
case 'right':
|
|
590
|
+
textX = toPos - labelHalfWidth - labelBoxPadding;
|
|
591
|
+
break;
|
|
592
|
+
|
|
593
|
+
case 'center':
|
|
594
|
+
default:
|
|
595
|
+
textX = ((toPos - fromPos) / 2) + fromPos;
|
|
596
|
+
break;
|
|
597
|
+
}
|
|
598
|
+
} else {
|
|
599
|
+
textX = maxX + labelWidth + labelBoxPadding;
|
|
600
|
+
|
|
601
|
+
switch (verticalAlign) {
|
|
602
|
+
case 'top':
|
|
603
|
+
textY = toPos + labelHalfHeight + labelBoxPadding;
|
|
604
|
+
break;
|
|
605
|
+
|
|
606
|
+
case 'bottom':
|
|
607
|
+
textY = fromPos - labelHalfHeight - labelBoxPadding;
|
|
608
|
+
break;
|
|
609
|
+
|
|
610
|
+
case 'middle':
|
|
611
|
+
default:
|
|
612
|
+
textY = ((fromPos - toPos) / 2) + toPos;
|
|
613
|
+
break;
|
|
285
614
|
}
|
|
615
|
+
}
|
|
286
616
|
|
|
617
|
+
return { textX, textY };
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Calculate position of plot line's label
|
|
622
|
+
* @param {object} dataPos data position
|
|
623
|
+
* @param {object} labelOpt label options
|
|
624
|
+
* @param {object} maxX max x position
|
|
625
|
+
* @param {object} minY min y position
|
|
626
|
+
*
|
|
627
|
+
* @returns {undefined}
|
|
628
|
+
*/
|
|
629
|
+
getPlotLineLabelPosition(dataPos, labelOpt, maxX, minY) {
|
|
630
|
+
const {
|
|
631
|
+
fontSize,
|
|
632
|
+
labelWidth,
|
|
633
|
+
labelHalfWidth,
|
|
634
|
+
labelHalfHeight,
|
|
635
|
+
labelBoxPadding,
|
|
636
|
+
} = labelOpt;
|
|
637
|
+
|
|
638
|
+
if (fontSize <= 0) {
|
|
639
|
+
return { textX: 0, textY: 0 };
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
let textX;
|
|
643
|
+
let textY;
|
|
644
|
+
|
|
645
|
+
if (this.type === 'x') {
|
|
646
|
+
textY = minY - labelBoxPadding - fontSize;
|
|
647
|
+
|
|
648
|
+
switch (labelOpt.textAlign) {
|
|
649
|
+
case 'left':
|
|
650
|
+
textX = dataPos - labelHalfWidth - labelBoxPadding;
|
|
651
|
+
break;
|
|
652
|
+
|
|
653
|
+
case 'right':
|
|
654
|
+
textX = dataPos + labelHalfWidth + labelBoxPadding;
|
|
655
|
+
break;
|
|
656
|
+
|
|
657
|
+
case 'center':
|
|
658
|
+
default:
|
|
659
|
+
textX = dataPos;
|
|
660
|
+
break;
|
|
661
|
+
}
|
|
662
|
+
} else {
|
|
663
|
+
textX = maxX + labelWidth + labelBoxPadding;
|
|
664
|
+
|
|
665
|
+
switch (labelOpt.verticalAlign) {
|
|
666
|
+
case 'top':
|
|
667
|
+
textY = dataPos - labelHalfHeight - labelBoxPadding;
|
|
668
|
+
break;
|
|
669
|
+
|
|
670
|
+
case 'bottom':
|
|
671
|
+
textY = dataPos + labelHalfHeight + labelBoxPadding;
|
|
672
|
+
break;
|
|
673
|
+
|
|
674
|
+
case 'middle':
|
|
675
|
+
default:
|
|
676
|
+
textY = dataPos;
|
|
677
|
+
break;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
return { textX, textY };
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Calculate Values for drawing label
|
|
686
|
+
* @param {object} labelOptions plot line Label Options
|
|
687
|
+
* @param {object} positions x, y Position
|
|
688
|
+
*
|
|
689
|
+
* @returns {undefined}
|
|
690
|
+
*/
|
|
691
|
+
drawPlotLabel(labelOptions, positions) {
|
|
692
|
+
if (!positions) {
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
const { textX, textY } = positions;
|
|
697
|
+
const {
|
|
698
|
+
label,
|
|
699
|
+
fontSize,
|
|
700
|
+
fontColor,
|
|
701
|
+
fillColor,
|
|
702
|
+
lineColor,
|
|
703
|
+
lineWidth,
|
|
704
|
+
labelBoxPadding,
|
|
705
|
+
labelWidth,
|
|
706
|
+
labelHalfWidth,
|
|
707
|
+
labelHalfHeight,
|
|
708
|
+
} = labelOptions;
|
|
709
|
+
|
|
710
|
+
if (fontSize <= 0) {
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
const ctx = this.ctx;
|
|
715
|
+
ctx.save();
|
|
716
|
+
ctx.beginPath();
|
|
717
|
+
ctx.font = Util.getLabelStyle(labelOptions);
|
|
718
|
+
|
|
719
|
+
let top = 0;
|
|
720
|
+
let bottom = 0;
|
|
721
|
+
let left = 0;
|
|
722
|
+
let right = 0;
|
|
723
|
+
|
|
724
|
+
if (this.type === 'x') {
|
|
725
|
+
top = textY - labelBoxPadding;
|
|
726
|
+
bottom = textY + fontSize;
|
|
727
|
+
left = textX - labelHalfWidth - labelBoxPadding;
|
|
728
|
+
right = textX + labelHalfWidth + labelBoxPadding;
|
|
729
|
+
} else {
|
|
730
|
+
top = textY - labelHalfHeight - labelBoxPadding;
|
|
731
|
+
bottom = textY + labelHalfHeight + labelBoxPadding;
|
|
732
|
+
left = textX - labelWidth;
|
|
733
|
+
right = textX + labelBoxPadding;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
ctx.fillStyle = fillColor;
|
|
737
|
+
ctx.strokeStyle = lineColor;
|
|
738
|
+
ctx.lineWidth = lineWidth;
|
|
739
|
+
ctx.moveTo(left, bottom);
|
|
740
|
+
ctx.lineTo(left, top);
|
|
741
|
+
ctx.lineTo(right, top);
|
|
742
|
+
ctx.lineTo(right, bottom);
|
|
743
|
+
ctx.lineTo(left, bottom);
|
|
744
|
+
ctx.fill();
|
|
745
|
+
|
|
746
|
+
if (lineWidth > 0) {
|
|
287
747
|
ctx.stroke();
|
|
288
|
-
ctx.closePath();
|
|
289
748
|
}
|
|
749
|
+
|
|
750
|
+
ctx.fillStyle = fontColor;
|
|
751
|
+
|
|
752
|
+
ctx.fillText(label, textX, textY);
|
|
753
|
+
ctx.closePath();
|
|
290
754
|
}
|
|
291
755
|
}
|
|
292
756
|
|
|
@@ -9,6 +9,14 @@ class LinearScale extends Scale {
|
|
|
9
9
|
* @returns {string} formatted label
|
|
10
10
|
*/
|
|
11
11
|
getLabelFormat(value) {
|
|
12
|
+
if (this.formatter) {
|
|
13
|
+
const formattedLabel = this.formatter(value);
|
|
14
|
+
|
|
15
|
+
if (typeof formattedLabel === 'string') {
|
|
16
|
+
return formattedLabel;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
return Util.labelSignFormat(value, this.decimalPoint);
|
|
13
21
|
}
|
|
14
22
|
|
|
@@ -101,6 +101,14 @@ class LogarithmicScale extends Scale {
|
|
|
101
101
|
* @returns {string} formatted label
|
|
102
102
|
*/
|
|
103
103
|
getLabelFormat(value) {
|
|
104
|
+
if (this.formatter) {
|
|
105
|
+
const formattedLabel = this.formatter(value);
|
|
106
|
+
|
|
107
|
+
if (typeof formattedLabel === 'string') {
|
|
108
|
+
return formattedLabel;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
104
112
|
return Util.labelSignFormat(value, this.decimalPoint);
|
|
105
113
|
}
|
|
106
114
|
|