반응형
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 를 이용해서 외부 데이터를 직접 바인딩할 수 있어 좀 더 가볍게 쓸 수 있을 거 같네요
반응형
'프로그래밍 > spreadjs' 카테고리의 다른 글
| SpreadJS 데이터 유효성 검사 사용기 (0) | 2025.12.08 |
|---|---|
| SpreadJS AI 도우미 - 수식 해설과 생성을 동시에! (2) | 2025.08.11 |
| SpreadJS로 JSON 데이터 바인딩하기 (0) | 2025.06.13 |
| 웹 브라우저에서 Excel 파일 내보내기 및 불러오기 - SpreadJS (1) | 2025.06.08 |
| 웹 브라우저에서 엑셀? 구현하기 - SpreadJS (0) | 2025.05.25 |