LWC에서 chart.js 사용하기

ahncheer·2023년 7월 18일
1

LWC & LWR

목록 보기
36/45

0. Static Resource에 Chart.js 업로드


Chart.js LWC로 미리 구현하신 분이 계셔서 이 분의 정적 자원을 다운받아 올렸습니다.

출처 : SFDC project with LWC and ChartJs example

1. HTML 작성

  <div class="chart" style="width: 1000px; height: 1000px;"></div>

2. JS 작성

import { LightningElement, track } from 'lwc';
import { loadScript } from 'lightning/platformResourceLoader';
import chartjs from '@salesforce/resourceUrl/chartJS';

export default class DePrdSoundPress extends LightningElement {
    @track chartValue;
    @track isFirstRender = true;
    async renderedCallback() {
        Promise.all([
            loadScript(this, chartjs)
        ]).then(async () => {
            if(this.isFirstRender) {
                console.log('loadScript 실행, chartjs : ', chartjs);
                const canvas = document.createElement('canvas');
                this.template.querySelector('div.chart').appendChild(canvas);
                const ctx = canvas.getContext('2d');
                this.chartValue = new Chart(ctx, this.setConfig());//this.config
                console.log('this.chartValue, ', this.chartValue);

                this.isFirstRender = false;
            }
            
        }).catch((error) => {
            console.log('errorMsg : ', error);
        });
    }
    setConfig() {
        console.log('setConfig');
        let config = {
            type: 'line',
            data: {
                labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
                datasets: [{
                    label: 'APAC RE Index',
                    backgroundColor: 'red',
                    borderColor: 'red',
                    fill: false,
                    data: [10, 20, 30, 40, 100, 50, 150 ],
                }, {
                    label: 'APAC PME',
                    backgroundColor: 'blue',
                    borderColor: 'blue',
                    fill: false,
                    data: [ 50, 300, 100, 450, 150, 200, 300 ],
                }]
            },
            options: {
                responsive: true,
                title: {
                    display: true,
                    text: 'Chart.js Line Chart - Logarithmic'
                },
                scales: {
                    xAxes: [{
                        display: true,
              scaleLabel: {
                display: true,
                labelString: 'Date'
              },
                
                }],
                    yAxes: [{
                        display: true,
                        //type: 'logarithmic',
              scaleLabel: {
                                display: true,
                                labelString: 'Index Returns'
                            },
                            ticks: {
                                min: 0,
                                max: 500,
    
                                // forces step size to be 5 units
                                stepSize: 100
                            }
                    }]
                }
            }
        };
        return config;
    }

}

3. 결과 확인

애니메이션과 기능(마우스 오버 시 라벨이 나오는 것)은 아래와 비슷합니다.
https://codepen.io/tejas-development/pen/RmyRWq

이 테스트는 LWR에서 진행했습니다.
앱 페이지 등에서는 시도해 보지 않아 실행이 되지 않을 수 있습니다.

+) 덤 -> 여러개 동시에 나열하기(설정이 같다는 전제 하에)

-- HTML 수정+추가

<div class="chart-area">
    <template if:true={chartNumList} for:each={chartNumList} for:item="item" for:index="index">
        <div class="chart-wrap" key={item}>
            <p>({item.index}) {item.name}</p>
            <div class="chart"></div>
        </div>
    </template>
</div>

-- JS 수정+추가


// renderedCallback에 아래 두개 넣기 
await this.createChartArea(5);
await this.createChart();

// setConfig가 List형식으로 들어오는 경우를 가정함
@track chartValue1;
@track chartValue2;
@track chartValue3;
@track chartValue4;
@track chartValue5;
@track chartNumList = [];

createChartArea(idx){
    let i = 0;
    let newList = [];
    do {
        i += 1;
        newList.push({index : i , name : 'Chart 이름 ' + i})
    } while (i < idx);
    this.chartNumList = newList;
    console.log('createChartArea End');
}
createChart(){
    console.log('this.chartNumList : ', this.chartNumList);
    let chartDivList = this.template.querySelectorAll('.chart');
    console.log('chartDivList : ', chartDivList);
    chartDivList.forEach((el, idx) => { 
        console.log('chartDiv : ', el);
        const canvas = document.createElement('canvas');
        el.appendChild(canvas);
        const ctx = canvas.getContext('2d');
        this['chartValue'+idx] = new Chart(ctx, this.setConfig());//this.config
    });
}

-- CSS

.chart-area {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 30px;
    max-width: 100%;
}
.chart-wrap {
    display: block;
    max-width: 100%;
}
profile
개인 공부 기록용.

2개의 댓글

comment-user-thumbnail
2023년 7월 18일

잘 읽었습니다. 좋은 정보 감사드립니다.

답글 달기
comment-user-thumbnail
2023년 7월 18일

글이 잘 정리되어 있네요. 감사합니다.

답글 달기