axidio-styleguide-library1-v2 0.2.6 → 0.2.7

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.
@@ -3002,8 +3002,8 @@ class GuageChartComponent extends ComponentUniqueId {
3002
3002
  this.chartConfiguration = {};
3003
3003
  this.dataType = '';
3004
3004
  this.datatype_status = false;
3005
- this.isHeaderVisible = true;
3006
3005
  this.uniqueId = this.getUniqueId();
3006
+ this.isHeaderVisible = true;
3007
3007
  this.defaultConfiguration = {
3008
3008
  margin: { top: 40, right: 20, bottom: 20, left: 20 },
3009
3009
  minAngle: -90,
@@ -3041,158 +3041,189 @@ class GuageChartComponent extends ComponentUniqueId {
3041
3041
  ngOnChanges() {
3042
3042
  this.redrawChart();
3043
3043
  }
3044
- onResized(_) {
3044
+ onResized(_event) {
3045
3045
  this.redrawChart();
3046
3046
  }
3047
+ /**
3048
+ * Clears the previous SVG and redraws chart
3049
+ */
3047
3050
  redrawChart() {
3048
- d3.select(`#${this.uniqueId}`).remove();
3049
- this.initializeChartConfig();
3050
- this.drawGaugeChart();
3051
+ d3.select('#' + this.uniqueId).remove();
3052
+ this.initializeLineChart();
3053
+ }
3054
+ /**
3055
+ * Main entry point for chart rendering
3056
+ */
3057
+ initializeLineChart() {
3058
+ this.prepareConfiguration();
3059
+ const { data, metaData, colorMaps, data_ready, angleValue, radius } = this.processChartData();
3060
+ const svg = this.createSvgContainer(radius);
3061
+ this.drawArcs(svg, data_ready, colorMaps, metaData);
3062
+ this.drawPointer(svg, metaData, data_ready, radius);
3063
+ this.drawLabels(svg, data_ready, radius, metaData);
3064
+ this.drawTexts(svg, metaData, radius);
3051
3065
  }
3052
- initializeChartConfig() {
3066
+ /**
3067
+ * Prepare chart configuration
3068
+ */
3069
+ prepareConfiguration() {
3053
3070
  for (const key in this.defaultConfiguration) {
3054
3071
  this.chartConfiguration[key] = ChartHelper.getValueByConfigurationType(key, this.defaultConfiguration, this.customChartConfiguration);
3055
3072
  }
3056
- if (this.chartConfiguration.isHeaderVisible !== undefined) {
3073
+ if (this.chartConfiguration.isHeaderVisible !== undefined)
3057
3074
  this.isHeaderVisible = this.chartConfiguration.isHeaderVisible;
3058
- }
3075
+ }
3076
+ /**
3077
+ * Process data, calculate colors and angles
3078
+ */
3079
+ processChartData() {
3059
3080
  const metaData = this.chartData.metaData;
3081
+ const data = this.chartData.data;
3082
+ const colorType = metaData.colorType || 'high';
3083
+ const colorMaps = colorType === 'low'
3084
+ ? this.chartConfiguration.low_colorMap
3085
+ : this.chartConfiguration.high_colorMap;
3060
3086
  if (metaData.dataType) {
3061
3087
  this.dataType = metaData.dataType === 'USD' ? '$ ' : metaData.dataType;
3062
- this.datatype_status = metaData.dataType === 'USD';
3088
+ this.datatype_status = true;
3063
3089
  }
3090
+ const data_ready = data.slice(0, -1).map((v, i) => data[i + 1] - v);
3091
+ const total = d3.sum(data_ready);
3092
+ const angleValue = data_ready.reduce((acc, curr, i) => {
3093
+ const prev = acc[i - 1] || 0;
3094
+ acc.push(prev + (curr / total) * 180);
3095
+ return acc;
3096
+ }, []);
3097
+ const width = parseInt(d3.select(this.containerElt.nativeElement).style('width')) -
3098
+ this.chartConfiguration.margin.left -
3099
+ this.chartConfiguration.margin.right;
3100
+ const height = parseInt(d3.select(this.guagecontainerElt.nativeElement).style('height')) -
3101
+ this.chartConfiguration.margin.top -
3102
+ this.chartConfiguration.margin.bottom -
3103
+ 56;
3104
+ const radius = Math.min(width, height) / 2;
3105
+ return { data, metaData, colorMaps, data_ready, angleValue, radius };
3064
3106
  }
3065
- drawGaugeChart() {
3066
- const { data, metaData } = this.chartData;
3067
- const colorMaps = metaData.colorType === 'low'
3068
- ? this.chartConfiguration.low_colorMap
3069
- : this.chartConfiguration.high_colorMap;
3070
- const chartContainer = d3.select(this.containerElt.nativeElement);
3071
- const guagecontainer = d3.select(this.guagecontainerElt.nativeElement);
3107
+ /**
3108
+ * Create SVG base container
3109
+ */
3110
+ createSvgContainer(radius) {
3072
3111
  const margin = this.chartConfiguration.margin;
3073
- const width = parseInt(chartContainer.style('width')) - margin.left - margin.right;
3074
- const height = parseInt(guagecontainer.style('height')) - margin.top - margin.bottom - 56;
3075
- const svg = this.createSvg(chartContainer, width, height);
3076
- const radius = Math.min(width, height) / 2;
3077
- this.adjustForScreenAndDrilldown(radius);
3078
- const { data_ready, angleValue, labelArray, range } = this.prepareGaugeData(data);
3079
- this.drawArcs(svg, data_ready, angleValue, radius, colorMaps, metaData);
3080
- this.drawPointer(svg, radius, data, metaData);
3081
- this.drawLabels(svg, radius, labelArray, range, metaData);
3082
- this.drawCenterTexts(svg, radius, metaData);
3083
- this.alignSvg(svg, chartContainer, margin);
3084
- }
3085
- createSvg(chartContainer, width, height) {
3086
- return chartContainer
3112
+ const chartContainer = d3.select(this.containerElt.nativeElement);
3113
+ const width = parseInt(chartContainer.style('width'));
3114
+ const height = parseInt(chartContainer.style('height'));
3115
+ const svg = chartContainer
3087
3116
  .append('svg')
3088
3117
  .attr('id', this.uniqueId)
3089
3118
  .attr('width', width)
3090
3119
  .attr('height', height)
3091
3120
  .call(ChartHelper.responsivefy)
3092
- .append('g');
3093
- }
3094
- adjustForScreenAndDrilldown(radius) {
3095
- if (this.chartConfiguration.isDrilldownChart) {
3096
- this.chartConfiguration.currentValueWidthScaleFactor += 40;
3097
- this.chartConfiguration.currentValueHeightScaleFactor += 20;
3098
- }
3099
- else if (window.innerWidth > 1400) {
3100
- this.chartConfiguration.currentValueHeightScaleFactor += 15;
3101
- this.chartConfiguration.currentValueWidthScaleFactor *= 2;
3102
- }
3103
- }
3104
- prepareGaugeData(data) {
3105
- const data_ready = data.slice(1).map((d, i) => d - data[i]);
3106
- const total = data_ready.reduce((a, b) => a + b, 0);
3107
- const angleValue = data_ready.map(((sum) => (unit) => (sum += (unit / total) * 180))(0));
3108
- const labelArray = [{ name: data[0], value: 0 }];
3109
- data_ready.reduce((acc, val, i) => {
3110
- const next = acc + val;
3111
- labelArray.push({ name: data[i + 1], value: next });
3112
- return next;
3113
- }, 0);
3114
- const range = data[data.length - 1] - data[0];
3115
- return { data_ready, angleValue, labelArray, range };
3121
+ .append('g')
3122
+ .attr('transform', `translate(${margin.left + radius}, ${margin.top + radius})`);
3123
+ return svg;
3116
3124
  }
3117
- drawArcs(svg, data_ready, angleValue, radius, colorMaps, metaData) {
3125
+ /**
3126
+ * Draw gauge arcs
3127
+ */
3128
+ drawArcs(svg, data_ready, colorMaps, metaData) {
3118
3129
  const arc = d3
3119
3130
  .arc()
3120
- .innerRadius(radius - this.chartConfiguration.ringWidth - this.chartConfiguration.ringInset)
3121
- .outerRadius(radius)
3122
- .startAngle((_, i) => this.deg2rad(i === 0 ? this.chartConfiguration.minAngle : this.chartConfiguration.minAngle + angleValue[i - 1]))
3123
- .endAngle((_, i) => this.deg2rad(i === data_ready.length - 1
3124
- ? this.chartConfiguration.maxAngle
3125
- : this.chartConfiguration.minAngle + angleValue[i]));
3126
- const arcs = svg.append('g').attr('class', 'arc').attr('transform', `translate(${radius},${radius})`);
3127
- arcs
3131
+ .innerRadius(this.chartConfiguration.ringWidth +
3132
+ this.chartConfiguration.ringInset -
3133
+ 20)
3134
+ .outerRadius(this.chartConfiguration.ringWidth + 40)
3135
+ .startAngle((_, i) => this.deg2rad(this.chartConfiguration.minAngle + (i ? i * 60 : 0)))
3136
+ .endAngle((_, i) => this.deg2rad(this.chartConfiguration.minAngle + (i + 1) * 60));
3137
+ const isClickable = metaData.hasDrillDown && metaData.currentValue > 0;
3138
+ svg
3139
+ .append('g')
3140
+ .attr('class', 'arc')
3128
3141
  .selectAll('path')
3129
3142
  .data(data_ready)
3130
3143
  .enter()
3131
3144
  .append('path')
3132
3145
  .attr('fill', (_, i) => colorMaps[i])
3133
3146
  .attr('d', arc)
3134
- .style('cursor', () => metaData.currentValue > 0 && metaData.hasDrillDown ? 'pointer' : 'default')
3147
+ .style('cursor', isClickable ? 'pointer' : 'default')
3135
3148
  .on('click', (event, d) => {
3136
- if (metaData.hasDrillDown && metaData.currentValue > 0) {
3137
- this.handleClick(this.getRange(d, data_ready, metaData));
3138
- }
3149
+ if (isClickable)
3150
+ this.handleClick(d);
3139
3151
  });
3140
3152
  }
3141
- drawPointer(svg, radius, data, metaData) {
3153
+ /**
3154
+ * Draw the pointer/needle
3155
+ */
3156
+ drawPointer(svg, metaData, data_ready, radius) {
3157
+ const pointerValue = metaData.currentValue - this.chartData.data[0];
3158
+ const range = this.chartData.data[this.chartData.data.length - 1] -
3159
+ this.chartData.data[0];
3160
+ const pointerAngle = this.chartConfiguration.minAngle + (pointerValue / range) * 180;
3142
3161
  const pointerHeadLength = Math.round(radius * this.chartConfiguration.pointerHeadLengthPercent);
3143
3162
  const lineData = [
3144
3163
  [this.chartConfiguration.pointerWidth / 2, 0],
3145
3164
  [0, -pointerHeadLength],
3146
- [-(this.chartConfiguration.pointerWidth / 2), 0],
3165
+ [-this.chartConfiguration.pointerWidth / 2, 0],
3147
3166
  [0, this.chartConfiguration.pointerTailLength],
3148
3167
  [this.chartConfiguration.pointerWidth / 2, 0],
3149
3168
  ];
3150
- const pointerLine = d3.line();
3151
- const pointerValue = metaData.currentValue - data[0];
3152
- const range = data[data.length - 1] - data[0];
3153
- const pointerAngle = this.chartConfiguration.minAngle + (pointerValue / range) * 180;
3154
3169
  svg
3155
3170
  .append('g')
3156
- .data([lineData])
3157
3171
  .attr('class', 'pointer')
3158
- .attr('transform', `translate(${radius},${radius})`)
3159
3172
  .append('path')
3160
- .attr('d', pointerLine)
3173
+ .attr('d', d3.line()(lineData))
3161
3174
  .attr('fill', this.chartConfiguration.pointerColor)
3162
- .attr('transform', `rotate(${pointerAngle}) translate(0,${-radius + this.chartConfiguration.ringWidth + pointerHeadLength})`);
3175
+ .attr('transform', `rotate(${pointerAngle}) translate(0, ${-radius +
3176
+ this.chartConfiguration.ringWidth +
3177
+ pointerHeadLength})`);
3163
3178
  }
3164
- drawLabels(svg, radius, labelArray, range, metaData) {
3165
- const lg = svg.append('g').attr('class', 'label').attr('transform', `translate(${radius},${radius})`);
3166
- const labelGroups = lg
3167
- .selectAll('.bubble')
3179
+ /**
3180
+ * Draw numeric labels around gauge
3181
+ */
3182
+ drawLabels(svg, data_ready, radius, metaData) {
3183
+ const data = this.chartData.data;
3184
+ const range = data[data.length - 1] - data[0];
3185
+ const labelArray = [{ name: data[0], value: 0 }];
3186
+ data_ready.reduce((sum, val, i) => {
3187
+ const newSum = sum + val;
3188
+ labelArray.push({ name: data[i + 1], value: newSum });
3189
+ return newSum;
3190
+ }, 0);
3191
+ const labelGroup = svg.append('g').attr('class', 'labels');
3192
+ labelGroup
3193
+ .selectAll('text')
3168
3194
  .data(labelArray)
3169
3195
  .enter()
3170
- .append('g')
3171
- .attr('transform', (d) => {
3172
- const angle = this.chartConfiguration.minAngle + (d.value / range) * 180;
3173
- return `rotate(${angle}) translate(0,${this.chartConfiguration.labelInset - radius - 20})`;
3174
- });
3175
- labelGroups
3176
3196
  .append('text')
3197
+ .attr('transform', (d) => {
3198
+ const newAngle = this.chartConfiguration.minAngle + (d.value / range) * 180;
3199
+ return `rotate(${newAngle}) translate(0, ${this.chartConfiguration.labelInset - radius - 20})`;
3200
+ })
3177
3201
  .attr('fill', 'var(--chart-text-color)')
3178
- .style('font-size', window.innerWidth < 1400 ? '12px' : '14px')
3202
+ .style('font-size', '14px')
3179
3203
  .style('font-weight', '600')
3180
- .text((d) => `${d.name}${metaData.dataType || ''}`);
3204
+ .text((d) => metaData.dataType ? `${d.name}${metaData.dataType}` : d.name);
3181
3205
  }
3182
- drawCenterTexts(svg, radius, metaData) {
3206
+ /**
3207
+ * Draw texts (value, status, date)
3208
+ */
3209
+ drawTexts(svg, metaData, radius) {
3210
+ const topY = radius / 2 - 10;
3211
+ const midY = topY + this.chartConfiguration.currentValueHeightScaleFactor;
3212
+ const bottomY = midY + this.chartConfiguration.currentValueHeightScaleFactor;
3183
3213
  svg
3184
3214
  .append('foreignObject')
3185
- .attr('transform', `translate(${radius - this.chartConfiguration.currentValueWidthScaleFactor / 2},${radius / 2 - 10})`)
3186
- .attr('width', this.chartConfiguration.currentValueWidthScaleFactor)
3187
- .attr('height', this.chartConfiguration.currentValueHeightScaleFactor)
3215
+ .attr('transform', `translate(${radius - 50}, ${topY})`)
3216
+ .attr('width', 100)
3217
+ .attr('height', 40)
3188
3218
  .append('xhtml:div')
3189
3219
  .attr('class', 'value-display')
3190
3220
  .html(`${metaData.currentValue}${metaData.dataType || ''}`);
3191
3221
  if (metaData.status) {
3192
3222
  svg
3193
3223
  .append('foreignObject')
3194
- .attr('transform', `translate(${radius - 60},${radius / 2 + 20})`)
3224
+ .attr('transform', `translate(${radius - 60}, ${midY})`)
3195
3225
  .attr('width', 120)
3226
+ .attr('height', 40)
3196
3227
  .append('xhtml:div')
3197
3228
  .attr('class', 'status-display')
3198
3229
  .html(metaData.status);
@@ -3200,22 +3231,15 @@ class GuageChartComponent extends ComponentUniqueId {
3200
3231
  if (metaData.dateRange) {
3201
3232
  svg
3202
3233
  .append('foreignObject')
3203
- .attr('transform', `translate(${radius - 105},${radius / 2 + 50})`)
3234
+ .attr('transform', `translate(${radius - 105}, ${bottomY})`)
3204
3235
  .attr('width', 210)
3236
+ .attr('height', 40)
3205
3237
  .append('xhtml:div')
3206
3238
  .attr('class', 'daterange-display')
3207
3239
  .html(`<span class="marginright-3"><i class="fa fa-calendar"></i></span>${metaData.dateRange}`);
3208
3240
  }
3209
3241
  }
3210
- alignSvg(svg, chartContainer, margin) {
3211
- const containerMid = parseInt(chartContainer.style('width')) / 2;
3212
- const nodeHalf = svg.node().getBoundingClientRect().width / 2;
3213
- svg.attr('transform', `translate(${containerMid - nodeHalf + margin.left},${margin.top})`);
3214
- }
3215
- getRange(d, data_ready, metaData) {
3216
- const data = this.chartData.data;
3217
- return `${data[0]} and ${data[data.length - 1]}`;
3218
- }
3242
+ /** Convert degrees to radians */
3219
3243
  deg2rad(deg) {
3220
3244
  return (deg * Math.PI) / 180;
3221
3245
  }