도리쓰에러쓰

[TIL] 프리온보딩 23일차 - 220525 본문

Project/원티드 프리온보딩 프론트엔드 코스

[TIL] 프리온보딩 23일차 - 220525

강도리 2022. 5. 26. 22:08

오늘은 매드업 과제 제출 날이다.

 

우선 데이터가 있는 JSON 파일을 차트에 맞게 데이터 가공하는게 어려웠다.

차트에 맞게 데이터 가공한 방법은 아래와 같다.

 

1️⃣ lodash 라이브러리를 통해 'channel' (페이스북, 구글, 네이버, 카카오) 별로 데이터 그룹화

const groupByData = groupBy(data, 'channel')

 

2️⃣ 선택한 날짜에 포함된 데이터를 더하여 데이터 가공

COMPANIES.forEach((company) => {
    groupByData[company].forEach((v) => {
        const selectDate = new Date(v.date)
        const startDate = new Date(recoilDate.startDate)
        const endDate = new Date(recoilDate.endDate)
        const target = filterData[company]

        if (startDate <= selectDate && selectDate <= endDate) {
            target.click = new BigNumber(target.click).plus(v.click).toNumber()
            target.convValue = new BigNumber(target.convValue).plus(v.convValue).toNumber()
            target.cost = new BigNumber(target.cost).plus(v.cost).toNumber()
            target.cpa = new BigNumber(target.cpa).plus(v.cpa).toNumber()
            target.cpc = new BigNumber(target.cpc).plus(v.cpc).toNumber()
            target.ctr = new BigNumber(target.ctr).plus(v.ctr).toNumber()
            target.imp = new BigNumber(target.imp).plus(v.imp).toNumber()
            target.roas = new BigNumber(target.roas).plus(v.roas).toNumber()
        }
    })
})

 

3️⃣ 차트에 필요한 데이터를 카테고리 별로 더하여 백분율로 데이터 가공

COMPANIES.forEach((company) => {
    const target = filterData[company]
    const sales = new BigNumber(target.roas).multipliedBy(target.cost).div(100).toNumber()
    const conv = new BigNumber(target.click).multipliedBy(target.roas).toNumber()

    sum.costSum = new BigNumber(sum.costSum).plus(target.cost).toNumber()
    sum.salesSum = Math.floor(new BigNumber(sum.salesSum).plus(sales).toNumber())
    sum.impSum = new BigNumber(sum.impSum).plus(target.imp).toNumber()
    sum.clickSum = new BigNumber(sum.clickSum).plus(target.click).toNumber()
    sum.convSum = Math.floor(new BigNumber(sum.convSum).plus(conv).toNumber())
 })
    
 COMPANIES.forEach((company) => {
    const target = filterData[company]
    const sales = new BigNumber(target.roas).multipliedBy(target.cost).div(100).toNumber()
    const conv = new BigNumber(target.click).multipliedBy(target.roas).toNumber()

    const costPercentage = Math.floor((target.cost * 100) / sum.costSum)
    const salesPercentage = Math.floor((sales * 100) / sum.salesSum)
    const impPercentage = Math.floor((target.imp * 100) / sum.impSum)
    const clickPercentage = Math.floor((target.click * 100) / sum.clickSum)
    const convPercentage = Math.floor((conv * 100) / sum.convSum)

    chartData.push([
      { category: CATEGORYS[0], value: costPercentage },
      { category: CATEGORYS[1], value: salesPercentage },
      { category: CATEGORYS[2], value: impPercentage },
      { category: CATEGORYS[3], value: clickPercentage },
      { category: CATEGORYS[4], value: convPercentage },
    ])
 })

 

4️⃣ Victory.js 라이브러리 이용하여 해당 데이터를 차트로 표현

<VictoryChart
  width={1000}
  domainPadding={{ x: 90, y: 10 }}
  theme={VictoryTheme.material}
  animate={{
    duration: 1000,
    onLoad: { duration: 1000 },
    easing: 'linear',
  }}
>
  <VictoryLegend
    x={620}
    y={333}
    orientation='horizontal'
    gutter={50}
    style={{ labels: { fill: CHART_STYLE.grayColor } }}
    colorScale={[...CHART_STYLE.colorscale]}
    data={[{ name: '네이버' }, { name: '카카오' }, { name: '구글' }, { name: '페이스북' }]}
  />
  <VictoryAxis
    tickFormat={CATEGORYS}
    style={{ axis: { stroke: '#EDEFF1' }, tickLabels: { fill: CHART_STYLE.grayColor } }}
  />
  <VictoryAxis
    dependentAxis
    tickFormat={(x) => `${x}%`}
    tickLabelComponent={<VictoryLabel dy={15} textAnchor='start' />}
    style={{ axis: { stroke: 'none' }, tickLabels: { fill: CHART_STYLE.grayColor, fontWeight: 'bold' } }}
   />
   <VictoryStack
     colorScale={[...CHART_STYLE.colorscale]}
     labels={[
       numberToDot({ num: sum.costSum }),
       numberToDot({ num: sum.salesSum }),
       numberToDot({ num: sum.impSum }),
       numberToDot({ num: sum.clickSum }),
       numberToDot({ num: sum.convSum }),
     ]}
     labelComponent={
       <VictoryTooltip
         style={{ fontSize: 14, fill: '#ffffff' }}
         renderInPortal
         flyoutStyle={{
           stroke: 'none',
           fill: '#3A474E',
         }}
         cornerRadius={5}
         flyoutPadding={{
           left: 25,
           right: 25,
           top: 10,
           bottom: 10,
          }}
          pointerLength={5}
          dy={-15}
        />
      }
    >
    <VictoryBar data={chartData[3]} {...CHART_STYLE.bar} />
    <VictoryBar data={chartData[2]} {...CHART_STYLE.bar} />
    <VictoryBar data={chartData[1]} {...CHART_STYLE.bar} />
    <VictoryBar data={chartData[0]} {...CHART_STYLE.bar} cornerRadius={{ top: 8 }} />
  </VictoryStack>
</VictoryChart>

 

🔽 결과 화면

 

Comments