프로그래밍/spreadjs

엑셀 차트 그려보기 (DataCharts) - SpreadJS

benscript 2025. 6. 22. 15:54
반응형

JSON 기반 데이터에 차트를 얹어야 할 일이 생겨서  SpreadJS의 DataChart 기능을 써봤습니다.  
기본 차트 기능도 있긴 한데  데이터관리자(Data Manager) 기반이라  “데이터만 연결하면 차트가 바로 그려진다”는 느낌이에요.

 


 

✅ DataChart가 뭐야?

- 일반 차트보다 유연하게 데이터를 Dynamic하게 시각화할 수 있는 기능
- DataManager에 직접 연결돼, JSON 업데이트를 반영함  
- 엑셀처럼 시트 내부 범위 기반이 아니라, 데이터 모델에 붙는 방식

📌 단점: 이 기능을 쓰려면 DataCharts 플러그이 필요하고, Excel 내보내기 하면 이미지로 저장됨

 

기본 코드

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link
      href="./css/gc.spread.sheets.excel2016colorful.18.0.6.css"
      rel="stylesheet"
    />
  </head>
  <body>
    <div id="ss" style="width: 100%; height: 600px"></div>

    <script
      src="./scripts/gc.spread.sheets.all.18.0.6.min.js"
      type="text/javascript"
    ></script>
    <script
      src=".scripts/plugins/gc.spread.sheets.shapes.18.0.6.min.js"
      type="text/javascript"
    ></script>
    <script
      src="./scripts/plugins/gc.spread.sheets.datacharts.18.0.6.min.js"
      type="text/javascript"
    ></script>
     <script
      src="./scripts/resources/ko/gc.spread.sheets.resources.ko.18.0.6.min.js"
      type="text/javascript"
    ></script>
    <script>
      window.onload = async function () {
        let spread = new GC.Spread.Sheets.Workbook("ss");
        const sheet = spread.getActiveSheet();

        const dataManager = spread.dataManager();

        const salesTable = createSalesTable(dataManager);
        await salesTable.fetch();

        const dataChart = sheet.dataCharts.add("data-chart", 10, 10, 600, 400);
        dataChart.setChartConfig({
          tableName: "Sales",
          config: {
            header: {
              title: "Bar Chart",
            },
          },
          plots: [
            {
              type: GC.Spread.Sheets.DataCharts.DataChartType.bar,
              encodings: {
                values: [
                  {
                    field: "Sales",
                    aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum,
                  },
                ],
                category: {
                  field: "Product",
                },
                color: {
                  field: "Product",
                },
              },
            },
          ],
        });
      };

      function createSalesTable(dataManager) {
        const records = [
          ["2021", "East", "SunLin", "Drinks", "Apple Juice", 140, 9],
          ["2021", "East", "JinShiPeng", "Drinks", "Apple Juice", 290, 17],
          ["2021", "East", "ZhangShang", "Drinks", "Apple Juice", 300, 28],
          ["2021", "East", "SunYang", "Drinks", "Apple Juice", 120, 10],
          ["2021", "East", "YuanChengJie", "Drinks", "Apple Juice", 220, 15],
          ["2021", "North", "ZhangYing", "Drinks", "Apple Juice", 250.0, 23],
          ["2021", "North", "WangWei", "Drinks", "Apple Juice", 180.0, 17],
          ["2021", "North", "ZhangWu", "Drinks", "Apple Juice", 233.0, 23],
          ["2021", "North", "HanWen", "Drinks", "Apple Juice", 123.0, 12],
          ["2021", "East", "SunLin", "Drinks", "Milk", 431.0, 38],
          ["2021", "East", "JinShiPeng", "Drinks", "Milk", 635.0, 56],
          ["2021", "East", "ZhangShang", "Drinks", "Milk", 324.0, 33],
          ["2021", "East", "SunYang", "Drinks", "Milk", 644.0, 68],
          ["2021", "East", "YuanChengJie", "Drinks", "Milk", 343.0, 19],
          ["2021", "North", "ZhangYing", "Drinks", "Milk", 234.0, 13],
          ["2021", "North", "WangWei", "Drinks", "Milk", 666.0, 39],
          ["2021", "North", "ZhangWu", "Drinks", "Milk", 700.0, 77],
          ["2021", "North", "HanWen", "Drinks", "Milk", 111.0, 8],
          ["2021", "East", "SunLin", "Drinks", "Orange Juice", 176.0, 18],
          ["2021", "East", "JinShiPeng", "Drinks", "Orange Juice", 500.0, 20],
          ["2021", "East", "ZhangShang", "Drinks", "Orange Juice", 340.0, 19],
          ["2021", "East", "SunYang", "Drinks", "Orange Juice", 540.0, 45],
          ["2021", "East", "YuanChengJie", "Drinks", "Orange Juice", 563.0, 56],
          ["2021", "North", "ZhangYing", "Drinks", "Orange Juice", 300.0, 19],
          ["2021", "North", "WangWei", "Drinks", "Orange Juice", 490.0, 44],
          ["2021", "North", "ZhangWu", "Drinks", "Orange Juice", 233.0, 25],
          ["2021", "North", "HanWen", "Drinks", "Orange Juice", 760.0, 78],
          ["2021", "East", "SunLin", "Dessert", "Chocolate", 333.0, 32],
          ["2021", "East", "JinShiPeng", "Dessert", "Chocolate", 420.0, 46],
          ["2021", "East", "ZhangShang", "Dessert", "Chocolate", 318.0, 37],
          ["2021", "East", "SunYang", "Dessert", "Chocolate", 256.0, 21],
          ["2021", "East", "YuanChengJie", "Dessert", "Chocolate", 583.0, 54],
          ["2021", "North", "ZhangYing", "Dessert", "Chocolate", 352.0, 33],
          ["2021", "North", "WangWei", "Dessert", "Chocolate", 384.0, 39],
          ["2021", "North", "ZhangWu", "Dessert", "Chocolate", 435.0, 42],
          ["2021", "North", "HanWen", "Dessert", "Chocolate", 356.0, 36],
          ["2021", "East", "SunLin", "Dessert", "Beef Jerky", 789.0, 73],
          ["2021", "East", "JinShiPeng", "Dessert", "Beef Jerky", 156.0, 14],
          ["2021", "East", "ZhangShang", "Dessert", "Beef Jerky", 289.0, 23],
          ["2021", "East", "SunYang", "Dessert", "Beef Jerky", 562.0, 45],
          ["2021", "East", "YuanChengJie", "Dessert", "Beef Jerky", 546.0, 56],
          ["2021", "North", "ZhangYing", "Dessert", "Beef Jerky", 218.0, 17],
          ["2021", "North", "WangWei", "Dessert", "Beef Jerky", 541.0, 56],
          ["2021", "North", "ZhangWu", "Dessert", "Beef Jerky", 219.0, 21],
          ["2021", "North", "HanWen", "Dessert", "Beef Jerky", 345.0, 21],
        ];
        const columns = [
          "Year",
          "Region",
          "Salesman",
          "ProductCategory",
          "Product",
          "Sales",
          "Return",
        ];
        return dataManager.addTable("Sales", {
          data: records.map((x) => {
            const record = {};
            columns.forEach((c, i) => (record[c] = x[i]));
            return record;
          }),
        });
      }
    </script>
  </body>
</html>

 

결과 이미지는 위와 같습니다

 

직접 써보니  dataManager 를 이용해서 외부 데이터를 직접 바인딩할 수 있어 좀 더 가볍게 쓸 수 있을 거 같네요

반응형