@mantine-vue/charts 3.1.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/cjs/index.cjs CHANGED
@@ -34,6 +34,7 @@ function registerECharts() {
34
34
  if (registered) return;
35
35
  (0, echarts_core.use)([
36
36
  echarts_charts.BarChart,
37
+ echarts_charts.CandlestickChart,
37
38
  echarts_charts.EffectScatterChart,
38
39
  echarts_charts.FunnelChart,
39
40
  echarts_charts.GaugeChart,
@@ -53,6 +54,8 @@ function registerECharts() {
53
54
  echarts_components.GridComponent,
54
55
  echarts_components.LegendComponent,
55
56
  echarts_components.MarkLineComponent,
57
+ echarts_components.MarkAreaComponent,
58
+ echarts_components.MarkPointComponent,
56
59
  echarts_components.PolarComponent,
57
60
  echarts_components.RadarComponent,
58
61
  echarts_components.TitleComponent,
@@ -326,6 +329,36 @@ function markLine(referenceLines) {
326
329
  }))
327
330
  };
328
331
  }
332
+ function markArea(referenceAreas) {
333
+ if (!referenceAreas?.length) return void 0;
334
+ return {
335
+ silent: true,
336
+ data: referenceAreas.map((area) => [{
337
+ xAxis: area.x1,
338
+ yAxis: area.y1,
339
+ itemStyle: {
340
+ color: resolveColor(area.color, "#868e96"),
341
+ opacity: .15
342
+ },
343
+ label: typeof area.label === "string" ? { formatter: area.label } : area.label
344
+ }, {
345
+ xAxis: area.x2,
346
+ yAxis: area.y2
347
+ }])
348
+ };
349
+ }
350
+ function markPoint(referenceDots) {
351
+ if (!referenceDots?.length) return void 0;
352
+ return {
353
+ silent: true,
354
+ data: referenceDots.map((dot) => ({
355
+ coord: [dot.x, dot.y],
356
+ symbolSize: (dot.r ?? 6) * 2,
357
+ itemStyle: { color: resolveColor(dot.color, "#868e96") },
358
+ label: typeof dot.label === "string" ? { formatter: dot.label } : dot.label
359
+ }))
360
+ };
361
+ }
329
362
  function cartesianOption(props, kind) {
330
363
  const data = list(props.data);
331
364
  const series = list(props.series);
@@ -347,13 +380,15 @@ function cartesianOption(props, kind) {
347
380
  const mapped = series.map((item, index) => {
348
381
  const itemKind = kind === "composite" ? item.type ?? "line" : kind === "area" ? "line" : kind;
349
382
  const color = resolveColor(item.color, resolveColor(`blue.${6 + index % 3}`));
350
- const stack = chartType === "stacked" || chartType === "percent" ? "stack" : item.stackId;
383
+ const stack = chartType === "stacked" || chartType === "percent" || chartType === "stream" ? "stack" : item.stackId;
351
384
  const base = {
352
385
  name: item.label ?? item.name,
353
386
  data: data.map((entry) => entry[item.name]),
354
387
  yAxisIndex: item.yAxisId ? 1 : 0,
355
388
  stack,
356
- markLine: index === 0 ? markLine(props.referenceLines) : void 0
389
+ markLine: index === 0 ? markLine(props.referenceLines) : void 0,
390
+ markArea: index === 0 ? markArea(props.referenceAreas) : void 0,
391
+ markPoint: index === 0 ? markPoint(props.referenceDots) : void 0
357
392
  };
358
393
  if (itemKind === "bar") return {
359
394
  ...base,
@@ -384,7 +419,7 @@ function cartesianOption(props, kind) {
384
419
  symbolSize: 6,
385
420
  lineStyle: {
386
421
  color,
387
- width: num(props.strokeWidth, 2),
422
+ width: chartType === "stream" ? 0 : num(props.strokeWidth, 2),
388
423
  type: item.strokeDasharray ? "dashed" : "solid"
389
424
  },
390
425
  itemStyle: {
@@ -401,6 +436,19 @@ function cartesianOption(props, kind) {
401
436
  }
402
437
  };
403
438
  });
439
+ if (kind === "area" && chartType === "stream") mapped.unshift({
440
+ type: "line",
441
+ stack: "stack",
442
+ silent: true,
443
+ symbol: "none",
444
+ data: data.map((entry) => -series.reduce((total, item) => {
445
+ const value = entry[item.name];
446
+ return total + (typeof value === "number" && Number.isFinite(value) ? value : 0);
447
+ }, 0) / 2),
448
+ lineStyle: { opacity: 0 },
449
+ areaStyle: { opacity: 0 },
450
+ tooltip: { show: false }
451
+ });
404
452
  return {
405
453
  animationDurationUpdate: num(props.tooltipAnimationDuration, 0),
406
454
  color: series.map((item) => resolveColor(item.color)),
@@ -429,7 +477,7 @@ function cartesianOption(props, kind) {
429
477
  },
430
478
  yAxis: horizontal ? [{
431
479
  ...valueAxis,
432
- show: bool(props.withYAxis, true),
480
+ show: chartType === "stream" ? false : bool(props.withYAxis, true),
433
481
  ...obj(props.yAxisProps)
434
482
  }, {
435
483
  ...valueAxis,
@@ -512,17 +560,30 @@ function scatterOption(props, bubble = false) {
512
560
  show: bool(props.withXAxis, true),
513
561
  ...obj(props.xAxisProps)
514
562
  },
515
- yAxis: {
563
+ yAxis: props.withRightYAxis ? [{
516
564
  type: "value",
517
565
  show: bool(props.withYAxis, true),
566
+ name: props.yAxisLabel,
567
+ ...obj(props.yAxisProps)
568
+ }, {
569
+ type: "value",
570
+ show: true,
571
+ position: "right",
572
+ name: props.rightYAxisLabel,
573
+ ...obj(props.rightYAxisProps)
574
+ }] : {
575
+ type: "value",
576
+ show: bool(props.withYAxis, true),
577
+ name: props.yAxisLabel,
518
578
  ...obj(props.yAxisProps)
519
579
  },
520
580
  series: (series.length ? series : [{
521
581
  name: String(props.name ?? "value"),
522
582
  color: props.color
523
- }]).map((item) => ({
583
+ }]).map((item, index) => ({
524
584
  type: "scatter",
525
585
  name: item.label ?? item.name,
586
+ yAxisIndex: item.yAxisId === "right" ? 1 : 0,
526
587
  data: data.filter((entry) => !entry.name || entry.name === item.name).map((entry) => [
527
588
  entry[xKey],
528
589
  entry[yKey],
@@ -530,10 +591,287 @@ function scatterOption(props, bubble = false) {
530
591
  entry
531
592
  ]),
532
593
  symbolSize: bubble ? (value) => Math.max(4, Math.sqrt(Number(value[2] ?? 1)) * num(props.range, 4)) : num(props.size, 10),
533
- itemStyle: { color: resolveColor(item.color) }
594
+ itemStyle: { color: resolveColor(item.color) },
595
+ markLine: index === 0 ? markLine(props.referenceLines) : void 0,
596
+ markArea: index === 0 ? markArea(props.referenceAreas) : void 0,
597
+ markPoint: index === 0 ? markPoint(props.referenceDots) : void 0
534
598
  }))
535
599
  };
536
600
  }
601
+ function gaugeOption(props) {
602
+ const min = num(props.min, 0);
603
+ const max = num(props.max, 100);
604
+ const value = num(props.value, min);
605
+ const sections = list(props.sections);
606
+ const range = max - min || 1;
607
+ 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")]];
608
+ const format = typeof props.valueFormatter === "function" ? props.valueFormatter : (input) => String(input);
609
+ return { series: [{
610
+ type: "gauge",
611
+ min,
612
+ max,
613
+ startAngle: 90 - num(props.startAngle, -120),
614
+ endAngle: 90 - num(props.endAngle, 120),
615
+ radius: "90%",
616
+ axisLine: { lineStyle: {
617
+ width: num(props.thickness, 12),
618
+ color: axisColors
619
+ } },
620
+ progress: sections.length ? { show: false } : {
621
+ show: true,
622
+ width: num(props.thickness, 12),
623
+ roundCap: bool(props.roundCaps, false),
624
+ itemStyle: { color: resolveColor(props.filledColor) }
625
+ },
626
+ pointer: typeof props.target === "number" ? {
627
+ show: true,
628
+ width: num(props.targetSize, 2),
629
+ length: "85%",
630
+ itemStyle: { color: resolveColor(props.targetColor, "#212529") }
631
+ } : { show: false },
632
+ axisTick: { show: false },
633
+ splitLine: { show: false },
634
+ axisLabel: { show: false },
635
+ anchor: { show: false },
636
+ title: { show: false },
637
+ detail: {
638
+ show: props.label !== null,
639
+ formatter: typeof props.label === "string" ? props.label : format(value),
640
+ color: "inherit"
641
+ },
642
+ data: [{ value: typeof props.target === "number" ? props.target : value }]
643
+ }] };
644
+ }
645
+ function normalizeSegmentValue(value) {
646
+ return Number.isFinite(value) ? Math.max(0, value) : 0;
647
+ }
648
+ function waffleOption(props) {
649
+ const rows = Math.max(1, num(props.rows, 10));
650
+ const columns = Math.max(1, num(props.columns, 10));
651
+ const cellCount = rows * columns;
652
+ const data = list(props.data);
653
+ const values = data.map((item) => normalizeSegmentValue(item.value));
654
+ const sum = values.reduce((total, value) => total + value, 0);
655
+ const denominator = props.total == null ? sum : Math.max(num(props.total, sum), sum);
656
+ const filledTarget = denominator ? Math.round(sum / denominator * cellCount) : 0;
657
+ const allocated = values.map((value) => sum ? Math.floor(value / sum * filledTarget) : 0);
658
+ let remainder = filledTarget - allocated.reduce((total, value) => total + value, 0);
659
+ const fractions = values.map((value, index) => ({
660
+ index,
661
+ fraction: sum ? value / sum * filledTarget - allocated[index] : 0
662
+ })).sort((a, b) => b.fraction - a.fraction);
663
+ for (let index = 0; index < fractions.length && remainder > 0; index += 1, remainder -= 1) allocated[fractions[index].index] += 1;
664
+ const cells = data.flatMap((_, segmentIndex) => Array.from({ length: allocated[segmentIndex] }, () => segmentIndex));
665
+ while (cells.length < cellCount) cells.push(-1);
666
+ const direction = String(props.fillDirection ?? "left-to-right");
667
+ const points = cells.map((segmentIndex, index) => {
668
+ let x = index % columns;
669
+ let y = Math.floor(index / columns);
670
+ if (direction === "right-to-left") x = columns - 1 - x;
671
+ if (direction === "top-to-bottom" || direction === "bottom-to-top") {
672
+ x = Math.floor(index / rows);
673
+ y = index % rows;
674
+ if (direction === "bottom-to-top") y = rows - 1 - y;
675
+ }
676
+ const item = data[segmentIndex];
677
+ return {
678
+ value: [
679
+ x,
680
+ y,
681
+ segmentIndex
682
+ ],
683
+ name: item?.name,
684
+ itemStyle: { color: item ? resolveColor(item.color) : resolveColor(props.emptyColor, "#e9ecef") }
685
+ };
686
+ });
687
+ return {
688
+ grid: {
689
+ left: 0,
690
+ right: 0,
691
+ top: 0,
692
+ bottom: bool(props.withLegend, true) ? 36 : 0
693
+ },
694
+ xAxis: {
695
+ type: "value",
696
+ min: -.5,
697
+ max: columns - .5,
698
+ show: false
699
+ },
700
+ yAxis: {
701
+ type: "value",
702
+ min: -.5,
703
+ max: rows - .5,
704
+ inverse: true,
705
+ show: false
706
+ },
707
+ legend: {
708
+ show: bool(props.withLegend, true),
709
+ data: data.map((item) => item.name),
710
+ top: props.legendPosition === "top" ? 0 : void 0,
711
+ bottom: props.legendPosition === "bottom" ? 0 : void 0,
712
+ left: props.legendPosition === "left" ? 0 : void 0,
713
+ right: props.legendPosition === "right" ? 0 : void 0
714
+ },
715
+ tooltip: {
716
+ show: bool(props.withTooltip, false),
717
+ formatter: (params) => {
718
+ const item = data[params.value?.[2]];
719
+ if (!item) return "";
720
+ return typeof props.getTooltipLabel === "function" ? String(props.getTooltipLabel({
721
+ ...item,
722
+ count: allocated[params.value[2]]
723
+ })) : `${item.name}: ${item.value}`;
724
+ }
725
+ },
726
+ series: [{
727
+ type: "scatter",
728
+ symbol: "roundRect",
729
+ symbolSize: num(props.cellSize, 20),
730
+ data: points
731
+ }]
732
+ };
733
+ }
734
+ function matrixOption(props) {
735
+ const data = list(props.data);
736
+ const xLabels = list(props.xLabels).length ? list(props.xLabels) : [...new Set(data.map((cell) => cell.x))];
737
+ const yLabels = list(props.yLabels).length ? list(props.yLabels) : [...new Set(data.map((cell) => cell.y))];
738
+ const values = data.flatMap((cell) => typeof cell.value === "number" ? [cell.value] : []);
739
+ const domain = props.domain ?? [Math.min(0, ...values), Math.max(1, ...values)];
740
+ const colors = list(props.colors).length ? list(props.colors).map((color) => resolveColor(color)) : [
741
+ "#ebfbee",
742
+ "#8ce99a",
743
+ "#40c057",
744
+ "#2b8a3e"
745
+ ];
746
+ return {
747
+ grid: {
748
+ left: bool(props.withYLabels, false) ? num(props.yLabelsWidth, 60) : 0,
749
+ right: 0,
750
+ top: props.xLabelsPosition === "top" && bool(props.withXLabels, false) ? num(props.xLabelsHeight, 60) : 0,
751
+ bottom: props.xLabelsPosition !== "top" && bool(props.withXLabels, false) ? num(props.xLabelsHeight, 60) : bool(props.withLegend, false) ? 30 : 0
752
+ },
753
+ xAxis: {
754
+ type: "category",
755
+ data: xLabels,
756
+ position: props.xLabelsPosition === "top" ? "top" : "bottom",
757
+ show: bool(props.withXLabels, false),
758
+ axisLabel: {
759
+ rotate: num(props.xLabelsRotation, -90),
760
+ fontSize: num(props.fontSize, 12)
761
+ }
762
+ },
763
+ yAxis: {
764
+ type: "category",
765
+ data: yLabels,
766
+ inverse: true,
767
+ show: bool(props.withYLabels, false),
768
+ axisLabel: { fontSize: num(props.fontSize, 12) }
769
+ },
770
+ visualMap: {
771
+ show: bool(props.withLegend, false),
772
+ min: domain[0],
773
+ max: domain[1],
774
+ inRange: { color: colors },
775
+ orient: "horizontal",
776
+ left: "center",
777
+ bottom: 0,
778
+ text: props.legendLabels ?? ["More", "Less"]
779
+ },
780
+ tooltip: {
781
+ show: bool(props.withTooltip, false) && typeof props.getTooltipLabel === "function",
782
+ formatter: (params) => {
783
+ const cell = data[params.dataIndex];
784
+ return String(props.getTooltipLabel?.(cell) ?? "");
785
+ },
786
+ ...obj(props.tooltipProps)
787
+ },
788
+ series: [{
789
+ type: "heatmap",
790
+ data: data.map((cell) => {
791
+ const extra = typeof props.getCellProps === "function" ? props.getCellProps(cell) : {};
792
+ const empty = cell.value === null || !Number.isFinite(cell.value);
793
+ return {
794
+ value: [
795
+ xLabels.indexOf(cell.x),
796
+ yLabels.indexOf(cell.y),
797
+ cell.value,
798
+ cell
799
+ ],
800
+ ...extra,
801
+ itemStyle: {
802
+ ...empty && props.emptyColor ? { color: resolveColor(props.emptyColor) } : {},
803
+ ...obj(extra.itemStyle)
804
+ }
805
+ };
806
+ }),
807
+ itemStyle: {
808
+ borderWidth: num(props.gap, 1),
809
+ borderColor: "transparent",
810
+ borderRadius: num(props.cellRadius, 2)
811
+ }
812
+ }]
813
+ };
814
+ }
815
+ function candlestickOption(props) {
816
+ const data = list(props.data);
817
+ const keys = {
818
+ open: "open",
819
+ high: "high",
820
+ low: "low",
821
+ close: "close",
822
+ ...obj(props.dataKeys)
823
+ };
824
+ const dataKey = String(props.dataKey ?? "date");
825
+ return {
826
+ grid: {
827
+ left: 48,
828
+ right: 16,
829
+ top: 16,
830
+ bottom: 38,
831
+ containLabel: true,
832
+ ...obj(props.gridProps)
833
+ },
834
+ tooltip: {
835
+ trigger: "axis",
836
+ show: bool(props.withTooltip, true),
837
+ ...obj(props.tooltipProps)
838
+ },
839
+ xAxis: {
840
+ type: "category",
841
+ data: data.map((item) => String(item[dataKey] ?? "")),
842
+ show: bool(props.withXAxis, true),
843
+ name: props.xAxisLabel,
844
+ ...obj(props.xAxisProps)
845
+ },
846
+ yAxis: {
847
+ type: "value",
848
+ scale: true,
849
+ show: bool(props.withYAxis, true),
850
+ name: props.yAxisLabel,
851
+ ...obj(props.yAxisProps)
852
+ },
853
+ series: [{
854
+ type: "candlestick",
855
+ data: data.map((item) => [
856
+ item[keys.open],
857
+ item[keys.close],
858
+ item[keys.low],
859
+ item[keys.high]
860
+ ]),
861
+ barMaxWidth: props.maxCandleWidth,
862
+ itemStyle: {
863
+ color: resolveColor(props.upColor, "#12b886"),
864
+ color0: resolveColor(props.downColor, "#fa5252"),
865
+ borderColor: resolveColor(props.upColor, "#12b886"),
866
+ borderColor0: resolveColor(props.downColor, "#fa5252"),
867
+ borderWidth: num(props.candleStrokeWidth, 1)
868
+ },
869
+ markLine: markLine(props.referenceLines),
870
+ markArea: markArea(props.referenceAreas),
871
+ markPoint: markPoint(props.referenceDots)
872
+ }]
873
+ };
874
+ }
537
875
  function sparklineOption(props) {
538
876
  const data = list(props.data);
539
877
  const trend = props.trendColors;
@@ -718,6 +1056,10 @@ var BarsList = createChartComponent("BarsList", (p) => cartesianOption({
718
1056
  withTooltip: false,
719
1057
  maxBarWidth: p.barHeight
720
1058
  }, "bar"));
1059
+ var GaugeChart = createChartComponent("GaugeChart", gaugeOption);
1060
+ var WaffleChart = createChartComponent("WaffleChart", waffleOption);
1061
+ var MatrixChart = createChartComponent("MatrixChart", matrixOption);
1062
+ var CandlestickChart = createChartComponent("CandlestickChart", candlestickOption);
721
1063
  //#endregion
722
1064
  //#region src/ChartTooltip/ChartTooltip.ts
723
1065
  var ChartTooltip = (0, vue.defineComponent)({
@@ -808,13 +1150,16 @@ exports.AreaChart = AreaChart;
808
1150
  exports.BarChart = BarChart;
809
1151
  exports.BarsList = BarsList;
810
1152
  exports.BubbleChart = BubbleChart;
1153
+ exports.CandlestickChart = CandlestickChart;
811
1154
  exports.ChartLegend = ChartLegend;
812
1155
  exports.ChartTooltip = ChartTooltip;
813
1156
  exports.CompositeChart = CompositeChart;
814
1157
  exports.DonutChart = DonutChart;
815
1158
  exports.FunnelChart = FunnelChart;
1159
+ exports.GaugeChart = GaugeChart;
816
1160
  exports.Heatmap = Heatmap;
817
1161
  exports.LineChart = LineChart;
1162
+ exports.MatrixChart = MatrixChart;
818
1163
  exports.PieChart = PieChart;
819
1164
  exports.RadarChart = RadarChart;
820
1165
  exports.RadialBarChart = RadialBarChart;
@@ -822,6 +1167,7 @@ exports.SankeyChart = SankeyChart;
822
1167
  exports.ScatterChart = ScatterChart;
823
1168
  exports.Sparkline = Sparkline;
824
1169
  exports.Treemap = Treemap;
1170
+ exports.WaffleChart = WaffleChart;
825
1171
  exports.getSeriesLabels = getSeriesLabels;
826
1172
 
827
1173
  //# sourceMappingURL=index.cjs.map