cats-charts 0.1.1 → 0.1.2
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/fesm2022/cats-charts.mjs +753 -1
- package/fesm2022/cats-charts.mjs.map +1 -1
- package/index.d.ts +138 -4
- package/package.json +1 -1
package/fesm2022/cats-charts.mjs
CHANGED
|
@@ -475,6 +475,7 @@ class Charts {
|
|
|
475
475
|
legendSelected = {};
|
|
476
476
|
defaultColors = ['#22c55e', '#3b82f6', '#ef4444', '#6b7280'];
|
|
477
477
|
defaultLegendColors = ['#3b82f6', '#FFC107', '#22c55e', '#ef4444'];
|
|
478
|
+
heatmapPivotColors = ['#dbeafe', '#93c5fd', '#3b82f6', '#1d4ed8', '#1e3a8a'];
|
|
478
479
|
// buildGraphicLegend(total: number | null, config: any, chartInstance: any, chartType?: string) {
|
|
479
480
|
// const pillHeight = 28;
|
|
480
481
|
// const spacing = 14;
|
|
@@ -1236,6 +1237,44 @@ class Charts {
|
|
|
1236
1237
|
return date.toLocaleDateString('en-US', { day: '2-digit', month: 'short' });
|
|
1237
1238
|
}
|
|
1238
1239
|
}
|
|
1240
|
+
formatHeatmapPivotDate(value, aggregation = 'day') {
|
|
1241
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
1242
|
+
if (Number.isNaN(date.getTime()))
|
|
1243
|
+
return String(value);
|
|
1244
|
+
switch (aggregation) {
|
|
1245
|
+
case 'year':
|
|
1246
|
+
return String(date.getFullYear());
|
|
1247
|
+
case 'quarter':
|
|
1248
|
+
return `Q${Math.floor(date.getMonth() / 3) + 1} ${date.getFullYear()}`;
|
|
1249
|
+
case 'month':
|
|
1250
|
+
return date.toLocaleDateString('en-US', { month: 'short', year: 'numeric' });
|
|
1251
|
+
case 'week': {
|
|
1252
|
+
const utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
|
|
1253
|
+
const dayOfWeek = utcDate.getUTCDay() || 7;
|
|
1254
|
+
utcDate.setUTCDate(utcDate.getUTCDate() + 4 - dayOfWeek);
|
|
1255
|
+
const year = utcDate.getUTCFullYear();
|
|
1256
|
+
const yearStart = new Date(Date.UTC(year, 0, 1));
|
|
1257
|
+
const week = Math.ceil(((utcDate.getTime() - yearStart.getTime()) / 86_400_000 + 1) / 7);
|
|
1258
|
+
return `W${week} ${year}`;
|
|
1259
|
+
}
|
|
1260
|
+
case 'hour':
|
|
1261
|
+
return date.toLocaleDateString('en-US', {
|
|
1262
|
+
day: '2-digit',
|
|
1263
|
+
month: 'short',
|
|
1264
|
+
hour: '2-digit',
|
|
1265
|
+
hour12: false,
|
|
1266
|
+
});
|
|
1267
|
+
case 'minute':
|
|
1268
|
+
return date.toLocaleTimeString('en-US', {
|
|
1269
|
+
hour: '2-digit',
|
|
1270
|
+
minute: '2-digit',
|
|
1271
|
+
hour12: false,
|
|
1272
|
+
});
|
|
1273
|
+
case 'day':
|
|
1274
|
+
default:
|
|
1275
|
+
return date.toLocaleDateString('en-US', { day: '2-digit', month: 'short' });
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1239
1278
|
getIsoWeek(date) {
|
|
1240
1279
|
const utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
|
|
1241
1280
|
const dayOfWeek = utcDate.getUTCDay() || 7;
|
|
@@ -4937,6 +4976,719 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
4937
4976
|
type: Output
|
|
4938
4977
|
}] } });
|
|
4939
4978
|
|
|
4979
|
+
echarts.use([
|
|
4980
|
+
HeatmapChart,
|
|
4981
|
+
GridComponent,
|
|
4982
|
+
LegendComponent,
|
|
4983
|
+
TitleComponent,
|
|
4984
|
+
TooltipComponent,
|
|
4985
|
+
VisualMapComponent,
|
|
4986
|
+
CanvasRenderer,
|
|
4987
|
+
]);
|
|
4988
|
+
class HeatmapPivot {
|
|
4989
|
+
chartService;
|
|
4990
|
+
cdr;
|
|
4991
|
+
chartContainer;
|
|
4992
|
+
config = { xAxisData: [], yAxisData: [], series: [] };
|
|
4993
|
+
theme;
|
|
4994
|
+
events = [];
|
|
4995
|
+
contextMenuOptions = [];
|
|
4996
|
+
showContextMenu = false;
|
|
4997
|
+
contextMenuClick = new EventEmitter();
|
|
4998
|
+
chartEvent = new EventEmitter();
|
|
4999
|
+
legendEvent = new EventEmitter();
|
|
5000
|
+
chartOption = {};
|
|
5001
|
+
chartInstance;
|
|
5002
|
+
cardPosition = { x: 0, y: 0 };
|
|
5003
|
+
openCard = false;
|
|
5004
|
+
columnTotals = [];
|
|
5005
|
+
xAxisState;
|
|
5006
|
+
yAxisState;
|
|
5007
|
+
yAxisLabelWidth;
|
|
5008
|
+
totalLabelWidth;
|
|
5009
|
+
normalizedSeriesData = [];
|
|
5010
|
+
eventCleanup = [];
|
|
5011
|
+
constructor(chartService, cdr) {
|
|
5012
|
+
this.chartService = chartService;
|
|
5013
|
+
this.cdr = cdr;
|
|
5014
|
+
}
|
|
5015
|
+
get deafultColors() {
|
|
5016
|
+
return this.chartService.heatmapPivotColors;
|
|
5017
|
+
}
|
|
5018
|
+
get hasSideLegendWidth() {
|
|
5019
|
+
return this.isSideLegend && !!this.config.customLegend?.maxWidth;
|
|
5020
|
+
}
|
|
5021
|
+
get legendShellMaxWidth() {
|
|
5022
|
+
return this.isSideLegend ? (this.config.customLegend?.maxWidth ?? null) : null;
|
|
5023
|
+
}
|
|
5024
|
+
get isSideLegend() {
|
|
5025
|
+
return (this.config.customLegend?.position === 'left' ||
|
|
5026
|
+
this.config.customLegend?.position === 'right');
|
|
5027
|
+
}
|
|
5028
|
+
ngOnInit() {
|
|
5029
|
+
this.buildOption();
|
|
5030
|
+
}
|
|
5031
|
+
ngOnChanges(changes) {
|
|
5032
|
+
if (!this.config)
|
|
5033
|
+
return;
|
|
5034
|
+
this.buildOption();
|
|
5035
|
+
if (changes['events'] || changes['showContextMenu']) {
|
|
5036
|
+
this.bindEvents();
|
|
5037
|
+
}
|
|
5038
|
+
// NgxEchartsDirective recreates the chart when its theme input changes.
|
|
5039
|
+
}
|
|
5040
|
+
buildOption() {
|
|
5041
|
+
const config = this.config;
|
|
5042
|
+
this.xAxisState = this.buildAxisState('x');
|
|
5043
|
+
this.yAxisState = this.buildAxisState('y');
|
|
5044
|
+
const yAxisLabelWidth = this.resolveYAxisLabelWidth();
|
|
5045
|
+
this.yAxisLabelWidth = yAxisLabelWidth;
|
|
5046
|
+
this.totalLabelWidth = this.resolveTotalLabelWidth(yAxisLabelWidth);
|
|
5047
|
+
this.columnTotals = this.xAxisState.values.map(() => 0);
|
|
5048
|
+
const series = (config.series ?? []).map((item) => ({
|
|
5049
|
+
...item,
|
|
5050
|
+
type: 'heatmap',
|
|
5051
|
+
coordinateSystem: 'cartesian2d',
|
|
5052
|
+
encode: { x: 0, y: 1, tooltip: [2] },
|
|
5053
|
+
data: this.normalizeData(item.data ?? []),
|
|
5054
|
+
itemStyle: {
|
|
5055
|
+
borderColor: '#ffffff',
|
|
5056
|
+
borderWidth: Math.max(config.cellGap ?? 6, 0),
|
|
5057
|
+
borderRadius: Math.max(config.cellBorderRadius ?? 3, 0),
|
|
5058
|
+
...item['itemStyle'],
|
|
5059
|
+
},
|
|
5060
|
+
label: {
|
|
5061
|
+
show: config.showLabel ?? true,
|
|
5062
|
+
position: 'inside',
|
|
5063
|
+
color: config.labelColor ?? '#252a31',
|
|
5064
|
+
fontSize: 14,
|
|
5065
|
+
formatter: config.labelFormatter ??
|
|
5066
|
+
((params) => {
|
|
5067
|
+
const value = params.value?.[2];
|
|
5068
|
+
return typeof value === 'number' ? this.chartService.compactValueFormat(value) : '-';
|
|
5069
|
+
}),
|
|
5070
|
+
...item['label'],
|
|
5071
|
+
},
|
|
5072
|
+
emphasis: { disabled: true, ...item['emphasis'] },
|
|
5073
|
+
}));
|
|
5074
|
+
this.normalizedSeriesData = series.map((item) => item.data);
|
|
5075
|
+
let min = Infinity;
|
|
5076
|
+
let max = -Infinity;
|
|
5077
|
+
for (const item of series) {
|
|
5078
|
+
for (const dataItem of item.data) {
|
|
5079
|
+
const point = this.pointValue(dataItem);
|
|
5080
|
+
const value = point[2];
|
|
5081
|
+
if (!Number.isFinite(value))
|
|
5082
|
+
continue;
|
|
5083
|
+
min = Math.min(min, value);
|
|
5084
|
+
max = Math.max(max, value);
|
|
5085
|
+
const column = Number(point[0]);
|
|
5086
|
+
if (this.columnTotals[column] !== undefined)
|
|
5087
|
+
this.columnTotals[column] += value;
|
|
5088
|
+
}
|
|
5089
|
+
}
|
|
5090
|
+
this.chartOption = {
|
|
5091
|
+
backgroundColor: config.backgroundColor ?? 'transparent',
|
|
5092
|
+
color: config.colors ?? this.deafultColors,
|
|
5093
|
+
title: [
|
|
5094
|
+
{
|
|
5095
|
+
show: config.showTitle ?? !!config.title,
|
|
5096
|
+
text: config.title,
|
|
5097
|
+
left: config.titlePosition ?? 'center',
|
|
5098
|
+
},
|
|
5099
|
+
...(config.showTotals !== false
|
|
5100
|
+
? [
|
|
5101
|
+
{
|
|
5102
|
+
id: 'heatmap-pivot-total-label',
|
|
5103
|
+
text: config.totalLabel ?? 'Total',
|
|
5104
|
+
left: 8,
|
|
5105
|
+
bottom: 12,
|
|
5106
|
+
padding: 0,
|
|
5107
|
+
textStyle: {
|
|
5108
|
+
color: '#182230',
|
|
5109
|
+
fontFamily: 'Arial, sans-serif',
|
|
5110
|
+
fontSize: 14,
|
|
5111
|
+
fontWeight: 600,
|
|
5112
|
+
width: this.totalLabelWidth,
|
|
5113
|
+
overflow: 'truncate',
|
|
5114
|
+
ellipsis: '...',
|
|
5115
|
+
},
|
|
5116
|
+
},
|
|
5117
|
+
]
|
|
5118
|
+
: []),
|
|
5119
|
+
],
|
|
5120
|
+
tooltip: {
|
|
5121
|
+
show: config.showTooltip ?? true,
|
|
5122
|
+
trigger: 'item',
|
|
5123
|
+
backgroundColor: '#ffffff',
|
|
5124
|
+
borderWidth: 0,
|
|
5125
|
+
padding: [10, 12],
|
|
5126
|
+
confine: true,
|
|
5127
|
+
textStyle: { color: '#434a51', fontFamily: 'Arial, sans-serif', fontSize: 12 },
|
|
5128
|
+
borderRadius: 6,
|
|
5129
|
+
shadowBlur: 16,
|
|
5130
|
+
shadowColor: 'rgba(16,24,40,0.12)',
|
|
5131
|
+
shadowOffsetY: 5,
|
|
5132
|
+
formatter: (params) => config.tooltipFormatter
|
|
5133
|
+
? config.tooltipFormatter(params, config)
|
|
5134
|
+
: this.formatTooltip(params),
|
|
5135
|
+
...config.tooltip,
|
|
5136
|
+
},
|
|
5137
|
+
legend: {
|
|
5138
|
+
show: !config.hideLegend && !config.customLegend,
|
|
5139
|
+
type: 'scroll',
|
|
5140
|
+
top: (config.showTitle ?? !!config.title) ? 30 : 0,
|
|
5141
|
+
icon: 'roundRect',
|
|
5142
|
+
textStyle: { color: '#434a51', fontSize: 14 },
|
|
5143
|
+
...config.legend,
|
|
5144
|
+
data: config.legend?.data ?? series.map((item) => item.name),
|
|
5145
|
+
selected: { ...this.readLegendSelected(), ...config.legend?.selected },
|
|
5146
|
+
selectedMode: config.legend?.selectedMode ??
|
|
5147
|
+
(config.customLegend?.selectionMode === 'exclusive' ? 'single' : true),
|
|
5148
|
+
},
|
|
5149
|
+
grid: [
|
|
5150
|
+
{
|
|
5151
|
+
left: this.labelGridLeft(yAxisLabelWidth),
|
|
5152
|
+
right: 0,
|
|
5153
|
+
top: 0,
|
|
5154
|
+
bottom: config.showTotals !== false ? 41 : 0,
|
|
5155
|
+
...config.grid,
|
|
5156
|
+
},
|
|
5157
|
+
...(config.showTotals !== false
|
|
5158
|
+
? [
|
|
5159
|
+
{
|
|
5160
|
+
left: 0,
|
|
5161
|
+
right: 0,
|
|
5162
|
+
bottom: 1,
|
|
5163
|
+
height: 40,
|
|
5164
|
+
containLabel: false,
|
|
5165
|
+
},
|
|
5166
|
+
]
|
|
5167
|
+
: []),
|
|
5168
|
+
],
|
|
5169
|
+
xAxis: [
|
|
5170
|
+
{
|
|
5171
|
+
position: 'top',
|
|
5172
|
+
axisLine: { show: false },
|
|
5173
|
+
axisTick: { show: false },
|
|
5174
|
+
splitLine: { show: false },
|
|
5175
|
+
...this.axisOptions('x'),
|
|
5176
|
+
axisLabel: {
|
|
5177
|
+
interval: 'auto',
|
|
5178
|
+
hideOverlap: true,
|
|
5179
|
+
margin: 14,
|
|
5180
|
+
color: '#434a51',
|
|
5181
|
+
fontFamily: 'Arial, sans-serif',
|
|
5182
|
+
fontSize: 14,
|
|
5183
|
+
formatter: this.xAxisState.type === 'time'
|
|
5184
|
+
? (value) => this.formatAxisValue('x', value)
|
|
5185
|
+
: undefined,
|
|
5186
|
+
...config.xAxis?.axisLabel,
|
|
5187
|
+
},
|
|
5188
|
+
},
|
|
5189
|
+
...this.totalsAxisOptions(),
|
|
5190
|
+
],
|
|
5191
|
+
yAxis: [
|
|
5192
|
+
{
|
|
5193
|
+
inverse: true,
|
|
5194
|
+
axisLine: { show: false },
|
|
5195
|
+
axisTick: { show: false },
|
|
5196
|
+
splitLine: { show: false },
|
|
5197
|
+
...this.axisOptions('y'),
|
|
5198
|
+
axisLabel: {
|
|
5199
|
+
interval: 0,
|
|
5200
|
+
margin: yAxisLabelWidth + 16,
|
|
5201
|
+
align: 'left',
|
|
5202
|
+
color: '#434a51',
|
|
5203
|
+
fontFamily: 'Arial, sans-serif',
|
|
5204
|
+
fontSize: 14,
|
|
5205
|
+
formatter: this.yAxisState.type === 'time'
|
|
5206
|
+
? (value) => this.formatAxisValue('y', value)
|
|
5207
|
+
: undefined,
|
|
5208
|
+
...config.yAxis?.axisLabel,
|
|
5209
|
+
width: yAxisLabelWidth,
|
|
5210
|
+
overflow: config.yAxis?.axisLabel?.overflow ?? 'truncate',
|
|
5211
|
+
ellipsis: config.yAxis?.axisLabel?.ellipsis ?? '...',
|
|
5212
|
+
},
|
|
5213
|
+
},
|
|
5214
|
+
...(config.showTotals !== false
|
|
5215
|
+
? [
|
|
5216
|
+
{
|
|
5217
|
+
gridIndex: 1,
|
|
5218
|
+
type: 'value',
|
|
5219
|
+
min: 0,
|
|
5220
|
+
max: 1,
|
|
5221
|
+
show: false,
|
|
5222
|
+
},
|
|
5223
|
+
]
|
|
5224
|
+
: []),
|
|
5225
|
+
],
|
|
5226
|
+
visualMap: this.buildVisualMaps(min, max),
|
|
5227
|
+
series,
|
|
5228
|
+
};
|
|
5229
|
+
}
|
|
5230
|
+
resolveYAxisLabelWidth() {
|
|
5231
|
+
const style = this.config.yAxis?.axisLabel;
|
|
5232
|
+
const chartWidth = this.chartContainer?.nativeElement.getBoundingClientRect().width
|
|
5233
|
+
|| (this.chartInstance && !this.chartInstance.isDisposed() ? this.chartInstance.getWidth() : 0)
|
|
5234
|
+
|| 360;
|
|
5235
|
+
const defaultMaxWidth = Math.max(100, Math.min(240, Math.round(chartWidth * 0.22)));
|
|
5236
|
+
const minWidth = Math.max(0, this.config.yAxisLabelMinWidth
|
|
5237
|
+
?? Math.min(50, this.config.yAxisLabelMaxWidth ?? defaultMaxWidth));
|
|
5238
|
+
const maxWidth = Math.max(minWidth, this.config.yAxisLabelMaxWidth ?? defaultMaxWidth);
|
|
5239
|
+
if (typeof style?.width === 'number' && Number.isFinite(style.width)) {
|
|
5240
|
+
return Math.min(maxWidth, Math.max(minWidth, style.width));
|
|
5241
|
+
}
|
|
5242
|
+
const font = `${style?.fontWeight ?? 400} ${style?.fontSize ?? 14}px ${style?.fontFamily ?? 'Arial, sans-serif'}`;
|
|
5243
|
+
let width = minWidth;
|
|
5244
|
+
this.yAxisState.values.forEach((_value, index) => {
|
|
5245
|
+
width = Math.max(width, echarts.format.getTextRect(this.formatAxisValue('y', index), font).width);
|
|
5246
|
+
});
|
|
5247
|
+
if (this.config.showTotals !== false) {
|
|
5248
|
+
width = Math.max(width, echarts.format.getTextRect(this.config.totalLabel ?? 'Total', '600 14px Arial, sans-serif').width);
|
|
5249
|
+
}
|
|
5250
|
+
return Math.min(maxWidth, width);
|
|
5251
|
+
}
|
|
5252
|
+
labelGridLeft(width) {
|
|
5253
|
+
const yAxisHidden = this.config.yAxis?.['show'] === false || this.config.yAxis?.axisLabel?.show === false;
|
|
5254
|
+
return yAxisHidden && this.config.showTotals === false ? 0 : width + 16;
|
|
5255
|
+
}
|
|
5256
|
+
resolveTotalLabelWidth(labelWidth) {
|
|
5257
|
+
const configuredLeft = this.config.grid?.left;
|
|
5258
|
+
const chartWidth = this.chartContainer?.nativeElement.getBoundingClientRect().width
|
|
5259
|
+
|| (this.chartInstance && !this.chartInstance.isDisposed() ? this.chartInstance.getWidth() : 0)
|
|
5260
|
+
|| 360;
|
|
5261
|
+
const defaultLeft = this.labelGridLeft(labelWidth);
|
|
5262
|
+
const left = configuredLeft === undefined ? defaultLeft
|
|
5263
|
+
: typeof configuredLeft === 'number' ? configuredLeft
|
|
5264
|
+
: configuredLeft.endsWith('%') ? parseFloat(configuredLeft) / 100 * chartWidth
|
|
5265
|
+
: parseFloat(configuredLeft);
|
|
5266
|
+
// Reserve eight pixels on each side of the heading before the total values.
|
|
5267
|
+
return Math.max(0, Math.min(labelWidth, (Number.isFinite(left) ? left : defaultLeft) - 16));
|
|
5268
|
+
}
|
|
5269
|
+
buildVisualMaps(min, max) {
|
|
5270
|
+
const config = this.config;
|
|
5271
|
+
const base = {
|
|
5272
|
+
show: false,
|
|
5273
|
+
min: config.min ?? (Number.isFinite(min) ? min : 0),
|
|
5274
|
+
max: config.max ?? (Number.isFinite(max) ? max : 100),
|
|
5275
|
+
dimension: 2,
|
|
5276
|
+
calculable: true,
|
|
5277
|
+
orient: 'horizontal',
|
|
5278
|
+
left: 'center',
|
|
5279
|
+
bottom: 0,
|
|
5280
|
+
inRange: { color: config.colors ?? this.deafultColors },
|
|
5281
|
+
};
|
|
5282
|
+
const rules = this.visualMapOptions();
|
|
5283
|
+
if (rules['type'] !== 'piecewise' && !rules['pieces'] && !rules['categories']) {
|
|
5284
|
+
return { ...base, ...rules };
|
|
5285
|
+
}
|
|
5286
|
+
return [
|
|
5287
|
+
{ ...base, type: 'continuous', show: false },
|
|
5288
|
+
{
|
|
5289
|
+
...base,
|
|
5290
|
+
...rules,
|
|
5291
|
+
type: 'piecewise',
|
|
5292
|
+
inRange: {
|
|
5293
|
+
colorAlpha: 1,
|
|
5294
|
+
...base.inRange,
|
|
5295
|
+
...(rules['inRange'] && typeof rules['inRange'] === 'object' ? rules['inRange'] : {}),
|
|
5296
|
+
},
|
|
5297
|
+
// An empty mapping preserves the color assigned by the continuous map.
|
|
5298
|
+
outOfRange: rules['outOfRange'] ?? {},
|
|
5299
|
+
},
|
|
5300
|
+
];
|
|
5301
|
+
}
|
|
5302
|
+
visualMapOptions() {
|
|
5303
|
+
const config = this.config.visualMap;
|
|
5304
|
+
if (!config?.pieces)
|
|
5305
|
+
return config ?? {};
|
|
5306
|
+
return {
|
|
5307
|
+
...config,
|
|
5308
|
+
type: config.type ?? 'piecewise',
|
|
5309
|
+
pieces: config.pieces.flatMap((piece) => {
|
|
5310
|
+
const { eq, neq, ne, opacity, ...options } = piece;
|
|
5311
|
+
const native = {
|
|
5312
|
+
...options,
|
|
5313
|
+
...(opacity !== undefined ? {
|
|
5314
|
+
colorAlpha: Math.min(100, Math.max(0, Number.isFinite(opacity) ? opacity : 100)) / 100,
|
|
5315
|
+
} : {}),
|
|
5316
|
+
};
|
|
5317
|
+
if (eq !== undefined)
|
|
5318
|
+
return [{ ...native, value: eq }];
|
|
5319
|
+
const excluded = neq ?? ne;
|
|
5320
|
+
if (excluded === undefined)
|
|
5321
|
+
return [native];
|
|
5322
|
+
if (native.value !== undefined)
|
|
5323
|
+
return native.value === excluded ? [] : [native];
|
|
5324
|
+
const { gt, gte, min, lt, lte, max, ...style } = native;
|
|
5325
|
+
const lower = Math.max(gt ?? -Infinity, gte ?? -Infinity, min ?? -Infinity);
|
|
5326
|
+
const upper = Math.min(lt ?? Infinity, lte ?? Infinity, max ?? Infinity);
|
|
5327
|
+
const lowerOpen = gt === lower;
|
|
5328
|
+
const upperOpen = lt === upper;
|
|
5329
|
+
const range = (start, end, startOpen, endOpen) => {
|
|
5330
|
+
if (start > end || (start === end && (startOpen || endOpen)))
|
|
5331
|
+
return [];
|
|
5332
|
+
return [
|
|
5333
|
+
{
|
|
5334
|
+
...style,
|
|
5335
|
+
...(Number.isFinite(start)
|
|
5336
|
+
? startOpen && start === excluded
|
|
5337
|
+
? // ECharts joins touching pieces; use the next representable number
|
|
5338
|
+
// so the excluded value cannot be reintroduced at their boundary.
|
|
5339
|
+
{ gte: this.nextNumericValue(start) }
|
|
5340
|
+
: { [startOpen ? 'gt' : 'gte']: start }
|
|
5341
|
+
: {}),
|
|
5342
|
+
...(Number.isFinite(end) ? { [endOpen ? 'lt' : 'lte']: end } : {}),
|
|
5343
|
+
},
|
|
5344
|
+
];
|
|
5345
|
+
};
|
|
5346
|
+
return [
|
|
5347
|
+
...range(lower, Math.min(upper, excluded), lowerOpen, excluded <= upper || upperOpen),
|
|
5348
|
+
...range(Math.max(lower, excluded), upper, excluded >= lower || lowerOpen, upperOpen),
|
|
5349
|
+
];
|
|
5350
|
+
}),
|
|
5351
|
+
};
|
|
5352
|
+
}
|
|
5353
|
+
nextNumericValue(value) {
|
|
5354
|
+
if (value === 0)
|
|
5355
|
+
return Number.MIN_VALUE;
|
|
5356
|
+
const buffer = new DataView(new ArrayBuffer(8));
|
|
5357
|
+
buffer.setFloat64(0, value);
|
|
5358
|
+
buffer.setBigUint64(0, buffer.getBigUint64(0) + (value > 0 ? 1n : -1n));
|
|
5359
|
+
return buffer.getFloat64(0);
|
|
5360
|
+
}
|
|
5361
|
+
totalsAxisOptions() {
|
|
5362
|
+
if (this.config.showTotals === false)
|
|
5363
|
+
return [];
|
|
5364
|
+
const options = this.axisOptions('x');
|
|
5365
|
+
const axisLine = { show: true, onZero: false, lineStyle: { color: '#e4e7ec', width: 1 } };
|
|
5366
|
+
const borderAxis = {
|
|
5367
|
+
gridIndex: 1,
|
|
5368
|
+
z: 10,
|
|
5369
|
+
type: 'category',
|
|
5370
|
+
data: [''],
|
|
5371
|
+
boundaryGap: true,
|
|
5372
|
+
axisLine,
|
|
5373
|
+
axisLabel: { show: false },
|
|
5374
|
+
axisTick: { show: false },
|
|
5375
|
+
splitLine: { show: false },
|
|
5376
|
+
axisPointer: { show: false },
|
|
5377
|
+
};
|
|
5378
|
+
const base = {
|
|
5379
|
+
...options,
|
|
5380
|
+
show: true,
|
|
5381
|
+
position: 'bottom',
|
|
5382
|
+
axisLine: { show: false },
|
|
5383
|
+
axisTick: { show: false },
|
|
5384
|
+
splitLine: { show: false },
|
|
5385
|
+
axisPointer: { show: false },
|
|
5386
|
+
};
|
|
5387
|
+
return [
|
|
5388
|
+
{
|
|
5389
|
+
...base,
|
|
5390
|
+
axisLabel: {
|
|
5391
|
+
show: true,
|
|
5392
|
+
interval: 0,
|
|
5393
|
+
margin: 13,
|
|
5394
|
+
color: '#182230',
|
|
5395
|
+
fontFamily: 'Arial, sans-serif',
|
|
5396
|
+
fontSize: 14,
|
|
5397
|
+
fontWeight: 600,
|
|
5398
|
+
formatter: (value) => {
|
|
5399
|
+
const index = this.xAxisState.values.findIndex((bucket) => String(bucket) === value);
|
|
5400
|
+
const total = this.columnTotals[index] ?? 0;
|
|
5401
|
+
return this.config.totalFormatter ? this.config.totalFormatter(total) : String(total);
|
|
5402
|
+
},
|
|
5403
|
+
},
|
|
5404
|
+
},
|
|
5405
|
+
{ ...borderAxis, position: 'top' },
|
|
5406
|
+
{ ...borderAxis, position: 'bottom' },
|
|
5407
|
+
];
|
|
5408
|
+
}
|
|
5409
|
+
pointValue(point) {
|
|
5410
|
+
return Array.isArray(point) ? point : point.value;
|
|
5411
|
+
}
|
|
5412
|
+
normalizeData(data) {
|
|
5413
|
+
return data.flatMap((point) => {
|
|
5414
|
+
const [x, y, value] = this.pointValue(point);
|
|
5415
|
+
const normalized = [
|
|
5416
|
+
this.normalizeCoordinate('x', x),
|
|
5417
|
+
this.normalizeCoordinate('y', y),
|
|
5418
|
+
value,
|
|
5419
|
+
];
|
|
5420
|
+
if (!normalized.every(Number.isFinite) || normalized[0] < 0 || normalized[1] < 0)
|
|
5421
|
+
return [];
|
|
5422
|
+
return [Array.isArray(point) ? normalized : { ...point, value: normalized }];
|
|
5423
|
+
});
|
|
5424
|
+
}
|
|
5425
|
+
buildAxisState(axis) {
|
|
5426
|
+
const options = axis === 'x' ? this.config.xAxis : this.config.yAxis;
|
|
5427
|
+
const axisData = axis === 'x' ? this.config.xAxisData : this.config.yAxisData;
|
|
5428
|
+
const type = options?.type ?? 'category';
|
|
5429
|
+
const coordinates = (this.config.series ?? []).flatMap((series) => (series.data ?? []).map((point) => this.pointValue(point)[axis === 'x' ? 0 : 1]));
|
|
5430
|
+
const resolvedCoordinates = coordinates.map((value) => typeof value === 'number' &&
|
|
5431
|
+
Number.isInteger(value) &&
|
|
5432
|
+
value >= 0 &&
|
|
5433
|
+
value < (axisData?.length ?? 0)
|
|
5434
|
+
? axisData[value]
|
|
5435
|
+
: value);
|
|
5436
|
+
const axisValues = type === 'time'
|
|
5437
|
+
? [...(axisData ?? []), ...resolvedCoordinates]
|
|
5438
|
+
: axisData?.length
|
|
5439
|
+
? axisData
|
|
5440
|
+
: coordinates;
|
|
5441
|
+
const values = [
|
|
5442
|
+
...new Set(axisValues.map((value) => (type === 'time' ? this.timestamp(value) : String(value)))),
|
|
5443
|
+
].filter((value) => type !== 'time' || Number.isFinite(value));
|
|
5444
|
+
if (type === 'time')
|
|
5445
|
+
values.sort((a, b) => a - b);
|
|
5446
|
+
return { type, values };
|
|
5447
|
+
}
|
|
5448
|
+
timestamp(value) {
|
|
5449
|
+
return value instanceof Date ? value.getTime() : new Date(value).getTime();
|
|
5450
|
+
}
|
|
5451
|
+
normalizeCoordinate(axis, value) {
|
|
5452
|
+
const state = axis === 'x' ? this.xAxisState : this.yAxisState;
|
|
5453
|
+
const axisData = axis === 'x' ? this.config.xAxisData : this.config.yAxisData;
|
|
5454
|
+
const indexed = typeof value === 'number' &&
|
|
5455
|
+
Number.isInteger(value) &&
|
|
5456
|
+
value >= 0 &&
|
|
5457
|
+
value < (axisData?.length ?? 0);
|
|
5458
|
+
const resolved = indexed ? axisData[value] : value;
|
|
5459
|
+
return state.values.indexOf(state.type === 'time' ? this.timestamp(resolved) : String(resolved));
|
|
5460
|
+
}
|
|
5461
|
+
axisOptions(axis) {
|
|
5462
|
+
const state = axis === 'x' ? this.xAxisState : this.yAxisState;
|
|
5463
|
+
const options = (axis === 'x' ? this.config.xAxis : this.config.yAxis) ?? {};
|
|
5464
|
+
const { type, minInterval, min, max, ...styles } = options;
|
|
5465
|
+
let bucketMin = min;
|
|
5466
|
+
let bucketMax = max;
|
|
5467
|
+
if (state.type === 'time') {
|
|
5468
|
+
if (min !== undefined) {
|
|
5469
|
+
const timestamp = this.timestamp(min);
|
|
5470
|
+
bucketMin =
|
|
5471
|
+
min === 'dataMin' ? 0 : state.values.findIndex((value) => Number(value) >= timestamp);
|
|
5472
|
+
if (bucketMin === -1)
|
|
5473
|
+
bucketMin = state.values.length;
|
|
5474
|
+
}
|
|
5475
|
+
if (max !== undefined) {
|
|
5476
|
+
const timestamp = this.timestamp(max);
|
|
5477
|
+
bucketMax =
|
|
5478
|
+
max === 'dataMax'
|
|
5479
|
+
? state.values.length - 1
|
|
5480
|
+
: state.values.reduce((last, value, index) => (Number(value) <= timestamp ? index : last), -1);
|
|
5481
|
+
}
|
|
5482
|
+
}
|
|
5483
|
+
// Native Cartesian heatmaps require category axes. Time values remain sorted
|
|
5484
|
+
// buckets and use the pivot date formatter for their displayed labels.
|
|
5485
|
+
return {
|
|
5486
|
+
...styles,
|
|
5487
|
+
type: 'category',
|
|
5488
|
+
boundaryGap: true,
|
|
5489
|
+
data: state.values.map(String),
|
|
5490
|
+
min: bucketMin,
|
|
5491
|
+
max: bucketMax,
|
|
5492
|
+
};
|
|
5493
|
+
}
|
|
5494
|
+
formatAxisValue(axis, value) {
|
|
5495
|
+
const state = axis === 'x' ? this.xAxisState : this.yAxisState;
|
|
5496
|
+
const index = typeof value === 'number'
|
|
5497
|
+
? value
|
|
5498
|
+
: state.values.findIndex((bucket) => String(bucket) === value);
|
|
5499
|
+
const resolved = state.values[index] ?? value;
|
|
5500
|
+
if (state.type === 'time') {
|
|
5501
|
+
return this.chartService.formatHeatmapPivotDate(resolved, axis === 'x' ? this.config.XAxisAggregation : this.config.YAxisAggregation);
|
|
5502
|
+
}
|
|
5503
|
+
return String(resolved);
|
|
5504
|
+
}
|
|
5505
|
+
formatTooltip(params) {
|
|
5506
|
+
const [x, y] = params.value ?? [];
|
|
5507
|
+
const rows = [
|
|
5508
|
+
['Row Dimension', this.formatAxisValue('x', x)],
|
|
5509
|
+
['Column Dimension', this.formatAxisValue('y', y)],
|
|
5510
|
+
];
|
|
5511
|
+
const selected = this.readLegendSelected();
|
|
5512
|
+
this.normalizedSeriesData.forEach((data, index) => {
|
|
5513
|
+
const series = this.config.series[index];
|
|
5514
|
+
if (selected[series.name] === false)
|
|
5515
|
+
return;
|
|
5516
|
+
const match = data.find((point) => {
|
|
5517
|
+
const value = this.pointValue(point);
|
|
5518
|
+
return value[0] === x && value[1] === y;
|
|
5519
|
+
});
|
|
5520
|
+
if (match) {
|
|
5521
|
+
rows.push([
|
|
5522
|
+
series.name,
|
|
5523
|
+
String(this.chartService.formatTooltipValue(this.pointValue(match)[2], this.config.tooltipCompactValue)),
|
|
5524
|
+
]);
|
|
5525
|
+
}
|
|
5526
|
+
});
|
|
5527
|
+
const extra = params.data?.[this.config.extraTooltipKey ?? 'tooltip'];
|
|
5528
|
+
if (extra && typeof extra === 'object' && !Array.isArray(extra)) {
|
|
5529
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
5530
|
+
rows.push([
|
|
5531
|
+
key,
|
|
5532
|
+
typeof value === 'number'
|
|
5533
|
+
? String(this.chartService.formatTooltipValue(value, this.config.tooltipCompactValue))
|
|
5534
|
+
: String(value ?? '-'),
|
|
5535
|
+
]);
|
|
5536
|
+
}
|
|
5537
|
+
}
|
|
5538
|
+
return `<div style="display:grid;grid-template-columns:112px 8px minmax(170px,1fr);row-gap:5px;line-height:16px">${rows
|
|
5539
|
+
.map(([label, content]) => `<span style="font-weight:600">${echarts.format.encodeHTML(String(label))}</span><span>:</span><span>${echarts.format.encodeHTML(String(content ?? '-'))}</span>`)
|
|
5540
|
+
.join('')}</div>`;
|
|
5541
|
+
}
|
|
5542
|
+
onChartInit(chart) {
|
|
5543
|
+
this.unbindEvents();
|
|
5544
|
+
this.chartInstance = chart;
|
|
5545
|
+
// Apply the width after ngx-echarts has installed the initial chart options.
|
|
5546
|
+
queueMicrotask(() => {
|
|
5547
|
+
if (this.chartInstance === chart)
|
|
5548
|
+
this.refreshLabelWidth();
|
|
5549
|
+
});
|
|
5550
|
+
this.bindEvents();
|
|
5551
|
+
this.cdr.markForCheck();
|
|
5552
|
+
}
|
|
5553
|
+
refreshLabelWidth() {
|
|
5554
|
+
const chart = this.chartInstance;
|
|
5555
|
+
if (!chart || chart.isDisposed() || !this.yAxisState)
|
|
5556
|
+
return;
|
|
5557
|
+
const width = this.resolveYAxisLabelWidth();
|
|
5558
|
+
const totalWidth = this.resolveTotalLabelWidth(width);
|
|
5559
|
+
if (width === this.yAxisLabelWidth && totalWidth === this.totalLabelWidth)
|
|
5560
|
+
return;
|
|
5561
|
+
const update = {
|
|
5562
|
+
yAxis: [{ axisLabel: {
|
|
5563
|
+
width,
|
|
5564
|
+
margin: this.config.yAxis?.axisLabel?.margin ?? width + 16,
|
|
5565
|
+
} }],
|
|
5566
|
+
};
|
|
5567
|
+
if (this.config.showTotals !== false) {
|
|
5568
|
+
update['title'] = [{ id: 'heatmap-pivot-total-label', textStyle: { width: totalWidth } }];
|
|
5569
|
+
}
|
|
5570
|
+
if (this.config.grid?.left === undefined) {
|
|
5571
|
+
update['grid'] = [{
|
|
5572
|
+
left: this.labelGridLeft(width),
|
|
5573
|
+
}];
|
|
5574
|
+
}
|
|
5575
|
+
chart.setOption(update, { lazyUpdate: true, silent: true });
|
|
5576
|
+
this.yAxisLabelWidth = width;
|
|
5577
|
+
this.totalLabelWidth = totalWidth;
|
|
5578
|
+
}
|
|
5579
|
+
bindEvents() {
|
|
5580
|
+
this.unbindEvents();
|
|
5581
|
+
const chart = this.chartInstance;
|
|
5582
|
+
if (!chart || chart.isDisposed())
|
|
5583
|
+
return;
|
|
5584
|
+
const eventNames = new Set(this.events);
|
|
5585
|
+
if (this.showContextMenu)
|
|
5586
|
+
eventNames.add('contextmenu');
|
|
5587
|
+
for (const eventName of eventNames) {
|
|
5588
|
+
const handler = (params) => {
|
|
5589
|
+
if (eventName === 'contextmenu') {
|
|
5590
|
+
this.openContextMenu(params?.event?.event);
|
|
5591
|
+
}
|
|
5592
|
+
this.chartEvent.emit({ type: eventName, data: params });
|
|
5593
|
+
};
|
|
5594
|
+
chart.on(eventName, handler);
|
|
5595
|
+
this.eventCleanup.push(() => {
|
|
5596
|
+
if (!chart.isDisposed())
|
|
5597
|
+
chart.off(eventName, handler);
|
|
5598
|
+
});
|
|
5599
|
+
if (eventName === 'click' || eventName === 'contextmenu') {
|
|
5600
|
+
const zr = chart.getZr();
|
|
5601
|
+
const backgroundHandler = (event) => {
|
|
5602
|
+
if (event.target)
|
|
5603
|
+
return;
|
|
5604
|
+
if (eventName === 'contextmenu') {
|
|
5605
|
+
this.openContextMenu(event.event);
|
|
5606
|
+
this.chartEvent.emit({
|
|
5607
|
+
type: 'contextmenu',
|
|
5608
|
+
data: { ...event, isZrEvent: true },
|
|
5609
|
+
});
|
|
5610
|
+
}
|
|
5611
|
+
else {
|
|
5612
|
+
this.chartEvent.emit({ type: 'blur', data: { ...event, type: 'blur' } });
|
|
5613
|
+
}
|
|
5614
|
+
};
|
|
5615
|
+
zr.on(eventName, backgroundHandler);
|
|
5616
|
+
this.eventCleanup.push(() => {
|
|
5617
|
+
if (!chart.isDisposed())
|
|
5618
|
+
zr.off(eventName, backgroundHandler);
|
|
5619
|
+
});
|
|
5620
|
+
}
|
|
5621
|
+
}
|
|
5622
|
+
}
|
|
5623
|
+
openContextMenu(event) {
|
|
5624
|
+
if (!event || !this.chartInstance || this.chartInstance.isDisposed())
|
|
5625
|
+
return;
|
|
5626
|
+
event.preventDefault();
|
|
5627
|
+
const rect = this.chartInstance.getDom().getBoundingClientRect();
|
|
5628
|
+
this.cardPosition = { x: event.clientX - rect.left, y: event.clientY - rect.top };
|
|
5629
|
+
this.openCard = this.showContextMenu || this.contextMenuOptions.length > 0;
|
|
5630
|
+
this.cdr.markForCheck();
|
|
5631
|
+
}
|
|
5632
|
+
onMenuClick(item) {
|
|
5633
|
+
this.contextMenuClick.emit(item);
|
|
5634
|
+
this.closeCard();
|
|
5635
|
+
}
|
|
5636
|
+
closeCard() {
|
|
5637
|
+
this.openCard = false;
|
|
5638
|
+
}
|
|
5639
|
+
onLegendEvent(event) {
|
|
5640
|
+
this.legendEvent.emit(event);
|
|
5641
|
+
this.chartEvent.emit({ type: `legend:${event.type}`, data: event });
|
|
5642
|
+
}
|
|
5643
|
+
readLegendSelected() {
|
|
5644
|
+
if (!this.chartInstance || this.chartInstance.isDisposed())
|
|
5645
|
+
return {};
|
|
5646
|
+
const option = this.chartInstance.getOption();
|
|
5647
|
+
return { ...option.legend?.[0]?.selected };
|
|
5648
|
+
}
|
|
5649
|
+
unbindEvents() {
|
|
5650
|
+
this.eventCleanup.forEach((cleanup) => cleanup());
|
|
5651
|
+
this.eventCleanup = [];
|
|
5652
|
+
}
|
|
5653
|
+
ngOnDestroy() {
|
|
5654
|
+
this.unbindEvents();
|
|
5655
|
+
if (this.chartInstance && !this.chartInstance.isDisposed()) {
|
|
5656
|
+
this.chartInstance.dispose();
|
|
5657
|
+
}
|
|
5658
|
+
}
|
|
5659
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: HeatmapPivot, deps: [{ token: Charts }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
5660
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: HeatmapPivot, isStandalone: true, selector: "lib-heatmap-pivot", inputs: { config: "config", theme: "theme", events: "events", contextMenuOptions: "contextMenuOptions", showContextMenu: "showContextMenu" }, outputs: { contextMenuClick: "contextMenuClick", chartEvent: "chartEvent", legendEvent: "legendEvent" }, host: { listeners: { "window:resize": "refreshLabelWidth()", "document:click": "closeCard()" } }, providers: [provideEchartsCore({ echarts })], viewQueries: [{ propertyName: "chartContainer", first: true, predicate: ["chartContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"heatmap-pivot-chart-shell\"\n [class.heatmap-pivot-chart-shell--legend-left]=\"config.customLegend?.position === 'left'\"\n [class.heatmap-pivot-chart-shell--legend-right]=\"config.customLegend?.position === 'right'\"\n [class.heatmap-pivot-chart-shell--legend-bottom]=\"config.customLegend?.position === 'bottom'\"\n>\n @if (\n config.customLegend && !config.hideLegend &&\n config.customLegend.position !== 'bottom' &&\n config.customLegend.position !== 'right'\n ) {\n <lib-chart-legend\n class=\"heatmap-pivot-chart-shell__legend\"\n [class.heatmap-pivot-chart-shell__legend--custom-width]=\"hasSideLegendWidth\"\n [style.--heatmap-pivot-chart-legend-max-width]=\"legendShellMaxWidth\"\n [chart]=\"chartInstance\"\n [series]=\"config.series\"\n [colors]=\"config.colors || deafultColors\"\n [config]=\"config.customLegend || {}\"\n (legendEvent)=\"onLegendEvent($event)\"\n ></lib-chart-legend>\n }\n\n <div\n #chartContainer\n echarts\n [options]=\"chartOption\"\n [theme]=\"theme\"\n (chartInit)=\"onChartInit($event)\"\n class=\"chart-container\"\n ></div>\n\n @if (\n config.customLegend && !config.hideLegend &&\n (config.customLegend.position === 'bottom' || config.customLegend.position === 'right')\n ) {\n <lib-chart-legend\n class=\"heatmap-pivot-chart-shell__legend\"\n [class.heatmap-pivot-chart-shell__legend--custom-width]=\"hasSideLegendWidth\"\n [style.--heatmap-pivot-chart-legend-max-width]=\"legendShellMaxWidth\"\n [chart]=\"chartInstance\"\n [series]=\"config.series\"\n [colors]=\"config.colors || deafultColors\"\n [config]=\"config.customLegend || {}\"\n (legendEvent)=\"onLegendEvent($event)\"\n ></lib-chart-legend>\n }\n</div>\n@if (openCard) {\n <lib-right-click-card\n [cardOptions]=\"contextMenuOptions\"\n (contextMenuClick)=\"onMenuClick($event)\"\n [cardPosition]=\"cardPosition\"\n ></lib-right-click-card>\n}\n", styles: [":host{display:block;height:100%;width:100%;font-family:Arial,sans-serif}.heatmap-pivot-chart-shell{display:flex;flex-direction:column;gap:8px;height:100%;min-height:0;min-width:0;width:100%;padding:10px 0 4px 10px;box-sizing:border-box;background:#fff}.heatmap-pivot-chart-shell--legend-left,.heatmap-pivot-chart-shell--legend-right{flex-direction:row}.heatmap-pivot-chart-shell--legend-bottom{flex-direction:column}.heatmap-pivot-chart-shell__legend{flex:0 0 auto;min-width:0}.heatmap-pivot-chart-shell--legend-left .heatmap-pivot-chart-shell__legend,.heatmap-pivot-chart-shell--legend-right .heatmap-pivot-chart-shell__legend{height:100%;max-width:min(var(--heatmap-pivot-chart-legend-max-width, 360px),70%);min-height:0}.chart-container{width:100%;height:100%;position:relative;flex:1 1 auto;min-height:0;min-width:0}@media (max-width: 640px){.heatmap-pivot-chart-shell,.heatmap-pivot-chart-shell--legend-left,.heatmap-pivot-chart-shell--legend-right{flex-direction:column}.heatmap-pivot-chart-shell--legend-left .heatmap-pivot-chart-shell__legend,.heatmap-pivot-chart-shell--legend-right .heatmap-pivot-chart-shell__legend{flex-basis:auto;max-width:none;width:auto}}\n"], dependencies: [{ kind: "directive", type: NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }, { kind: "component", type: ChartLegendComponent, selector: "lib-chart-legend", inputs: ["chart", "series", "colors", "config", "itemTemplate"], outputs: ["legendEvent"] }, { kind: "component", type: RightClickCard, selector: "lib-right-click-card", inputs: ["cardPosition", "cardOptions"], outputs: ["contextMenuClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
5661
|
+
}
|
|
5662
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: HeatmapPivot, decorators: [{
|
|
5663
|
+
type: Component,
|
|
5664
|
+
args: [{ selector: 'lib-heatmap-pivot', standalone: true, imports: [NgxEchartsDirective, ChartLegendComponent, RightClickCard], providers: [provideEchartsCore({ echarts })], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"heatmap-pivot-chart-shell\"\n [class.heatmap-pivot-chart-shell--legend-left]=\"config.customLegend?.position === 'left'\"\n [class.heatmap-pivot-chart-shell--legend-right]=\"config.customLegend?.position === 'right'\"\n [class.heatmap-pivot-chart-shell--legend-bottom]=\"config.customLegend?.position === 'bottom'\"\n>\n @if (\n config.customLegend && !config.hideLegend &&\n config.customLegend.position !== 'bottom' &&\n config.customLegend.position !== 'right'\n ) {\n <lib-chart-legend\n class=\"heatmap-pivot-chart-shell__legend\"\n [class.heatmap-pivot-chart-shell__legend--custom-width]=\"hasSideLegendWidth\"\n [style.--heatmap-pivot-chart-legend-max-width]=\"legendShellMaxWidth\"\n [chart]=\"chartInstance\"\n [series]=\"config.series\"\n [colors]=\"config.colors || deafultColors\"\n [config]=\"config.customLegend || {}\"\n (legendEvent)=\"onLegendEvent($event)\"\n ></lib-chart-legend>\n }\n\n <div\n #chartContainer\n echarts\n [options]=\"chartOption\"\n [theme]=\"theme\"\n (chartInit)=\"onChartInit($event)\"\n class=\"chart-container\"\n ></div>\n\n @if (\n config.customLegend && !config.hideLegend &&\n (config.customLegend.position === 'bottom' || config.customLegend.position === 'right')\n ) {\n <lib-chart-legend\n class=\"heatmap-pivot-chart-shell__legend\"\n [class.heatmap-pivot-chart-shell__legend--custom-width]=\"hasSideLegendWidth\"\n [style.--heatmap-pivot-chart-legend-max-width]=\"legendShellMaxWidth\"\n [chart]=\"chartInstance\"\n [series]=\"config.series\"\n [colors]=\"config.colors || deafultColors\"\n [config]=\"config.customLegend || {}\"\n (legendEvent)=\"onLegendEvent($event)\"\n ></lib-chart-legend>\n }\n</div>\n@if (openCard) {\n <lib-right-click-card\n [cardOptions]=\"contextMenuOptions\"\n (contextMenuClick)=\"onMenuClick($event)\"\n [cardPosition]=\"cardPosition\"\n ></lib-right-click-card>\n}\n", styles: [":host{display:block;height:100%;width:100%;font-family:Arial,sans-serif}.heatmap-pivot-chart-shell{display:flex;flex-direction:column;gap:8px;height:100%;min-height:0;min-width:0;width:100%;padding:10px 0 4px 10px;box-sizing:border-box;background:#fff}.heatmap-pivot-chart-shell--legend-left,.heatmap-pivot-chart-shell--legend-right{flex-direction:row}.heatmap-pivot-chart-shell--legend-bottom{flex-direction:column}.heatmap-pivot-chart-shell__legend{flex:0 0 auto;min-width:0}.heatmap-pivot-chart-shell--legend-left .heatmap-pivot-chart-shell__legend,.heatmap-pivot-chart-shell--legend-right .heatmap-pivot-chart-shell__legend{height:100%;max-width:min(var(--heatmap-pivot-chart-legend-max-width, 360px),70%);min-height:0}.chart-container{width:100%;height:100%;position:relative;flex:1 1 auto;min-height:0;min-width:0}@media (max-width: 640px){.heatmap-pivot-chart-shell,.heatmap-pivot-chart-shell--legend-left,.heatmap-pivot-chart-shell--legend-right{flex-direction:column}.heatmap-pivot-chart-shell--legend-left .heatmap-pivot-chart-shell__legend,.heatmap-pivot-chart-shell--legend-right .heatmap-pivot-chart-shell__legend{flex-basis:auto;max-width:none;width:auto}}\n"] }]
|
|
5665
|
+
}], ctorParameters: () => [{ type: Charts }, { type: i0.ChangeDetectorRef }], propDecorators: { chartContainer: [{
|
|
5666
|
+
type: ViewChild,
|
|
5667
|
+
args: ['chartContainer']
|
|
5668
|
+
}], config: [{
|
|
5669
|
+
type: Input
|
|
5670
|
+
}], theme: [{
|
|
5671
|
+
type: Input
|
|
5672
|
+
}], events: [{
|
|
5673
|
+
type: Input
|
|
5674
|
+
}], contextMenuOptions: [{
|
|
5675
|
+
type: Input
|
|
5676
|
+
}], showContextMenu: [{
|
|
5677
|
+
type: Input
|
|
5678
|
+
}], contextMenuClick: [{
|
|
5679
|
+
type: Output
|
|
5680
|
+
}], chartEvent: [{
|
|
5681
|
+
type: Output
|
|
5682
|
+
}], legendEvent: [{
|
|
5683
|
+
type: Output
|
|
5684
|
+
}], refreshLabelWidth: [{
|
|
5685
|
+
type: HostListener,
|
|
5686
|
+
args: ['window:resize']
|
|
5687
|
+
}], closeCard: [{
|
|
5688
|
+
type: HostListener,
|
|
5689
|
+
args: ['document:click']
|
|
5690
|
+
}] } });
|
|
5691
|
+
|
|
4940
5692
|
echarts.use([
|
|
4941
5693
|
ScatterChart,
|
|
4942
5694
|
GridComponent,
|
|
@@ -7560,5 +8312,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
7560
8312
|
* Generated bundle index. Do not edit.
|
|
7561
8313
|
*/
|
|
7562
8314
|
|
|
7563
|
-
export { BarChart, ChartLegendAdapter, ChartLegendComponent, Charts, CustomChartComponent, DoughnutChart, GanttChart, GaugeChart, Heatmap, LinesChart, PieChart, RightClickCard, SankeyChart, ScatterChartComp, StackedAreaChart, StatusTimelineComponent };
|
|
8315
|
+
export { BarChart, ChartLegendAdapter, ChartLegendComponent, Charts, CustomChartComponent, DoughnutChart, GanttChart, GaugeChart, Heatmap, HeatmapPivot, LinesChart, PieChart, RightClickCard, SankeyChart, ScatterChartComp, StackedAreaChart, StatusTimelineComponent };
|
|
7564
8316
|
//# sourceMappingURL=cats-charts.mjs.map
|