1

I'm working in a module that has some different components that uses Highcharts. In one of them I'm using treemap and I'm importing this module like this:

import { Component, OnInit, ViewChild, Input, SimpleChanges, OnChanges, OnDestroy } from '@angular/core'; import { ApiService } from 'src/common/services/api.services'; import * as Highcharts from 'highcharts'; import More from 'highcharts/highcharts-more'; import noData from 'highcharts/modules/no-data-to-display'; import Tree from 'highcharts/modules/treemap'; import { Subscription } from 'rxjs'; // highcharts noData(Highcharts); More(Highcharts); noData(Highcharts); Tree(Highcharts); @Component({ selector: 'app-performance-tree-map', templateUrl: './performance-tree-map.component.html', styleUrls: ['./performance-tree-map.component.scss'] }) export class PerformanceTreeMapComponent implements OnInit, OnChanges, OnDestroy { public matrixSusbscription: Subscription; @ViewChild('canvas') private canvas; @Input() public evaluationId; @Input() public structureId; @Input() public familyId; private highChartOptions = { colorAxis: { minColor: '#FFFFFF', maxColor: Highcharts.getOptions().colors[0] }, drillUpButton: { theme: { width: 120, height: 15 } }, series: [{ type: 'treemap', layoutAlgorithm: 'squarified', allowDrillToNode: true, animationLimit: 1000, dataLabels: { enabled: false }, levelIsConstant: false, levels: [{ level: 1, dataLabels: { enabled: true }, borderWidth: 3 }], turboThreshold: 100000, data: [], }], tooltip: { formatter: function () { if (this.point.isChildren) { return this.point.name; } return this.point.realValue || this.point.value; } }, title: { text: '' }, //legend: { // enabled: false //} }; constructor(private apiService: ApiService) { } ngOnInit() { } ngOnDestroy(): void { if (this.matrixSusbscription) { this.matrixSusbscription.unsubscribe(); } } ngOnChanges(changes: SimpleChanges): void { if (Object.values(changes).some(value => value.isFirstChange())) return; if (Object.keys(changes).some(k => k === 'evaluationId')) { if (changes.evaluationId.currentValue !== changes.evaluationId.previousValue) { this.evaluationId = changes.evaluationId.currentValue; this.getPerformanceMatrix(); } } if (Object.keys(changes).some(k => k === 'structureId')) { if (changes.structureId.currentValue !== changes.structureId.previousValue) { this.structureId = changes.structureId.currentValue; this.getPerformanceMatrix(); } } if (Object.keys(changes).some(k => k === 'familyId')) { if (changes.familyId.currentValue !== changes.familyId.previousValue) { this.familyId = changes.familyId.currentValue; this.getPerformanceMatrix(); } } } private getPerformanceMatrix() { this.matrixSusbscription = this.apiService.getPerformanceMatrix(this.structureId, this.familyId, this.evaluationId) .subscribe(data => this.fillMatrix(data)); } public descriptions = [ { value: 5, text: 'Desempeño ejemplar', color: '#173463' }, { value: 4, text: 'Excelente nivel de desempeño', color: '#B4C7E7' }, { value: 3, text: 'Buen nivel de desempeño', color: '#00AD49' }, { value: 2, text: 'Necesita consolidar comportamientos', color: '#FFC000' }, { value: 1, text: 'Alejado del perfi', color: '#FF0000' }, ]; private fillMatrix(data) { this.highChartOptions.series[0].data = []; let performancePoint; let employeePoint; data.forEach((performance, index) => { const desc = this.descriptions.find(d => d.value === performance.roundCount); performancePoint = { id: `id_${performance.roundCount}`, name: performance.title, color: desc.color, realValue: performance.count, value: 100, isChildren: false }; performance.employees.forEach(employee => { employeePoint = { id: `id_${performance.employee}`, name: `${employee.name} ${employee.lastName1} ${employee.lastName2}`, parent: `id_${performance.roundCount}`, value: 10, isChildren: true }; this.highChartOptions.series[0].data.push(employeePoint); }); this.highChartOptions.series[0].data.push(performancePoint); }); // @ts-ignore Highcharts.chart(this.canvas.nativeElement, this.highChartOptions); } } 

And other component that imports heatmap module

import { Component, OnInit, ViewChild, Input, SimpleChanges, OnChanges, OnDestroy, ViewEncapsulation } from '@angular/core'; import { ApiService } from 'src/common/services/api.services'; import { MatDialog } from '@angular/material'; import { PerformanceVsPotentialGridModalComponent } from './performance-vs-potential-grid-modal/performance-vs-potential-grid-modal.component'; import { Subscription } from 'rxjs'; import { AuthService } from 'src/common/services/auth.service'; import * as _ from 'lodash'; import * as Highcharts from 'highcharts'; import noData from 'highcharts/modules/no-data-to-display'; import heatmap from 'highcharts/modules/heatmap'; import accessibility from 'highcharts/modules/accessibility'; noData(Highcharts); heatmap(Highcharts); accessibility(Highcharts); @Component({ selector: 'app-performance-vs-potential', templateUrl: './performance-vs-potential.component.html', styleUrls: ['./performance-vs-potential.component.scss'], }) export class PerformanceVsPotentialComponent implements OnInit, OnChanges, OnDestroy { public matrixSusbscription: Subscription; @Input() public evaluationId; @Input() public structureId; @Input() public familyId; public isAdmin = false; public isRRHH = false; @ViewChild('canvas') private canvas; private highChartOptions = { chart: { type: 'heatmap', marginTop: 40, marginBottom: 80, plotBorderWidth: 1 }, title: { text: 'Crecimiento en la empresa' }, xAxis: { categories: ['No', 'Si, con desarrollo', 'Si'], }, yAxis: { categories: ['Desempeño ejemplar Excelente nivel de desempeño', 'Buen nivel de desempeño', 'Necesita consolidar comportamientos Alejado del perfil'], title: { text: 'Resultado Evaluación' }, reversed: true }, accessibility: { point: { descriptionFormatter: function (point) { var ix = point.index + 1, xName = getPointCategoryName(point, 'x'), yName = getPointCategoryName(point, 'y'), val = point.value; return ix + '. ' + xName + ' sales ' + yName + ', ' + val + '.'; } } }, colorAxis: { min: 0, minColor: '#FFFFFF', maxColor: Highcharts.getOptions().colors[0] }, // legend: { // align: 'right', // layout: 'vertical', // margin: 0, // verticalAlign: 'top', // y: 25, // symbolHeight: 280 // }, legend: { enabled: false }, tooltip: { formatter: function () { return '<b>' + getPointCategoryName(this.point, 'x') + '</b> sold <br><b>' + this.point.value + '</b> items on <br><b>' + getPointCategoryName(this.point, 'y') + '</b>'; } }, series: [{ name: 'Crecimiento vs Evaluación', borderWidth: 1, data: [], dataLabels: { enabled: true, color: '#000000' } }], responsive: { rules: [{ condition: { maxWidth: 500 }, chartOptions: { yAxis: { labels: { formatter: function () { return this.value.charAt(0); } } } } }] } }; constructor(private apiService: ApiService, public dialog: MatDialog, private authService: AuthService) { } ngOnInit() { const token = this.authService.decryptedToken(); if (token.roles.includes('ADMIN')) { this.isAdmin = true; } if (token.roles.includes('RRHH')) { this.isRRHH = true; } } ngOnDestroy(): void { if (this.matrixSusbscription) { this.matrixSusbscription.unsubscribe(); } } ngOnChanges(changes: SimpleChanges): void { if (Object.values(changes).some(value => value.isFirstChange())) return; if (Object.keys(changes).some(k => k === 'evaluationId')) { if (changes.evaluationId.currentValue !== changes.evaluationId.previousValue) { this.evaluationId = changes.evaluationId.currentValue; this.getMatrix(); } } if (Object.keys(changes).some(k => k === 'structureId')) { if (changes.structureId.currentValue !== changes.structureId.previousValue) { this.structureId = changes.structureId.currentValue; this.getMatrix(); } } if (Object.keys(changes).some(k => k === 'familyId')) { if (changes.familyId.currentValue !== changes.familyId.previousValue) { this.familyId = changes.familyId.currentValue; this.getMatrix(); } } } // private colorAxes = [{ // min: 0, // minColor: '#FFFFFF', // maxColor: Highcharts.getOptions().colors[0] // }, { // min: 0, // minColor: '#FFFFFF', // maxColor: Highcharts.getOptions().colors[1] // }, { // min: 0, // minColor: '#FFFFFF', // maxColor: Highcharts.getOptions().colors[2] // }, { // min: 0, // minColor: '#FFFFFF', // maxColor: Highcharts.getOptions().colors[3] // }]; public getMatrix() { this.matrixSusbscription = this.apiService.performanceVSPotentialMatrix(this.structureId, this.familyId, this.evaluationId) .subscribe(data => this.fillMatrix(data)); } private fillMatrix(matrix) { this.highChartOptions.series[0].data = []; if (!matrix || matrix.length <= 0) return; const bajoDesempenoBajoPotencial = matrix.find(e => e.potential === 'bajoDesempeno' && e.performance === 'bajoPotencial') || { employees: [] }; const bajoDesempenoBajoPotencialCount = _.isNil(bajoDesempenoBajoPotencial) ? 0 : bajoDesempenoBajoPotencial.employees.length; const bajoDesempenoMedioPotencial = matrix.find(e => e.potential === 'bajoDesempeno' && e.performance === 'medioPotencial') || { employees: [] }; const bajoDesempenoMedioPotencialCount = _.isNil(bajoDesempenoMedioPotencial) ? 0 : bajoDesempenoMedioPotencial.employees.length; const bajoDesempenoAltoPotencial = matrix.find(e => e.potential === 'bajoDesempeno' && e.performance === 'altoPotencial') || { employees: [] }; const bajoDesempenoAltoPotencialCount = _.isNil(bajoDesempenoAltoPotencial) ? 0 : bajoDesempenoAltoPotencial.employees.length; const medioDesempenoBajoPotencial = matrix.find(e => e.potential === 'medioDesempeno' && e.performance === 'bajoPotencial') || { employees: [] }; const medioDesempenoBajoPotencialCount = _.isNil(medioDesempenoBajoPotencial) ? 0 : medioDesempenoBajoPotencial.employees.length; const medioDesempenoMedioPotencial = matrix.find(e => e.potential === 'medioDesempeno' && e.performance === 'medioPotencial') || { employees: [] }; const medioDesempenoMedioPotencialCount = _.isNil(medioDesempenoMedioPotencial) ? 0 : medioDesempenoMedioPotencial.employees.length; const medioDesempenoAltoPotencial = matrix.find(e => e.potential === 'medioDesempeno' && e.performance === 'altoPotencial') || { employees: [] }; const medioDesempenoAltoPotencialCount = _.isNil(medioDesempenoAltoPotencial) ? 0 : medioDesempenoAltoPotencial.employees.length; const altoDesempenoBajoPotencial = matrix.find(e => e.potential === 'altoDesempeno' && e.performance === 'bajoPotencial') || { employees: [] }; const altoDesempenoBajoPotencialCount = _.isNil(altoDesempenoBajoPotencial) ? 0 : altoDesempenoBajoPotencial.employees.length; const altoDesempenoMedioPotencial = matrix.find(e => e.potential === 'altoDesempeno' && e.performance === 'medioPotencial') || { employees: [] }; const altoDesempenoMedioPotencialCount = _.isNil(altoDesempenoMedioPotencial) ? 0 : altoDesempenoMedioPotencial.employees.length; const altoDesempenoAltoPotencial = matrix.find(e => e.potential === 'altoDesempeno' && e.performance === 'altoPotencial') || { employees: [] }; const altoDesempenoAltoPotencialCount = _.isNil(altoDesempenoAltoPotencial) ? 0 : altoDesempenoAltoPotencial.employees.length; this.highChartOptions.series[0].data.push([0, 0, altoDesempenoBajoPotencialCount]); this.highChartOptions.series[0].data.push([0, 1, altoDesempenoMedioPotencialCount]); this.highChartOptions.series[0].data.push([0, 2, altoDesempenoAltoPotencialCount]); this.highChartOptions.series[0].data.push([1, 0, medioDesempenoBajoPotencialCount]); this.highChartOptions.series[0].data.push([1, 1, medioDesempenoMedioPotencialCount]); this.highChartOptions.series[0].data.push([1, 2, medioDesempenoAltoPotencialCount]); this.highChartOptions.series[0].data.push([2, 0, bajoDesempenoBajoPotencialCount]); this.highChartOptions.series[0].data.push([2, 1, bajoDesempenoMedioPotencialCount]); this.highChartOptions.series[0].data.push([2, 2, bajoDesempenoAltoPotencialCount]); // @ts-ignore Highcharts.chart(this.canvas.nativeElement, this.highChartOptions); } public openDialog(employees) { this.dialog.open(PerformanceVsPotentialGridModalComponent, { data: Object.assign({}, { employees }) }); } } function getPointCategoryName(point, dimension) { var series = point.series, isY = dimension === 'y', axis = series[isY ? 'yAxis' : 'xAxis']; return axis.categories[point[isY ? 'y' : 'x']]; } 

The problem Is when I'm import heapmap on the second component, the colors are mixing, the heatmap legend bar is appearing in all charts that aren't heatmap charts. Before I have this component everything worked fine.

Component 1 before importing component 2: enter image description here

Component 1 after importing component 2 : enter image description here

In this stackblitz example you can find the bug:

https://stackblitz.com/edit/angular-je2xri?file=src%2Fapp%2Fapp.component.html

1
  • 1
    Could you provide a live demo that recreates the problem? The configuration object that you use in your second demo defines color axis: colorAxis: { min: 0, minColor: '#FFFFFF', maxColor: Highcharts.getOptions().colors[0] }, Have you tried removing it? Commented Feb 12, 2020 at 7:43

1 Answer 1

2

As @KamilKulig suggested. The solution was removing colorAxis from chart properties

colorAxis: { min: 0, minColor: '#FFFFFF', maxColor: Highcharts.getOptions().colors[0] } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.