[]
SpreadJS는 워크시트에 수식이 포함된 기본 도형 및 사용자 정의 도형을 추가하여 도형 모델을 수정할 수 있도록 지원합니다.
이 기능을 사용하면 사용자가 스프레드시트, 다른 도형 또는 데이터 원본의 수식을 통해 속성이 평가되는 동적 도형을 생성할 수 있습니다. 이를 통해 도형 데이터를 이러한 수식과 바인딩할 수 있습니다.
아래는 이 기능이 특히 유용한 몇 가지 시나리오입니다:
사용자가 스프레드시트의 수식을 기반으로 동적으로 업데이트되는 순서도를 생성하고자 할 때
사용자가 동일한 직급의 직원에 대해 동일한 배경 도형을 유지하면서 회사 직원의 계층 차트를 관리하고자 할 때
사용자가 스프레드시트에서 값이 업데이트될 때마다 도형 내의 매출 수치를 업데이트하고자 할 때
수식이 포함된 도형을 추가하려면 다음 작업을 참조하시기 바랍니다:
사용자는 워크시트에 수식이 포함된 기본 도형을 추가할 수 있습니다. 아래는 기본 수식으로 생성된 도형의 예입니다.
아래의 코드 샘플은 워크시트에 수식이 포함된 기본 도형을 추가하는 방법을 보여줍니다.
//수식이 포함된 기본 도형 추가
window.onload = function ()
{
var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
var sheet = spread.getActiveSheet();
sheet.name("BuiltInShape");
sheet.setArray(0, 0, [
["x", 430], ["y", 25],
["width", 280], ["height", 160],
["angle", 0], ["background color and tranparency", "green", 0.5],
["border color and width", "blue", 0],
["shape text", "The demo text for built-in shape"],
["text font", "18px Georgia"],
["text color", "white"],
]);
sheet.setColumnWidth(0, 220);
sheet.setColumnWidth(1, 100);
sheet.setColumnWidth(2, 70);
sheet.setColumnWidth(3, 70);
sheet.setColumnWidth(4, 70);
sheet.setColumnWidth(5, 70);;
var shape1 = sheet.shapes.add("shape1",
GC.Spread.Sheets.Shapes.AutoShapeType.oval, 100, 50, 100, 150);
shape1.x("=BuiltInShape!B1");
shape1.y("=BuiltInShape!B2");
shape1.width("=BuiltInShape!B3");
shape1.height("=BuiltInShape!B4");
shape1.rotate("=BuiltInShape!B5");
shape1.text("=BuiltInShape!B8");
var shape1Style = shape1.style();
shape1Style.fill.color = "=BuiltInShape!B6";
shape1Style.fill.transparency = "=BuiltInShape!C6";
shape1Style.line.color = "=BuiltInShape!B7";
shape1Style.line.transparency = "=BuiltInShape!C7";
shape1Style.textEffect.font = "=BuiltInShape!B9";
shape1Style.textEffect.color = "=BuiltInShape!B10";
shape1.style(shape1Style);
};
사용자는 도형의 속성에 대해 정의된 수식뿐만 아니라 해당 속성에 대해 수식이 참조하는 값을 얻을 수 있습니다. 예를 들어 위 기본 도형에서 높이에 대한 수식은 =BuiltInShape!B4
로 정의되며, 해당 셀(B4)에는 160
이라는 값이 있습니다.
아래 코드 샘플은 getFormula 메서드를 사용하여 속성에 대한 수식을 가져오고 해당 속성의 값을 가져오는 방법을 보여줍니다.
// 활성 시트 가져오기
var activeSheet = spread.getSheet(0);
activeSheet.setArray(0, 0, [
["x", 10],
["y", 200],
["width", 300],
["height", 140],
["angle", 0],
["background color and tranparency", "red", 0.5],
["border color and width", "blue", 5],
["shape text", "The demo text for cloud shape"],
["text font", "15px Georgia"],
["text color", "Yellow"],
]);
var shape1 = activeSheet.shapes.add("shape1", GC.Spread.Sheets.Shapes.AutoShapeType.cloud, 50, 200, 100, 150);
var shapeStyle = shape1.style();
shapeStyle.fill.color = '=Sheet1!B6';
shape1.style(shapeStyle);
// setFormula() 메서드로 속성 설정
shape1.setFormula("x", "=Sheet1!B1");
shape1.setFormula("y", "=Sheet1!B2");
shape1.setFormula("width", "=Sheet1!B3");
shape1.setFormula("height", "=Sheet1!B4");
shape1.setFormula("rotate", "=Sheet1!B5");
shape1.setFormula("text", "=Sheet1!B8");
shape1.setFormula("style.fill.color", "=Sheet1!B6");
shape1.setFormula("style.fill.transparency", "=Sheet1!C6");
shape1.setFormula("style.line.color", "=Sheet1!B7");
shape1.setFormula("style.line.width", "=Sheet1!C7");
shape1.setFormula("style.textEffect.font", "=Sheet1!B9");
shape1.setFormula("style.textEffect.color", "=Sheet1!B10");
// getFormula() 메서드로 수식 가져오기
console.log("Formula for Width : " + shape1.getFormula("width"));
console.log("Formula for Height : " + shape1.getFormula("height"));
// 속성으로 값 확인
console.log("Value of Width: ", shape1.width());
console.log("Value of Height: ", shape1.height());
activeSheet.setColumnWidth(0, 280);
activeSheet.setColumnWidth(1, 100);
for (var i = 2; i < 8; i++)
activeSheet.setColumnWidth(i, 70);
사용자는 시트에 수식이 포함된 사용자 정의 도형을 추가할 수 있습니다. 아래 이미지는 사용자 정의 수식으로 생성된 도형 예시입니다.
아래의 코드 샘플은 시트에 수식이 포함된 도형을 추가하는 방법을 보여줍니다.
// 수식이 포함된 도형 추가
window.onload = function ()
{
var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
var sheet = spread.getActiveSheet();
sheet.name("CustomShape");
sheet.setArray(0, 0, [
["left", 480], ["top", 60], ["width", 400], ["height", 240],["angle"],
["background color and tranparency", "green", 0.5],
["border color and width", "blue", 0],
["shape text", "The demo text for custom shape"],
["text font", "15px Georgia"],
["text color", "red"],
["margins", 1, 2, 3, 4],
["horizontalAlignment", 1],
["verticalAlignment", 1],
["textDirection", "horizontal"],
["allowTextToOverflowShape", false],
["wrapTextInShape", true],
["line width", 3],
["line style", 5, "capType", 2, "joinType", 1],
["endPoints", 1, 1, 1, 5, 2, 2],
]);
sheet.setColumnWidth(0, 280);
sheet.setColumnWidth(1, 100);
sheet.setColumnWidth(2, 70);
sheet.setColumnWidth(3, 70);
sheet.setColumnWidth(4, 70);
sheet.setColumnWidth(5, 70);
sheet.setCellType(11, 1,
createComboCellType(GC.Spread.Sheets.HorizontalAlign, 2));
sheet.setCellType(12, 1, createComboCellType(GC.Spread.Sheets.VerticalAlign));
sheet.setCellType(17, 1,
createComboCellType(GC.Spread.Sheets.Shapes.PresetLineDashStyle));
sheet.setCellType(17, 3, createComboCellType(GC.Spread.Sheets.Shapes.LineCapStyle));
sheet.setCellType(17, 5,
createComboCellType(GC.Spread.Sheets.Shapes.LineJoinStyle));
sheet.setCellType(18, 1,
createComboCellType(GC.Spread.Sheets.Shapes.ArrowheadStyle));
sheet.setCellType(18, 4,
createComboCellType(GC.Spread.Sheets.Shapes.ArrowheadStyle));
sheet.setCellType(18, 2,
createComboCellType(GC.Spread.Sheets.Shapes.ArrowheadLength));
sheet.setCellType(18, 5,
createComboCellType(GC.Spread.Sheets.Shapes.ArrowheadLength));
sheet.setCellType(18, 3,
createComboCellType(GC.Spread.Sheets.Shapes.ArrowheadWidth));
sheet.setCellType(18, 6,
createComboCellType(GC.Spread.Sheets.Shapes.ArrowheadWidth));
sheet.setFormula(4, 1, "=ROW(CustomShape!B10)");
var model =
{
left: "=CustomShape!B1",
top: "=CustomShape!B2",
width: "=CustomShape!B3",
height: "=CustomShape!B4",
angle: "=CustomShape!B5",
options: {
endPoints: {
beginArrow:
{
type: "=CustomShape!B19", widthType:
"=CustomShape!C19", lengthType: "=CustomShape!D19"
},
endArrow: { type: "=CustomShape!E19", widthType:
"=CustomShape!F19", lengthType: "=CustomShape!G19" }
},
fill:
{
type: 1, // 단색 채우기 (현재는 단색 채우기만 지원)
color: "=CustomShape!B6",
transparency: "=CustomShape!C6"
},
stroke:
{
type: 1, // 단색 채우기 (현재는 단색 채우기만 지원)
color: "=CustomShape!B7",
transparency: "=CustomShape!C7",
width: "=CustomShape!B17",
lineStyle: "=CustomShape!B18",
capType: "=CustomShape!D18",
joinType: "=CustomShape!F18"
},
textFormatOptions:
{
text: "=CustomShape!B8", // "도형 텍스트",
font: "=CustomShape!B9", // "bold 15px Georgia
fill:
{
type: 1, // 단색 채우기 (현재는 단색 채우기만 지원)
color: "=CustomShape!B10"
},
margins:
{
left: "=CustomShape!B11",
top: "=CustomShape!C11",
right: "=CustomShape!D11",
bottom: "=CustomShape!E11"
},
verticalAlignment:
"=CustomShape!B13", // (0: top, 1: center, 2: bottom)
horizontalAlignment:
"=CustomShape!B12", // (0: left, 1: center, 2: right)
textDirection:
"=CustomShape!B14", //f "vertical", "rotate90", "rotate270"
allowTextToOverflowShape: "=CustomShape!B15",
wrapTextInShape: "=CustomShape!B16"
}
},
variables: {
xOffset: 40,
yOffset: 10
},
path: [[
["M", "=controls.0.x", 0], // M: 좌표 (x, y)으로 이동
["L", "=width - controls.0.x", 0], // L: 좌표 (x, y)까지 선을 그림
["L", "=width - 2 * variables.xOffset", "=height"], ["L", "=variables.xOffset", "=height"],
["Z"]
], // Z: 경로 닫기
[
["M", "=width - variables.xOffset", "=variables.yOffset"],
["L", "=width", "=variables.yOffset"],
["L", "=width", "=height - 4 * variables.yOffset"],
["L", "=width - variables.xOffset", "=height"]
]
],
controls: [
{
x: "=BOUND(0.3*width, 0, false, 0, 0.5*width)",// → 위치 및 범위 제한을 제공하기 위한 수식 사용 (여기서는 기본 위치가 (0, 너비의 0.2)이며, y 범위는 0부터 너비의 0.5까지)
y: 0,
xBehavior: 0, // x 방향으로 조정 시 0 (수평 방향), 그렇지 않으면 1
yBehavior: 1 // y 방향으로 조정 시 0 (수직 방향), 그렇지 않으면 1
}
],
connectionPoints: [
{
x: "=0.5*width",
y: 0
},
{
x: "=0.5*controls.0.x",
y: "=0.5*height"
},
{
x: "=0.5*width",
y: "=1*height"
},
{
x: "=width-0.5*controls.0.x",
y: "=0.5*height"
}
],
textRect:
{ left: "=controls.0.x", top: 20, bottom: "=height - 20",
right: "=width - variables.xOffset" }};
sheet.shapes.add('shape2', model);
};
function createComboCellType(enumType, max)
{
var combo = new GC.Spread.Sheets.CellTypes.ComboBox();
var items = [];
for (var name in enumType)
{
var value = enumType[name];
if (!max || value <= max)
{
items.push
({
text: name,
value: value
});
}
}
combo.items(items);
combo.editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.value);
return combo;
}
참고: Shape API 세트는 사용자 정의 옵션처럼 수식 또는 값을 모두 허용하지만, 항상 해당 속성의 값을 반환합니다. A1 스타일을 사용할 경우
sheetName!A10
형식의 범위 참조가 필요하며,ROW(Sheet1!B30)
과 같은 컨텍스트 의존 수식도 지원됩니다.
사용자는 도형의 속성에 대해 정의된 수식뿐만 아니라, 해당 수식이 참조하는 값을 가져올 수도 있습니다. 예를 들어, 위 사용자 정의 도형에서는 도형의 높이(height) 속성에 대한 수식이 "=CustomShape!B4"
로 정의되어 있으며, B4 셀에는 높이 값으로 240이 설정되어 있습니다.
다음 코드 샘플은 getFormula 메서드를 사용하여 사용자 정의 도형의 속성에 설정된 수식과 값을 가져오는 방법을 보여줍니다.
// 활성 시트를 가져옴
var activeSheet = spread.getSheet(0);
activeSheet.name("CustomShape");
// 데이터 설정
activeSheet.setArray(0, 0, [
["left", 480],
["top", 60],
["width", 300],
["height", 240],
["angle"],
["background color and tranparency", "green", 0.5],
["border color and width", "blue", 0],
["shape text", "The demo text for custom shape"],
["text font", "15px Georgia"],
["text color", "red"],
["margins", 1, 2, 3, 4],
["horizontalAlignment", 1],
["verticalAlignment", 1],
["textDirection", "horizontal"],
["allowTextToOverflowShape", false],
["wrapTextInShape", true],
["line width", 3],
["line style", 5, "capType", 2, "joinType", 1],
["endPoints", 1, 1, 1, 5, 2, 2],
]);
activeSheet.setFormula(4, 1, "=ROW(CustomShape!B10)");
var model = {
left: "=CustomShape!B1",
top: "=CustomShape!B2",
width: "=CustomShape!B3",
height: "=CustomShape!B4",
angle: "=CustomShape!B5",
options: {
endPoints: {
beginArrow: {
type: "=CustomShape!B19", widthType: "=CustomShape!C19", lengthType: "=CustomShape!D19"
},
endArrow: { type: "=CustomShape!E19", widthType: "=CustomShape!F19", lengthType: "=CustomShape!G19" }
},
fill: {
type: 1, // 단색 채우기 (현재는 단색 채우기만 지원)
color: "=CustomShape!B6",
transparency: "=CustomShape!C6"
},
stroke: {
type: 1, // 단색 채우기 (현재는 단색 채우기만 지원)
color: "=CustomShape!B7",
transparency: "=CustomShape!C7",
width: "=CustomShape!B17",
lineStyle: "=CustomShape!B18",
capType: "=CustomShape!D18",
joinType: "=CustomShape!F18"
},
textFormatOptions: {
text: "=CustomShape!B8", // "도형 텍스트",
font: "=CustomShape!B9", // "bold 15px Georgia", // CSS 글꼴 및 줌 관련 코드는 이를 지원하도록 업데이트되어야 합니다
fill: {
type: 1, // 단색 채우기 (현재는 단색 채우기만 지원)
color: "=CustomShape!B10"
},
margins: {
left: "=CustomShape!B11",
top: "=CustomShape!C11",
right: "=CustomShape!D11",
bottom: "=CustomShape!E11"
},
verticalAlignment: "=CustomShape!B13", // (0: top, 1: center, 2: bottom)
horizontalAlignment: "=CustomShape!B12", // (0: left, 1: center, 2: right)
textDirection: "=CustomShape!B14", //f "vertical", "rotate90", "rotate270"
allowTextToOverflowShape: "=CustomShape!B15",
wrapTextInShape: "=CustomShape!B16"
}
},
variables: {
xOffset: 40,
yOffset: 10
},
path: [[
["M", "=controls.0.x", 0], // M: 좌표 (x, y)으로 이동
["L", "=width - controls.0.x", 0], // L: 좌표 (x, y)까지 선을 그림
["L", "=width - 2 * variables.xOffset", "=height"], ["L", "=variables.xOffset", "=height"],
["Z"]], // Z: 경로 닫기
[
["M", "=width - variables.xOffset", "=variables.yOffset"],
["L", "=width", "=variables.yOffset"],
["L", "=width", "=height - 4 * variables.yOffset"],
["L", "=width - variables.xOffset", "=height"]
]
],
controls: [
{
// 포지션 및 범위 제한용 수식 사용 (기본 위치 (0, 0.3 * width), y 범위는 0 ~ 0.5 * width)
x: "=BOUND(0.3*width, 0, false, 0, 0.5*width)",
y: 0,
xBehavior: 0, // x 방향으로 조정 시 0 (수평 방향), 그렇지 않으면 1
yBehavior: 1 // y 방향으로 조정 시 0 (수직 방향), 그렇지 않으면 1
}
],
connectionPoints: [
{
x: "=0.5*width",
y: 0
},
{
x: "=0.5*controls.0.x",
y: "=0.5*height"
},
{
x: "=0.5*width",
y: "=1*height"
},
{
x: "=width-0.5*controls.0.x",
y: "=0.5*height"
}
],
textRect: { left: "=controls.0.x", top: 20, bottom: "=height - 20", right: "=width - variables.xOffset" }
};
var shape2 = activeSheet.shapes.add('shape2', model);
// getFormula() 메서드를 사용해 width와 height 속성에 지정된 수식 가져오기
console.log("Width's Formula is: " + shape2.getFormula("width"));
console.log("Height's Formula is: " + shape2.getFormula("height"));
// 속성 메서드를 사용해 실제 width와 height 값 가져오기
console.log("Width value ", shape2.width());
console.log("Height value ", shape2.height());
// 열 너비 설정
activeSheet.setColumnWidth(0, 210);
activeSheet.setColumnWidth(1, 60);
for (var i = 2; i < 6; i++) {
activeSheet.setColumnWidth(i, 50);
}