@mantine-vue/charts 3.2.0 → 3.3.0

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/esm/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { computed, defineComponent, h, ref } from "vue";
2
2
  import VChart from "vue-echarts";
3
3
  import { use } from "echarts/core";
4
- import { BarChart as BarChart$1, EffectScatterChart, FunnelChart as FunnelChart$1, GaugeChart, GraphChart, HeatmapChart, LineChart as LineChart$1, PieChart as PieChart$1, RadarChart as RadarChart$1, SankeyChart as SankeyChart$1, ScatterChart as ScatterChart$1, TreemapChart } from "echarts/charts";
5
- import { AriaComponent, CalendarComponent, DataZoomComponent, DatasetComponent, GraphicComponent, GridComponent, LegendComponent, MarkLineComponent, PolarComponent, RadarComponent, TitleComponent, ToolboxComponent, TooltipComponent, TransformComponent, VisualMapComponent } from "echarts/components";
4
+ import { BarChart as BarChart$1, CandlestickChart as CandlestickChart$1, EffectScatterChart, FunnelChart as FunnelChart$1, GaugeChart as GaugeChart$1, GraphChart, HeatmapChart, LineChart as LineChart$1, PieChart as PieChart$1, RadarChart as RadarChart$1, SankeyChart as SankeyChart$1, ScatterChart as ScatterChart$1, TreemapChart } from "echarts/charts";
5
+ import { AriaComponent, CalendarComponent, DataZoomComponent, DatasetComponent, GraphicComponent, GridComponent, LegendComponent, MarkAreaComponent, MarkLineComponent, MarkPointComponent, PolarComponent, RadarComponent, TitleComponent, ToolboxComponent, TooltipComponent, TransformComponent, VisualMapComponent } from "echarts/components";
6
6
  import { CanvasRenderer, SVGRenderer } from "echarts/renderers";
7
7
  //#region src/internal/echarts.ts
8
8
  var registered = false;
@@ -10,9 +10,10 @@ function registerECharts() {
10
10
  if (registered) return;
11
11
  use([
12
12
  BarChart$1,
13
+ CandlestickChart$1,
13
14
  EffectScatterChart,
14
15
  FunnelChart$1,
15
- GaugeChart,
16
+ GaugeChart$1,
16
17
  GraphChart,
17
18
  HeatmapChart,
18
19
  LineChart$1,
@@ -29,6 +30,8 @@ function registerECharts() {
29
30
  GridComponent,
30
31
  LegendComponent,
31
32
  MarkLineComponent,
33
+ MarkAreaComponent,
34
+ MarkPointComponent,
32
35
  PolarComponent,
33
36
  RadarComponent,
34
37
  TitleComponent,
@@ -302,6 +305,36 @@ function markLine(referenceLines) {
302
305
  }))
303
306
  };
304
307
  }
308
+ function markArea(referenceAreas) {
309
+ if (!referenceAreas?.length) return void 0;
310
+ return {
311
+ silent: true,
312
+ data: referenceAreas.map((area) => [{
313
+ xAxis: area.x1,
314
+ yAxis: area.y1,
315
+ itemStyle: {
316
+ color: resolveColor(area.color, "#868e96"),
317
+ opacity: .15
318
+ },
319
+ label: typeof area.label === "string" ? { formatter: area.label } : area.label
320
+ }, {
321
+ xAxis: area.x2,
322
+ yAxis: area.y2
323
+ }])
324
+ };
325
+ }
326
+ function markPoint(referenceDots) {
327
+ if (!referenceDots?.length) return void 0;
328
+ return {
329
+ silent: true,
330
+ data: referenceDots.map((dot) => ({
331
+ coord: [dot.x, dot.y],
332
+ symbolSize: (dot.r ?? 6) * 2,
333
+ itemStyle: { color: resolveColor(dot.color, "#868e96") },
334
+ label: typeof dot.label === "string" ? { formatter: dot.label } : dot.label
335
+ }))
336
+ };
337
+ }
305
338
  function cartesianOption(props, kind) {
306
339
  const data = list(props.data);
307
340
  const series = list(props.series);
@@ -323,13 +356,15 @@ function cartesianOption(props, kind) {
323
356
  const mapped = series.map((item, index) => {
324
357
  const itemKind = kind === "composite" ? item.type ?? "line" : kind === "area" ? "line" : kind;
325
358
  const color = resolveColor(item.color, resolveColor(`blue.${6 + index % 3}`));
326
- const stack = chartType === "stacked" || chartType === "percent" ? "stack" : item.stackId;
359
+ const stack = chartType === "stacked" || chartType === "percent" || chartType === "stream" ? "stack" : item.stackId;
327
360
  const base = {
328
361
  name: item.label ?? item.name,
329
362
  data: data.map((entry) => entry[item.name]),
330
363
  yAxisIndex: item.yAxisId ? 1 : 0,
331
364
  stack,
332
- markLine: index === 0 ? markLine(props.referenceLines) : void 0
365
+ markLine: index === 0 ? markLine(props.referenceLines) : void 0,
366
+ markArea: index === 0 ? markArea(props.referenceAreas) : void 0,
367
+ markPoint: index === 0 ? markPoint(props.referenceDots) : void 0
333
368
  };
334
369
  if (itemKind === "bar") return {
335
370
  ...base,
@@ -360,7 +395,7 @@ function cartesianOption(props, kind) {
360
395
  symbolSize: 6,
361
396
  lineStyle: {
362
397
  color,
363
- width: num(props.strokeWidth, 2),
398
+ width: chartType === "stream" ? 0 : num(props.strokeWidth, 2),
364
399
  type: item.strokeDasharray ? "dashed" : "solid"
365
400
  },
366
401
  itemStyle: {
@@ -377,6 +412,19 @@ function cartesianOption(props, kind) {
377
412
  }
378
413
  };
379
414
  });
415
+ if (kind === "area" && chartType === "stream") mapped.unshift({
416
+ type: "line",
417
+ stack: "stack",
418
+ silent: true,
419
+ symbol: "none",
420
+ data: data.map((entry) => -series.reduce((total, item) => {
421
+ const value = entry[item.name];
422
+ return total + (typeof value === "number" && Number.isFinite(value) ? value : 0);
423
+ }, 0) / 2),
424
+ lineStyle: { opacity: 0 },
425
+ areaStyle: { opacity: 0 },
426
+ tooltip: { show: false }
427
+ });
380
428
  return {
381
429
  animationDurationUpdate: num(props.tooltipAnimationDuration, 0),
382
430
  color: series.map((item) => resolveColor(item.color)),
@@ -405,7 +453,7 @@ function cartesianOption(props, kind) {
405
453
  },
406
454
  yAxis: horizontal ? [{
407
455
  ...valueAxis,
408
- show: bool(props.withYAxis, true),
456
+ show: chartType === "stream" ? false : bool(props.withYAxis, true),
409
457
  ...obj(props.yAxisProps)
410
458
  }, {
411
459
  ...valueAxis,
@@ -488,17 +536,30 @@ function scatterOption(props, bubble = false) {
488
536
  show: bool(props.withXAxis, true),
489
537
  ...obj(props.xAxisProps)
490
538
  },
491
- yAxis: {
539
+ yAxis: props.withRightYAxis ? [{
492
540
  type: "value",
493
541
  show: bool(props.withYAxis, true),
542
+ name: props.yAxisLabel,
543
+ ...obj(props.yAxisProps)
544
+ }, {
545
+ type: "value",
546
+ show: true,
547
+ position: "right",
548
+ name: props.rightYAxisLabel,
549
+ ...obj(props.rightYAxisProps)
550
+ }] : {
551
+ type: "value",
552
+ show: bool(props.withYAxis, true),
553
+ name: props.yAxisLabel,
494
554
  ...obj(props.yAxisProps)
495
555
  },
496
556
  series: (series.length ? series : [{
497
557
  name: String(props.name ?? "value"),
498
558
  color: props.color
499
- }]).map((item) => ({
559
+ }]).map((item, index) => ({
500
560
  type: "scatter",
501
561
  name: item.label ?? item.name,
562
+ yAxisIndex: item.yAxisId === "right" ? 1 : 0,
502
563
  data: data.filter((entry) => !entry.name || entry.name === item.name).map((entry) => [
503
564
  entry[xKey],
504
565
  entry[yKey],
@@ -506,10 +567,287 @@ function scatterOption(props, bubble = false) {
506
567
  entry
507
568
  ]),
508
569
  symbolSize: bubble ? (value) => Math.max(4, Math.sqrt(Number(value[2] ?? 1)) * num(props.range, 4)) : num(props.size, 10),
509
- itemStyle: { color: resolveColor(item.color) }
570
+ itemStyle: { color: resolveColor(item.color) },
571
+ markLine: index === 0 ? markLine(props.referenceLines) : void 0,
572
+ markArea: index === 0 ? markArea(props.referenceAreas) : void 0,
573
+ markPoint: index === 0 ? markPoint(props.referenceDots) : void 0
510
574
  }))
511
575
  };
512
576
  }
577
+ function gaugeOption(props) {
578
+ const min = num(props.min, 0);
579
+ const max = num(props.max, 100);
580
+ const value = num(props.value, min);
581
+ const sections = list(props.sections);
582
+ const range = max - min || 1;
583
+ const axisColors = sections.length ? sections.map((section) => [Math.max(0, Math.min(1, (section.value - min) / range)), resolveColor(section.color)]) : [[1, resolveColor(props.trackColor, "#e9ecef")]];
584
+ const format = typeof props.valueFormatter === "function" ? props.valueFormatter : (input) => String(input);
585
+ return { series: [{
586
+ type: "gauge",
587
+ min,
588
+ max,
589
+ startAngle: 90 - num(props.startAngle, -120),
590
+ endAngle: 90 - num(props.endAngle, 120),
591
+ radius: "90%",
592
+ axisLine: { lineStyle: {
593
+ width: num(props.thickness, 12),
594
+ color: axisColors
595
+ } },
596
+ progress: sections.length ? { show: false } : {
597
+ show: true,
598
+ width: num(props.thickness, 12),
599
+ roundCap: bool(props.roundCaps, false),
600
+ itemStyle: { color: resolveColor(props.filledColor) }
601
+ },
602
+ pointer: typeof props.target === "number" ? {
603
+ show: true,
604
+ width: num(props.targetSize, 2),
605
+ length: "85%",
606
+ itemStyle: { color: resolveColor(props.targetColor, "#212529") }
607
+ } : { show: false },
608
+ axisTick: { show: false },
609
+ splitLine: { show: false },
610
+ axisLabel: { show: false },
611
+ anchor: { show: false },
612
+ title: { show: false },
613
+ detail: {
614
+ show: props.label !== null,
615
+ formatter: typeof props.label === "string" ? props.label : format(value),
616
+ color: "inherit"
617
+ },
618
+ data: [{ value: typeof props.target === "number" ? props.target : value }]
619
+ }] };
620
+ }
621
+ function normalizeSegmentValue(value) {
622
+ return Number.isFinite(value) ? Math.max(0, value) : 0;
623
+ }
624
+ function waffleOption(props) {
625
+ const rows = Math.max(1, num(props.rows, 10));
626
+ const columns = Math.max(1, num(props.columns, 10));
627
+ const cellCount = rows * columns;
628
+ const data = list(props.data);
629
+ const values = data.map((item) => normalizeSegmentValue(item.value));
630
+ const sum = values.reduce((total, value) => total + value, 0);
631
+ const denominator = props.total == null ? sum : Math.max(num(props.total, sum), sum);
632
+ const filledTarget = denominator ? Math.round(sum / denominator * cellCount) : 0;
633
+ const allocated = values.map((value) => sum ? Math.floor(value / sum * filledTarget) : 0);
634
+ let remainder = filledTarget - allocated.reduce((total, value) => total + value, 0);
635
+ const fractions = values.map((value, index) => ({
636
+ index,
637
+ fraction: sum ? value / sum * filledTarget - allocated[index] : 0
638
+ })).sort((a, b) => b.fraction - a.fraction);
639
+ for (let index = 0; index < fractions.length && remainder > 0; index += 1, remainder -= 1) allocated[fractions[index].index] += 1;
640
+ const cells = data.flatMap((_, segmentIndex) => Array.from({ length: allocated[segmentIndex] }, () => segmentIndex));
641
+ while (cells.length < cellCount) cells.push(-1);
642
+ const direction = String(props.fillDirection ?? "left-to-right");
643
+ const points = cells.map((segmentIndex, index) => {
644
+ let x = index % columns;
645
+ let y = Math.floor(index / columns);
646
+ if (direction === "right-to-left") x = columns - 1 - x;
647
+ if (direction === "top-to-bottom" || direction === "bottom-to-top") {
648
+ x = Math.floor(index / rows);
649
+ y = index % rows;
650
+ if (direction === "bottom-to-top") y = rows - 1 - y;
651
+ }
652
+ const item = data[segmentIndex];
653
+ return {
654
+ value: [
655
+ x,
656
+ y,
657
+ segmentIndex
658
+ ],
659
+ name: item?.name,
660
+ itemStyle: { color: item ? resolveColor(item.color) : resolveColor(props.emptyColor, "#e9ecef") }
661
+ };
662
+ });
663
+ return {
664
+ grid: {
665
+ left: 0,
666
+ right: 0,
667
+ top: 0,
668
+ bottom: bool(props.withLegend, true) ? 36 : 0
669
+ },
670
+ xAxis: {
671
+ type: "value",
672
+ min: -.5,
673
+ max: columns - .5,
674
+ show: false
675
+ },
676
+ yAxis: {
677
+ type: "value",
678
+ min: -.5,
679
+ max: rows - .5,
680
+ inverse: true,
681
+ show: false
682
+ },
683
+ legend: {
684
+ show: bool(props.withLegend, true),
685
+ data: data.map((item) => item.name),
686
+ top: props.legendPosition === "top" ? 0 : void 0,
687
+ bottom: props.legendPosition === "bottom" ? 0 : void 0,
688
+ left: props.legendPosition === "left" ? 0 : void 0,
689
+ right: props.legendPosition === "right" ? 0 : void 0
690
+ },
691
+ tooltip: {
692
+ show: bool(props.withTooltip, false),
693
+ formatter: (params) => {
694
+ const item = data[params.value?.[2]];
695
+ if (!item) return "";
696
+ return typeof props.getTooltipLabel === "function" ? String(props.getTooltipLabel({
697
+ ...item,
698
+ count: allocated[params.value[2]]
699
+ })) : `${item.name}: ${item.value}`;
700
+ }
701
+ },
702
+ series: [{
703
+ type: "scatter",
704
+ symbol: "roundRect",
705
+ symbolSize: num(props.cellSize, 20),
706
+ data: points
707
+ }]
708
+ };
709
+ }
710
+ function matrixOption(props) {
711
+ const data = list(props.data);
712
+ const xLabels = list(props.xLabels).length ? list(props.xLabels) : [...new Set(data.map((cell) => cell.x))];
713
+ const yLabels = list(props.yLabels).length ? list(props.yLabels) : [...new Set(data.map((cell) => cell.y))];
714
+ const values = data.flatMap((cell) => typeof cell.value === "number" ? [cell.value] : []);
715
+ const domain = props.domain ?? [Math.min(0, ...values), Math.max(1, ...values)];
716
+ const colors = list(props.colors).length ? list(props.colors).map((color) => resolveColor(color)) : [
717
+ "#ebfbee",
718
+ "#8ce99a",
719
+ "#40c057",
720
+ "#2b8a3e"
721
+ ];
722
+ return {
723
+ grid: {
724
+ left: bool(props.withYLabels, false) ? num(props.yLabelsWidth, 60) : 0,
725
+ right: 0,
726
+ top: props.xLabelsPosition === "top" && bool(props.withXLabels, false) ? num(props.xLabelsHeight, 60) : 0,
727
+ bottom: props.xLabelsPosition !== "top" && bool(props.withXLabels, false) ? num(props.xLabelsHeight, 60) : bool(props.withLegend, false) ? 30 : 0
728
+ },
729
+ xAxis: {
730
+ type: "category",
731
+ data: xLabels,
732
+ position: props.xLabelsPosition === "top" ? "top" : "bottom",
733
+ show: bool(props.withXLabels, false),
734
+ axisLabel: {
735
+ rotate: num(props.xLabelsRotation, -90),
736
+ fontSize: num(props.fontSize, 12)
737
+ }
738
+ },
739
+ yAxis: {
740
+ type: "category",
741
+ data: yLabels,
742
+ inverse: true,
743
+ show: bool(props.withYLabels, false),
744
+ axisLabel: { fontSize: num(props.fontSize, 12) }
745
+ },
746
+ visualMap: {
747
+ show: bool(props.withLegend, false),
748
+ min: domain[0],
749
+ max: domain[1],
750
+ inRange: { color: colors },
751
+ orient: "horizontal",
752
+ left: "center",
753
+ bottom: 0,
754
+ text: props.legendLabels ?? ["More", "Less"]
755
+ },
756
+ tooltip: {
757
+ show: bool(props.withTooltip, false) && typeof props.getTooltipLabel === "function",
758
+ formatter: (params) => {
759
+ const cell = data[params.dataIndex];
760
+ return String(props.getTooltipLabel?.(cell) ?? "");
761
+ },
762
+ ...obj(props.tooltipProps)
763
+ },
764
+ series: [{
765
+ type: "heatmap",
766
+ data: data.map((cell) => {
767
+ const extra = typeof props.getCellProps === "function" ? props.getCellProps(cell) : {};
768
+ const empty = cell.value === null || !Number.isFinite(cell.value);
769
+ return {
770
+ value: [
771
+ xLabels.indexOf(cell.x),
772
+ yLabels.indexOf(cell.y),
773
+ cell.value,
774
+ cell
775
+ ],
776
+ ...extra,
777
+ itemStyle: {
778
+ ...empty && props.emptyColor ? { color: resolveColor(props.emptyColor) } : {},
779
+ ...obj(extra.itemStyle)
780
+ }
781
+ };
782
+ }),
783
+ itemStyle: {
784
+ borderWidth: num(props.gap, 1),
785
+ borderColor: "transparent",
786
+ borderRadius: num(props.cellRadius, 2)
787
+ }
788
+ }]
789
+ };
790
+ }
791
+ function candlestickOption(props) {
792
+ const data = list(props.data);
793
+ const keys = {
794
+ open: "open",
795
+ high: "high",
796
+ low: "low",
797
+ close: "close",
798
+ ...obj(props.dataKeys)
799
+ };
800
+ const dataKey = String(props.dataKey ?? "date");
801
+ return {
802
+ grid: {
803
+ left: 48,
804
+ right: 16,
805
+ top: 16,
806
+ bottom: 38,
807
+ containLabel: true,
808
+ ...obj(props.gridProps)
809
+ },
810
+ tooltip: {
811
+ trigger: "axis",
812
+ show: bool(props.withTooltip, true),
813
+ ...obj(props.tooltipProps)
814
+ },
815
+ xAxis: {
816
+ type: "category",
817
+ data: data.map((item) => String(item[dataKey] ?? "")),
818
+ show: bool(props.withXAxis, true),
819
+ name: props.xAxisLabel,
820
+ ...obj(props.xAxisProps)
821
+ },
822
+ yAxis: {
823
+ type: "value",
824
+ scale: true,
825
+ show: bool(props.withYAxis, true),
826
+ name: props.yAxisLabel,
827
+ ...obj(props.yAxisProps)
828
+ },
829
+ series: [{
830
+ type: "candlestick",
831
+ data: data.map((item) => [
832
+ item[keys.open],
833
+ item[keys.close],
834
+ item[keys.low],
835
+ item[keys.high]
836
+ ]),
837
+ barMaxWidth: props.maxCandleWidth,
838
+ itemStyle: {
839
+ color: resolveColor(props.upColor, "#12b886"),
840
+ color0: resolveColor(props.downColor, "#fa5252"),
841
+ borderColor: resolveColor(props.upColor, "#12b886"),
842
+ borderColor0: resolveColor(props.downColor, "#fa5252"),
843
+ borderWidth: num(props.candleStrokeWidth, 1)
844
+ },
845
+ markLine: markLine(props.referenceLines),
846
+ markArea: markArea(props.referenceAreas),
847
+ markPoint: markPoint(props.referenceDots)
848
+ }]
849
+ };
850
+ }
513
851
  function sparklineOption(props) {
514
852
  const data = list(props.data);
515
853
  const trend = props.trendColors;
@@ -694,6 +1032,10 @@ var BarsList = createChartComponent("BarsList", (p) => cartesianOption({
694
1032
  withTooltip: false,
695
1033
  maxBarWidth: p.barHeight
696
1034
  }, "bar"));
1035
+ var GaugeChart = createChartComponent("GaugeChart", gaugeOption);
1036
+ var WaffleChart = createChartComponent("WaffleChart", waffleOption);
1037
+ var MatrixChart = createChartComponent("MatrixChart", matrixOption);
1038
+ var CandlestickChart = createChartComponent("CandlestickChart", candlestickOption);
697
1039
  //#endregion
698
1040
  //#region src/ChartTooltip/ChartTooltip.ts
699
1041
  var ChartTooltip = defineComponent({
@@ -780,6 +1122,6 @@ function getSeriesLabels(series) {
780
1122
  return Object.fromEntries((series ?? []).map((item) => [item.name, item.label ?? item.name]));
781
1123
  }
782
1124
  //#endregion
783
- export { AreaChart, BarChart, BarsList, BubbleChart, ChartLegend, ChartTooltip, CompositeChart, DonutChart, FunnelChart, Heatmap, LineChart, PieChart, RadarChart, RadialBarChart, SankeyChart, ScatterChart, Sparkline, Treemap, getSeriesLabels };
1125
+ export { AreaChart, BarChart, BarsList, BubbleChart, CandlestickChart, ChartLegend, ChartTooltip, CompositeChart, DonutChart, FunnelChart, GaugeChart, Heatmap, LineChart, MatrixChart, PieChart, RadarChart, RadialBarChart, SankeyChart, ScatterChart, Sparkline, Treemap, WaffleChart, getSeriesLabels };
784
1126
 
785
1127
  //# sourceMappingURL=index.mjs.map