각도로 지시문을 사용하여 표에 열 지도를 구현하는 방법

각도로 지시문을 사용하여 표에 열 지도를 구현하는 방법

반응형

지시사항을 사용하여 Angular의 테이블에 히트맵을 추가하는 것이 얼마나 쉬운지 알아보겠습니다. 표의 다른 열에 별도의 열 지도를 만드는 매우 간단하고 우아한 솔루션을 선택할 것입니다.

내가 항상 말했듯이, 디렉티브는 Angular의 정말 강력한 기능입니다. 많은 멋진 기능을 구현하기 위한 우아한 솔루션으로 사용될 수 있습니다. 직권상정에 도달했을 때 지시적 접근법이 왜 더 말이 되는지 분명히 알 수 있습니다.

테이블의 히트맵

표에서 히트맵을 자주 볼 수는 없지만 히트맵은 시각화 측면에서 어느 정도 가치를 더해줄 수 있습니다. 일종의 비교 또는 범위가 있는 데이터 집합에서는 이 방법이 타당할 수 있습니다.

왜 지시하는가?

이 질문을 염두에 두고 있다면, 왜 이 기능을 구현하기 위한 지침을 만드는 것이 타당한지에 대한 몇 가지 이유가 있습니다.

논리를 구성 요소 외부로 완전히 이동할 수 있으므로 더 간단하고 희박합니다. 구성 요소에서 논리가 분리되면 재사용이 더 용이해집니다.

재사용 가능한 방식으로 구축되면 확장 및 유지관리가 쉬워집니다.

히트맵 논리

이 기능을 구현하기 위해 여기서 수행해야 할 작업을 살펴보겠습니다. 기본적으로 히트맵은 색상이나 색상의 변화를 통해 사용자에게 무언가의 크기를 알려줍니다.

숫자 집합이 있다면:

[1,2,3,4,5,6,7,8,9,10]

여기서는 값을 바탕으로 색의 강도를 조정할 수 있습니다. 의미 1은 가장 밝은 색조이고 10은 색상 그 자체입니다. 그래서 우리는 이 값들을 색깔의 강도에 맞추기만 하면 됩니다. 우리는 그 반대 조건도 가질 수 있습니다.

이것을 실행하는 다른 방법들이 있다.

1. 알파 채널 사용

색상 투명도를 의미하는 알파 채널만 변경하면 RGBA 또는 HSLA를 사용하여 히트맵을 쉽게 구현할 수 있습니다.

배경색을 기반으로 접근 가능한 텍스트 색상을 생성하려고 하기 때문에 이 접근 방식을 사용하지 않습니다. 이렇게 하면 모든 색상 중지 시 텍스트를 읽을 수 있습니다.

2. HSL 색 표현식의 사용

여기서는 HSL 색상 식을 사용하여 L(Lightness) 파라미터를 조작하여 각 값에 맞는 색상을 쉽게 얻을 수 있습니다.

HSL은 색을 표현하는 정말 좋은 방법이고 색을 조작하는 것은 매우 쉽습니다.

HSL은 Hue 포화 광도를 의미하며 HSLA와 알파 채널을 가질 수도 있다.

여기서 아이디어는 각 값에 대한 밝기 계수를 찾는 것입니다. 우리가 할 수 있는 방법은 이렇습니다.

여기서 원래의 색상 값은 HSLA로 먼저 구문 분석됩니다.

hsla (234, 77%, 46%, 1) --> 가벼움 = 46%

우리는 최소 밝기 값 즉 0.46을 가지고 있다. 따라서 가장 높은 값의 밝기는 46%이고 다른 값의 경우 더 높습니다. 밝기가 증가하면 흰색에 가까워진다.

다음은 공식입니다.

const color = '#1b2dd0'; const [h,s,l,a] = parseHSLA(color); // <-- [234, 0.77,0.46,1] const highestValue = 10; const maxLightness = 1 - l; // <-- 1 - 0.46 = 0.54 const lightness = 1 - (value * maxLightness / highestValue); // 1 --> 1 - (1 * 0.54 / 10) = (1 - 0.05) ~ 95% // 5 --> 1 - (5 * 0.46 / 10) = (1 - 0.23) ~ 77% // 10 -> 1 - (10 * 0.54 / 10) = (1 - 0.54) ~ 46%

여기 10이 가장 낮은 숫자이기 때문에 95%가 매우 밝은 색이 필요합니다.

밝기 비율(%)이 증가하면 색상이 더 희어집니다.

자, 이제 논리를 정리했습니다. 지시사항부터 시작해보죠!

열 지도 지시문 작성 중

이 기능에 대한 여러 지침을 만들 예정이기 때문에 "지침"(복수)을 언급했습니다. 그 중 3가지를 구체적으로 말하면요. 세 가지 중 두 가지는 요소에 태그를 지정하고 일부 메타데이터를 설정하기 위한 것입니다.

열 지도 표

열 지도 열

히트맵 셀

템플릿의 지시사항을 사용하는 방법은 다음과 같습니다.

Company Manager Employees Contractors { item.company } { item?.manager } { item?.employees } { item?.contractors }

히트맵 셀 지침

@Directive({ selector: '[heatMapCell]', }) export class HeatmapCellDirective { @Input('heatMapCell') heatMap = 0; @Input('id') colId = null; constructor(public el: ElementRef) {} }

우리는 값을 지시어에 전달하기 위한 입력이 있고 또한 표에서 셀이 속한 열의 ID를 받아들입니다. 나중에 요소를 조작할 수 있도록 ElementRef를 주입합니다.

열 지도 열 지시

@Directive({ selector: '[heatMapColumn]', }) export class HeatmapColumnDirective { @Input('id') colId = null; @Input('heatMapColumn') options = {}; }

여기서는 색상 등과 같은 스타일링 옵션과 칼럼의 ID도 전달할 수 있습니다.

열 지도 표 지시

이것이 모든 작업이 완료되는 주요 지시사항입니다. 이 지시는 테이블 위에 놓여 있다. 그리고 다른 지시사항은 기둥과 세포에 배치됩니다.

여기서는 ContentChildren을 사용하여 부모 지침에서 자식 지침에 액세스하는 방법을 볼 수 있습니다.

@Directive({ selector: '[heatMapTable]', }) export class HeatmapTableDirective implements AfterViewInit { @ContentChildren(HeatmapCellDirective, { descendants: true }) heatMapCells: QueryList; // <-- Get all the cells @ContentChildren(HeatmapColumnDirective, { descendants: true }) heatMapColumns: QueryList; // <-- Get all the columns highestValues = {}; cells: HeatmapCellDirective[] = []; columns: HeatmapColumnDirective[] = []; config = {}; ngAfterViewInit() { this.cells = this.heatMapCells.toArray(); this.columns = this.heatMapColumns.toArray(); this.setOptions(); this.calculateHighestValues(); this.applyHeatMap(); } private setOptions() { this.columns.forEach((col) => { this.config = { ...this.config, [col.colId]: col.options, }; }); } private calculateHighestValues() { return this.cells.forEach(({ colId, heatMap }) => { if (!Object.prototype.hasOwnProperty.call(this.highestValues, colId)) { this.highestValues[colId] = 0; } if (heatMap > this.highestValues?.[colId]) this.highestValues[colId] = heatMap; }); } private applyHeatMap() { this.cells.forEach((cell) => { const { bgColor, color } = this.getColor(cell.colId, cell.heatMap); if (bgColor) cell.el.nativeElement.style.backgroundColor = bgColor; if (color) cell.el.nativeElement.style.color = color; }); } private getColor(id: string, value: number) { const color = this.config[id].color; let textColor = null; let bgColor = null; if (color != null) { const [h, s, l, a] = parseToHsla(color); const maxLightness = 1 - l; const percentage = (value * maxLightness) / this.highestValues[id]; const lightness = +percentage.toFixed(3); bgColor = hsla(h, s, 1 - lightness, a); textColor = readableColor(bgColor); } return { bgColor, color: textColor, }; }

제가 코드를 해독해 보겠습니다.

셀 및 열에 액세스

열 지도를 적용해야 하는 셀에 액세스할 수 있습니다.

@ContentChildren(HeatmapCellDirective, { descendants: true }) heatMapCells: QueryList;

이 heatMapCell 변수에는 heatMapCell이 적용된 td 목록이 포함됩니다. { 하위 항목: true }을(를) 설정하십시오.

참고: 참이면 요소의 모든 하위 항목이 포함됩니다. 거짓인 경우 요소의 직접 하위 항목만 쿼리합니다.

각 열에 대한 옵션 저장

개체의 각 열에 대해 제공된 옵션을 저장할 수 있습니다. 현재는 색상만 구성 중이지만, 이 개체는 각 열에 대한 열 지도를 사용자 지정하기 위한 다양한 옵션에 사용할 수 있습니다.

config = { "employees": { "color": "#000fff" }, "contractors": { "color": "#309c39" } }

각 열에 대한 가장 높은 값 계산

이제 각 열에 대해 가장 높은 값을 계산하여 colId를 키로 하여 객체에 저장할 수 있습니다.

highestValues = { employees: 1239, contractors: 453 }

히트맵 스타일 적용

이제 세포를 순환시키고 배경색상과 색상을 세포에 적용할 수 있습니다. 셀에 ElementRef를 주입했으므로 el 속성을 사용하여 스타일을 수정할 수 있습니다.

cell.el.nativeElement.style.backgroundColor = 'blue';

위에 설명한 논리에 기초하여 각 셀의 색상을 찾는 도우미 함수를 가지고 있습니다.

private getColor(id: string, value: number) { const color = this.config[id].color; let textColor = null; let bgColor = null; if (color != null) { const [h, s, l, a] = parseToHsla(color); const maxLightness = 1 - l; const percentage = (value * maxLightness) / this.highestValues[id]; const lightness = +percentage.toFixed(3); bgColor = hsla(h, s, 1 - lightness, a); textColor = readableColor(bgColor); } return { bgColor, color: textColor, }; }

색상 조작은 색상을 혼동할 수 있는 많은 유틸리티를 제공하는 매우 단순한 라이브러리 색상2k를 사용하여 수행됩니다.

우리는 주어진 색상의 광도에 따라 최상의 대비를 위해 검은색 또는 흰색으로 반환되는 readibleColor()라는 것을 사용해 왔다. 이렇게 하면 히트맵에 더 쉽게 접근할 수 있습니다.

데모 및 코드

스택블리츠 링크

마지막 생각

보시다시피 구성 요소에 코드가 많지 않습니다. 모든 논리는 지침 안에서 훌륭하게 처리된다. 이 지침에서 유일하게 복잡한 것은 색을 찾는 것입니다. 다른 모든 것은 간단합니다.

이것은 매우 기본적인 구현이며 완벽하지도 않다. 이를 개선하기 위해 검증 및 오류 처리도 추가해야 할 수 있습니다. 또한 오름차순/내림차순 열 지도, 색상 범위, 양수 및 음수 열 지도 등과 같은 더 많은 옵션을 제공하여 이 기능을 확장할 수 있습니다.

블로그 게시물의 전체적인 아이디어는 이 기능을 구현하기 위해 지침이 어떻게 사용될 수 있는지 보여주는 것입니다.

나와 연결하세요.

트위터

깃헙

링크드인

Compito - 오픈 소스 프로젝트 관리 앱

피자 사줘

코멘트 섹션에 당신의 생각을 추가하세요.

안전 유지 ️

from http://every-issue.tistory.com/18 by ccl(A) rewrite - 2021-10-13 00:26:38